jiangping
2024-09-24 6a2689a44840490a64cf66b37eb09e45eb1da244
Merge remote-tracking branch 'origin/master'
已添加3个文件
已修改36个文件
2463 ■■■■■ 文件已修改
admin/.env.development 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/meeting/bookings.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/platform/index.js 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaPlatformWindow.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/meeting/bookings.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/LogisticsRecord/leaveAuth.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/LogisticsRecord/operation.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/LogisticsRecord/waybill.vue 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/components/PlatformQueuing.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/components/PlatformSign.vue 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/platform.vue 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/queueUp.vue 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/manifest.json 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/driver/login.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/driver/reservedRecord.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/driver/taskDetail.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/staff/task/driver.vue 346 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/staff/task/visitorApprove.vue 1135 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/staffLogin/login.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pda/manifest.json 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pda/pages.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pda/pages/index/control.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pda/pages/index/index.vue 105 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pda/pages/index/login.vue 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pda/static/back.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pda/utils/config.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/meeting/meeting_service/src/main/java/com/doumee/service/business/impl/BookingsServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/meeting/meeting_service/src/main/java/com/doumee/service/business/impl/RoomsServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/PlatformJobCloudController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/openapi/HkOpenApiController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Platform.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/PlatformJob.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/openapi/response/PlatformStatusListResponse.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/openapi/response/PlatformWarnEventListResponse.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/web/reqeust/SignInDTO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/PlatformService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/PlatformJobServiceImpl.java 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/PlatformServiceImpl.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/.env.development
@@ -2,5 +2,6 @@
NODE_ENV = 'development'
VUE_APP_API_URL  = 'http://localhost:10010'
VUE_APP_API_URL  = 'http://192.168.137.1:10010'
VUE_APP_API_URL  = 'http://192.168.0.103:10010'
# VUE_APP_API_URL  = 'http://10.50.250.178:8088/gateway_interface'
s
admin/src/api/meeting/bookings.js
@@ -31,6 +31,10 @@
export function startById(data) {
  return request.post('/meetingAdmin/cloudService/business/meeting/start', data)
}
// ç»“束
export function meetingEndById(data) {
  return request.post('/meetingAdmin/cloudService/business/meeting/reservationOver', data)
}
// æå‰å¼€å§‹
export function startEarlyById(data) {
  return request.post('/meetingAdmin/cloudService/business/meeting/startEarly', data)
admin/src/api/platform/index.js
@@ -1,108 +1,112 @@
import request from '@/utils/request'
// èŽ·å–æœˆå°ç»„ä¿¡æ¯
export function getPlatformGroupList (data) {
export function getPlatformGroupList(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/getPlatformGroupList', data)
}
// å«å·åˆ—表
export function platformCallList (data) {
export function platformCallList(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/platformCallList', data)
}
// å«å·
export function platformCallNumber (data) {
export function platformCallNumber(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/platformCallNumber', data)
}
// å¼€å§‹ä½œä¸š
export function platformBeginWork (data) {
export function platformBeginWork(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/beginWork', data)
}
// å®Œæˆä½œä¸š
export function platformFinishWork (data) {
export function platformFinishWork(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/finishWork', data)
}
// è¿‡å·
export function platformOverNumber (data) {
export function platformOverNumber(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/platformOverNumber', data)
}
// å¼‚常挂起
export function platformErr (data) {
export function platformErr(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/platformErr', data)
}
// å¼‚常挂起
export function platformMove (data) {
export function platformMove(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/platformMove', data)
}
// æœˆå°é…ç½®
export function updUserPlatformConfig (data) {
export function updUserPlatformConfig(data) {
  return request.get('/visitsAdmin/cloudService/business/platform/updUserPlatformConfig?ids=' + data)
}
// æ ¹æ®æœˆå°ç»„获取月台列表信息
export function listByGroupId (id) {
export function listByGroupId(id) {
  return request.get('/visitsAdmin/cloudService/business/platform/listByGroupId?groupId=' + id)
}
// æœˆå°åˆ—表 ç¼–辑
export function PlatformEdit (data) {
export function PlatformEdit(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/updateById', data, {
    trim: true
  })
}
// æœˆå°åˆ—表 åˆ é™¤
export function PlatformDel (id) {
export function PlatformDel(id) {
  return request.get('/visitsAdmin/cloudService/business/platform/delete/' + id, {
    trim: true
  })
}
// æœˆå°è°ƒåº¦ä¸­å¿ƒ åˆ—表
export function getPlatformJob (data) {
export function getPlatformJob(data) {
  return request.post('/visitsAdmin/cloudService/business/platformJob/page', data, {
    trim: true
  })
}
// è½¦è¾†æŽ’队情况
export function platformLineUpPage (data) {
export function platformLineUpPage(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/platformLineUpPage', data, {
    trim: true
  })
}
// å…¥å›­åŽŸå› 
export function platformReasonList () {
export function platformReasonList() {
  return request.get('/visitsAdmin/cloudService/business/platformBooks/platformReasonList')
}
// ç‰©æµè½¦é¢„约
export function platformBooksApply (data) {
export function platformBooksApply(data) {
  return request.post('/visitsAdmin/cloudService/business/platformBooks/apply', data)
}
// èŽ·å–æœˆå°ç»„ ç­‰å¾…与异常挂起数据
export function getPlatformGroupWork (id) {
export function getPlatformGroupWork(id) {
  return request.get('/visitsAdmin/cloudService/business/platform/getPlatformGroupWork?platformGroupId=' + id)
}
// æœˆå°å…¥å›­é¢„约 åˆ†é¡µåˆ—表
export function platformBooksPage (data) {
export function platformBooksPage(data) {
  return request.post('/visitsAdmin/cloudService/business/platformBooks/page', data)
}
// æœˆå°å…¥å›­é¢„约 åˆ—表导出
export function platformBooksExport (data) {
export function platformBooksExport(data) {
  return request.post('/visitsAdmin/cloudService/business/platformBooks/exportExcel', data, {
    trim: true,
    download: true
  })
}
// æœˆå°è°ƒåº¦ä½œä¸šä»»åŠ¡ åˆ†é¡µåˆ—表
export function platformJobPage (data) {
export function platformJobPage(data) {
  return request.post('/visitsAdmin/cloudService/business/platformJob/page', data)
}
// æœˆå°è°ƒåº¦ä½œä¸šä»»åŠ¡ åˆ é™¤
export function platformJobDel (id) {
export function platformJobDel(id) {
  return request.get('/visitsAdmin/cloudService/business/platformJob/delete?id=' + id)
}
// æœˆå°è°ƒåº¦ä½œä¸šä»»åŠ¡ ç­¾åˆ°
export function platformJobSign(data) {
  return request.post('/visitsAdmin/cloudService/business/platformJob/signIn', data)
}
// æœˆå°è°ƒåº¦ä½œä¸šä»»åŠ¡ ç¦»å›­æŽˆæƒ
export function platformPowerLevel (data) {
export function platformPowerLevel(data) {
  return request.post('/visitsAdmin/cloudService/business/platform/powerLevel', data)
}
// æœˆå°è°ƒåº¦ä½œä¸šä»»åŠ¡ åˆ—表导出
export function platformJobExport (data) {
export function platformJobExport(data) {
  return request.post('/visitsAdmin/cloudService/business/platformJob/exportExcel', data, {
    trim: true,
    download: true
admin/src/components/business/OperaPlatformWindow.vue
@@ -1,60 +1,42 @@
<template>
  <GlobalWindow
    :title="title"
    width="50%"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
  >
  <GlobalWindow :title="title" width="50%" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm">
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="月台名称:"  >
       <span>{{form.name}}</span>
      <el-form-item label="月台名称:">
        <span>{{ form.name }}</span>
      </el-form-item>
      <el-form-item label="月台编码:" prop="code">
        <el-input v-model="form.code" placeholder="请输入月台编码" v-trim/>
       <span class="tip-warn"><i class="el-icon-warning"></i>说明:对应WMS系统中的编码</span>
        <el-input v-model="form.code" placeholder="请输入月台编码" v-trim />
        <span class="tip-warn"><i class="el-icon-warning"></i>说明:对应WMS系统中的编码</span>
      </el-form-item>
      <el-form-item label="所属月台分组:" prop="groupId">
        <el-select v-model="form.groupId"  >
          <el-option
              v-for="item in groupList"
              :key="item.id"
              :label="item.name"
              :value="item.id">
        <el-select v-model="form.groupId">
          <el-option v-for="item in groupList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="广播设备:" prop="broadcastIds">
        <el-select v-model="form.broadcastIds" multiple >
          <el-option
              v-for="item in broadcastList"
              :key="item.id"
              :label="item.name"
              :value="item.id">
        <el-select v-model="form.broadcastIds" multiple>
          <el-option v-for="item in broadcastList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="LED设备:" prop="ledIds">
        <el-select v-model="form.ledIds" multiple >
          <el-option
              v-for="item in ledList"
              :key="item.id"
              :label="item.name"
              :value="item.id">
        <el-select v-model="form.ledIds" multiple>
          <el-option v-for="item in ledList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="同时作业数量:" prop="workingNum" >
        <el-input type="number" v-model="form.workingNum" placeholder="请输入同时作业数量" v-trim/>
      <el-form-item label="同时作业数量:" prop="workingNum">
        <el-input type="number" v-model="form.workingNum" placeholder="请输入同时作业数量" v-trim />
      </el-form-item>
      <el-form-item label="月台作业效率(万只/小时):" prop="workRate">
        <el-input type="number"  v-model="form.workRate" placeholder="请输入月台作业效率(万只/小时)" v-trim/>
        <el-input type="number" v-model="form.workRate" placeholder="请输入月台作业效率(万只/小时)" v-trim />
      </el-form-item>
      <el-form-item label="作业超时报警时间(分钟):" prop="workTimeoutAlarmTime">
        <el-input type="number"  v-model="form.workTimeoutAlarmTime" placeholder="请输入作业超时报警时间(分钟)" v-trim/>
        <el-input type="number" v-model="form.workTimeoutAlarmTime" placeholder="请输入作业超时报警时间(分钟)" v-trim />
      </el-form-item>
      <el-form-item label="停留超时报警时间(分钟):" prop="stayTmeoutAlarmTime">
        <el-input type="number"  v-model="form.stayTmeoutAlarmTime" placeholder="请输入停留超时报警时间(分钟)" v-trim/>
      <el-form-item label="停留超时报警时间(分钟):" prop="stayTimeoutAlarmTime">
        <el-input type="number" v-model="form.stayTimeoutAlarmTime" placeholder="请输入停留超时报警时间(分钟)" v-trim />
      </el-form-item>
    </el-form>
  </GlobalWindow>
@@ -70,7 +52,7 @@
  name: 'OperaPlatformWindow',
  extends: BaseOpera,
  components: { GlobalWindow },
  data () {
  data() {
    return {
      // è¡¨å•数据
      groupList: [],
@@ -86,7 +68,7 @@
        endTime: '',
        workingNum: 1,
        workRate: '',
        stayTmeoutAlarmTime: '',
        stayTimeoutAlarmTime: '',
        workTimeoutAlarmTime: '',
      },
      // éªŒè¯è§„则
@@ -95,7 +77,7 @@
      }
    }
  },
  created () {
  created() {
    this.config({
      api: '/platform/platform',
      'field.id': 'id'
@@ -107,7 +89,7 @@
     * @title çª—口标题
     * @target ç¼–辑的对象
     */
    open (title, target) {
    open(title, target) {
      this.title = title
      this.visible = true
      this.loadGroupList()
@@ -130,19 +112,19 @@
        this.form.workingNum = this.form.workingNum || 1
      })
    },
    loadGroupList () {
    loadGroupList() {
      allList({})
        .then(res => {
          this.groupList = res || []
        })
    },
    loadLedList () {
    loadLedList() {
      deviceList({ type: 2 })
        .then(res => {
          this.ledList = res || []
        })
    },
    loadBroadcastList () {
    loadBroadcastList() {
      deviceList({ type: 3 })
        .then(res => {
          this.broadcastList = res || []
@@ -152,7 +134,7 @@
}
</script>
<style scoped>
.labelTip{
.labelTip {
  font-size: 12px;
  color: #666666;
}
admin/src/views/meeting/bookings.vue
@@ -98,7 +98,7 @@
            'business:bookings:update',
            'business:bookings:delete',
          ])
        " label="操作" min-width="100" align="center" fixed="right">
        " label="操作" min-width="140" align="center" fixed="right">
          <template slot-scope="{ row }">
            <template>
              <el-button type="text" @click="$refs.operaBookingsDetailWindow.open('会议详情', row)">查看详情</el-button>
@@ -106,6 +106,7 @@
                @click="$refs.operaBookingsWindow.open('编辑会议预约', row)"
                v-permissions="['business:bookings:update']">编辑</el-button>
              <el-button type="text" v-if="row.meetingStatus == '1'" @click="handleStart(row)">开始</el-button>
              <el-button type="text" v-if="row.meetingStatus == '2'" @click="handleEnd(row)">结束</el-button>
              <el-button v-if="row.meetingStatus == '1'" type="text" @click="cancelMeeting(row.id)"
                v-permissions="['business:bookings:update']">撤回</el-button>
            </template>
@@ -132,7 +133,7 @@
import { findList } from '@/api/meeting/rooms'
import { getSystemDictData } from '@/api/system/dictData'
import { fetchList } from '@/api/business/company'
import { cancelById, bookingsDetail, startEarlyById, startById } from '@/api/meeting/bookings'
import { cancelById, bookingsDetail, startEarlyById, startById, meetingEndById } from '@/api/meeting/bookings'
import { timeForMat } from '@/utils/util'
export default {
  name: 'Bookings',
@@ -276,6 +277,18 @@
            })
        })
    },
    handleEnd(row) {
      this.$dialog.messageWaring('结束会议', '是否结束当前会议?')
        .then(() => {
          meetingEndById({ id: row.id })
            .then(() => {
              this.$message.success('会议已结束')
              this.handlePageChange()
            })
            .catch(e => {
            })
        })
    },
    cancelMeeting(id) {
      this.$dialog.messageWaring('取消会议', '是否取消当前会议?')
        .then(() => {
admin/src/views/platform/LogisticsRecord/leaveAuth.vue
@@ -16,7 +16,7 @@
    </div>
    <el-table class="mb20" v-loading="loading" :data="list" stripe>
      <el-table-column type="index" label="序号" width="70" show-overflow-tooltip />
      <el-table-column prop="code" label="运单号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="billCode" label="运单号" min-width="100" show-overflow-tooltip />
      <!-- <el-table-column prop="totalNum" label="总作业量(万支)" min-width="100" show-overflow-tooltip /> -->
      <el-table-column prop="carCodeFront" label="车牌号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="carCodeBack" label="电子锁状态" min-width="100" show-overflow-tooltip>
admin/src/views/platform/LogisticsRecord/operation.vue
@@ -17,7 +17,7 @@
      <el-button :loading="exLoading" @click="handleEx" v-permissions="['business:platformjob:exportExcel']">导出</el-button>
    </div>
    <el-table class="mb20" v-loading="loading" :data="list" stripe>
      <el-table-column prop="code" label="运单号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="billCode" label="运单号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="totalNum" label="总作业量(万支)" min-width="100" show-overflow-tooltip />
      <el-table-column prop="carCodeFront" label="车牌前照号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="carCodeBack" label="车牌后照号" min-width="100" show-overflow-tooltip />
@@ -31,7 +31,7 @@
      <el-table-column prop="startDate" label="作业开始时间" min-width="150" show-overflow-tooltip />
      <el-table-column prop="doneDate" label="作业完成时间" min-width="150" show-overflow-tooltip />
      <el-table-column prop="workTime" label="作业时长" min-width="100" show-overflow-tooltip />
      <el-table-column prop="platformName" label="叫号月台" min-width="100" show-overflow-tooltip />
      <el-table-column prop="platformNames" label="叫号月台" min-width="100" show-overflow-tooltip />
      <el-table-column label="作业情况" fixed="right" min-width="100" show-overflow-tooltip>
        <template v-slot="scope">
          <span>{{ statusMap[scope.row.status] }}</span>
admin/src/views/platform/LogisticsRecord/waybill.vue
@@ -1,12 +1,9 @@
<template>
  <div class="main_app">
    <QueryForm v-model="filters" :query-form-config="queryFormConfig" @changeForm='changeForm' @handleQuery="getList(1)" @clear="clear">
    <QueryForm v-model="filters" :query-form-config="queryFormConfig" @changeForm='changeForm' @handleQuery="getList(1)"
      @clear="clear">
      <template #fastdate>
        <el-radio-group
          v-model="filters.fastdate"
          size="small"
          @input="changeRadio"
        >
        <el-radio-group v-model="filters.fastdate" size="small" @input="changeRadio">
          <el-radio-button label="0">当天</el-radio-button>
          <el-radio-button label="6">近7天</el-radio-button>
          <el-radio-button label="29">近30天</el-radio-button>
@@ -14,10 +11,11 @@
      </template>
    </QueryForm>
    <div class="pt16">
      <el-button :loading="exLoading" @click="handleEx" v-permissions="['business:platformJob:exportExcel']">导出</el-button>
      <el-button :loading="exLoading" @click="handleEx"
        v-permissions="['business:platformjob:exportExcel']">导出</el-button>
    </div>
    <el-table class="mb20" v-loading="loading" :data="list" stripe>
      <el-table-column prop="code" label="运单号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="billCode" label="运单号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="carCodeFront" label="车牌前照号" min-width="100" show-overflow-tooltip />
      <!-- <el-table-column prop="carCodeBack" label="车牌后照号" min-width="100" show-overflow-tooltip /> -->
      <el-table-column prop="taskOrigin" label="任务来源" min-width="100" show-overflow-tooltip />
@@ -41,9 +39,9 @@
      </el-table-column>
      <el-table-column prop="name" label="操作" min-width="120" align="center" fixed="right" show-overflow-tooltip>
        <template v-slot="scope">
          <el-button v-if="scope.row.status == 12" type="text" class="red" v-permissions="['business:platformJob:delete']"
          <el-button type="text" class="red" v-permissions="['business:platformjob:delete']"
            @click="handleDel(scope.row)">删除</el-button>
          <el-button type="text" v-permissions="['business:platformJob:query']"
          <el-button type="text" v-permissions="['business:platformjob:query']"
            @click="handleDetail(scope.row)">预约详情</el-button>
        </template>
      </el-table-column>
@@ -58,7 +56,7 @@
<script>
import Pagination from '@/components/common/Pagination'
import QueryForm from '@/components/common/QueryForm'
import { platformJobPage,  platformJobExport,platformJobDel } from '@/api'
import { platformJobPage, platformJobExport, platformJobDel } from '@/api'
import { statusMap } from '../config'
import DriverDetail from "@/views/task/driverDetail"
import GlobalWindow from '@/components/common/GlobalWindow'
@@ -91,7 +89,7 @@
      list: [],
      queryFormConfig: {
        formItems: [
        {
          {
            filed: 'code',
            type: 'input',
            label: '运单号'
@@ -127,12 +125,12 @@
    this.getList()
  },
  methods: {
    changeRadio (day) {
    changeRadio(day) {
      const arr = [dayjs().subtract(day, 'day').format('YYYY-MM-DD') + ' 00:00:00', dayjs().format('YYYY-MM-DD') + ' 23:59:59']
      this.$set(this.filters, 'selDate', arr)
      this.getList()
    },
    changeForm (str) {
    changeForm(str) {
      if (str === 'selDate') {
        this.$set(this.filters, 'fastdate', null)
        this.getList()
admin/src/views/platform/components/PlatformQueuing.vue
@@ -1,6 +1,6 @@
<template>
  <GlobalWindow
    title="月台叫号-xx号月台"
    :title="'月台叫号-'+title"
    :visible.sync="isShowModal"
    :showConfirm="false"
    width="800px"
@@ -92,6 +92,7 @@
        page: 1
      },
      carCodeFront: '',
      title: '',
      activePlat: {},
      dataList: []
admin/src/views/platform/components/PlatformSign.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,222 @@
<template>
  <GlobalWindow title="车辆签到" :visible.sync="isShowModal" :showConfirm="false" width="800px">
    <div class="queuing_modal">
      <div class="df_ac mb20">
        <span>搜索车辆:</span>
        <el-input class="flex1 mr20" v-model="carCodeFront" placeholder="请输入车牌号"></el-input>
        <el-button type="primary" @click="getList">查找</el-button>
        <el-button @click="reset">重置</el-button>
      </div>
      <div class="list">
        <div class="item" v-for="item in dataList" :key="item.id">
          <div class="head df_sb">
            <div v-if="item.carCodeFront" class="code">
              <span>{{ item.carCodeFront.slice(0, 1) }}</span>
              <span>{{ item.carCodeFront.slice(1, 2) }}</span>
              <span>·</span>
              <span>{{ item.carCodeFront.slice(2) }}</span>
            </div>
            <div class="status" :class="{ red: item.status == 0 }">{{ statusMap[item.status] }}</div>
          </div>
          <div class="info">
            <div v-if="item.type == 4" class="ite">
              <span>合同单号:</span>
              <span>{{ item.contractNum }}</span>
            </div>
            <div v-else class="ite">
              <span>运输单号:</span>
              <span>{{ item.billCode }}</span>
            </div>
            <div class="ite">
              <span>驾驶员:</span>
              <span>{{ item.driverName }}</span>
            </div>
            <div class="ite">
              <span>手机号:</span>
              <span>{{ item.drivierPhone }}</span>
            </div>
            <div class="ite">
              <span>总运输量:</span>
              <span>{{ item.totalNum }}万支</span>
            </div>
            <div v-if="item.type != 4" class="ite" style="width: 66%">
              <span>运输公司:</span>
              <span>{{ item.carrierName }}</span>
            </div>
          </div>
          <div class="footer df_sb">
            <div v-if="item.type != 4" class="detail">运单详情</div>
            <div v-else></div>
            <el-button type="primary" @click="handleCall(item)">签到</el-button>
          </div>
        </div>
      </div>
      <pagination @size-change="handleSizeChange" @current-change="handlePageChange" :pagination="pagination">
      </pagination>
    </div>
  </GlobalWindow>
</template>
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import Pagination from '@/components/common/Pagination'
import { platformJobPage, platformJobSign } from '@/api'
import { statusMap } from '../config'
import { Message } from 'element-ui'
export default {
  components: {
    GlobalWindow,
    Pagination
  },
  data() {
    return {
      statusMap,
      isShowModal: false,
      subLoading: false,
      pagination: {
        total: 0,
        pageSize: 10,
        page: 1
      },
      carCodeFront: '',
      // activePlat: {},
      dataList: []
    }
  },
  methods: {
    handleCall(item) {
      // const activePlatform = this.activePlat
      platformJobSign({ jobId: item.id, signType: '2' }).then(res => {
        Message.success('签到成功')
        this.$emit('success')
        this.getList()
      })
    },
    getList() {
      const { activePlat, pagination, carCodeFront } = this
      platformJobPage({
        model: { platformGroupId: activePlat.id, queryStatus: '0,1' },
        page: pagination.page,
        capacity: pagination.pageSize
      }).then(res => {
        this.dataList = res.records
        this.pagination.total = res.total
      })
    },
    reset() {
      this.carCodeFront = ''
      this.pagination.page = 1
      this.pagination.pageSize = 10
      this.getList()
    },
    handleSizeChange(e) {
      this.pagination.pageSize = e
      this.getList()
    },
    handlePageChange(e) {
      this.pagination.page = e
      this.getList()
    },
    handleSub() {
      const { param } = this
      this.subLoading = true
      PlatformEdit({
        ...param
      }).then(res => {
        this.subLoading = false
        this.isShowEdit = false
        this.$tip.success('提交成功')
        this.getList()
      }, () => {
        this.subLoading = false
      })
    }
  }
}
</script>
<style lang="scss" scoped>
@import "@/assets/style/variables.scss";
.queuing_modal {
  padding: 10px 30px;
  .list {
    .item {
      background: #f4fafb;
      border-radius: 2px;
      border: 1px solid #dfe2e8;
      margin-bottom: 10px;
      padding: 16px;
      .head {
        margin-bottom: 15px;
        .plate {
          width: 90px;
          text-align: center;
          font-size: 15px;
          color: #111111;
          padding: 4px 5px;
          font-weight: 700;
          border: 1px solid #279baa;
          background-color: #fff;
        }
        .status {
          color: $primaryColor;
        }
        .code {
          display: flex;
          font-weight: 600;
          height: 30px;
          line-height: 30px;
          font-size: 15px;
          color: #111111;
          background-color: #fff;
          border-radius: 4px;
          border: 1px solid $primaryColor;
          padding-right: 4px;
          span {
            &:nth-of-type(1) {
              background: $primaryColor;
              padding: 0 8px;
              color: #fff;
            }
            &:nth-of-type(2) {
              padding-left: 4px;
            }
          }
        }
      }
      .info {
        display: flex;
        flex-wrap: wrap;
        .ite {
          width: 33.3%;
          margin-bottom: 8px;
          span {
            &:nth-child(1) {
              color: #666666;
            }
          }
        }
      }
      .footer {
        .detail {
          color: $primaryColor;
        }
      }
    }
  }
}
</style>
admin/src/views/platform/index.vue
@@ -389,6 +389,7 @@
        this.$refs.PlatformQueuingRef.isShowModal = true
        this.$refs.PlatformQueuingRef.activePlat = { ...item }
        this.$refs.PlatformQueuingRef.getList()
        this.$refs.PlatformQueuingRef.title = item.name
      })
    },
    handleDetail () {
admin/src/views/platform/platform.vue
@@ -4,15 +4,12 @@
    <SearchFormCollapse slot="search-form" :need-more="false">
      <el-form ref="searchForm" :model="searchForm" label-width="100px" inline>
        <el-form-item label="" prop="name">
          <el-input v-model="searchForm.name" clearable placeholder="请输入月台名称" @keypress.enter.native="search"></el-input>
          <el-input v-model="searchForm.name" clearable placeholder="请输入月台名称"
            @keypress.enter.native="search"></el-input>
        </el-form-item>
        <el-form-item label="" >
          <el-select v-model="searchForm.groupId"     placeholder="请选择月台分组" @change="search" clearable>
            <el-option
                v-for="item in groupList"
                :key="item.id"
                :label="item.name"
                :value="item.id">
        <el-form-item label="">
          <el-select v-model="searchForm.groupId" placeholder="请选择月台分组" @change="search" clearable>
            <el-option v-for="item in groupList" :key="item.id" :label="item.name" :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
@@ -25,71 +22,57 @@
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:hksync:platforms']">
        <li><el-button type="primary" :loading="working" @click="syncData" icon="el-icon-plus" v-permissions="['business:hksync:platforms']">同步</el-button></li>
        <li><el-button type="primary" :loading="working1" @click="syncStatus" icon="el-icon-plus" v-permissions="['business:hksync:platforms']">同步实时状态</el-button></li>
        <li><el-button type="primary" :loading="working" @click="syncData" icon="el-icon-plus"
            v-permissions="['business:hksync:platforms']">同步</el-button></li>
        <li><el-button type="primary" :loading="working1" @click="syncStatus" icon="el-icon-plus"
            v-permissions="['business:hksync:platforms']">同步实时状态</el-button></li>
      </ul>
      <el-table
        v-loading="isWorking.search"
        :data="tableData.list"
        stripe
        @selection-change="handleSelectionChange"
      >
      <el-table v-loading="isWorking.search" :data="tableData.list" stripe @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="name" label="月台名称" fixed min-width="100px"></el-table-column>
        <el-table-column prop="code" label="月台编码" fixed min-width="100px"></el-table-column>
        <el-table-column prop="groupName" label="所属月台组" fixed min-width="150px"></el-table-column>
        <el-table-column prop="workingNum" label="同时叫号车辆数" min-width="120px"></el-table-column>
        <el-table-column label="禁/启用" min-width="120px">
          <template slot-scope="{row}">
            <el-switch
                @change="changeStatus($event, row)"
                v-model="row.status"
                active-color="#13ce66"
                inactive-color="#ff4949"
                :active-value="0"
                :inactive-value="1">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column prop="stayTmeoutAlarmTime" label="停留超时报警时间(分钟)" min-width="180px">
          <template scope="{row}">{{row.stayTmeoutAlarmTime?(row.stayTmeoutAlarmTime):'-'}}</template>
        <el-table-column prop="stayTimeoutAlarmTime" label="停留超时报警时间(分钟)" min-width="180px">
          <template scope="{row}">{{ row.stayTimeoutAlarmTime ? (row.stayTimeoutAlarmTime) : '-' }}</template>
        </el-table-column>
        <el-table-column prop="workTimeoutAlarmTime" label="作业超时报警时间(分钟)" min-width="180px">
          <template scope="{row}"> {{row.workTimeoutAlarmTime?(row.workTimeoutAlarmTime):'-'}}</template>
          <template scope="{row}"> {{ row.workTimeoutAlarmTime ? (row.workTimeoutAlarmTime) : '-' }}</template>
        </el-table-column>
        <el-table-column prop="workRate" label="月台作业效率(万只/小时)" min-width="180px"></el-table-column>
        <el-table-column prop="platformStatus" label="月台状态" min-width="100px">
        <!-- <el-table-column prop="platformStatus" label="月台状态" min-width="100px">
          <template scope="{row}">
            <span v-if="row.platformStatus == 0">无车</span>
            <span v-if="row.platformStatus == 1">有车</span>
            <span v-if="row.platformStatus == 2">超时停靠</span>
            <span v-if="row.platformStatus == 3">错误停靠</span>
          </template>
        </el-table-column>
        </el-table-column> -->
        <el-table-column prop="broadcastNames" label="关联广播" min-width="100px"></el-table-column>
        <el-table-column prop="ledNames" label="关联LED" min-width="100px"></el-table-column>
        <el-table-column prop="hkDate" label="同步时间" min-width="150px"></el-table-column>
        <el-table-column
          v-if="containPermissions(['business:platform:update', 'business:platform:delete'])"
          label="操作"
          min-width="120"
          fixed="right"
        >
        <el-table-column label="月台状态" fixed="right" width="100px">
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaPlatformWindow.open('编辑月台信息表', row)" icon="el-icon-edit" v-permissions="['business:platform:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:platform:delete']">删除</el-button>
            <el-switch @change="changeStatus($event, row)" v-model="row.status" active-color="#13ce66"
              inactive-color="#ff4949" :active-value="0" :inactive-value="1">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column v-if="containPermissions(['business:platform:update', 'business:platform:delete'])" label="操作"
          min-width="120" fixed="right">
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaPlatformWindow.open('编辑月台信息表', row)" icon="el-icon-edit"
              v-permissions="['business:platform:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete"
              v-permissions="['business:platform:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
        :pagination="tableData.pagination"
      >
      <pagination @size-change="handleSizeChange" @current-change="handlePageChange" :pagination="tableData.pagination">
      </pagination>
    </template>
    <!-- æ–°å»º/修改 -->
    <OperaPlatformWindow ref="operaPlatformWindow" @success="handlePageChange"/>
    <OperaPlatformWindow ref="operaPlatformWindow" @success="handlePageChange" />
  </TableLayout>
</template>
@@ -104,7 +87,7 @@
  name: 'Platform',
  extends: BaseTable,
  components: { SearchFormCollapse, TableLayout, Pagination, OperaPlatformWindow },
  data () {
  data() {
    return {
      groupList: [],
      // æœç´¢
@@ -116,7 +99,7 @@
      }
    }
  },
  created () {
  created() {
    this.config({
      module: '月台信息表',
      api: '/platform/platform',
@@ -127,19 +110,19 @@
    this.loadGroupList()
  },
  methods: {
    loadGroupList () {
    loadGroupList() {
      allList({})
        .then(res => {
          this.groupList = res || []
        })
    },
    changeStatus (e, row) {
    changeStatus(e, row) {
      this.api.updateStatusById({
        id: row.id,
        status: e
      })
    },
    syncData () {
    syncData() {
      this.$dialog.actionConfirm('操作确认提醒', '您确认同步全部信息吗?')
        .then(() => {
          this.isWorking.working = true
@@ -155,9 +138,9 @@
              this.isWorking.working = false
            })
        })
        .catch(() => {})
        .catch(() => { })
    },
    syncStatus () {
    syncStatus() {
      this.$dialog.actionConfirm('操作确认提醒', '您确认同步全部信息吗?')
        .then(() => {
          this.isWorking.working = true
@@ -173,7 +156,7 @@
              this.isWorking.working = false
            })
        })
        .catch(() => {})
        .catch(() => { })
    }
  }
}
admin/src/views/platform/queueUp.vue
@@ -8,8 +8,11 @@
        </div>
      </div>
    </div>
    <QueryForm v-model="filters" :query-form-config="queryQueueUpConfig" @handleQuery="getList(1)" @clear="clear">
    </QueryForm>
    <div class="df_sb">
      <QueryForm v-model="filters" :query-form-config="queryQueueUpConfig" @handleQuery="getList(1)" @clear="clear">
      </QueryForm>
      <el-button @click="openSign" type="primary" style="align-self: flex-start;">车辆签到</el-button>
    </div>
    <div class="main_content">
      <div class="static_wrap">
        <span>等待:<span class="num">{{ staticParam.waitNum }}</span></span>
@@ -31,7 +34,7 @@
        </template>
      </el-table-column>
      <el-table-column prop="carrierName" label="运输公司" min-width="200" />
      <el-table-column prop="code" label="运单号" min-width="200" />
      <el-table-column prop="billCode" label="运单号" min-width="200" />
      <el-table-column prop="totalNum" label="总运输量(万支)" min-width="130" />
      <el-table-column prop="driverName" label="驾驶员" min-width="140">
        <template slot-scope="{ row }">
@@ -49,12 +52,9 @@
    <pagination @size-change="handleSizeChange" @current-change="handlePageChange" :pagination="pagination" />
    <!--  -->
    <WaybillDetail
      ref="WaybillDetailRef"
      v-if="isShowDetail"
      @success="getList"
      @close="isShowDetail = false"
    />
    <PlatformSign ref="PlatformSignRef" v-if="isPlatformSign" @success="getPlatGroupList"
      @close="isPlatformSign = false" />
    <WaybillDetail ref="WaybillDetailRef" v-if="isShowDetail" @success="getList" @close="isShowDetail = false" />
  </div>
</template>
@@ -68,10 +68,12 @@
} from '@/api'
import { queryQueueUpConfig } from './config'
import WaybillDetail from './components/WaybillDetail.vue'
import PlatformSign from './components/PlatformSign.vue'
export default {
  components: {
    Pagination,
    QueryForm,
    PlatformSign,
    WaybillDetail
  },
  data() {
@@ -82,6 +84,7 @@
      staticParam: {},
      dataList: [],
      loading: false,
      isPlatformSign: false,
      pagination: {
        pageSize: 10,
        page: 1,
@@ -96,6 +99,14 @@
    this.getPlatGroupList()
  },
  methods: {
    openSign() {
      this.isPlatformSign = true
      this.$nextTick(() => {
        this.$refs.PlatformSignRef.isShowModal = true
        this.$refs.PlatformSignRef.activePlat = this.activeGroup
        this.$refs.PlatformSignRef.getList()
      })
    },
    getPlatGroupList() {
      getPlatformGroupList({
        queryData: 1,
@@ -201,6 +212,7 @@
  color: #111111;
  border-radius: 4px;
  border: 1px solid #dfdede;
  span {
    &:nth-of-type(1) {
      background: $primary-color;
h5/manifest.json
@@ -91,8 +91,8 @@
            "proxy" : {
                "/admin_interface" : {
                    // è¿™ä¸ªå­—段名需与你配置的basePrefixUrl一致,系统识别到带有/dev-api请求的地址时,会在前面拼接上代理服务器地址
                    "target" : "http://172.20.10.7:10010", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    // "target" : "http://192.168.31.42:10010", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    // "target" : "http://172.20.10.7:10010", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    "target" : "http://192.168.0.103:10010", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    // "target" : "http://10.50.250.178:8088/gateway_interface", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    "changeOrigin" : true, // å…è®¸è·¨åŸŸ 
                    "pathRewrite" : {
@@ -101,6 +101,15 @@
                }
            },
            "https" : false
        },
        "sdkConfigs" : {
            "maps" : {
                "amap" : {
                    "key" : "d9a554b1808ce10a12a932ed9b0db1d0",
                    "securityJsCode" : "",
                    "serviceHost" : ""
                }
            }
        }
    }
}
h5/pages/driver/login.vue
@@ -37,7 +37,7 @@
  data() {
    return {
      form: {
                username: '13333333333',
                username: '18056814089',
                password: '1'
      },
      isShowProtocol: false,
h5/pages/driver/reservedRecord.vue
@@ -23,7 +23,7 @@
          </view>
          <view class="box_list_item_nr_item">
            <text>司机姓名:</text>
            <text>{{item.driverName}}</text>
            <text>{{item.driverName}} {{item.driverPhone}}</text>
          </view>
          <view class="box_list_item_nr_item">
            <text>车辆信息:</text>
h5/pages/driver/taskDetail.vue
@@ -188,8 +188,10 @@
        status: '0'
      },
            jobId: '',
            lat: '',
            lnt: '',
            // lat: '',
            // lnt: '',
            lat: '31.783205',
            lnt: '117.262635',
            nowTime: '',
            signDistance: uni.getStorageSync('driverGuide').signDistance,
      showDetail: false,
@@ -197,17 +199,12 @@
  },
    onLoad(option) {
        this.jobId = option.id
        if(option.status && option.status == '1'){
            this.getLocation()
        }else{
            this.getDetail()
        }
        // this.getDetail({
        //     jobId: option.id,
        //     lat: 31.769137,
        //     lnt: 117.232241,
        // })
        // if(option.status && option.status == '1'){
        //     this.getLocation()
        // }else{
        //     this.getDetail()
        // }
        this.getDetail()
        setInterval(() => {
            this.nowTime = dayjs().format('HH:mm:ss')
        })
@@ -243,7 +240,7 @@
                    this.getDetail()
        },
                fail:(err) => {
                    console.log('err', err);
                    this.showToast('获取定位失败')
                }
      })
    },
h5/pages/staff/task/driver.vue
@@ -3,6 +3,9 @@
    <view class="status_wrap">
      <view class="name">{{info.driverName}}的入园预约</view>
      <view class="desc">{{info.carCodeFront}}</view>
            <view class="desc" :class="{
                gray: info.businessStatus == '2' || info.businessStatus == '3' || info.businessStatus == '4',
              }">{{ infoStatus }}</view>
      <view class="status" v-if="info.status != 2 && info.status != 3">{{ statusMap[info.status] }}</view>
            <image v-if="info.status == 2" class="icon" src="@/static/ic_passed@2x.png" mode=""></image>
            <image v-if="info.status == 3" class="icon" src="@/static/ic_refused@2x.png" mode=""></image>
@@ -58,58 +61,43 @@
    <!-- æµç¨‹ -->
    <view class="flow_wrap">
      <view class="flow_title">流程</view>
      <view class="list" v-if="info.approveDateVO != null && info.approveDateVO.approveList != null">
        <view class="item" v-for="item,index in info.approveDateVO.approveList">
                    <view v-if="index != info.approveDateVO.approveList.length - 1" class="separate"></view>
          <view class="avatar">
            <image
                v-if="item.type == 1"
              class="img"
              src="@/static/staff/ic_chaosong@2x.png"
            />
            <image
                v-else-if="item.approveType == 1 || item.approveType == 0"
              class="img"
              src="@/static/staff/ic_shenpiren@2x.png"
            />
            <span v-else class="img_name">{{item.memberName && item.memberName.slice(0,1)}}</span>
            <image
                            v-if="item.status == 2"
              class="status"
              src="@/static/staff/liucheng_success@2x.png"
              mode="widthFix"
            />
                        <image
                            v-if="item.status == 3"
                          class="status"
                          src="@/static/staff/liucheng_fail@2x.png"
                          mode="widthFix"
                        />
          </view>
          <view class="content">
            <view class="head">
              <view class="event">{{ item.title }}</view>
              <view class="time">{{item.createDate}}</view>
            </view>
            <view class="name_wrap">
              <text>{{item.memberName}}<text v-if="item.statusInfo" class="status">({{item.statusInfo}})</text></text>
            </view>
                        <div v-if="item.checkInfo" class="remark">
                            {{ item.checkInfo }}
                        </div>
                        <view v-if="item.approveType == 1" class="carbon">
                          <view class="carbon_item" v-for="child in item.approveList"
                :key="child.id">
                            <image :src="
                    child.faceImg
                      ? child.faceImg
                      : require('@/static/meeting/common/default_user@2x.png')
                  "></image>
                            <view class="text">{{ child.memberName }}</view>
                          </view>
                        </view>
          </view>
        </view>
      <view class="list" v-if="
          info.approveDateVO != null && info.approveDateVO.approveList != null
        ">
          <view class="item" v-for="(item, index) in info.approveDateVO.approveList" :key="item.id">
              <view class="separate"></view>
              <view class="avatar">
                  <image v-if="item.type == 1" class="img" src="@/static/staff/ic_chaosong@2x.png" />
                  <image v-else-if="item.approveType == 1 || item.approveType == 0" class="img"
                      src="@/static/staff/ic_shenpiren@2x.png" />
                  <span v-else class="img_name">{{item.memberName && item.memberName.slice(0,1)}}</span>
                  <image v-if="item.status == 2" class="status" src="@/static/staff/liucheng_success@2x.png"
                      mode="widthFix" />
                  <image v-if="item.status == 3" class="status" src="@/static/staff/liucheng_fail@2x.png" mode="widthFix" />
              </view>
              <view class="content">
                  <view class="head">
                      <view class="event">{{ item.title }}</view>
                      <view class="time">{{ item.checkDate }}</view>
                  </view>
                  <view class="name_wrap">
                      <text>{{ item.memberName
                }}<text :class="{ status: item.statusInfo == '处理中' || item.status == '1'  }"
                              v-if="item.statusInfo">({{ item.statusInfo }})</text></text>
                  </view>
                  <view v-if="item.checkInfo" class="remark">{{
              item.checkInfo
            }}</view>
                  <!-- æŠ„送人 -->
                  <view v-if="item.approveType == 0 || item.type == 1 || item.approveType == 1" class="children">
                      <view class="child" v-for="child in item.approveList" :key="child.id">
                          <image v-if="child.faceImg" class="child_img" :src="child.faceImg" />
                          <view v-else class="child_name">{{ child.memberName && child.memberName.slice(0,1) }}</view>
                          <view>{{ child.memberName }}</view>
                      </view>
                  </view>
              </view>
          </view>
      </view>
    </view>
    <view class="emyty"></view>
@@ -149,6 +137,7 @@
    return {
      showApprModal: false,
            checkInfo: '',
            infoStatus: '',
            flag: '1',
      info: {},
            type: 0,
@@ -163,6 +152,7 @@
  },
    onLoad(option) {
        this.type = option.objType
        this.infoStatus = option.info
        this.getDetail(option.id)
    },
  methods: {
@@ -222,101 +212,110 @@
  padding-bottom: 0;
  .flow_wrap {
    padding: 30rpx 0;
      padding: 30rpx 0;
  
    .flow_title {
      font-weight: 600;
      font-size: 32rpx;
      color: #222222;
      margin-bottom: 24rpx;
    }
      .flow_title {
          font-weight: 600;
          font-size: 32rpx;
          color: #222222;
          margin-bottom: 24rpx;
      }
  
    .list {
      .item {
        display: flex;
        margin-bottom: 48rpx;
        position: relative;
        .separate {
          position: absolute;
          width: 4rpx;
          height: 100%;
          background-color: #eeeeee;
          left: 40rpx;
          transform: translate(-50%, 0);
          top: 80rpx;
        }
        .avatar {
          width: 80rpx;
          height: 80rpx;
          position: relative;
          margin-right: 20rpx;
      .list {
          .item {
              display: flex;
              margin-bottom: 48rpx;
              position: relative;
              .separate {
                  position: absolute;
                  width: 4rpx;
                  height: 100%;
                  background-color: #eeeeee;
                  left: 40rpx;
                  transform: translate(-50%, 0);
                  top: 80rpx;
              }
              .avatar {
                  width: 80rpx;
                  height: 80rpx;
                  position: relative;
                  margin-right: 20rpx;
                  display: flex;
                  align-items: center;
                  justify-content: center;
          .img {
            width: 80rpx;
            height: 80rpx;
            border-radius: 50%;
          }
                  .img_name{
                  .img {
                      width: 80rpx;
                      height: 80rpx;
                      border-radius: 50%;
                  }
                  .img_name {
                      font-size: 32rpx;
                      color: #FFFFFF;
                  }
          .status {
            width: 28rpx;
            height: 28rpx;
            border-radius: 50%;
            position: absolute;
            right: 0;
            bottom: 0;
          }
        }
  
        .content {
          flex: 1;
                  .status {
                      width: 28rpx;
                      height: 28rpx;
                      border-radius: 50%;
                      position: absolute;
                      right: 0;
                      bottom: 0;
                  }
              }
  
          .head {
            display: flex;
            justify-content: space-between;
            margin-bottom: 4rpx;
              .content {
                  flex: 1;
  
            .event {
              font-size: 30rpx;
            }
                  .head {
                      display: flex;
                      justify-content: space-between;
                      margin-bottom: 4rpx;
  
            .time {
              font-size: 26rpx;
              color: #999999;
            }
          }
                      .event {
                          font-size: 30rpx;
                      }
  
          .name_wrap {
            font-size: 26rpx;
            color: #777777;
                      .time {
                          font-size: 26rpx;
                          color: #999999;
                      }
                  }
  
            .status {
              color: $uni-color-primary;
            }
          }
          .children {
            display: flex;
            flex-wrap: wrap;
            margin-top: 12rpx;
            .child {
              display: flex;
              flex-direction: column;
              justify-content: center;
              align-items: center;
              margin-right: 12rpx;
                  .name_wrap {
                      font-size: 26rpx;
                      color: #777777;
                      .status {
                          color: $uni-color-primary;
                      }
                  }
                  .children {
                      display: flex;
                      flex-wrap: wrap;
                      margin-top: 12rpx;
                      .child {
                          display: flex;
                          flex-direction: column;
                          justify-content: center;
                          align-items: center;
                          margin-right: 12rpx;
                          font-size: 26rpx;
                          color: #777777;
              .child_img {
                width: 48rpx;
                height: 48rpx;
                border-radius: 50%;
                          .child_img {
                              width: 48rpx;
                              height: 48rpx;
                              border-radius: 50%;
                              margin-bottom: 2rpx;
              }
                          .child_name{
                          }
                          .child_name {
                              margin-bottom: 2rpx;
                              width: 48rpx;
                              height: 48rpx;
@@ -328,46 +327,51 @@
                              color: #FFFFFF;
                              background-color: $uni-color-primary;
                          }
            }
          }
                      }
                  }
  
          .remark {
            margin-top: 12rpx;
            background-color: #f7f7f7;
            padding: 14rpx 20rpx;
            border-radius: 8rpx;
            font-size: 26rpx;
            color: #666666;
            line-height: 36rpx;
          }
        }
        .carbon {
          display: flex;
          width: 590rpx;
          overflow-x: auto;
          margin-top: 12rpx;
          .carbon_item {
            text-align: center;
            flex-shrink: 0;
            width: 100rpx;
            image {
              width: 60rpx;
              height: 60rpx;
              margin: 0 auto;
            }
            view {
              font-size: 26rpx;
              color: #777777;
            }
          }
        }
        &:nth-last-child(1) {
          .separate {
            height: 0;
          }
        }
      }
    }
                  .remark {
                      margin-top: 12rpx;
                      background-color: #f7f7f7;
                      padding: 14rpx 20rpx;
                      border-radius: 8rpx;
                      font-size: 26rpx;
                      color: #666666;
                      line-height: 36rpx;
                  }
              }
              .carbon {
                  display: flex;
                  width: 590rpx;
                  overflow-x: auto;
                  margin-top: 12rpx;
                  .carbon_item {
                      text-align: center;
                      flex-shrink: 0;
                      width: 100rpx;
                      image {
                          width: 60rpx;
                          height: 60rpx;
                          margin: 0 auto;
                      }
                      view {
                          font-size: 26rpx;
                          color: #777777;
                      }
                  }
              }
              &:nth-last-child(1) {
                  .separate {
                      height: 0;
                  }
              }
          }
      }
  }
  .module_list {
@@ -425,7 +429,11 @@
    .desc {
      font-size: 26rpx;
      color: #999999;
            margin-bottom: 12rpx;
    }
        .gray {
            color: #999999;
        }
    .status {
      position: absolute;
h5/pages/staff/task/visitorApprove.vue
@@ -1,580 +1,555 @@
<template>
  <view class="main_app">
    <view class="status_wrap">
      <view class="name">{{ info.name }}提交的{{ cateList[type].name }}</view>
      <view
        class="desc"
        :class="{
          gray: info.businessStatus == '2' || info.businessStatus == '3' || info.businessStatus == '4',
        }"
        >{{ infoStatus }}</view
      >
      <view v-if="info.businessStatus == '0' || info.businessStatus == '1'" class="status">{{
        statusMap[info.businessStatus]
      }}</view>
      <image
        v-if="info.businessStatus == '2'"
        src="@/static/ic_passed@2x.png"
        mode="widthFix"
        class="status_img"
      ></image>
      <image
        v-if="info.businessStatus == '3'"
        src="@/static/ic_refused@2x.png"
        mode="widthFix"
        class="status_img"
      ></image>
    </view>
    <!--  -->
    <view class="emyty"></view>
    <view class="module_list">
      <view class="item">
        <view class="label">被访人</view>
        <view class="value">{{ info.visitUserName }}</view>
      </view>
      <view class="item">
        <view class="label">预计入/离园时间</view>
        <view class="value" v-if="info.visitTime">{{ info.visitTime }}</view>
      </view>
      <view class="emyty"></view>
      <view class="item">
        <view class="label">访客信息</view>
        <view class="value">
          <image
            class="avatar"
            :src="
              info.prefix
                ? info.prefix + info.faceImg
                : require('@/static/meeting/common/default_user@2x.png')
            "
            mode="widthFix"
          ></image>
          <view class="info">
            <text class="name">{{ info.name }} {{ info.phone }}</text>
            <text>身份证号:{{ info.idCardDecode }}</text>
            <text>入园车辆:{{ info.carNos }}</text>
          </view>
        </view>
      </view>
      <view class="item">
        <view class="label">公司名称</view>
        <view class="value">{{ info.companyName }}</view>
      </view>
      <view class="item">
        <view class="label">施工人员</view>
        <view class="value">{{ info.type == 0 ? "否" : "是" }}</view>
      </view>
      <view class="item">
        <view class="label">来访事由</view>
        <view class="value">{{ info.visitReason }}</view>
      </view>
            <view v-if="info.constructionReason" class="item">
              <view class="label">施工内容</view>
              <view class="value">{{ info.constructionReason }}</view>
            </view>
    </view>
    <!-- æµç¨‹ -->
    <view class="flow_wrap">
      <view class="flow_title">流程</view>
      <view
        class="list"
        v-if="
          info.approveDateVO != null && info.approveDateVO.approveList != null
        "
      >
        <view
          class="item"
          v-for="(item, index) in info.approveDateVO.approveList"
          :key="item.id"
        >
          <view class="separate"></view>
          <view class="avatar">
                        <image
                            v-if="item.type == 1"
                          class="img"
                          src="@/static/staff/ic_chaosong@2x.png"
                        />
            <image
                v-else-if="item.approveType == 1 || item.approveType == 0"
              class="img"
              src="@/static/staff/ic_shenpiren@2x.png"
            />
                        <span v-else class="img_name">{{item.memberName && item.memberName.slice(0,1)}}</span>
            <image
                v-if="item.status == 2"
              class="status"
              src="@/static/staff/liucheng_success@2x.png"
              mode="widthFix"
            />
            <image
                v-if="item.status == 3"
              class="status"
              src="@/static/staff/liucheng_fail@2x.png"
              mode="widthFix"
            />
          </view>
          <view class="content">
            <view class="head">
              <view class="event">{{ item.title }}</view>
              <view class="time">{{ item.checkDate }}</view>
            </view>
            <view class="name_wrap">
              <text
                >{{ item.memberName
                }}<text :class="{ status: item.statusInfo == '处理中' || item.status == '1'  }" v-if="item.statusInfo"
                  >({{ item.statusInfo }})</text
                ></text
              >
            </view>
            <view v-if="item.checkInfo" class="remark">{{
              item.checkInfo
            }}</view>
            <!-- æŠ„送人 -->
            <view v-if="item.approveType == 0 || item.type == 1 || item.approveType == 1" class="children">
              <view
                class="child"
                v-for="child in item.approveList"
                :key="child.id"
              >
                <image
                                    v-if="child.faceImg"
                  class="child_img"
                  :src="child.faceImg"
                />
                                <view v-else class="child_name">{{ child.memberName && child.memberName.slice(0,1) }}</view>
                <view>{{ child.memberName }}</view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>
    <view class="emyty"></view>
    <view
      v-if="
        info.approveDateVO != null &&
        info.approveDateVO.canBeApproved != null &&
        info.approveDateVO.canBeApproved == 1
      "
      class="main_footer"
    >
      <view class="btn" @click="handleSub(3)">拒绝</view>
      <view class="btn agree" @click="handleSub(2)">同意</view>
    </view>
    <u-popup
      :show="showApprModal"
      :round="10"
      :safeAreaInsetBottom="true"
      mode="bottom"
      @close="showApprModal = false"
    >
      <view class="appr_modal">
        <view class="title">{{ param.status == 2 ? "同意" : "拒绝" }}</view>
        <textarea
          v-model="param.checkInfo"
          :placeholder="
            param.status == 2 ? '同意说明,非必填' : '拒绝说明,必填'
          "
          placeholder-class="placeholder9"
        />
        <view class="main_footer">
          <view class="btn" @click="showApprModal = false">取消</view>
          <view class="btn agree" @click="onSubmit">提交</view>
        </view>
      </view>
    </u-popup>
  </view>
</template>
<script>
import {
  getVisitedDetail, // è®¿å®¢é¢„约详情
  carUseBookAppr
} from '@/api'
export default {
  data() {
    return {
      showApprModal: false,
      param: {},
      info: {},
      id: '',
      type: '',
            infoStatus: '',
      cateList: [
        { name: '访客申请', id: 0 },
        { name: '访客报备', id: 1 },
        { name: '用车申请', id: 2 },
        { name: '隐患随手拍', id: 3 },
        { name: '物流车申请', id: 4 },
      ],
      statusMap: {
        0: '待审批',
        1: '审批中',
        2: '已通过',
        3: '已拒绝',
        4: '已取消',
      }
    }
  },
  onLoad(op) {
    this.id = op.id
    this.type = op.objType
    this.infoStatus = op.info
    this.getDetail()
  },
  methods: {
    getDetail() {
      const { id } = this
      getVisitedDetail({ id }).then(res => {
        this.info = res.data
                if(this.info.approveDateVO && this.info.approveDateVO.approveList.length > 0 ){
                    this.info.approveDateVO.approveList.forEach(item => {
                        if(item.approveList && item.approveList.length == 1 && item.type !== 1){
                            item.title = item.approveList[0].title
                            item.faceImg = item.approveList[0].faceImg
                            item.memberName = item.approveList[0].memberName
                            item.statusInfo = item.approveList[0].statusInfo
                            item.status = item.approveList[0].status
                            item.approveList = []
                        }
                    })
                }
      })
    },
    onSubmit() {
      const { param, info } = this
            if(param.status == '3' && !param.checkInfo){
                return uni.showToast({
              title: '请输入拒绝说明',
              icon: 'none'
            })
            }
      carUseBookAppr({
        status: param.status,
        objType: info.type,
        objId: this.id,
        // driverId: param.driverId,
        checkInfo: param.checkInfo
      }).then(res => {
        if (res.code === 200) {
          this.showApprModal = false
          setTimeout(() => {
            uni.showToast({
              title: '操作成功',
              icon: 'success'
            })
          })
          uni.navigateBack()
        }
      })
    },
    handleSub(status) {
      // this.param.flag =
      this.param = {
        status
      }
      this.showApprModal = true
    },
  },
}
</script>
<style>
page {
  background-color: #f7f7f7;
}
</style>
<style lang="scss">
.main_app {
  background-color: #fff;
  padding-bottom: 0;
  .flow_wrap {
    padding: 30rpx 0;
    .flow_title {
      font-weight: 600;
      font-size: 32rpx;
      color: #222222;
      margin-bottom: 24rpx;
    }
    .list {
      .item {
        display: flex;
        margin-bottom: 48rpx;
        position: relative;
        .separate {
          position: absolute;
          width: 4rpx;
          height: 100%;
          background-color: #eeeeee;
          left: 40rpx;
          transform: translate(-50%, 0);
          top: 80rpx;
        }
        .avatar {
          width: 80rpx;
          height: 80rpx;
          position: relative;
          margin-right: 20rpx;
                    display: flex;
                    align-items: center;
                    justify-content: center;
          .img {
            width: 80rpx;
            height: 80rpx;
            border-radius: 50%;
          }
                    .img_name{
                        font-size: 32rpx;
                        color: #FFFFFF;
                    }
          .status {
            width: 28rpx;
            height: 28rpx;
            border-radius: 50%;
            position: absolute;
            right: 0;
            bottom: 0;
          }
        }
        .content {
          flex: 1;
          .head {
            display: flex;
            justify-content: space-between;
            margin-bottom: 4rpx;
            .event {
              font-size: 30rpx;
            }
            .time {
              font-size: 26rpx;
              color: #999999;
            }
          }
          .name_wrap {
            font-size: 26rpx;
            color: #777777;
            .status {
              color: $uni-color-primary;
            }
          }
          .children {
            display: flex;
            flex-wrap: wrap;
            margin-top: 12rpx;
            .child {
              display: flex;
              flex-direction: column;
              justify-content: center;
              align-items: center;
              margin-right: 12rpx;
                            font-size: 26rpx;
                            color: #777777;
              .child_img {
                width: 48rpx;
                height: 48rpx;
                border-radius: 50%;
                                margin-bottom: 2rpx;
              }
                            .child_name{
                                margin-bottom: 2rpx;
                                width: 48rpx;
                                height: 48rpx;
                                text-align: center;
                                justify-content: center;
                                padding-top: 4rpx;
                                font-size: 28rpx;
                                border-radius: 50%;
                                color: #FFFFFF;
                                background-color: $uni-color-primary;
                            }
            }
          }
          .remark {
            margin-top: 12rpx;
            background-color: #f7f7f7;
            padding: 14rpx 20rpx;
            border-radius: 8rpx;
            font-size: 26rpx;
            color: #666666;
            line-height: 36rpx;
          }
        }
        .carbon {
          display: flex;
          width: 590rpx;
          overflow-x: auto;
          margin-top: 12rpx;
          .carbon_item {
            text-align: center;
            flex-shrink: 0;
            width: 100rpx;
            image {
              width: 60rpx;
              height: 60rpx;
              margin: 0 auto;
            }
            view {
              font-size: 26rpx;
              color: #777777;
            }
          }
        }
        &:nth-last-child(1) {
          .separate {
            height: 0;
          }
        }
      }
    }
  }
  .module_list {
    .item {
      padding: 30rpx 0;
      border-bottom: 1rpx solid #e5e5e5;
      .label {
        font-size: 26rpx;
        color: #666666;
        margin-bottom: 20rpx;
      }
      .value {
        font-size: 30rpx;
        display: flex;
        align-items: center;
        .avatar {
          margin-right: 20rpx;
          width: 120rpx;
          height: 120rpx;
          border-radius: 8rpx;
          border: 2rpx solid #e5e5e5;
        }
        .info {
          flex: 1;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
          font-size: 26rpx;
          color: #666666;
          .name {
            font-size: 30rpx;
            color: #333333;
          }
        }
      }
    }
  }
  .status_wrap {
    position: relative;
    padding: 30rpx 0;
    .name {
      font-weight: 600;
      font-size: 32rpx;
      margin-bottom: 20rpx;
      color: #222222;
    }
    .desc {
      font-size: 26rpx;
      color: #ed4545;
    }
    .gray {
      color: #999999;
    }
    .status {
      position: absolute;
      right: -30rpx;
      top: 0;
      height: 60rpx;
      line-height: 60rpx;
      padding: 0 32rpx;
      border-radius: 0rpx 0rpx 0rpx 30rpx;
      background-color: #e9edff;
      color: $uni-color-primary;
    }
    .status_img {
      position: absolute;
      right: 0rpx;
      top: 20rpx;
      width: 120rpx;
    }
  }
  .main_footer {
    padding-bottom: 64rpx;
    display: flex;
    justify-content: space-between;
    width: 100%;
    left: 0;
    // padding: 30rpx 10rpx 60rpx;
    display: flex;
    justify-content: space-between;
    background: #ffffff;
    .btn {
      width: 336rpx;
      height: 88rpx;
      line-height: 88rpx;
      background: #ffffff;
      border-radius: 44rpx;
      border: 1rpx solid #999999;
      font-size: 32rpx;
      text-align: center;
      margin: 16rpx 0;
    }
    .agree {
      background: $uni-color-primary;
      color: #fff;
      border: 1rpx solid $uni-color-primary;
    }
  }
  .appr_modal {
    padding: 36rpx 30rpx 0;
    .title {
      font-weight: 600;
      font-size: 32rpx;
      color: #222222;
      margin-bottom: 40rpx;
      text-align: center;
    }
    textarea {
      box-sizing: border-box;
      width: 690rpx;
      background-color: #f7f7f7;
      font-size: 28rpx;
      color: #333333;
      padding: 24rpx;
      border-radius: 8rpx;
      margin-bottom: 30rpx;
    }
  }
  .emyty {
    width: 750rpx;
    height: 20rpx;
    background-color: #f7f7f7;
    margin: 0 -30rpx;
  }
}
</style>
<template>
    <view class="main_app">
        <view class="status_wrap">
            <view class="name">{{ info.name }}提交的{{ cateList[type].name }}</view>
            <view class="desc" :class="{
          gray: info.businessStatus == '2' || info.businessStatus == '3' || info.businessStatus == '4',
        }">{{ infoStatus }}</view>
            <view v-if="info.businessStatus == '0' || info.businessStatus == '1'" class="status">{{
        statusMap[info.businessStatus]
      }}</view>
            <image v-if="info.businessStatus == '2'" src="@/static/ic_passed@2x.png" mode="widthFix" class="status_img">
            </image>
            <image v-if="info.businessStatus == '3'" src="@/static/ic_refused@2x.png" mode="widthFix" class="status_img">
            </image>
        </view>
        <!--  -->
        <view class="emyty"></view>
        <view class="module_list">
            <view class="item">
                <view class="label">被访人</view>
                <view class="value">{{ info.visitUserName }}</view>
            </view>
            <view class="item">
                <view class="label">预计入/离园时间</view>
                <view class="value" v-if="info.visitTime">{{ info.visitTime }}</view>
            </view>
            <view class="emyty"></view>
            <view class="item">
                <view class="label">访客信息</view>
                <view class="value">
                    <image class="avatar" :src="
              info.prefix
                ? info.prefix + info.faceImg
                : require('@/static/meeting/common/default_user@2x.png')
            " mode="widthFix"></image>
                    <view class="info">
                        <text class="name">{{ info.name }} {{ info.phone }}</text>
                        <text>身份证号:{{ info.idCardDecode }}</text>
                        <text>入园车辆:{{ info.carNos }}</text>
                    </view>
                </view>
            </view>
            <view class="item">
                <view class="label">公司名称</view>
                <view class="value">{{ info.companyName }}</view>
            </view>
            <view class="item">
                <view class="label">施工人员</view>
                <view class="value">{{ info.type == 0 ? "否" : "是" }}</view>
            </view>
            <view class="item">
                <view class="label">来访事由</view>
                <view class="value">{{ info.visitReason }}</view>
            </view>
            <view v-if="info.constructionReason" class="item">
                <view class="label">施工内容</view>
                <view class="value">{{ info.constructionReason }}</view>
            </view>
        </view>
        <!-- æµç¨‹ -->
        <view class="flow_wrap">
            <view class="flow_title">流程</view>
            <view class="list" v-if="
          info.approveDateVO != null && info.approveDateVO.approveList != null
        ">
                <view class="item" v-for="(item, index) in info.approveDateVO.approveList" :key="item.id">
                    <view class="separate"></view>
                    <view class="avatar">
                        <image v-if="item.type == 1" class="img" src="@/static/staff/ic_chaosong@2x.png" />
                        <image v-else-if="item.approveType == 1 || item.approveType == 0" class="img"
                            src="@/static/staff/ic_shenpiren@2x.png" />
                        <span v-else class="img_name">{{item.memberName && item.memberName.slice(0,1)}}</span>
                        <image v-if="item.status == 2" class="status" src="@/static/staff/liucheng_success@2x.png"
                            mode="widthFix" />
                        <image v-if="item.status == 3" class="status" src="@/static/staff/liucheng_fail@2x.png" mode="widthFix" />
                    </view>
                    <view class="content">
                        <view class="head">
                            <view class="event">{{ item.title }}</view>
                            <view class="time">{{ item.checkDate }}</view>
                        </view>
                        <view class="name_wrap">
                            <text>{{ item.memberName
                }}<text :class="{ status: item.statusInfo == '处理中' || item.status == '1'  }"
                                    v-if="item.statusInfo">({{ item.statusInfo }})</text></text>
                        </view>
                        <view v-if="item.checkInfo" class="remark">{{
              item.checkInfo
            }}</view>
                        <!-- æŠ„送人 -->
                        <view v-if="item.approveType == 0 || item.type == 1 || item.approveType == 1" class="children">
                            <view class="child" v-for="child in item.approveList" :key="child.id">
                                <image v-if="child.faceImg" class="child_img" :src="child.faceImg" />
                                <view v-else class="child_name">{{ child.memberName && child.memberName.slice(0,1) }}</view>
                                <view>{{ child.memberName }}</view>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
        </view>
        <view class="emyty"></view>
        <view v-if="
        info.approveDateVO != null &&
        info.approveDateVO.canBeApproved != null &&
        info.approveDateVO.canBeApproved == 1
      " class="main_footer">
            <view class="btn" @click="handleSub(3)">拒绝</view>
            <view class="btn agree" @click="handleSub(2)">同意</view>
        </view>
        <u-popup :show="showApprModal" :round="10" :safeAreaInsetBottom="true" mode="bottom" @close="showApprModal = false">
            <view class="appr_modal">
                <view class="title">{{ param.status == 2 ? "同意" : "拒绝" }}</view>
                <textarea v-model="param.checkInfo" :placeholder="
            param.status == 2 ? '同意说明,非必填' : '拒绝说明,必填'
          " placeholder-class="placeholder9" />
                <view class="main_footer">
                    <view class="btn" @click="showApprModal = false">取消</view>
                    <view class="btn agree" @click="onSubmit">提交</view>
                </view>
            </view>
        </u-popup>
    </view>
</template>
<script>
    import {
        getVisitedDetail, // è®¿å®¢é¢„约详情
        carUseBookAppr
    } from '@/api'
    export default {
        data() {
            return {
                showApprModal: false,
                param: {},
                info: {},
                id: '',
                type: '',
                infoStatus: '',
                cateList: [{
                        name: '访客申请',
                        id: 0
                    },
                    {
                        name: '访客报备',
                        id: 1
                    },
                    {
                        name: '用车申请',
                        id: 2
                    },
                    {
                        name: '隐患随手拍',
                        id: 3
                    },
                    {
                        name: '物流车申请',
                        id: 4
                    },
                ],
                statusMap: {
                    0: '待审批',
                    1: '审批中',
                    2: '已通过',
                    3: '已拒绝',
                    4: '已取消',
                }
            }
        },
        onLoad(op) {
            this.id = op.id
            this.type = op.objType
            this.infoStatus = op.info
            this.getDetail()
        },
        methods: {
            getDetail() {
                const {
                    id
                } = this
                getVisitedDetail({
                    id
                }).then(res => {
                    this.info = res.data
                    if (this.info.approveDateVO && this.info.approveDateVO.approveList.length > 0) {
                        this.info.approveDateVO.approveList.forEach(item => {
                            if (item.approveList && item.approveList.length == 1 && item.type !== 1) {
                                item.title = item.approveList[0].title
                                item.faceImg = item.approveList[0].faceImg
                                item.memberName = item.approveList[0].memberName
                                item.statusInfo = item.approveList[0].statusInfo
                                item.status = item.approveList[0].status
                                item.approveList = []
                            }
                        })
                    }
                })
            },
            onSubmit() {
                const {
                    param,
                    info
                } = this
                if (param.status == '3' && !param.checkInfo) {
                    return uni.showToast({
                        title: '请输入拒绝说明',
                        icon: 'none'
                    })
                }
                carUseBookAppr({
                    status: param.status,
                    objType: info.type,
                    objId: this.id,
                    // driverId: param.driverId,
                    checkInfo: param.checkInfo
                }).then(res => {
                    if (res.code === 200) {
                        this.showApprModal = false
                        setTimeout(() => {
                            uni.showToast({
                                title: '操作成功',
                                icon: 'success'
                            })
                        })
                        uni.navigateBack()
                    }
                })
            },
            handleSub(status) {
                // this.param.flag =
                this.param = {
                    status
                }
                this.showApprModal = true
            },
        },
    }
</script>
<style>
    page {
        background-color: #f7f7f7;
    }
</style>
<style lang="scss">
    .main_app {
        background-color: #fff;
        padding-bottom: 0;
        .flow_wrap {
            padding: 30rpx 0;
            .flow_title {
                font-weight: 600;
                font-size: 32rpx;
                color: #222222;
                margin-bottom: 24rpx;
            }
            .list {
                .item {
                    display: flex;
                    margin-bottom: 48rpx;
                    position: relative;
                    .separate {
                        position: absolute;
                        width: 4rpx;
                        height: 100%;
                        background-color: #eeeeee;
                        left: 40rpx;
                        transform: translate(-50%, 0);
                        top: 80rpx;
                    }
                    .avatar {
                        width: 80rpx;
                        height: 80rpx;
                        position: relative;
                        margin-right: 20rpx;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        .img {
                            width: 80rpx;
                            height: 80rpx;
                            border-radius: 50%;
                        }
                        .img_name {
                            font-size: 32rpx;
                            color: #FFFFFF;
                        }
                        .status {
                            width: 28rpx;
                            height: 28rpx;
                            border-radius: 50%;
                            position: absolute;
                            right: 0;
                            bottom: 0;
                        }
                    }
                    .content {
                        flex: 1;
                        .head {
                            display: flex;
                            justify-content: space-between;
                            margin-bottom: 4rpx;
                            .event {
                                font-size: 30rpx;
                            }
                            .time {
                                font-size: 26rpx;
                                color: #999999;
                            }
                        }
                        .name_wrap {
                            font-size: 26rpx;
                            color: #777777;
                            .status {
                                color: $uni-color-primary;
                            }
                        }
                        .children {
                            display: flex;
                            flex-wrap: wrap;
                            margin-top: 12rpx;
                            .child {
                                display: flex;
                                flex-direction: column;
                                justify-content: center;
                                align-items: center;
                                margin-right: 12rpx;
                                font-size: 26rpx;
                                color: #777777;
                                .child_img {
                                    width: 48rpx;
                                    height: 48rpx;
                                    border-radius: 50%;
                                    margin-bottom: 2rpx;
                                }
                                .child_name {
                                    margin-bottom: 2rpx;
                                    width: 48rpx;
                                    height: 48rpx;
                                    text-align: center;
                                    justify-content: center;
                                    padding-top: 4rpx;
                                    font-size: 28rpx;
                                    border-radius: 50%;
                                    color: #FFFFFF;
                                    background-color: $uni-color-primary;
                                }
                            }
                        }
                        .remark {
                            margin-top: 12rpx;
                            background-color: #f7f7f7;
                            padding: 14rpx 20rpx;
                            border-radius: 8rpx;
                            font-size: 26rpx;
                            color: #666666;
                            line-height: 36rpx;
                        }
                    }
                    .carbon {
                        display: flex;
                        width: 590rpx;
                        overflow-x: auto;
                        margin-top: 12rpx;
                        .carbon_item {
                            text-align: center;
                            flex-shrink: 0;
                            width: 100rpx;
                            image {
                                width: 60rpx;
                                height: 60rpx;
                                margin: 0 auto;
                            }
                            view {
                                font-size: 26rpx;
                                color: #777777;
                            }
                        }
                    }
                    &:nth-last-child(1) {
                        .separate {
                            height: 0;
                        }
                    }
                }
            }
        }
        .module_list {
            .item {
                padding: 30rpx 0;
                border-bottom: 1rpx solid #e5e5e5;
                .label {
                    font-size: 26rpx;
                    color: #666666;
                    margin-bottom: 20rpx;
                }
                .value {
                    font-size: 30rpx;
                    display: flex;
                    align-items: center;
                    .avatar {
                        margin-right: 20rpx;
                        width: 120rpx;
                        height: 120rpx;
                        border-radius: 8rpx;
                        border: 2rpx solid #e5e5e5;
                    }
                    .info {
                        flex: 1;
                        display: flex;
                        flex-direction: column;
                        justify-content: space-between;
                        font-size: 26rpx;
                        color: #666666;
                        .name {
                            font-size: 30rpx;
                            color: #333333;
                        }
                    }
                }
            }
        }
        .status_wrap {
            position: relative;
            padding: 30rpx 0;
            .name {
                font-weight: 600;
                font-size: 32rpx;
                margin-bottom: 20rpx;
                color: #222222;
            }
            .desc {
                font-size: 26rpx;
                color: #ed4545;
            }
            .gray {
                color: #999999;
            }
            .status {
                position: absolute;
                right: -30rpx;
                top: 0;
                height: 60rpx;
                line-height: 60rpx;
                padding: 0 32rpx;
                border-radius: 0rpx 0rpx 0rpx 30rpx;
                background-color: #e9edff;
                color: $uni-color-primary;
            }
            .status_img {
                position: absolute;
                right: 0rpx;
                top: 20rpx;
                width: 120rpx;
            }
        }
        .main_footer {
            padding-bottom: 64rpx;
            display: flex;
            justify-content: space-between;
            width: 100%;
            left: 0;
            // padding: 30rpx 10rpx 60rpx;
            display: flex;
            justify-content: space-between;
            background: #ffffff;
            .btn {
                width: 336rpx;
                height: 88rpx;
                line-height: 88rpx;
                background: #ffffff;
                border-radius: 44rpx;
                border: 1rpx solid #999999;
                font-size: 32rpx;
                text-align: center;
                margin: 16rpx 0;
            }
            .agree {
                background: $uni-color-primary;
                color: #fff;
                border: 1rpx solid $uni-color-primary;
            }
        }
        .appr_modal {
            padding: 36rpx 30rpx 0;
            .title {
                font-weight: 600;
                font-size: 32rpx;
                color: #222222;
                margin-bottom: 40rpx;
                text-align: center;
            }
            textarea {
                box-sizing: border-box;
                width: 690rpx;
                background-color: #f7f7f7;
                font-size: 28rpx;
                color: #333333;
                padding: 24rpx;
                border-radius: 8rpx;
                margin-bottom: 30rpx;
            }
        }
        .emyty {
            width: 750rpx;
            height: 20rpx;
            background-color: #f7f7f7;
            margin: 0 -30rpx;
        }
    }
</style>
h5/pages/staffLogin/login.vue
@@ -71,7 +71,7 @@
  data() {
    return {
      form: {
        username: '13996529050',
        username: '18056814089',
        password: '123456',
                code: 1
      },
pda/manifest.json
@@ -16,13 +16,13 @@
            "historyApiFallback": true,
            "disableHostCheck": true,
            "proxy": {
                "/admin_interface": {
                "/gateway_interface": {
                    // è¿™ä¸ªå­—段名需与你配置的basePrefixUrl一致,系统识别到带有/dev-api请求的地址时,会在前面拼接上代理服务器地址
                    // "target" : "http://192.168.0.173/admin_interface", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    "target": "http://192.168.0.139:10010", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    "target" : "http://10.50.250.178:8088/gateway_interface", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    // "target": "http://192.168.0.139:10010", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    "changeOrigin": true, // å…è®¸è·¨åŸŸ 
                    "pathRewrite": {
                        "^/admin_interface": "" // é‡å†™åœ°å€ï¼Œå¦‚果实际接口中是不带/dev-api,需要将这个前缀置空,因为这个前缀只是为了识别用,识别完之后就没用了
                        "^/gateway_interface": "" // é‡å†™åœ°å€ï¼Œå¦‚果实际接口中是不带/dev-api,需要将这个前缀置空,因为这个前缀只是为了识别用,识别完之后就没用了
                    }
                }
            },
pda/pages.json
@@ -13,7 +13,7 @@
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "调度平台",
                "navigationStyle": "custom",
                "enablePullDownRefresh": false
            }
        },
pda/pages/index/control.vue
@@ -8,7 +8,7 @@
            <view class="data_list">
              <view class="line" v-for="(platform, i) in item.platformList" :key="platform.id">
                <view class="name">{{platform.name}}</view>
                <u-switch v-model="platform.status" activeColor="#279BAA" inactiveColor="#cccccc" :inactiveValue="0" :activeValue="1" @change="e => changeStatus(platform)" />
                <u-switch v-model="platform.status" activeColor="#279BAA" inactiveColor="#cccccc" :inactiveValue="1" :activeValue="0" @change="e => changeStatus(platform)" />
              </view>
            </view>
        </template>
pda/pages/index/index.vue
@@ -1,30 +1,37 @@
<template>
  <view class="main_app">
    <view class="banner">
      <image src="@/static/banner_diaodu@2x.png" mode=""></image>
    </view>
    <view class="module">
      <view class="item" @click="jump('/pages/index/center')">
        <image src="@/static/ic_yuetaidiaodu@2x.png" mode=""></image>
        <view class="text">月台调度中心</view>
      </view>
      <view class="item" @click="jump('/pages/index/queueup')">
        <image src="@/static/ic_cheliangpaidui@2x.png" mode=""></image>
        <view class="text">车队排队情况</view>
      </view>
      <view class="item" @click="jump('/pages/index/control')">
        <image src="@/static/ic_qiyong@2x.png" mode=""></image>
        <view class="text">月台启用停用</view>
      </view>
      <view class="item" @click="jump('/pages/index/set')">
        <image src="@/static/ic_peizhiyuetai@2x.png" mode=""></image>
        <view class="text">配置显示月台</view>
      </view>
    </view>
    <!-- footer -->
    <view class="main_footer">
      <image src="@/static/logo@2x.png" mode=""></image>
      <text>安徽安泰物流有限责任公司版权所有</text>
  <view class="main_app">
        <view class="main_header">
            <image src="../../static/back.svg" class="back"></image>
            <view class="title">调度平台</view>
            <view class="loginout" @click="loginout">退出登录</view>
        </view>
    <view class="main_content">
        <view class="banner">
          <image src="@/static/banner_diaodu@2x.png" mode=""></image>
        </view>
        <view class="module">
          <view class="item" @click="jump('/pages/index/center')">
            <image src="@/static/ic_yuetaidiaodu@2x.png" mode=""></image>
            <view class="text">月台调度中心</view>
          </view>
          <view class="item" @click="jump('/pages/index/queueup')">
            <image src="@/static/ic_cheliangpaidui@2x.png" mode=""></image>
            <view class="text">车队排队情况</view>
          </view>
          <view class="item" @click="jump('/pages/index/control')">
            <image src="@/static/ic_qiyong@2x.png" mode=""></image>
            <view class="text">月台启用停用</view>
          </view>
          <view class="item" @click="jump('/pages/index/set')">
            <image src="@/static/ic_peizhiyuetai@2x.png" mode=""></image>
            <view class="text">配置显示月台</view>
          </view>
        </view>
        <!-- footer -->
        <view class="main_footer">
          <image src="@/static/logo@2x.png" mode=""></image>
          <text>安徽安泰物流有限责任公司版权所有</text>
        </view>
    </view>
  </view>
</template>
@@ -39,7 +46,24 @@
  onLoad() {
  },
  methods: {
  methods: {
        loginout() {
            uni.showModal({
                title: '提示',
                content: '确认要退出登录吗',
                success: (res) => {
                    if (res.confirm) {
                        uni.clearStorageSync({})
                        uni.redirectTo({
                            url: '/pages/index/login'
                        })
                    } else if (res.cancel) {
                        console.log('用户点击取消');
                    }
                }
            });
        },
    jump(path) {
      uni.navigateTo({
        url: path
@@ -48,11 +72,32 @@
  }
}
</script>
<style lang="scss">
<style lang="scss">
    .main_header{
        width: 100%;
        height: 176rpx;
        padding: 88rpx 30rpx 0;
        display: flex;
        justify-content: space-between;
        align-items: center;
        background-color: $uni-color-primary;
        color: #fff;
        .back{
            width: 42rpx;
            height: 42rpx;
        }
        .title{
            font-weight: 500;
            font-size: 36rpx;
        }
    }
.main_app {
  padding: 30rpx;
  min-height: 100vh;
  background: #f7f7f7;
  background: #f7f7f7;
    padding: 0;
    .main_content{
        padding: 30rpx;
    }
  .banner {
    width: 100%;
    height: 270rpx;
pda/pages/index/login.vue
@@ -4,9 +4,6 @@
    <image class="login_logo" src="@/static/logo@2x.png" mode="widthFix" />
    <view class="login_title" style="marginTop: 40rpx;">安泰物流智慧园区</view>
    <view class="login_title" style="marginBottom: 60rpx;">数字化月台调度平台</view>
        <view class="">
            {{err}}
        </view>
    <view class="login_list">
      <view class="login_list_item">
        <image src="@/static/login_ic_phone@2x.png" mode="widthFix" />
@@ -91,7 +88,7 @@
              })
            }
          }, err => {
                this.err = JSON.stringify(err)
                // this.err = JSON.stringify(err)
            })
        },
    getContent() {
pda/static/back.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1727082453936" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4342" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M395.21518 513.604544l323.135538-312.373427c19.052938-18.416442 19.052938-48.273447 0-66.660212-19.053961-18.416442-49.910737-18.416442-68.964698 0L291.75176 480.290811c-19.052938 18.416442-19.052938 48.273447 0 66.660212l357.633237 345.688183c9.525957 9.207709 22.01234 13.796214 34.497699 13.796214 12.485359 0 24.971741-4.588505 34.466999-13.82896 19.052938-18.416442 19.052938-48.242747 0-66.660212L395.21518 513.604544z" fill="#ffffff" p-id="4343"></path></svg>
pda/utils/config.js
@@ -1,5 +1,5 @@
export const baseUrl = 'admin_interface/'
export const baseUrl = 'gateway_interface/'
// export const baseUrl = 'http://192.168.0.139:10010/admin_interface/'
export const uploadAvatar = `${baseUrl}visitsAdmin/cloudService/web/public/uploadFtp.do`
export const uploadUrl = `${baseUrl}visitsAdmin/cloudService/public/uploadBatch`
server/meeting/meeting_service/src/main/java/com/doumee/service/business/impl/BookingsServiceImpl.java
@@ -1133,7 +1133,7 @@
                    .eq(Bookings::getRoomId,bookings.getRoomId())
                    .ne(Bookings::getId,bookings.getId())
            )>Constants.ZERO){
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"存在未开启会议,无法进行开始会议");
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"存在未开启会议,无法开始会议");
            };
            if(bookingsMapper.selectCount(new QueryWrapper<Bookings>()
@@ -1144,11 +1144,11 @@
                    .eq(Bookings::getStatus,Constants.ZERO)
                    .eq(Bookings::getRoomId,bookings.getRoomId())
            )>Constants.ZERO){
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"当前开启时间与其他会议存在冲突,无法进行开始会议");
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"当前开启时间与其他会议存在冲突,无法开始会议");
            };
        }else{
            if(bookings.getStartTime().getTime() > System.currentTimeMillis()){
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"未到会议申请开始时间,无法进行开始");
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"未到会议申请开始时间,无法开始");
            }
        }
        bookings.setStartTimeReal(new Date());
server/meeting/meeting_service/src/main/java/com/doumee/service/business/impl/RoomsServiceImpl.java
@@ -370,7 +370,7 @@
        Integer re = recordisExist(rooms.getId());
        if (Constants.equalsInteger(re, Constants.ONE)) {
            //存下预约记录不允许更新开放时间和粒度分钟
           // throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "会议室存在预约中的记录,不允许修改");
//            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "会议室存在预约中的记录,不允许修改");
            rooms.setStartTime(null);
            rooms.setEndTime(null);
            rooms.setIntervalTime(null);
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/PlatformJobCloudController.java
@@ -10,6 +10,7 @@
import com.doumee.core.utils.Constants;
import com.doumee.dao.business.model.PlatformJob;
import com.doumee.dao.web.reqeust.JobDetailDTO;
import com.doumee.dao.web.reqeust.SignInDTO;
import com.doumee.service.business.PlatformJobService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -89,4 +90,12 @@
    public ApiResponse<PlatformJob>  jobDetail (@RequestBody JobDetailDTO jobDetailDTO, @RequestHeader(Constants.HEADER_USER_TOKEN) String token){
        return ApiResponse.success(platformJobService.getDetail(jobDetailDTO));
    }
    @ApiOperation("任务签到")
    @PostMapping("/signIn")
    public ApiResponse  signIn (@RequestBody SignInDTO signInDTO, @RequestHeader(Constants.HEADER_USER_TOKEN) String token){
        signInDTO.setLoginUserInfo(getLoginUser(token));
        platformJobService.signIn(signInDTO);
        return ApiResponse.success("操作成功");
    }
}
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/openapi/HkOpenApiController.java
@@ -195,4 +195,12 @@
    public ApiResponse<List<PlatformWarnEventListResponse>> warningEventList(@RequestBody PlatformWarnEventListRequest param) {
        return ApiResponse.success(new ArrayList<>());
    }
    @LoginNoRequired
    @PreventRepeat
    @ApiOperation("【月台】月台状态")
    @PostMapping("/platform/getStatusList")
    public ApiResponse<List<PlatformStatusListResponse>> getStatusList() {
        return ApiResponse.success(platformService.getPlatformStatusList());
    }
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Platform.java
@@ -46,7 +46,6 @@
    @ApiModelProperty(value = "更新时间")
    @ExcelColumn(name="更新时间")
    private Date editDate;
    @ApiModelProperty(value = "是否删除0否 1是", example = "1")
@@ -102,7 +101,6 @@
    @ApiModelProperty(value = "最后事件推送时间")
    @ExcelColumn(name="最后事件推送时间")
    private Date lastEventTime;
    @ApiModelProperty(value = "监控点名称,多个用英文逗号隔开")
@@ -158,10 +156,10 @@
    private String groupName;
    @ApiModelProperty(value = "关联LED编码集合,英文逗号隔开", example = "1")
    @TableField(exist = false)
    private String ledIds;
    private List<Integer> ledIds;
    @ApiModelProperty(value = "关联广播编码集合,英文逗号隔开", example = "1")
    @TableField(exist = false)
    private String broadcastIds;
    private List<Integer> broadcastIds;
    @ApiModelProperty(value = "关联LED名称集合,英文逗号隔开", example = "1")
    @TableField(exist = false)
    private String ledNames;
@@ -185,6 +183,10 @@
    @TableField(exist = false)
    private Integer workStatus;
    @ApiModelProperty(value = "作业车辆车牌照")
    @TableField(exist = false)
    private String workCarCode;
    @ApiModelProperty(value = "月台作业数据")
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/PlatformJob.java
@@ -95,8 +95,8 @@
    @ExcelColumn(name="签到时间")
    private Date signDate;
    @ApiModelProperty(value = "签到方式 0app签到 1扫码签到", example = "1")
    @ExcelColumn(name="签到方式 0app签到 1扫码签到")
    @ApiModelProperty(value = "签到方式 0app签到 1扫码签到 2后台签到", example = "1")
    @ExcelColumn(name="签到方式 0app签到 1扫码签到 2后台签到")
    private Integer singType;
    @ApiModelProperty(value = "通知WMS作业绑定月台时间")
    @ExcelColumn(name="通知WMS作业绑定月台时间")
server/visits/dmvisit_service/src/main/java/com/doumee/dao/openapi/response/PlatformStatusListResponse.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.doumee.dao.openapi.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2023/12/7 11:19
 */
@Data
@ApiModel("【月台】月台状态")
public class PlatformStatusListResponse {
    @ApiModelProperty(value = "月台ID" )
    private String platformHkId;
    @ApiModelProperty(value = "月台名称" )
    private String platformName;
    @ApiModelProperty(value = "车牌号" )
    private String carCode;
    @ApiModelProperty(value = "月台状态 0-无车 1-有车 2-超时停靠 3-错误停靠" )
    private Integer status;
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/openapi/response/PlatformWarnEventListResponse.java
@@ -21,4 +21,8 @@
    private Date createDate;
    @ApiModelProperty(value = "事件内容说明")
    private String content;
    @ApiModelProperty(value = "月台名称")
    private String platformName;
    @ApiModelProperty(value = "月台编码")
    private String platfromHkId;
}
server/visits/dmvisit_service/src/main/java/com/doumee/dao/web/reqeust/SignInDTO.java
@@ -21,7 +21,7 @@
    @ApiModelProperty(value = "任务主键")
    private Integer jobId;
    @ApiModelProperty(value = "签到类型: 0=app签到 1=扫码签到")
    @ApiModelProperty(value = "签到类型: 0=app签到 1=扫码签到 2=后台签到")
    private Integer signType;
    @ApiModelProperty(value = "签到二维码值")
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/PlatformService.java
@@ -4,6 +4,7 @@
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.model.Platform;
import com.doumee.dao.openapi.response.PlatformNumByStatusResponse;
import com.doumee.dao.openapi.response.PlatformStatusListResponse;
import java.util.List;
@@ -101,4 +102,6 @@
    PlatformNumByStatusResponse getPlatformNumByStatusResponse();
    List<PlatformStatusListResponse>  getPlatformStatusList();
}
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/PlatformJobServiceImpl.java
@@ -239,8 +239,8 @@
                .eq(pageWrap.getModel().getPlatformGroupId() != null, PlatformJob::getPlatformGroupId, pageWrap.getModel().getPlatformGroupId())
                .apply(pageWrap.getModel().getQueryStatus() != null, " find_in_set(t.`STATUS`,'"+pageWrap.getModel().getQueryStatus()+"')")
                .ge(pageWrap.getModel().getBeginWorkDateStart() != null, PlatformJob::getStartDate, Utils.Date.getStart(pageWrap.getModel().getBeginWorkDateStart()))
                .le(pageWrap.getModel().getBeginWorkDateEnd() != null, PlatformJob::getStartDate, Utils.Date.getEnd(pageWrap.getModel().getBeginWorkDateEnd()))
                .ge(pageWrap.getModel().getBeginWorkDateStart() != null, PlatformJob::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getBeginWorkDateStart()))
                .le(pageWrap.getModel().getBeginWorkDateEnd() != null, PlatformJob::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getBeginWorkDateEnd()))
                .eq(pageWrap.getModel().getJobType() != null && Constants.equalsInteger(Constants.ONE,pageWrap.getModel().getJobType()), PlatformJob::getType, Constants.platformJobType.sgscxh)
                .ne(pageWrap.getModel().getJobType() != null && Constants.equalsInteger(Constants.ZERO,pageWrap.getModel().getJobType()), PlatformJob::getType, Constants.platformJobType.sgscxh)
        ;
@@ -373,7 +373,8 @@
            }else{
                platformJob.setWaitTime("等待叫号");
            }
        }else if(Constants.equalsInteger(platformJob.getStatus(),Constants.PlatformJobStatus.WORKING.getKey())){
        }else if(Constants.equalsInteger(platformJob.getStatus(),Constants.PlatformJobStatus.WORKING.getKey())
        || Constants.equalsInteger(platformJob.getStatus(),Constants.PlatformJobStatus.DONE.getKey())){
            //查询最后开始任务的月台记录  æ—¥å¿—表  å› ä¸ºå­˜åœ¨å¼‚常挂起 è½¬ç§» ç­‰é—®é¢˜
            PlatformLog platformLog = platformLogMapper.selectOne(new QueryWrapper<PlatformLog>().lambda()
                    .eq(PlatformLog::getJobId,platformJob.getId())
@@ -416,7 +417,7 @@
                .leftJoin(Platform.class,Platform::getId,PlatformJob::getPlatformId)
                .eq(PlatformJob::getIsdeleted,Constants.ZERO)
                .eq(PlatformJob::getDrivierPhone,loginUserInfo.getMobile())
                .like(PlatformJob::getArriveDate,DateUtil.getCurrDate())
//                .like(PlatformJob::getArriveDate,DateUtil.getCurrDate())
                .orderByDesc(PlatformJob::getId)
        );
        for (PlatformJob platformJob:platformJobList) {
@@ -462,8 +463,9 @@
        PlatformJob oldPlatformJob = new PlatformJob();
        BeanUtils.copyProperties(platformJob,oldPlatformJob);
        platformJob.setConfirmTaskDate(new Date());
        platformJob.setArriveDate(confirmTaskDTO.getArriveDate());
        platformJob.setCarCodeBack(confirmTaskDTO.getCarCodeBack());
        platformJob.setStatus(Constants.PlatformJobStatus.WART_SIGN_IN.getKey());
        platformJob.setEditDate(new Date());
        platformJobMapper.updateById(platformJob);
@@ -488,19 +490,31 @@
        if(Objects.isNull(platformJob)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(platformJob.getStatus(),Constants.PlatformJobStatus.WART_SIGN_IN.getKey())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"业务状态已流转,请刷新查看");
        }
        PlatformJob oldPlatformJob = new PlatformJob();
        BeanUtils.copyProperties(platformJob,oldPlatformJob);
        if(Constants.equalsInteger(signInDTO.getSignType(),Constants.ZERO)){
            if(!Constants.equalsInteger(platformJob.getStatus(),Constants.PlatformJobStatus.WART_SIGN_IN.getKey())){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"业务状态已流转,请刷新查看");
            }
            this.distanceSignIn(signInDTO,platformJob);
        }else if(Constants.equalsInteger(signInDTO.getSignType(),Constants.ONE)){
            if(!Constants.equalsInteger(platformJob.getStatus(),Constants.PlatformJobStatus.WART_SIGN_IN.getKey())){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"业务状态已流转,请刷新查看");
            }
            this.sceneSignIn(signInDTO);
        }else if(Constants.equalsInteger(signInDTO.getSignType(),Constants.TWO)){
            if(!(Constants.equalsInteger(platformJob.getStatus(),Constants.PlatformJobStatus.WAIT_CONFIRM.getKey())||
                    Constants.equalsInteger(platformJob.getStatus(),Constants.PlatformJobStatus.WART_SIGN_IN.getKey()))
            ){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"业务状态已流转,请刷新查看");
            }
        }else{
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"签到类型错误");
        }
        platformJob.setSignDate(new Date());
        platformJob.setSingType(Constants.ZERO);
        platformJob.setSingType(signInDTO.getSignType());
        platformJob.setStatus(Constants.PlatformJobStatus.WAIT_CALL.getKey());
        platformJobMapper.updateById(platformJob);
        //存储操作日志
@@ -508,12 +522,12 @@
                Constants.PlatformJobLogType.SIGN.getInfo());
    }
    public void distanceSignIn(SignInDTO signInDTO , PlatformJob platformJob){
        if(Objects.isNull(signInDTO.getLat())
                || Objects.isNull(signInDTO.getLnt())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"经纬度信息异常");
        }
        //获取签到点的经纬度
        Double lat = Double.parseDouble(systemDictDataBiz.queryByCode(Constants.PLATFORM,Constants.SIGN_IN_PLACE_LAT).getCode());
        Double lnt = Double.parseDouble(systemDictDataBiz.queryByCode(Constants.PLATFORM,Constants.SIGN_IN_PLACE_LNT).getCode());
@@ -529,6 +543,7 @@
    }
    public void sceneSignIn(SignInDTO signInDTO){
        if( StringUtils.isNotBlank(signInDTO.getQrCodeKey())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
@@ -716,6 +731,7 @@
        || Constants.equalsInteger(platformJob.getType(),Constants.FOUR)){
            //TODO ä¸‹å‘入园权限
        }
        //存储操作日志
        savePlatformLog(Constants.PlatformJobLogType.IN_WAIT.getKey(),oldPlatformJob,platformJob,
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/PlatformServiceImpl.java
@@ -1,5 +1,6 @@
package com.doumee.service.business.impl;
import cn.emay.sdk.util.StringUtil;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.LoginUserInfo;
@@ -7,25 +8,28 @@
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.Constants;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.DeviceMapper;
import com.doumee.dao.business.PlatformDeviceMapper;
import com.doumee.dao.business.PlatformMapper;
import com.doumee.dao.business.join.PlatformJoinMapper;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.business.model.Platform;
import com.doumee.dao.business.model.PlatformGroup;
import com.doumee.dao.business.model.*;
import com.doumee.dao.openapi.response.PlatformNumByStatusResponse;
import com.doumee.dao.openapi.response.PlatformStatusListResponse;
import com.doumee.service.business.PlatformDeviceService;
import com.doumee.service.business.PlatformService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -40,10 +44,62 @@
    private PlatformMapper platformMapper;
    @Autowired
    private PlatformJoinMapper platformJoinMapper;
    @Autowired
    private PlatformDeviceMapper platformDeviceMapper;
    @Autowired
    private DeviceMapper deviceMapper;
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public Integer create(Platform platform) {
        platform.setCreateDate(new Date());
        platform.setIsdeleted(Constants.ZERO);
        platform.setCreator(platform.getLoginUserInfo().getId());
        platformMapper.insert(platform);
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(platform.getLedIds())){
            List<PlatformDevice> platformDeviceList = new ArrayList<>();
            for (Integer ledId:platform.getLedIds()) {
                Device device = deviceMapper.selectById(ledId);
                if(Objects.isNull(device)){
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"未查询到led设备信息【"+ledId+"】");
                }
                PlatformDevice platformDevice = new PlatformDevice();
                platformDevice.setIsdeleted(Constants.ZERO);
                platformDevice.setPlatformId(platform.getId());
                platformDevice.setCreateDate(new Date());
                platformDevice.setCreator(platform.getLoginUserInfo().getId());
                platformDevice.setType(Constants.ZERO);
                platformDevice.setDeviceId(ledId.toString());
                platformDevice.setHkId(device.getHkId());
                platformDevice.setName(device.getName());
                platformDeviceList.add(platformDevice);
            }
            platformDeviceMapper.insert(platformDeviceList);
        }
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(platform.getBroadcastIds())){
            List<PlatformDevice> platformDeviceList = new ArrayList<>();
            for (Integer broadcastId:platform.getBroadcastIds()) {
                Device device = deviceMapper.selectById(broadcastId);
                if(Objects.isNull(device)){
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"未查询到广播设备信息【"+broadcastId+"】");
                }
                PlatformDevice platformDevice = new PlatformDevice();
                platformDevice.setIsdeleted(Constants.ZERO);
                platformDevice.setPlatformId(platform.getId());
                platformDevice.setCreateDate(new Date());
                platformDevice.setCreator(platform.getLoginUserInfo().getId());
                platformDevice.setType(Constants.TWO);
                platformDevice.setDeviceId(broadcastId.toString());
                platformDevice.setHkId(device.getHkId());
                platformDevice.setName(device.getName());
                platformDeviceList.add(platformDevice);
            }
            platformDeviceMapper.insert(platformDeviceList);
        }
        return platform.getId();
    }
@@ -67,7 +123,60 @@
    }
    @Override
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public void updateById(Platform platform) {
        platform.setEditor(platform.getLoginUserInfo().getId());
        platform.setEditDate(new Date());
        //删除LED/广播数据
        platformDeviceMapper.delete(new QueryWrapper<PlatformDevice>().lambda()
                .eq(PlatformDevice::getPlatformId,platform.getId())
                .in(PlatformDevice::getType,Constants.ZERO,Constants.TWO)
        );
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(platform.getLedIds())){
            List<PlatformDevice> platformDeviceList = new ArrayList<>();
            String ledNames = "";
            for (Integer ledId:platform.getLedIds()) {
                Device device = deviceMapper.selectById(ledId);
                if(Objects.isNull(device)){
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"未查询到led设备信息【"+ledId+"】");
                }
                PlatformDevice platformDevice = new PlatformDevice();
                platformDevice.setIsdeleted(Constants.ZERO);
                platformDevice.setPlatformId(platform.getId());
                platformDevice.setCreateDate(new Date());
                platformDevice.setCreator(platform.getLoginUserInfo().getId());
                platformDevice.setType(Constants.ZERO);
                platformDevice.setDeviceId(ledId.toString());
                platformDevice.setHkId(device.getHkId());
                platformDevice.setName(device.getName());
                platformDeviceList.add(platformDevice);
            }
            platformDeviceMapper.insert(platformDeviceList);
            platform.setLedNames(ledNames);
        }
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(platform.getBroadcastIds())){
            List<PlatformDevice> platformDeviceList = new ArrayList<>();
            String ledNames = "";
            for (Integer broadcastId:platform.getBroadcastIds()) {
                Device device = deviceMapper.selectById(broadcastId);
                if(Objects.isNull(device)){
                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"未查询到广播设备信息【"+broadcastId+"】");
                }
                PlatformDevice platformDevice = new PlatformDevice();
                platformDevice.setIsdeleted(Constants.ZERO);
                platformDevice.setPlatformId(platform.getId());
                platformDevice.setCreateDate(new Date());
                platformDevice.setCreator(platform.getLoginUserInfo().getId());
                platformDevice.setType(Constants.TWO);
                platformDevice.setDeviceId(broadcastId.toString());
                platformDevice.setHkId(device.getHkId());
                platformDevice.setName(device.getName());
                platformDeviceList.add(platformDevice);
            }
            platformDeviceMapper.insert(platformDeviceList);
        }
        platformMapper.updateById(platform);
    }
@@ -160,7 +269,35 @@
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        return PageData.from(platformMapper.selectJoinPage(page,Platform.class, queryWrapper));
        PageData<Platform> platformPageData = PageData.from(platformMapper.selectJoinPage(page,Platform.class, queryWrapper));
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(platformPageData.getRecords())){
            for (Platform platform:platformPageData.getRecords()) {
                List<PlatformDevice> ledDevice =  platformDeviceMapper.selectList(new QueryWrapper<PlatformDevice>().lambda()
                        .eq(PlatformDevice::getPlatformId,platform.getId())
                        .eq(PlatformDevice::getType,Constants.ZERO)
                );
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(ledDevice)){
                    platform.setLedNames(String.join(",", ledDevice.stream().map(m->m.getName()).collect(Collectors.toList())));
                    platform.setLedIds(
                            ledDevice.stream().map(m->Integer.valueOf(m.getDeviceId())).collect(Collectors.toList())
                    );
                }
                List<PlatformDevice> broadcastDevice =  platformDeviceMapper.selectList(new QueryWrapper<PlatformDevice>().lambda()
                        .eq(PlatformDevice::getPlatformId,platform.getId())
                        .eq(PlatformDevice::getType,Constants.TWO)
                );
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(broadcastDevice)){
                    platform.setBroadcastNames(String.join(",", broadcastDevice.stream().map(m->m.getName()).collect(Collectors.toList())));
                    platform.setBroadcastIds(
                            broadcastDevice.stream().map(m->Integer.valueOf(m.getDeviceId())).collect(Collectors.toList())
                    );
                }
            }
        }
        return platformPageData;
    }
    @Override
@@ -197,6 +334,35 @@
    @Override
    public List<PlatformStatusListResponse>  getPlatformStatusList(){
        List<Platform> platformList =  platformJoinMapper.selectJoinList(Platform.class,new MPJLambdaWrapper<Platform>()
                .selectAll(Platform.class)
                .select(" ( select count(1) from platform_job pj where t.id = pj.PLATFORM_ID and pj.STATUS = "+Constants.PlatformJobStatus.WORKING.getKey()+" ) as workStatus ")
                .select(" ( select pj.CAR_CODE_FRONT from platform_job pj where t.id = pj.PLATFORM_ID and pj.STATUS = "+Constants.PlatformJobStatus.WORKING.getKey()+" limit 1  ) as workCarCode ")
                .eq(Platform::getIsdeleted,Constants.ZERO)
        );
        List<PlatformStatusListResponse> platformStatusListResponses = new ArrayList<>();
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(platformList)){
            for (Platform platform:platformList) {
                PlatformStatusListResponse response = new PlatformStatusListResponse();
                response.setPlatformHkId(platform.getHkId());
                response.setPlatformName(platform.getName());
                response.setStatus(platform.getPlatformStatus());
                if(Constants.equalsInteger(platform.getPlatformStatus(),Constants.ONE)){
                    response.setCarCode(platform.getWorkCarCode());
                }
            }
        }
        return platformStatusListResponses;
    }
}