Files
jg_app/src/pages/views/CanVehicle/index.vue
2026-04-10 17:10:36 +08:00

777 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="container" style="padding-top: 13vw">
<TopNav navTitle="车辆盘查" :showRight="false" :showLeft="true" />
<div class="tip_text">
盘查结果{{ clxx.pcbqsm }}
</div>
<!-- <div class="head-nav-banner" v-if="clxx.jdcsyr"></div>
<div class="top" v-if="clxx.jdcsyr">
<div class="basic-info">
<div class="img-box">
<img :class="_getBase64(clxx)" :src="clxx.baseUrl" width="60" />
</div>
<div class="IDcard-info">
<div class="text">{{ clxx.hphm }}</div>
<div>所有人: {{ clxx.jdcsyr }}</div>
<div>车主身份证{{ clxx.jdcsyrsfzh }}</div>
<div>识别代码: {{ clxx.clsbdh }}</div>
</div>
</div>
</div>
<div class="bg_ban"></div>
<div class="center" v-if="clxx.jdcsyr">
<div class="associated-information">
<div class="sign-title">关联信息</div>
<div class="content1">
<div class="item-box" @click="goCanTrack">
<div class="ass-item-box">
<div class="circlebox bg2"></div>
<span>盘查轨迹</span>
</div>
</div>
</div>
</div>
<div class="pick-up-information">
<div class="sign-title">采集信息</div>
<div class="pick-box">
<van-badge class="pick-item-box pbg3" :content="wpdjList.length" @click="isShowSignIn = true">
<div>物品登记</div>
<div class="tp"></div>
</van-badge>
<van-popup v-model:show="isShowSignIn" :style="{ width: '90vw' }">
<van-form @submit="onSubmitWp">
<van-cell-groub>
<van-field name="uploader" label="物品图片">
<template #input>
<van-uploader v-model="wpTpIdList" multiple :max-count="3" :after-read="upLoadImg2" />
</template>
</van-field>
</van-cell-groub>
<van-cell-groub>
<van-field v-model="wpdjForm.wpms" label="物品描述" placeholder="物品描述" rows="2" maxlength="50"
show-word-limit></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field :rules="[{ required: true, message: '请填写物品数量' }]" v-model="wpdjForm.wpsl" label="物品数量"
placeholder="物品数量" type="number"></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field :rules="[{ required: true, message: '请选择物品类型' }]" readonly is-link v-model="wpdjForm.wplx"
label="物品类型" placeholder="选择物品类型" @click="showPicker = true"></van-field>
</van-cell-groub>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" size="small">提交</van-button>
</div>
</van-form>
</van-popup>
</div>
</div>
<div class="vehicular">
<div class="sign-title">
<span>同乘人员</span><span class="chooseP" @click="isWithStaff = true;">选择人员</span>
</div>
<div class="ry_item">
<div v-if="rypcidList.length === 0" style="text-align: center">
暂无数据
</div>
<div v-else>
<div class="item_flex" v-for="(item, index) in rypcidList" :key="index + 'ryid'">
<van-badge>
<div class="item_tcry">
<span style="width: 15vw">{{
rypcOptions.filter((e) => e.value === item)[0].xm
}}</span>
&emsp;
<span>{{
rypcOptions.filter((e) => e.value === item)[0].sfzh
}}</span>
</div>
<template #content>
<van-icon name="cross" class="badge-icon" @click="deleterypc(index)" />
</template>
</van-badge>
<van-button v-if="
rypcOptions.filter((e) => e.value === item)[0].pcclJg == 1
" round class="fxBtn" type="default" style="padding: 0 12px" size="mini">放行</van-button>
<van-button v-else-if="
rypcOptions.filter((e) => e.value === item)[0].pcclJg == 2
" round class="yjBtn" style="padding: 0 12px" type="default" size="mini">移交</van-button>
<van-button v-else round class="fxBtn" style="padding: 0 12px" type="default" size="mini">盘查</van-button>
</div>
</div>
</div>
<van-popup v-model:show="isWithStaff" :style="{ height: '55%', width: '70%', borderRadius: '8px' }">
<div class="staff-title">选择同乘人员</div>
<div class="staff-content">
<div style="text-align: center; margin-top: 16px" v-if="rypcOptions.length === 0">
暂无同乘人员~
</div>
<div v-else>
<van-checkbox-group v-model="rypcidList">
<van-cell-group inset>
<van-cell v-for="(item, index) in rypcOptions" :key="index + 'rypcid'" :title="item.xm"
@click="toggle(index)">
<template #right-icon>
<van-checkbox :name="item.value" :ref="(el) => (checkboxRefs[index] = el)"
@click.stop></van-checkbox>
</template>
</van-cell>
</van-cell-group>
</van-checkbox-group>
</div>
</div>
<div class="staff-sure">
<van-button size="small" class="yjBtn" type="default" block @click="prLoad">盘人</van-button>
<van-button size="small" class="fxBtn" type="default" @click="onOkTcry" block>确认</van-button>
</div>
</van-popup>
<div class="veh-box">
<div class="no-veh">暂无乘坐车辆~</div>
</div>
</div>
</div>
<div class="bg_ban"></div>
<div class="upload" v-if="clxx.jdcsyr">
<div class="tsxx" v-show="fileList.length === 0">
点击上传图片
<br />
最多可上传 3 张照片
</div>
<van-uploader v-model="fileList" multiple :max-count="3" :after-read="upLoadImg">
<van-button class="up_btn" icon="plus"></van-button>
</van-uploader>
</div> -->
<!-- <div class="bg_ban" style="height: 100px"></div> -->
<div class="bottom-box">
<div @click="save('1')">
<img src="../../../assets/images/new/fangxing.png" />
放行
</div>
<div @click="save('2')" class="yj">
<img src="../../../assets/images/new/yijiao.png" />
移交
</div>
</div>
<van-popup v-model:show="showPicker" position="bottom">
<van-picker :columns="D_BZ_BPCRCWP" @confirm="onConfirmWp" @cancel="showPicker = false" />
</van-popup>
<!-- 移交弹窗 -->
<van-popup v-model:show="showYj" round :style="{ width: '90vw' }">
<van-form @submit="onYj">
<van-cell-groub>
<van-field :rules="[{ required: true, message: '请填写移交单位' }]" v-model="yjForm.pcclYjdw" label="移交单位"
placeholder="移交单位"></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field :rules="[{ required: true, message: '请选择移交原因' }]" readonly is-link v-model="yjForm.pcclYjyy"
label="移交原因" placeholder="选择移交原因" @click="showYjyy = true"></van-field>
</van-cell-groub>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" size="small">移交</van-button>
</div>
</van-form>
</van-popup>
<!-- 移交原因 -->
<van-popup round v-model:show="showYjyy" position="bottom">
<van-picker :columns="D_BZ_BPCCLYJYY" @cancel="showYjyy = false" @confirm="onConfirmYjyy"></van-picker>
</van-popup>
<checkedPeople ref="peo" />
</div>
</template>
<script setup>
import ImageCompressor from "image-compressor.js";
import TopNav from "../../../components/topNav";
import checkedPeople from "./components/checkPeople";
import { ref, reactive, onMounted, onBeforeUpdate, watch } from "vue";
import { useRouter } from "vue-router";
import { selectCl, saveBpccl, upImage, getClry2h } from "../../../api/common";
import { getDictList, setDict } from "../../../utils/dict";
import { zlPrPc } from "../../../api/zlzx.js";
import { getBase64, hintToast } from "../../../utils/tools.js";
const router = useRouter();
//移交表单
const { D_BZ_BPCRCWP, D_BZ_BPCCLYJYY } = getDictList("D_BZ_BPCRCWP", "D_BZ_BPCCLYJYY");
const yjForm = ref({});
const zlId = ref("");
const loading = ref(true);
const showEmpty = ref(false);
const copyCphm = ref("");
const wpTpIdList = ref([]);
const peo = ref(null);
const fileList = ref([]);
const isWithStaff = ref(false);
const showYj = ref(false);
const gps = ref({});
const clxx = ref({});
const showYjyy = ref(false);
const rypcidList = ref([]);//人员盘查id集合
const rypcOptions = ref([]);
const checkboxRefs = ref([]);
const wpdjList = ref([]);//物品登记数据
const wpdjForm = ref({
wpms: "",
wpTpIdList: [],
wpsl: 1,
wplx: "",
});
const tpIdList = ref([]);
const isShowSignIn = ref(false);// 物品登记
const addfileList = ref([]);
const result = ref("");
const showPicker = ref(false);
onBeforeUpdate(() => {
checkboxRefs.value = [];
});
onMounted(() => {
zlId.value = router.currentRoute.value.query.zlId;
copyCphm.value = router.currentRoute.value.query.hphm;
getTcry();
try {
gps = JSON.parse(bridge.getLocation());
} catch (error) { }
let hphm = router.currentRoute.value.query.hphm;
if (hphm) {
clxxQueryDetail(hphm);
} else {
hintToast("无车辆信息,请重试!");
showEmpty.value = true;
loading.value = false;
}
});
function toggle(index) {
checkboxRefs.value[index].toggle();
}
function onOkTcry() {
isWithStaff.value = false;
}
//获取base64地址
function _getBase64(item) {
getBase64((res) => { item.baseUrl = res; }, `http://10.64.201.128:2366/xlpcAdminNew/requestservice/czrk/ryxp.jpg?sfzh=${item.jdcsyrsfzh}`);
}
// 盘查人员
function prLoad() {
peo.value.handleOpen();
}
// 移交原因
function onConfirmYjyy(val) {
showYjyy.value = false;
yjForm.value.pcclYjyy = val.text;
}
function deleterypc(e) {
rypcidList.value.splice(e, 1);
}
function onSubmitWp() {
isShowSignIn.value = false;
wpdjList.value.push({
wpms: wpdjForm.value.wpms,
wpTpIdList: wpdjForm.value.wpTpIdList,
wplx: wpdjForm.value.wplxdm,
wpsl: wpdjForm.value.wpsl,
});
wpTpIdList.value = [];
wpdjForm.value = {
wpms: "",
wpTpIdList: [],
wpsl: 1,
wplx: "",
};
}
function onConfirmWp(val) {
showPicker.value = false;
wpdjForm.value.wplx = val.text;
wpdjForm.value.wplxdm = val.dm;
}
function getTcry() {
getClry2h().then((res) => {
rypcOptions.value = res.map((item) => {
return {
xm: item.xm,
value: item.id,
sfzh: item.sfzh,
pcclJg: item.pcclJg,
};
});
});
}
function clxxQueryDetail(hphm) {
let hplx = router.currentRoute.value.query.hplx
selectCl({
hphm: hphm,
hpzl: hplx,
jd: gps.app_x,
wd: gps.app_y,
sjly: "",
zdxh: gps.zdxh,
pcsrlx: router.currentRoute.value.query.pcsrlx,
zdch: gps.zdch,
zdsim: gps.zdsim,
glxtdm: "",
glxtid: "",
jzid: "",
bbid: "",
pcfs: "",
}).then((res) => {
loading.value = false;
if (res) {
clxx.value = res;
} else {
hintToast("查无此车,请核对信息!");
router.go(-1);
}
//如果是指令页面跳转过来 嗲用
if (zlId.value) {
zlPrPc({ pclxdm: 2, pcryclId: clxx.value.id, zlId: zlId.value }).then((res) => { });
}
});
}
// 关联信息
function goCanTrack() {
router.push({
path: "/TrackInventory", query: { hphm: clxx.value.hphm },
});
}
// 放行移交
function save(val) {
if (val === "1") {
clxx.value.pcclJg = val;
clxx.value.pcclJgmc = "放行";
clxx.value.jd = gps.app_x;
clxx.value.wd = gps.app_y;
const formData = {
id: clxx.value.id,
pcclJg: "1",
pcclJgmc: "放行",
tpIdList: tpIdList.value,
clWpList: wpdjList.value,
rypcidList: rypcidList.value,
};
saveBpccl(formData).then((res) => {
hintToast("放行成功!");
router.go(-1);
});
} else {
clxx.value.pcclJg = val;
clxx.value.pcclJgmc = "移交";
showYj.value = true;
}
}
// 移交
function onYj() {
const formData = {
id: clxx.value.id,
pcclJg: "2",
pcclJgmc: "移交",
pcclYjdw: yjForm.value.pcclYjdw,
pcclYjyy: yjForm.value.pcclYjyy,
tpIdList: tpIdList.value,
clWpList: wpdjList.value,
rypcidList: rypcidList.value,
};
saveBpccl(formData).then((res) => {
hintToast("移交成功!");
router.go(-1);
});
}
// 上传图片
async function upLoadImg(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!tpIdList.value.includes(res)) tpIdList.value.push(res);
});
}
// 上传图片
async function upLoadImg2(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!wpdjForm.value.wpTpIdList.includes(res)) wpdjForm.value.wpTpIdList.push(res);
});
}
//压缩图片
const _compressImage = (file) => {
return new Promise((resolve, reject) => {
new ImageCompressor(file, {
quality: 0.6, //压缩质量
success(res) {
resolve(res);
},
error(e) {
reject(e);
},
});
});
};
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.bg_ban {
background: #eff0f5;
height: 12px;
}
.container {
// height: 100vh;
margin-bottom: 8vh;
}
.top {
background-image: url("../../../assets/images/new/cl_bg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
height: 22vw;
padding: 3vh 5vw;
margin: 0 4vw 12px;
position: relative;
z-index: 2;
}
.basic-info {
color: #4d4d4d;
display: flex;
flex-direction: row;
.img-box {
flex: 1;
>img {
border-radius: 5px;
border: 1px solid #1143ca;
overflow: hidden;
}
}
.IDcard-info {
flex: 3;
@include font_size($font_medium_s);
.text {
// @include font_size($font_large);
@include font_size($font_medium);
font-weight: bold;
color: #1f6cec;
}
}
}
.contact-way {
margin-top: 3vh;
line-height: 3vh;
@include font_size($font_medium_s);
.one-line {
display: flex;
.phoneNum {
width: 50%;
}
}
}
.fxBtn {
background: linear-gradient(148deg, #5897ff, #1862de);
color: #f2f2f2;
}
.yjBtn {
background: linear-gradient(148deg, #ffbb6b, #ff7a45);
color: #f2f2f2;
}
.center {
padding: 0 3vw;
.sign-title {
padding-left: 14px;
position: relative;
line-height: 3vh;
@include font_size($font_medium);
font-weight: bold;
display: flex;
justify-content: space-between;
margin: 1vh 0;
.chooseP {
@include font_size($font_medium_s);
color: rgb(0, 102, 255);
font-weight: normal;
}
}
.sign-title::after {
content: "";
position: absolute;
left: 0;
top: 2px;
bottom: 2px;
width: 4px;
background: linear-gradient(0deg, #7ec2ff 0%, #0e8aff 100%);
border-radius: 1px;
}
.associated-information {
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.item-box {
margin: 2vw 4vw;
display: flex;
.ass-item-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
.content1 {
display: flex;
.circlebox {
width: 15vw;
height: 15vw;
// border-radius: 15vw;
text-align: center;
line-height: 15vw;
margin-bottom: 2vw;
}
.bg1 {
background: url("../../../assets/images/new/zhda.png");
background-size: contain;
background-repeat: no-repeat;
}
.bg2 {
background: url("../../../assets/images/new/pcgj.png");
background-size: contain;
background-repeat: no-repeat;
}
.bg3 {
background: url("../../../assets/images/new/tcry.png");
background-size: contain;
background-repeat: no-repeat;
}
}
}
.pick-up-information {
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.pick-box {
display: flex;
justify-content: flex-start;
margin: 3vw 0;
}
.pick-item-box {
padding: 3vw 3vw 10vw;
width: 30%;
margin-right: 2vw;
// border-radius: 3vw;
position: relative;
.tp {
position: absolute;
bottom: 0;
right: 0;
}
}
.pbg1 {
background: url("../../../assets/images/new/bg-blue.png") no-repeat;
background-size: cover;
}
.pbg2 {
background: url("../../../assets/images/new/bg-orgin.png") no-repeat;
background-size: cover;
}
.pbg3 {
color: #397361;
background: url("../../../assets/images/new/wpdj.png") no-repeat;
background-size: 100% 100%;
}
}
.vehicular {
@include font_color($font-color-theme);
.no-veh {
text-align: center;
}
.veh-box {
margin: 1vh 0;
}
}
}
.line1 {
width: 100vw;
background-color: #eee;
height: 1vh;
}
.upload {
padding: 1vh 3vw;
height: 80px;
position: relative;
.tsxx {
position: absolute;
color: #a8a8a8;
top: 0;
left: 30%;
bottom: 0;
padding: 8% 0;
font-size: 14px;
}
.up_btn {
height: 80px;
width: 80px;
color: #a8a8a8;
font-size: 24px;
background: #f2f2f2 url("../../../assets/images/new/upimg_bg.png") no-repeat;
background-size: 100% 100%;
}
}
.bottom-box {
text-align: center;
background: #fff;
border-top: 1px solid #ddddde;
position: fixed;
bottom: 0;
width: 100vw;
height: 6vh;
line-height: 6vh;
display: flex;
>div {
height: 6vh;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
>img {
width: 20px;
margin-right: 8px;
}
}
.yj {
background: #f0f0f0;
}
}
.upload-box {
margin: 1vh 3vw;
}
.ry_item {
background: #f8f8f8;
opacity: 0.7;
margin-bottom: 16px;
line-height: 1.8em;
}
.staff-title {
height: 6vh;
background-color: rgb(13, 106, 245);
text-align: center;
line-height: 6vh;
color: #fff;
}
.staff-sure {
position: fixed;
bottom: 5vw;
right: 5vw;
left: 5vw;
.yjBtn {
margin-bottom: 12px;
border-radius: 8px;
}
.fxBtn {
border-radius: 8px;
}
}
.head-nav-banner {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 35vw;
z-index: 1;
background: #1143ca;
}
::v-deep .headBlue {
background-color: #1143ca !important;
}
.navTitle {
position: absolute;
top: 0;
color: #fff;
// @include font_size($font_large);
font-size: 5.5vw;
text-align: center;
width: 100%;
padding: 3vw 0;
}
.item_tcry {
padding: 2px 24px;
background: #d2e3ff;
border-radius: 8px;
>span {
display: inline-block;
}
}
.badge-icon {
display: block;
font-size: 10px;
line-height: 16px;
}
.item_flex {
padding: 6px 0;
display: flex;
justify-content: space-between;
}
.tip_text{
font-size: 18px;
margin-top: 10px;
}
</style>