| | |
| | | method: 'post' |
| | | }) |
| | | } |
| | | |
| | | // 检查任务是否重复(根据联系人电话和创建日期) |
| | | export function checkTaskDuplicate(phone, createDate) { |
| | | return request({ |
| | | url: '/task/checkDuplicate', |
| | | method: 'get', |
| | | params: { |
| | | phone: phone, |
| | | createDate: createDate |
| | | } |
| | | }) |
| | | } |
| | |
| | | title: '检查附件...' |
| | | }); |
| | | |
| | | const response = await checkTaskConsentAttachment(taskId); |
| | | // 注意:这里会被请求拦截器处理,code !== 200 时会 reject |
| | | const response = await checkTaskConsentAttachment(taskId).catch(err => { |
| | | // 拦截器 reject 的情况,返回一个默认对象 |
| | | console.log('请求被拦截器 reject,err:', err); |
| | | return { code: -1, msg: '未上传知情同意书' }; |
| | | }); |
| | | |
| | | uni.hideLoading(); |
| | | console.log('检查附件结果:', response); |
| | | |
| | | if (response.code === 200) { |
| | | if (response && response.code === 200) { |
| | | // 已上传知情同意书,继续更新状态 |
| | | console.log('已上传知情同意书,继续完成任务'); |
| | | this.$modal |
| | | .confirm("确认任务已完成?") |
| | | .then(() => { |
| | |
| | | }) |
| | | .catch(() => {}); |
| | | } else { |
| | | // 未上传知情同意书,显示提示 |
| | | this.$modal.confirm('任务未上传知情同意书,无法完成任务。是否现在去上传?').then(() => { |
| | | // 未上传知情同意书或其他错误,阻止完成 |
| | | const message = (response && response.msg) || '任务未上传知情同意书,无法完成任务'; |
| | | console.log('未上传知情同意书,阻止完成'); |
| | | |
| | | this.$modal.confirm(message + '。是否现在去上传?').then(() => { |
| | | // 跳转到任务详情页上传附件 |
| | | this.$tab.navigateTo(`/pagesTask/detail?id=${taskId}`); |
| | | }).catch(() => {}); |
| | | } |
| | | } catch (error) { |
| | | uni.hideLoading(); |
| | | console.error('检查附件失败:', error); |
| | | console.error('检查附件异常:', error); |
| | | |
| | | // 如果检查失败,询问用户是否继续 |
| | | this.$modal.confirm('检查附件状态失败,是否继续完成任务?').then(() => { |
| | | this.updateTaskStatus(taskId, status, remark); |
| | | }).catch(() => {}); |
| | | // 如果检查失败(网络异常等),不允许完成任务 |
| | | this.$modal.showToast('检查附件状态失败,无法完成任务'); |
| | | } |
| | | }, |
| | | |
| | |
| | | title: '检查附件...' |
| | | }); |
| | | |
| | | const response = await checkTaskConsentAttachment(taskId); |
| | | // 注意:这里会被请求拦截器处理,code !== 200 时会 reject |
| | | const response = await checkTaskConsentAttachment(taskId).catch(err => { |
| | | // 拦截器 reject 的情况,返回一个默认对象 |
| | | console.log('请求被拦截器 reject,err:', err); |
| | | return { code: -1, msg: '未上传知情同意书' }; |
| | | }); |
| | | |
| | | uni.hideLoading(); |
| | | console.log('检查附件结果:', response); |
| | | |
| | | if (response.code === 200) { |
| | | if (response && response.code === 200) { |
| | | // 已上传知情同意书,继续更新状态 |
| | | console.log('已上传知情同意书,继续完成任务'); |
| | | this.$modal |
| | | .confirm("确认任务已完成?") |
| | | .then(() => { |
| | |
| | | }) |
| | | .catch(() => {}); |
| | | } else { |
| | | // 未上传知情同意书,显示提示 |
| | | this.$modal.confirm('任务未上传知情同意书,无法完成任务。是否现在去上传?').then(() => { |
| | | // 未上传知情同意书或其他错误,阻止完成 |
| | | const message = (response && response.msg) || '任务未上传知情同意书,无法完成任务'; |
| | | console.log('未上传知情同意书,阻止完成'); |
| | | |
| | | this.$modal.confirm(message + '。是否现在去上传?').then(() => { |
| | | // 跳转到任务详情页上传附件 |
| | | uni.navigateTo({ |
| | | url: `/pagesTask/detail?id=${taskId}` |
| | |
| | | } |
| | | } catch (error) { |
| | | uni.hideLoading(); |
| | | console.error('检查附件失败:', error); |
| | | console.error('检查附件异常:', error); |
| | | |
| | | // 如果检查失败,询问用户是否继续 |
| | | this.$modal.confirm('检查附件状态失败,是否继续完成任务?').then(() => { |
| | | this.updateTaskStatus(taskId, status, remark); |
| | | }).catch(() => {}); |
| | | // 如果检查失败(网络异常等),不允许完成任务 |
| | | this.$modal.showToast('检查附件状态失败,无法完成任务'); |
| | | } |
| | | }, |
| | | |
| | |
| | | import { mapState } from 'vuex' |
| | | import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue' |
| | | import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue' |
| | | import { addTask } from "@/api/task" |
| | | import { addTask, checkTaskDuplicate } from "@/api/task" |
| | | import { listAvailableVehicles, getUserBoundVehicle } from "@/api/vehicle" |
| | | import { searchHospitals, searchHospitalsByDeptRegion } from "@/api/hospital" |
| | | import DepartureSelector from './components/DepartureSelector.vue' |
| | |
| | | return |
| | | } |
| | | |
| | | // 获取当前日期(格式YYYY-MM-DD) |
| | | const today = new Date() |
| | | const createDate = today.getFullYear() + '-' + |
| | | String(today.getMonth() + 1).padStart(2, '0') + '-' + |
| | | String(today.getDate()).padStart(2, '0') |
| | | const phone = this.taskForm.patient.phone |
| | | |
| | | // 先检查是否重复 |
| | | uni.showLoading({ |
| | | title: '检查中...' |
| | | }) |
| | | |
| | | checkTaskDuplicate(phone, createDate).then(response => { |
| | | uni.hideLoading() |
| | | |
| | | // 如果接口返回错误,说明存在重复 |
| | | if (response.code !== 200) { |
| | | this.$modal.showToast(response.msg || '该联系电话在当天已有任务,不能重复提交') |
| | | return |
| | | } |
| | | |
| | | // 检查通过,继续提交 |
| | | this.doSubmitTask() |
| | | }).catch(error => { |
| | | uni.hideLoading() |
| | | console.error('重复性检查失败:', error) |
| | | this.$modal.showToast('检查失败,请重试') |
| | | }) |
| | | }, |
| | | |
| | | // 执行实际的提交操作 |
| | | doSubmitTask() { |
| | | this.$modal.confirm('确定要保存任务吗?').then(() => { |
| | | this.loading = true |
| | | const submitData = this.buildSubmitData() |
| | |
| | | class="form-input" |
| | | type="digit" |
| | | placeholder="请输入行驶公里数" |
| | | v-model="taskForm.distance" |
| | | v-model="taskForm.transferDistance" |
| | | /> |
| | | </view> |
| | | |
| | |
| | | plannedEndTime: '', |
| | | startLocation: '', |
| | | endLocation: '', |
| | | distance: '', |
| | | transferDistance: '', |
| | | remark: '' |
| | | }, |
| | | vehicles: [], |
| | |
| | | // 百度地图返回的距离单位是米,需要转换为公里 |
| | | const distanceInMeters = response.data.distance |
| | | const distanceInKm = distanceInMeters / 1000 |
| | | this.taskForm.distance = distanceInKm.toFixed(2) |
| | | this.taskForm.transferDistance = distanceInKm.toFixed(2) |
| | | |
| | | console.log('距离计算成功:', distanceInMeters, '米 =', distanceInKm, '公里') |
| | | |
| | |
| | | plannedEndTime: this.taskForm.plannedEndTime, |
| | | departureAddress: this.taskForm.startLocation, |
| | | destinationAddress: this.taskForm.endLocation, |
| | | estimatedDistance: this.taskForm.distance ? parseFloat(this.taskForm.distance) : null, |
| | | transferDistance: this.taskForm.transferDistance ? parseFloat(this.taskForm.transferDistance) : null, |
| | | remark: this.taskForm.remark |
| | | } |
| | | |
| | |
| | | class="form-input" |
| | | type="digit" |
| | | placeholder="请输入公里数" |
| | | v-model="taskForm.distance" |
| | | v-model="taskForm.transferDistance" |
| | | /> |
| | | </view> |
| | | |
| | |
| | | }, |
| | | startAddress: '', |
| | | endAddress: '', |
| | | distance: '', |
| | | transferDistance: '', |
| | | price: '' |
| | | }, |
| | | vehicles: [], |
| | |
| | | this.addressCoordinates.endAddress.lat, |
| | | this.addressCoordinates.endAddress.lng |
| | | ).then(distance => { |
| | | this.taskForm.distance = distance.toFixed(2) |
| | | this.taskForm.transferDistance = distance.toFixed(2) |
| | | }).catch(error => { |
| | | console.error('距离计算失败:', error) |
| | | }) |
| | |
| | | passenger: this.taskForm.passenger, |
| | | startAddress: this.taskForm.startAddress, |
| | | endAddress: this.taskForm.endAddress, |
| | | distance: this.taskForm.distance ? parseFloat(this.taskForm.distance) : null, |
| | | transferDistance: this.taskForm.transferDistance ? parseFloat(this.taskForm.transferDistance) : null, |
| | | price: this.taskForm.price ? parseFloat(this.taskForm.price) : null |
| | | } |
| | | |
| | |
| | | title: '检查附件...' |
| | | }); |
| | | |
| | | const response = await checkTaskConsentAttachment(this.taskId); |
| | | // 注意:这里会被请求拦截器处理,code !== 200 时会 reject |
| | | const response = await checkTaskConsentAttachment(this.taskId).catch(err => { |
| | | // 拦截器 reject 的情况,返回一个默认对象 |
| | | console.log('请求被拦截器 reject,err:', err); |
| | | return { code: -1, msg: '未上传知情同意书' }; |
| | | }); |
| | | |
| | | uni.hideLoading(); |
| | | console.log('检查附件结果:', response); |
| | | |
| | | if (response.code === 200) { |
| | | // 后台返回 code: 200 表示已上传,code: -1 表示未上传 |
| | | if (response && response.code === 200) { |
| | | // 已上传知情同意书,继续更新状态 |
| | | console.log('已上传知情同意书,继续完成任务'); |
| | | this.getLocationAndUpdateStatus(status, remark); |
| | | } else { |
| | | // 未上传知情同意书,显示提示 |
| | | this.$modal.confirm('任务未上传知情同意书,无法完成任务。是否现在去上传?').then(() => { |
| | | // 未上传知情同意书或其他错误,阻止完成 |
| | | const message = (response && response.msg) || '任务未上传知情同意书,无法完成任务'; |
| | | console.log('未上传知情同意书,阻止完成'); |
| | | |
| | | this.$modal.confirm(message + '。是否现在去上传?').then(() => { |
| | | // 滚动到附件上传区域 |
| | | this.$nextTick(() => { |
| | | uni.pageScrollTo({ |
| | |
| | | } |
| | | } catch (error) { |
| | | uni.hideLoading(); |
| | | console.error('检查附件失败:', error); |
| | | console.error('检查附件异常:', error); |
| | | |
| | | // 如果检查失败,询问用户是否继续 |
| | | this.$modal.confirm('检查附件状态失败,是否继续完成任务?').then(() => { |
| | | this.getLocationAndUpdateStatus(status, remark); |
| | | }).catch(() => {}); |
| | | // 如果检查失败(网络异常等),不允许完成任务 |
| | | this.$modal.showToast('检查附件状态失败,无法完成任务'); |
| | | } |
| | | }, |
| | | |
| | |
| | | destinationLatitude: this.addressCoordinates.endAddress ? this.addressCoordinates.endAddress.lat : null, |
| | | |
| | | // 距离和价格(主任务字段) |
| | | distance: this.taskForm.distance ? parseFloat(this.taskForm.distance) : null, |
| | | transferDistance: this.taskForm.transferDistance ? parseFloat(this.taskForm.transferDistance) : null, |
| | | price: this.taskForm.price ? parseFloat(this.taskForm.price) : null, |
| | | |
| | | // 乘客信息(嵌套对象) |
| | |
| | | class="form-input" |
| | | type="digit" |
| | | placeholder="请输入行驶公里数" |
| | | v-model="taskForm.distance" |
| | | v-model="taskForm.transferDistance" |
| | | /> |
| | | </view> |
| | | |
| | |
| | | plannedEndTime: '', |
| | | startLocation: '', |
| | | endLocation: '', |
| | | distance: '', |
| | | transferDistance: '', |
| | | remark: '' |
| | | }, |
| | | loading: false |
| | |
| | | this.taskForm.plannedEndTime = this.taskDetail.plannedEndTime || '' |
| | | this.taskForm.startLocation = this.taskDetail.departureAddress || '' |
| | | this.taskForm.endLocation = this.taskDetail.destinationAddress || '' |
| | | this.taskForm.distance = this.taskDetail.estimatedDistance || '' |
| | | this.taskForm.transferDistance = this.taskDetail.transferDistance || '' |
| | | this.taskForm.remark = this.taskDetail.remark || '' |
| | | |
| | | // 设置车辆信息 |
| | |
| | | |
| | | // 监听mixin中的距离计算完成事件 |
| | | this.$once('distance-calculated', (distance) => { |
| | | this.taskForm.distance = this.formatDistance(distance) |
| | | this.taskForm.transferDistance = this.formatDistance(distance) |
| | | }) |
| | | |
| | | this.closeMapSelector() |
| | |
| | | destinationLatitude: this.addressCoordinates.endLocation ? this.addressCoordinates.endLocation.lat : null, |
| | | |
| | | // 距离(主任务字段) |
| | | distance: this.taskForm.distance ? parseFloat(this.taskForm.distance) : null, |
| | | transferDistance: this.taskForm.transferDistance ? parseFloat(this.taskForm.transferDistance) : null, |
| | | |
| | | remark: this.taskForm.remark |
| | | } |
| | |
| | | public AjaxResult appAdd(@RequestBody TaskCreateVO createVO) { |
| | | return toAjax(sysTaskService.insertSysTask(createVO)); |
| | | } |
| | | |
| | | /** |
| | | * 检查任务是否重复(根据联系人电话和创建日期) |
| | | * @param phone 联系人电话 |
| | | * @param createDate 任务创建日期(格式:YYYY-MM-DD) |
| | | * @return 是否存在重复任务 |
| | | */ |
| | | @GetMapping("/checkDuplicate") |
| | | public AjaxResult checkDuplicate( |
| | | @RequestParam("phone") String phone, |
| | | @RequestParam("createDate") String createDate) { |
| | | |
| | | if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(createDate)) { |
| | | return AjaxResult.error("参数不能为空"); |
| | | } |
| | | |
| | | boolean isDuplicate = sysTaskService.checkTaskDuplicate(phone, createDate); |
| | | |
| | | if (isDuplicate) { |
| | | return AjaxResult.error("该联系电话在该日期已有任务,不能重复提交"); |
| | | } |
| | | |
| | | return AjaxResult.success("未发现重复任务"); |
| | | } |
| | | |
| | | /** |
| | | * 修改任务(后台管理端) |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 检查任务是否上传了知情同意书 |
| | | * |
| | | * @param taskId 任务ID |
| | | * @return 检查结果 |
| | | */ |
| | | @PostMapping("/task/check/{taskId}") |
| | | public AjaxResult checkTaskAttachment(@PathVariable("taskId") Long taskId) { |
| | | try { |
| | | |
| | | Boolean ret=taskAttachmentSyncService.checkAttachment(taskId,"1"); |
| | | if(ret){ |
| | | logger.info("检查任务 {} 的知情同意书附件", taskId); |
| | | |
| | | Boolean ret = taskAttachmentSyncService.checkAttachment(taskId, "1"); |
| | | |
| | | if (ret) { |
| | | logger.info("任务 {} 已上传知情同意书", taskId); |
| | | return AjaxResult.success("已上传知情同意书"); |
| | | }else{ |
| | | return AjaxResult.error(-1,"未上传知情同意书"); |
| | | } else { |
| | | logger.warn("任务 {} 未上传知情同意书", taskId); |
| | | return AjaxResult.error(-1, "未上传知情同意书"); |
| | | } |
| | | }catch (Exception e){ |
| | | } catch (Exception e) { |
| | | logger.error("检查任务 {} 的附件失败", taskId, e); |
| | | return AjaxResult.error("检查失败:" + e.getMessage()); |
| | | } |
| | | } |
| | |
| | | public List<SysTask> selectTaskByVehicleIdAndDate(@Param("vehicleId") Long vehicleId, |
| | | @Param("startTime") String startTime, |
| | | @Param("endTime") String endTime); |
| | | |
| | | /** |
| | | * 根据联系人电话和创建日期查询任务数量 |
| | | * |
| | | * @param phone 联系人电话 |
| | | * @param createDate 任务创建日期(格式:YYYY-MM-DD) |
| | | * @return 任务数量 |
| | | */ |
| | | public int countTaskByPhoneAndDate(@Param("phone") String phone, @Param("createDate") String createDate); |
| | | } |
| | |
| | | * @return 结果 |
| | | */ |
| | | public com.ruoyi.common.core.domain.AjaxResult cancelAssigneeReady(Long taskId, Long userId); |
| | | |
| | | /** |
| | | * 检查任务是否重复(根据联系人电话和创建日期) |
| | | * |
| | | * @param phone 联系人电话 |
| | | * @param createDate 任务创建日期(格式:YYYY-MM-DD) |
| | | * @return true-存在重复,false-不重复 |
| | | */ |
| | | public boolean checkTaskDuplicate(String phone, String createDate); |
| | | |
| | | } |
| | |
| | | public AjaxResult cancelAssigneeReady(Long taskId, Long userId) { |
| | | return sysTaskAssigneeService.cancelAssigneeReady(taskId, userId); |
| | | } |
| | | |
| | | /** |
| | | * 检查任务是否重复(根据联系人电话和创建日期) |
| | | * |
| | | * @param phone 联系人电话 |
| | | * @param createDate 任务创建日期(格式:YYYY-MM-DD) |
| | | * @return true-存在重复,false-不重复 |
| | | */ |
| | | @Override |
| | | public boolean checkTaskDuplicate(String phone, String createDate) { |
| | | int count = sysTaskMapper.countTaskByPhoneAndDate(phone, createDate); |
| | | return count > 0; |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | import java.io.BufferedReader; |
| | | import java.io.InputStreamReader; |
| | | import java.io.OutputStream; |
| | | import java.math.BigDecimal; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.net.URLEncoder; |
| | |
| | | return adminID; |
| | | } |
| | | |
| | | private String getCoo(BigDecimal lng, BigDecimal lat){ |
| | | return lng+","+lat; |
| | | } |
| | | /** |
| | | * 构建同步参数 |
| | | */ |
| | |
| | | params.put("ServiceOrdCoName", StringUtils.nvl(emergency.getPatientContact(), "")); |
| | | params.put("ServiceOrdCoPhone", StringUtils.nvl(emergency.getPatientPhone(), "")); |
| | | params.put("ServiceOrdCoTies", ""); // 联系人与患者关系 |
| | | |
| | | //ServiceOrdTraVia |
| | | // 患者信息 |
| | | params.put("ServiceOrdPtName", StringUtils.nvl(emergency.getPatientName(), "")); |
| | | params.put("ServiceOrdPtAge", ""); // 年龄 |
| | |
| | | params.put("ServiceOrdTraStreetCoo", ""); // 出发地坐标 |
| | | params.put("ServiceOrdTraEnd", StringUtils.nvl(task.getDestinationAddress(), StringUtils.nvl(emergency.getHospitalInAddress(), ""))); |
| | | params.put("ServiceOrdTraEndCoo", ""); // 目的地坐标 |
| | | params.put("ServiceOrdTraVia", ""); // 途经地 |
| | | params.put("ServiceOrdTraVia", emergency.getHospitalOutAddress()!=null ? emergency.getHospitalOutAddress() : ""); // 途经地 |
| | | |
| | | // 距离和价格信息 |
| | | params.put("ServiceOrdViaDistance", "0"); // 中途距离 |
| | | params.put("ServiceOrdTraDistance", emergency.getTransferDistance() != null ? emergency.getTransferDistance().toString() : "0"); |
| | | params.put("ServiceOrdTraDuration", ""); // 预计行程时间 |
| | | params.put("ServiceOrdTraUnitPrice", "0"); // 单价/公里 |
| | | params.put("ServiceOrdTraOfferPrice", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); |
| | | // params.put("ServiceOrdTraOfferPrice", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); |
| | | params.put("ServiceOrdTraTxnPrice", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); |
| | | params.put("ServiceOrdTraPrePayment", "0"); // 需预付款 |
| | | params.put("SettlementPrice", "0"); // 结算价 |
| | |
| | | public class TaskStatusPushConverter { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(TaskStatusPushConverter.class); |
| | | |
| | | /** 服务单状态 |
| | | * 1 咨询单 |
| | | * 2 未调度 |
| | | * 3 已调度 |
| | | * 4 取消单 |
| | | */ |
| | | /** |
| | | * 1 1 - 完全未确认 |
| | | * 2 2 - 部分已确认 |
| | | * 3 未出车 |
| | | * 4 3 - 已出车(去接患者途中) |
| | | * 5 已出车(等待患者) |
| | | * 6 4 - 已出车(服务中) |
| | | * 7 5 - 已送达(回程中) |
| | | * 8 已返回 |
| | | * 9 跑空单,已返回 |
| | | * 10 取消 |
| | | * 0 0 - 新调度单(未下发) |
| | | * 11 已提交,等待审核 |
| | | * 12 审核完成 |
| | | * 13 审核不通过 |
| | | * 14 已驻点 |
| | | */ |
| | | /** |
| | | * 将新系统TaskStatus转换为旧系统状态码 |
| | | * |
| | |
| | | return 8; |
| | | case CANCELLED: // 已取消 |
| | | return 10; |
| | | case ARRIVED: // 已到达 |
| | | return 6; |
| | | case PENDING: // 待处理 - 不同步 |
| | | case ARRIVED: // 已到达 - 不同步 |
| | | default: |
| | | // log.debug("新系统状态不需要同步到旧系统: {}", taskStatus.getInfo()); |
| | | return null; |
| | |
| | | #{taskId} |
| | | </foreach> |
| | | </delete> |
| | | |
| | | <!-- 根据联系人电话和创建日期查询任务数量 --> |
| | | <select id="countTaskByPhoneAndDate" resultType="int"> |
| | | select count(1) |
| | | from sys_task t |
| | | inner join sys_task_emergency e on t.task_id = e.task_id |
| | | where t.del_flag = '0' |
| | | and e.patient_phone = #{phone} |
| | | and DATE(t.create_time) = #{createDate} |
| | | </select> |
| | | </mapper> |