lion 2 weeks ago
parent a70ffe6bff
commit b7aca24e83

@ -1,5 +1,5 @@
const mode = 'production'; //devLocal本地测试、devOnline线上测试、production生产环境
let ROOTPATH = 'https://visitor-test.ali251.langye.net'; //域名
let ROOTPATH = 'http://yxbd-fangke.ali251.langye.net'; //域名
switch (mode) {
case 'devLocal':
ROOTPATH = ROOTPATH

@ -23,7 +23,7 @@ const install = (Vue, vm) => {
// 访客管理相关API方法
let visitList = (params = {}) => vm.$u.get(apiApp.visitList, params);
let visitDetail = (params = {}) => vm.$u.post(apiApp.visitDetail, params);
let visitDetail = (params = {}) => vm.$u.get(apiApp.visitDetail, params);
let visitUpdate = (params = {}) => vm.$u.post(apiApp.visitUpdate, params);
let visitCancel = (params = {}) => vm.$u.get(apiApp.visitCancel, params);

@ -1,25 +1,41 @@
import axios from "axios";
export function openDevice(data){
console.log("连接读卡器")
/** 与 szbd-visitor-web 门岗 visitlist.vue 一致:中控在线身份证扫描服务 */
const ZK_SCAN_READ_IDCARD_URL =
"https://127.0.0.1:24011/ZKIDROnline/ScanReadIdCardInfo?OP-DEV=1&CMD-URL=4&REPEAT=1&READTYPE=1";
/**
* 调用本地中控服务读取身份证返回体为含 IDNumber 的字符串需解析出号码
*/
export function scanReadIdCardInfo() {
return axios.get(ZK_SCAN_READ_IDCARD_URL, {
headers: {
"Content-Type": "application/json",
},
});
}
/** 兼容旧版:本地 19196 读卡服务(可选) */
export function openDevice(data) {
console.log("连接读卡器");
return axios({
url:'http:127.0.0.1:19196/OpenDevice',
method:'GET'
})
url: "http://127.0.0.1:19196/OpenDevice",
method: "GET",
});
}
export function readIdCard(data){
console.log("读身份证")
export function readIdCard(data) {
console.log("读身份证");
return axios({
url:'http:127.0.0.1:19196/readcard',
method:'GET'
})
url: "http://127.0.0.1:19196/readcard",
method: "GET",
});
}
export function closeDevice(data){
console.log("关闭读卡器")
export function closeDevice(data) {
console.log("关闭读卡器");
return axios({
url:'http:127.0.0.1:19196/CloseDevice',
method:'GET'
})
url: "http://127.0.0.1:19196/CloseDevice",
method: "GET",
});
}

@ -1,8 +1,8 @@
/*
* 公共方法
*
*/
import moment from 'moment';
/*
* 公共方法
*
*/
import moment from 'moment';
import { lang } from 'moment';
import { ROOTPATH } from "@/common/config.js"
const base = {
@ -88,7 +88,7 @@ const base = {
// 分享
shareInfo : () => {
return{
title:"柯唯访客在线核销",
title:"BD柯唯访客在线核销",
imageUrl:"",
page:'/pages/index/index'
}
@ -172,8 +172,8 @@ const base = {
return form
}
}
export {
base
}
export {
base
}

@ -1,5 +1,5 @@
{
"name" : "柯唯访客在线核销",
"name" : "BD柯唯访客在线核销",
"appid" : "__UNI__DF76F27",
"description" : "",
"versionName" : "1.0.2",
@ -117,7 +117,7 @@
"disableHostCheck" : true,
"https" : false
},
"title" : "柯唯访客在线核销",
"title" : "BD柯唯访客在线核销",
"sdkConfigs" : {
"maps" : {}
}

@ -1,23 +1,23 @@
{
"easycom": {
"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
},
"pages": [{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom"
}
}, {
"path": "pages/login/index",
"style": {
"navigationStyle": "custom"
}
}],
"preloadRule": {},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "柯唯访客在线核销",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#96d6e9"
}
{
"easycom": {
"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
},
"pages": [{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom"
}
}, {
"path": "pages/login/index",
"style": {
"navigationStyle": "custom"
}
}],
"preloadRule": {},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "BD柯唯访客在线核销",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#96d6e9"
}
}

@ -5,6 +5,7 @@
<view class="gate-header">
<view class="gate-left">
<view class="today-visitors" @click="openList">访</view>
<view class="export-visitors" @click="exportVisitors">访</view>
</view>
</view>
@ -121,17 +122,17 @@
visitData.time ? visitData.time : ""
}}</text>
</view>
<view class="info-item" v-if="visitData.visit_time_detail">
<view class="info-item" v-if="visitData.visit_time_detail || visitData.visit_time">
<text class="info-label">到访时段</text>
<text class="info-value"
>{{ visitData.visit_time_detail.start_time }} -
{{ visitData.visit_time_detail.end_time }}</text
>{{ (visitData.visit_time_detail || visitData.visit_time).start_time }} -
{{ (visitData.visit_time_detail || visitData.visit_time).end_time }}</text
>
</view>
<view class="info-item" v-if="visitData.visit_area_detail">
<view class="info-item" v-if="visitData.visit_area_detail || visitData.visit_area">
<text class="info-label">前往区域</text>
<text class="info-value">{{
visitData.visit_area_detail.name
(visitData.visit_area_detail || visitData.visit_area).name
}}</text>
</view>
<view class="info-item" v-if="visitData.reason">
@ -416,7 +417,7 @@
</template>
<script>
import { openDevice, readIdCard, closeDevice } from "@/common/reader.js";
import { openDevice, scanReadIdCardInfo } from "@/common/reader.js";
export default {
data() {
return {
@ -599,6 +600,7 @@ export default {
1: "普通访客",
2: "施工访客",
3: "物流车辆",
4: "VIP访客",
};
return typeMap[type] || "未知类型";
},
@ -743,12 +745,9 @@ export default {
}
this.personNoValue = visitor.person_no;
this.remarkValue = visitor.remark;
if (
visitor.vehicle_images_detail &&
visitor.vehicle_images_detail.length > 0
) {
if (visitor.file_detail && visitor.file_detail.length > 0) {
let arr = [];
visitor.vehicle_images_detail.map((item) => {
visitor.file_detail.map((item) => {
arr.push({
id: item.id,
url: item.url,
@ -764,7 +763,8 @@ export default {
}
//
this.codeForm.code = visitor.code;
this.codeForm.type = visitor.audit_status == 1 ? 1 : 2; //(visitor.audit_status == 3 && visitor.accept_admin_sign ? 2 : 0)
// 1()/4() => 3() =>
this.codeForm.type = visitor.audit_status == 3 ? 2 : 1;
this.visitShow = true;
} else {
@ -790,41 +790,72 @@ export default {
}
},
//
cancelCode() {
console.log(this.codeForm);
if (this.codeForm.type == 0) {
async cancelCode() {
if (!this.gateAdminId) {
uni.showToast({
title: "请提醒陪同人签字",
title: "请先选择门岗人员",
icon: "none",
});
return;
}
this.$u.api.visitCancel(this.codeForm).then((res) => {
// if (res.code == 200) {
// this.$successMessage(res.msg, '', 'success')
// }
console.log(res);
uni.showToast({
title: "核销成功",
icon: "none",
});
const mainPersonNo = this.personNoValue ? [this.personNoValue] : [];
const followPersonNo = (this.visitData?.follw_people || [])
.map((person) => person.follw_people_person_no)
.filter((v) => !!v);
const personNoArr = [...mainPersonNo, ...followPersonNo];
const carNoArr = Array.isArray(this.visitData?.cars)
? this.visitData.cars.filter((v) => !!v)
: [];
const params = {
...this.codeForm,
admin_id: this.gateAdminId,
person_no: personNoArr,
car_no: carNoArr,
};
await this.$u.api.visitCancel(params);
uni.showToast({
title: "核销成功",
icon: "none",
});
},
//
// szbd-visitor-web gate/visitlist.vue 线 ScanReadIdCardInfo H5
getIdcard() {
const that = this;
this.select.idcard = "";
readIdCard().then((res) => {
console.log("读取身份证", res);
if (res.data.resultFlag == 0) {
this.select.idcard = res.data.certNumber;
this.getList();
} else {
scanReadIdCardInfo()
.then((res) => {
console.log(res);
console.log(res.data);
if (!res.data) {
return;
}
const raw =
typeof res.data === "string" ? res.data : String(res.data);
const data1 = raw.split('"IDNumber"');
if (!data1[1]) {
uni.showToast({
title: "解析身份证数据失败",
icon: "none",
});
return;
}
const data2 = data1[1].split(",");
const data3 = data2[0].replace(/[^\d]/g, "");
that.select.idcard = data3;
that.getList();
})
.catch((err) => {
console.log(err);
const msg =
(err.response && err.response.statusText) ||
err.message ||
"读取失败";
uni.showToast({
title: "读取身份证失败",
title: msg,
icon: "none",
});
}
});
});
},
//
@ -1031,16 +1062,15 @@ export default {
this.updating = true;
try {
const updateParams = {
...this.visitData,
id: this.visitData.id,
remark: this.remarkValue,
person_no: this.personNoValue,
// follw_people follw_people_person_no
follw_people: this.visitData.follw_people || [],
};
// type==3
if (this.visitData.type == 3) {
updateParams.vehicle_images = (this.vehicleImages || [])
updateParams.file = (this.vehicleImages || [])
.filter((img) => img && img.id)
.map((img) => img.id);
}
@ -1084,6 +1114,23 @@ export default {
}
};
// 访/
if (this.visitData.type == 3) {
const currentIds = (this.vehicleImages || [])
.filter((item) => item && item.id)
.map((item) => item.id);
const hasNewPhoto = currentIds.some(
(id) => !this.originalVehicleImageIds.includes(id)
);
if (!hasNewPhoto) {
uni.showToast({
title: "物流访客每次进/离厂前必须上传当次照片",
icon: "none",
});
return;
}
}
//
const isVehicleType = this.visitData.type == 3; //
@ -1137,6 +1184,61 @@ export default {
this.todayVisitors = [];
}
},
// 访
exportVisitors() {
const query = {
is_export: 1,
};
if (this.select.start_date) {
query.start_date = this.select.start_date;
}
if (this.select.end_date) {
query.end_date = this.select.end_date;
}
const queryString = Object.keys(query)
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`)
.join("&");
const url = `${this.$u.http.config.baseUrl}/api/admin/gate/visit-list?${queryString}`;
const token = this.$store.state.vuex_token;
if (!token) {
uni.showToast({
title: "登录状态无效,请重新登录",
icon: "none",
});
return;
}
uni.downloadFile({
url,
header: {
Authorization: `Bearer ${token}`,
},
success: (res) => {
if (res.statusCode === 200) {
uni.openDocument({
filePath: res.tempFilePath,
showMenu: true,
fail: () => {
uni.showToast({
title: "下载成功,请在下载列表查看",
icon: "none",
});
},
});
} else {
uni.showToast({
title: "导出失败",
icon: "none",
});
}
},
fail: () => {
uni.showToast({
title: "导出失败,请稍后重试",
icon: "none",
});
},
});
},
},
};
</script>
@ -1169,6 +1271,10 @@ export default {
}
.gate-left {
display: flex;
align-items: center;
gap: 32rpx;
.today-visitors {
color: #ffffff;
font-size: 36rpx;
@ -1183,6 +1289,21 @@ export default {
opacity: 0.7;
}
}
.export-visitors {
color: #ffffff;
font-size: 30rpx;
font-weight: 500;
cursor: pointer;
@media (max-width: 750px) {
font-size: 28rpx;
}
&:active {
opacity: 0.7;
}
}
}
.gate-right {
@ -1421,7 +1542,7 @@ export default {
}
/* #ifdef H5 */
/* H5下身份证输入宽度为70%,右侧显示查询入口 */
/* H5 下与门岗页一致:身份证输入 70%右侧「查询身份证」30% */
@media all {
.idcard-group .form-input {
width: 70%;

@ -61,7 +61,7 @@
</view>
<view class="footer">
<text class="copyright">© 2025 访客管理系统</text>
<text class="copyright">© BD管理系统</text>
</view>
</view>
</template>

File diff suppressed because one or more lines are too long

@ -2,7 +2,7 @@
## 一、系统概述
柯唯访客核销系统是一个专门用于门岗访客管理的信息化系统支持H5浏览器版本和Android APK版本。系统主要用于访客信息查询、核销、登记等功能实现访客进出厂区的数字化管理。
BD柯唯访客核销系统是一个专门用于门岗访客管理的信息化系统支持H5浏览器版本和Android APK版本。系统主要用于访客信息查询、核销、登记等功能实现访客进出厂区的数字化管理。
### 主要功能
- ✅ 访客信息查询与核销
@ -41,10 +41,10 @@
主界面包含以下部分:
#### 📌 头部导航
#### 头部导航
- **访客列表**:点击可查看当前日期的访客记录
#### 📝 查询表单
#### 查询表单
包含以下几个查询字段:
| 字段 | 类型 | 说明 | 必填 |
@ -58,7 +58,7 @@
### 3.2 H5版本特殊功能
#### 🔍 身份证读取功能
#### 身份证读取功能
1. 确保已连接身份证读卡器设备
2. 在"身份证件"输入框右侧点击"查询身份证"按钮
3. 系统自动读取身份证信息并填充到输入框
@ -115,7 +115,7 @@
查询成功后,系统会弹出"访客信息"弹窗,包含以下信息模块:
#### 📋 拜访信息
#### 拜访信息
- 拜访类型(普通访客/施工访客/物流车辆)
- 拜访日期范围
- 到访时段
@ -124,19 +124,19 @@
- 到访车辆信息
- 车辆类型
#### 👤 拜访人信息
#### 拜访人信息
- 姓名
- 联系电话
- 证件类型和号码
- 单位名称
- CDA编号
#### 👥 随访人员信息(如有)
#### 随访人员信息(如有)
- 姓名、联系电话
- 证件类型和号码
- 多条记录会分隔显示
#### 🏢 被访人信息
#### 被访人信息
- 被访人姓名
- 陪同人(如有)
- 收货人(如有)
@ -146,15 +146,15 @@
在弹窗底部可进行以下操作:
#### 📝 ID卡输入
#### ID卡输入
- 输入人员ID卡号
- 用于员工身份识别
#### 📝 备注信息
#### 备注信息
- 输入备注说明
- 支持多行文本输入
#### 📸 车辆照片上传(仅物流车辆)
#### 车辆照片上传(仅物流车辆)
- 点击"+添加照片"按钮
- 选择拍摄方式:
- **选择照片**:从手机相册选择
@ -230,11 +230,11 @@
| 状态 | 说明 | 可操作 |
|------|------|--------|
| 🟠 待学习 | 访客需要完成安全学习 | ❌ |
| 🔵 待审核 | 访客申请待审核 | ❌ |
| 🟢 通过(待进厂) | 审核通过,等待进厂 | ✅ 可核销 |
| 🔴 驳回 | 访客申请被驳回 | ❌ |
| 🟢 已进厂 | 已进入厂区 | ✅ 可核销 |
| 待学习 | 访客需要完成安全学习 | ❌ |
| 待审核 | 访客申请待审核 | ❌ |
| 通过(待进厂) | 审核通过,等待进厂 | ✅ 可核销 |
| 驳回 | 访客申请被驳回 | ❌ |
| 已进厂 | 已进入厂区 | ✅ 可核销 |
| ⚫ 已离厂 | 已完成离厂核销 | ❌ |
| ⚫ 已取消 | 访客已取消访问 | ❌ |

Loading…
Cancel
Save