Commit 849c265f authored by 夏敏伟's avatar 夏敏伟

首次提交

parents
Pipeline #506 canceled with stages
# just a flag
ENV = 'prodution'
# base api
VITE_APP_API_NAME = '/api'
\ No newline at end of file
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
# 项目插件
目前store有两种,一种是pinia,另外一种是vuex,据网友说第一种好用点,样式提供了scss以及less,项目路由vue-router,样式datav,ui框架ant-design-vue,项目不需要在页面使用引入vue的ref,reactive等,可直接使用。
此项目是旅馆项目。
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>旅馆项目</title>
<style>
html,body{
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
This diff is collapsed.
{
"name": "xxx_phaseTwo_web",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@kjgl77/datav-vue3": "^1.6.1",
"ant-design-vue": "^3.2.20",
"axios": "^1.4.0",
"cropperjs": "^1.5.13",
"dayjs": "^1.11.9",
"nprogress": "^0.2.0",
"pinia": "^2.1.4",
"pinia-plugin-persistedstate": "^3.2.0",
"vue": "^3.3.4",
"vue-router": "^4.2.4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"less": "^4.1.3",
"sass": "^1.63.6",
"unplugin-auto-import": "^0.16.6",
"unplugin-vue-components": "^0.25.1",
"vite": "^4.4.0"
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
\ No newline at end of file
<script setup>
import zhCN from 'ant-design-vue/es/locale/zh_CN';
</script>
<template>
<a-config-provider :locale="zhCN">
<router-view></router-view>
</a-config-provider>
</template>
<style scoped>
</style>
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//获取所有国家
export const getAllCountry = () => {
return request({
url: '/agile/rest/index/api/default/queryNationalityType',
method: 'GET'
});
}
//获取签证类型
export const getAllVisa = () => {
return request({
url: '/agile/rest/index/api/default/queryVisaType',
method: 'GET'
});
}
//获取性别
export const getAllGender = () => {
return request({
url: '/agile/rest/index/api/default/queryGenderType',
method: 'GET'
});
}
//获取外宾证件种类
export const getAllForeignGuest = () => {
return request({
url: '/agile/rest/index/api/default/queryForeignGuestType',
method: 'GET'
});
}
//获取内宾证件种类
export const getAllInternalGuest = () => {
return request({
url: '/agile/rest/index/api/default/queryInternalGuestType',
method: 'GET'
});
}
//获取车牌类型
export const getAllPlateNumber = () => {
return request({
url: '/agile/rest/index/api/default/queryPlateNumberType',
method: 'GET'
});
}
//入境事由
export const getAllReasonEntry = () => {
return request({
url: '/agile/rest/index/api/default/queryReasonEntryType',
method: 'GET'
});
}
//查询省市县
export const getAllProvinciaUrbanAreas = () => {
return request({
url: '/agile/rest/index/api/default/queryProvincialUrbanAreas',
method: 'GET'
});
}
//查询民族
export const getAllNation = () => {
return request({
url: '/agile/rest/index/api/default/queryNationType',
method: 'GET'
});
}
//查询房间类型
export const getAllRoomType = () => {
return request({
url: '/agile/rest/index/api/default/queryRoomType',
method: 'GET'
});
}
//查询所有字典
export const getAllCode = () => {
return request({
url: '/rest/hotel/code/queryList',
method: 'GET'
});
}
//图片上传
export const uploadImg = (data) => {
return request({
url: '/rest/file/upload?bucket=PHOTO',
method: 'POST',
data
});
}
//查看图片路径
export const getImgByUrl = (params) => {
return request({
url: '/rest/file/pathPhoto',
method: 'POST',
params
});
}
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//获取派出所组织机构
export const getDeptTree = () => {
return request({
url: '/rest/hotel/dept/queryTree',
method: 'GET'
});
}
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
/**内宾分页查询 */
export const inlandQuery = (data) => {
return request({
url: '/rest/hotel/domesticGuestCheckIn/queryListByParams',
method: 'POST',
data
});
}
/**内宾单个查询 */
export const inlandQueryOne = (params) => {
return request({
url: '/rest/hotel/domesticGuestCheckIn/queryDomesticGuestDetail',
method: 'GET',
params
});
}
/**内宾登记 */
export const inlandAdd = (data) => {
return request({
url: '/rest/hotel/domesticGuestCheckIn/add',
method: 'POST',
data
});
}
/**内宾更新 */
export const inlandEdit = (data) => {
return request({
url: '/rest/hotel/domesticGuestCheckIn/updateInfo',
method: 'POST',
data
});
}
/**内宾删除 */
export const inlandDelete = (data) => {
return request({
url: '/rest/hotel/domesticGuestCheckIn/bulkRemove',
method: 'POST',
data
});
}
/**内宾离店 */
export const inlandCheckOut = (data) => {
return request({
url: '/rest/hotel/domesticGuestCheckIn/departure',
method: 'POST',
data
});
}
// /**内宾个人信息查询 */
// export const inlandOneQuery = params => {
// return request({
// url: '/rest/hotel/domesticGuestCheckIn/departure',
// method: 'GET',
// params
// });
// }
/**字典查询 */
export const inlandGender = params => {
return request({
url: '/agile/rest/index/api/default/queryGenderType',
method: 'GET',
params
});
}
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//新增外宾
export const addForeignGuestCheckIn = (data) => {
return request({
url: '/rest/hotel/foreignGuestCheckIn/add',
method: 'POST',
data
});
}
//查询外宾
export const getForeignGuestCheckInList = (data) => {
return request({
url: '/rest/hotel/foreignGuestCheckIn/queryListByParams',
method: 'POST',
data
});
}
//外宾离店
export const departureForeignGuestCheckIn = (data) => {
return request({
url: '/rest/hotel/foreignGuestCheckIn/departure',
method: 'POST',
data
});
}
//更新外宾
export const updateForeignGuestCheckInList = (data) => {
return request({
url: '/rest/hotel/foreignGuestCheckIn/updateInfo',
method: 'POST',
data
});
}
//查询外宾详情
export const queryForeignGuestDetail = (params) => {
return request({
url: '/rest/hotel/foreignGuestCheckIn/queryForeignGuestDetail',
method: 'GET',
params
});
}
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//根据派出所编号查找旅馆
export const queryHotelByDept = (params) => {
return request({
url: '/rest/hotel/hotel/queryList',
method: 'GET',
params
});
}
//根据旅馆编号查找旅馆信息
export const queryHotel = (params) => {
return request({
url: '/rest/hotel/hotel/queryHotelInfo',
method: 'POST',
params
});
}
//修改旅馆基本信息
export const updateHotel = (data) => {
return request({
url: '/rest/hotel/hotel/updateInfo',
method: 'POST',
data
});
}
//多图片上传
export const upLoadArrayImage = (data) => {
return request({
url: "/rest/hotel/hotel/uploadImage",
method: 'POST',
data
})
}
//删除旅馆单图片上传的图片
export const removeArrayImage = (data) => {
return request({
url: "/rest/file/batchRemove",
method: 'POST',
data
})
}
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//查询主页面菜单
export const getTree = (data) => {
return request({
url: '/rest/system/menu/queryTree',
method: "POST",
data
})
};
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
/**恢复内宾 */
export const restoreDomesticGuestsToStay = (data) => {
return request({
url: '/rest/hotel/domesticGuestCheckIn/restoreDomesticGuestsToStay',
method: 'POST',
data
});
}
/**恢复外宾 */
export const restoreForeignGuestsToStay = (data) => {
return request({
url: '/rest/hotel/foreignGuestCheckIn/restoreForeignGuestsToStay',
method: 'POST',
data
});
}
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//权限查询
export const queryRole = () => {
return request({
url: '/rest/system/role/queryList',
method: 'GET'
})
}
//权限菜单提交
export const grantMenuRole = (data,roleId) => {
return request({
url: '/rest/system/role/grantMenu/'+roleId,
method: 'POST',
data
})
}
//角色新增
export const addRoles = (data) => {
return request({
url: '/rest/system/role/add',
method: 'POST',
data
})
}
//角色编辑
export const updateRoles = (data) => {
return request({
url: '/rest/system/role/updateInfo',
method: 'POST',
data
})
}
//角色删除
export const bulkRemoveRoles = (data) => {
return request({
url: '/rest/system/role/bulkRemove',
method: 'POST',
data
})
}
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//获取所有房间号
export const getAllRoom = params => {
return request({
url: '/rest/hotel/room/queryList',
method: 'GET',
params
});
}
//新增房间号
export const addRooms = data => {
return request({
url: '/rest/hotel/room/batchAddRoom',
method: 'POST',
data
});
}
//预览新增房间号
export const previewRooms = data => {
return request({
url: '/rest/hotel/room/createRooms',
method: 'POST',
data
});
}
//分页查询房间
export const getRooms = data=>{
return request({
url:'/rest/hotel/room/queryListByParams',
method:'POST',
data
})
}
//编辑房间
export const updateRoomsInfo = data=>{
return request({
url:'/rest/hotel/room/updateInfo',
method:'POST',
data
})
}
//删除房间
export const bulkRemoveRooms = data=>{
return request({
url:'/rest/hotel/room/bulkRemove',
method:'POST',
data
})
}
//查询房间状态 上部分
export const queryRoomStatus = params=>{
return request({
url:'/rest/hotel/hotelManger/statistics',
method:'POST',
params
})
}
//查询房间状态 下部分
export const queryStatisticsRoomStatus = params=>{
return request({
url:'/rest/hotel/hotelManger/statisticsRoomStatus',
method:'POST',
params
})
}
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//入境事由
export const getAllTeam = (params) => {
return request({
url: '/rest/hotel/team/queryList',
method: 'GET',
params
});
}
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//获取验证码
export const getVerifyCode = (params) => {
return request({
url: "/rest/system/user/verifyCode",
method: "GET",
params,
responseType: 'arraybuffer'
});
};
//查询用户列表
export const getUserList = (data) => {
return request({
url: '/rest/system/user/queryList',
method: "POST",
data
})
}
//用户登录
export const login = (data) => {
return request({
url: '/rest/system/user/login',
method: 'POST',
data
})
}
//用户注册
export const register = (data) => {
return request({
url: '/rest/system/user/add',
method: 'POST',
data
});
}
//修改用户密码
export const editPassword = params => {
return request({
url: "/rest/system/user/updatePassword",
method: 'GET',
params
})
}
//重置密码
export const resetPassword = params => {
return request({
url: "/rest/system/user/resetPassword",
method: 'GET',
params
})
}
//图片上传
export const upLoadImg = (data) => {
return request({
url: "/rest/file/uploadPhoto",
method: 'POST',
data
})
}
//用户新增
export const addPersonnel = (data) => {
return request({
url: "/rest/system/user/add",
method: 'POST',
data
})
}
//用户更新
export const updatePersonnel = (data) => {
return request({
url: "/rest/system/user/updateInfo",
method: 'POST',
data
})
}
//删除用户
export const removePersonnel = (params) => {
return request({
url: "/rest/system/user/remove",
method: 'GET',
params
})
}
\ No newline at end of file
import request from "@/utils/request";
/**
* @param data请求接口传递的参数
* @return {Promise}
*/
//新增访客
export const addVisitorRegist = (data) => {
return request({
url: '/rest/hotel/visitorRegist/add',
method: 'POST',
data
});
}
//查询访客
export const getVisitorList = (data) => {
return request({
url: '/rest/hotel/visitorRegist/queryListByParams',
method: 'POST',
data
});
}
//编辑访客
export const updateVisitorRegist = (data) => {
return request({
url: '/rest/hotel/visitorRegist/updateInfo',
method: 'POST',
data
});
}
//离店访客
export const departureVisitorRegist = (data) => {
return request({
url: '/rest/hotel/visitorRegist/departure',
method: 'POST',
data
});
}
//查询访客详情
export const queryVisitorRegistDetail = (params) => {
return request({
url: '/rest/hotel/visitorRegist/queryVisitorRegistDetail',
method: 'GET',
params
});
}
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
\ No newline at end of file
import { Modal, message } from 'ant-design-vue';
import 'ant-design-vue/es/message/style/css';
import 'ant-design-vue/es/modal/style/css';
export default {
install(app) {
//挂载全局对象
app.config.globalProperties.$message = message
app.config.globalProperties.$Modal = Modal
}
}
\ No newline at end of file
<template>
<a-modal class="handleForm" :visible="visible" :title="title" :width="600" :bodyStyle="{ padding: '16px 24px' }" @ok="handleOk" @cancel="handleCancel" :destroyOnClose="true" :maskClosable="false">
<video ref="local_video1" width="560" height="480" style="object-fit: fill" autoplay></video>
</a-modal>
</template>
<script setup>
import { reactive, ref, defineProps, onMounted, getCurrentInstance } from "vue";
import { message } from 'ant-design-vue';
const props = defineProps({
visible: Boolean,
title: String,
});
const emit = defineEmits(["handleSubmit", "changeCancel"]);
const local_video = ref("");
/**打开摄像头 */
const OnCamera = () => {
navigator.getUserMedia(
{
audio: false,
video: true,
},
function (stream) {
local_video.value.srcObject = stream;
},
function (error) {
console.log(error);
message.warning('未找到摄像头设备,请检查设备是否插紧');
}
);
};
/**关闭摄像头 */
const OffCamera = () => {
if (local_video.value.srcObject != null) {
let stream = local_video.value.srcObject;
stream.getTracks().forEach(function (track) {
track.stop();
});
local_video.value.srcObject = null;
}
};
const imgBase64 = ref("");
/**截图 */
const screenshot = () => {
const canvas = document.createElement("canvas");
const canvasCtx = canvas.getContext("2d");
const ratio = window.devicePixelRatio || 1;
canvasCtx.scale(ratio, ratio);
canvas.width = local_video.value.offsetWidth * ratio;
canvas.height = local_video.value.offsetHeight * ratio;
canvasCtx.drawImage(local_video.value, 0, 0, canvas.width, canvas.height);
imgBase64.value = canvas.toDataURL("image/png");
OffCamera();
};
// 提交事件
const handleOk = async () => {
screenshot();
await emit("handleSubmit", imgBase64, handleCancel);
};
// 关闭弹框事件
const handleCancel = async () => {
OffCamera();
await emit("changeCancel", false);
};
onMounted(() => {
const instance = getCurrentInstance();
local_video.value = instance?.refs.local_video1;
OnCamera();
});
</script>
<style lang="less" scoped>
.handleForm {
:deep(.ant-modal-content .ant-modal-close-x) {
width: 49px;
height: 49px;
line-height: 49px;
}
:deep(.ant-modal-content .ant-modal-body) {
padding-block: 16px;
}
.form {
:deep(.ant-form-item-with-help) {
margin-bottom: -16px;
}
:deep(.ant-input-number, .ant-picker) {
width: 100%;
}
:deep(.ant-form-item) {
margin-right: 0;
margin-bottom: 10px;
}
}
.dropPoint {
display: flex;
justify-content: space-between;
align-items: center;
> .ant-input {
flex: 1;
margin-right: 10px;
}
}
}
</style>
\ No newline at end of file
<template>
<a-modal
class="handleForm"
:visible="visible"
:title="title"
:width="800"
:bodyStyle="{ padding: '16px 24px' }"
@ok="handleOk"
@cancel="handleCancel"
:destroyOnClose="true"
:maskClosable="false"
>
<div style="display: flex">
<div style="width: 65%">
<!--使用ref属性给图片元素命名为imageRef-->
<img ref="imageRef" :src="imageSrc" alt="image" style="width: 600px" />
<div style="margin-top: 20px">
<a-space :size="40">
<a-button type="primary" @click="retake">重拍</a-button>
<a-button type="primary" @click="cropImage">裁剪图片</a-button>
</a-space>
</div>
</div>
<div style="width: 35%; text-align: center; margin-left: 20px">
<div style="font-size: 20px; line-height: 70px; font-weight: 600">
<span>预览</span>
</div>
<div>
<a-image
width="186.829px"
height="230px"
:src="croppedImage"
fallback="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAYAAADQvc6UAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAwSDCIMogwMCcmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis7PPOq3QdDFcvjV3jOD1boQVTPQrgSkktTgbSf4A4LbmgqISBgTEFyFYuLykAsTuAbJEioKOA7DkgdjqEvQHEToKwj4DVhAQ5A9k3gGyB5IxEoBmML4BsnSQk8XQkNtReEOBxcfXxUQg1Mjc0dyHgXNJBSWpFCYh2zi+oLMpMzyhRcASGUqqCZ16yno6CkYGRAQMDKMwhqj/fAIcloxgHQqxAjIHBEugw5sUIsSQpBobtQPdLciLEVJYzMPBHMDBsayhILEqEO4DxG0txmrERhM29nYGBddr//5/DGRjYNRkY/l7////39v///y4Dmn+LgeHANwDrkl1AuO+pmgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAwqADAAQAAAABAAAAwwAAAAD9b/HnAAAHlklEQVR4Ae3dP3PTWBSGcbGzM6GCKqlIBRV0dHRJFarQ0eUT8LH4BnRU0NHR0UEFVdIlFRV7TzRksomPY8uykTk/zewQfKw/9znv4yvJynLv4uLiV2dBoDiBf4qP3/ARuCRABEFAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghgg0Aj8i0JO4OzsrPv69Wv+hi2qPHr0qNvf39+iI97soRIh4f3z58/u7du3SXX7Xt7Z2enevHmzfQe+oSN2apSAPj09TSrb+XKI/f379+08+A0cNRE2ANkupk+ACNPvkSPcAAEibACyXUyfABGm3yNHuAECRNgAZLuYPgEirKlHu7u7XdyytGwHAd8jjNyng4OD7vnz51dbPT8/7z58+NB9+/bt6jU/TI+AGWHEnrx48eJ/EsSmHzx40L18+fLyzxF3ZVMjEyDCiEDjMYZZS5wiPXnyZFbJaxMhQIQRGzHvWR7XCyOCXsOmiDAi1HmPMMQjDpbpEiDCiL358eNHurW/5SnWdIBbXiDCiA38/Pnzrce2YyZ4//59F3ePLNMl4PbpiL2J0L979+7yDtHDhw8vtzzvdGnEXdvUigSIsCLAWavHp/+qM0BcXMd/q25n1vF57TYBp0a3mUzilePj4+7k5KSLb6gt6ydAhPUzXnoPR0dHl79WGTNCfBnn1uvSCJdegQhLI1vvCk+fPu2ePXt2tZOYEV6/fn31dz+shwAR1sP1cqvLntbEN9MxA9xcYjsxS1jWR4AIa2Ibzx0tc44fYX/16lV6NDFLXH+YL32jwiACRBiEbf5KcXoTIsQSpzXx4N28Ja4BQoK7rgXiydbHjx/P25TaQAJEGAguWy0+2Q8PD6/Ki4R8EVl+bzBOnZY95fq9rj9zAkTI2SxdidBHqG9+skdw43borCXO/ZcJdraPWdv22uIEiLA4q7nvvCug8WTqzQveOH26fodo7g6uFe/a17W3+nFBAkRYENRdb1vkkz1CH9cPsVy/jrhr27PqMYvENYNlHAIesRiBYwRy0V+8iXP8+/fvX11Mr7L7ECueb/r48eMqm7FuI2BGWDEG8cm+7G3NEOfmdcTQw4h9/55lhm7DekRYKQPZF2ArbXTAyu4kDYB2YxUzwg0gi/41ztHnfQG26HbGel/crVrm7tNY+/1btkOEAZ2M05r4FB7r9GbAIdxaZYrHdOsgJ/wCEQY0J74TmOKnbxxT9n3FgGGWWsVdowHtjt9Nnvf7yQM2aZU/TIAIAxrw6dOnAWtZZcoEnBpNuTuObWMEiLAx1HY0ZQJEmHJ3HNvGCBBhY6jtaMoEiJB0Z29vL6ls58vxPcO8/zfrdo5qvKO+d3Fx8Wu8zf1dW4p/cPzLly/dtv9Ts/EbcvGAHhHyfBIhZ6NSiIBTo0LNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiEC/wGgKKC4YMA4TAAAAABJRU5ErkJggg=="
/>
</div>
</div>
</div>
</a-modal>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.css";
const props = defineProps({
//图片地址
imageSrc: {
type: String,
required: true,
},
//aspectRatio:置裁剪框为固定的宽高比
aspectRatio: {
type: Number,
default: 0.812,
},
//viewMode: 视图控制
viewMode: {
type: Number,
default: 1,
},
//autoCropArea: 设置裁剪区域占图片的大小 值为 0-1 默认 0.8 表示 80%的区域
autoCropArea: {
type: Number,
default: 0.8,
},
visible: Boolean,
title: String,
});
//绑定图片的dom对象
const imageRef = ref(null);
let cropper = null;
//使用Cropper构造函数创建裁剪器实例,并将图片元素和一些裁剪选项传入
onMounted(() => {
new_Cropper();
});
/**导入图片 */
const new_Cropper = () => {
cropper = new Cropper(imageRef.value, {
aspectRatio: props.aspectRatio,
viewMode: props.viewMode,
autoCropArea: props.autoCropArea,
});
};
//定义方法
const emit = defineEmits([
"updateImageSrc",
"changeCancel",
"handleSubmit",
"handleRetake",
]);
//在cropImage函数中,获取裁剪后的图片数据URL,并使用emit方法触发updateImageSrc事件,
// 将裁剪后的图片数据URL传递给父组件。
const croppedImage = ref("");
const cropImage = () => {
const canvas = cropper.getCroppedCanvas();
croppedImage.value = canvas.toDataURL();
// emit("updateImageSrc", croppedImage);
};
/**重拍 */
const retake = async () => {
await emit("handleRetake", {}, handleCancel);
};
// 提交事件
const handleOk = async () => {
await emit("handleSubmit", croppedImage, handleCancel);
};
// 关闭弹框事件
const handleCancel = async () => {
await emit("changeCancel");
};
//销毁
onBeforeUnmount(() => {
cropper.destroy();
});
</script>
\ No newline at end of file
<script setup>
import { onMounted, reactive } from "vue";
import { getInfo } from "../api/commonapi";//引入接口方法
import { BorderBox3 as DvBorderBox3 } from '@kjgl77/datav-vue3'
const userInfo = reactive({
userName: "XXX",
age: "XX",
});
onMounted(() => {
//调接口,处理返回结果
getInfo({ orgid: "3348847743" }).then((res) => {
userInfo.userName=res.userName
userInfo.age=res.age
});
});
</script>
<template>
<h1>{{ userInfo.userName }}---{{ userInfo.age }}</h1>
<div w50rem h18rem flex justify-center items-center bg-dark>
<dv-decoration1 style="width:200px;height:50px;" />
</div>
</template>
<style scoped>
</style>
\ No newline at end of file
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router/index'//引入路由
//ant-design-vue
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
import * as Icons from '@ant-design/icons-vue';
// import base from './base';
import DataVVue3 from '@kjgl77/datav-vue3'
// 引用
import {createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
// 创建Pinia实例
const Pinia = createPinia()
Pinia.use(piniaPluginPersistedstate);
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
dayjs.locale('zh-zn');
const app = createApp(App)
app.use(router)
.use(Antd)
// .use(base)
.use(Pinia)
.use(DataVVue3)
.mount('#app')
for (const i in Icons){
app.component(i,Icons[i])
}
\ No newline at end of file
// 用于处理动态菜单数据,将其转为 route 形式
export const addRoutes = (menulist = [], routes = []) => {
let temp = [];
let route = [];
for (let i = 0; i < menulist.length; i++) {
if (menulist[i].children && menulist[i].children.length > 0) {
route = getRoute(menulist[i]);
route.children = addRoutes(menulist[i].children);
routes.push(route);
} else {
temp.push(getRoute(menulist[i]));
}
}
// 返回路由结果
return routes.concat(temp)
}
// 路由懒加载
const loadView = (path) => {
return () => import(`../view${path}.vue`);
}
// 返回路由的基本格式
const getRoute = item => {
// const modules =
// import.meta.glob('../views/**/*.vue')
let route = {
path: item.path,
name: item.label,
component: loadView(item.path) ,
// 路由的子路由
children: []
};
// 返回 route
return route
}
\ No newline at end of file
import {
createRouter,
createWebHashHistory
} from "vue-router";
import nProgress from 'nprogress'
import 'nprogress/nprogress.css'
import {
useStore
} from '../store/index';
nProgress.configure({
showSpinner: false
})
const router = createRouter({
// 内部提供了 history 模式的实现
// createWebHistory路由模式路径不带#号(生产环境下不能直接访问项目,需要nginx转发)
// createWebHashHistory路由模式路径带#号
history: createWebHashHistory(),
routes: [{
path: "/login",
name: "login",
component: () => import("../views/login/login.vue"),
},
{
path: "/",
name: "homepage",
component: () => import("../views/homePage/homepage.vue"),
redirect: '/inland/inlandAdd',
meta: {
keepAlive: false
},
children: [{
path: "/hotel/index",
name: "旅馆概况",
component: () => import("@/views/hotel/index.vue"),
},
{
path: "/inland/inland",
name: "内宾基本情况",
component: () => import("@/views/inland/inland.vue"),
},
{
path: "/inland/inlandAdd",
name: "内宾入住",
component: () => import("@/views/inland/inlandAdd.vue"),
},
{
path: "/abroad/abroad",
name: "外宾基本情况",
component: () => import("@/views/abroad/abroad.vue"),
},
{
path: "/abroad/abroadAdd",
name: "外宾入住",
component: () => import("@/views/abroad/abroadAdd.vue"),
},
{
path: "/room/room",
name: "房号管理",
component: () => import("@/views/room/room.vue"),
},
{
path: "/visitor/visitor",
name: "访客管理",
component: () => import("@/views/visitor/visitor.vue"),
},
{
path: "/visitor/visitorAdd",
name: "访客登记",
component: () => import("@/views/visitor/visitorAdd.vue"),
},
{
path: "/departure/departure",
name: "离店",
component: () => import("@/views/departure/departure.vue"),
},
{
path: "/hotel/hotelEdit",
name: "旅馆基础信息管理",
component: () => import("@/views/hotel/hotelEdit.vue"),
},
{
path: "/restoreCheckIn/restoreCheckIn",
name: "酒店误操作恢复在住",
component: () => import("@/views/restoreCheckIn/restoreCheckIn.vue"),
},
{
path: "/employeeManagement/personnelManagement",
name: "人员管理",
component: () => import("@/views//employeeManagement/personnelManagement.vue"),
},
{
path: "/employeeManagement/rolesManagement",
name: "角色管理",
component: () => import("@/views//employeeManagement/rolesManagement.vue"),
}
]
},
],
});
// 全局前置守卫
router.beforeEach(async (to, from, next) => {
nProgress.start()
const usestor = useStore();
const hasToken = usestor.token;
// 1.路由跳转前先判断是否有token
if (hasToken) {
// 1.1登录成功,跳转到首页
if (to.path === '/login') {
next();
nProgress.done();
} else {
// 1.2登录成功,去其他页面----要判断是否有用户信息
const hasUserInfo = usestor.userInfo.username;
//有用户信息
if (hasUserInfo) {
// 1.2.1如果没有从已有的所有路由中匹配到路由,有从上个路由过来的就直接跳到上个路由,否则就跳到登录页
if (to.matched.length === 0) {
// next({name: ''})----通过名称导航到特定路由。name: 是我要导航到的路由名称
from.name ? next({
name: from.name
}) : next('/login');
} else {
next();
}
} else {
// 1.2.2 登录成功但 没有用户信息----先通过store获取用户信息,根据用户来获取并添加动态路由
next();
}
}
} else {
//2.没有token的话可以访问白名单页面(登录页面)
if (to.name == 'login') {
next()
} else {
next('/login');
}
// console.log(1);
nProgress.done();
}
})
// 全局后置钩子
router.afterEach(() => {
nProgress.done(true)
})
export default router;
\ No newline at end of file
import {
defineStore
} from 'pinia'
import {
login
} from '@/api/user';
import {
message
} from 'ant-design-vue';
import router from '@/router/index';
import {
getAllRoom
} from '@/api/room.js'
import {
// getAllCountry,
// getAllVisa,
// getAllGender,
// getAllForeignGuest,
// getAllInternalGuest,
// getAllPlateNumber,
// getAllReasonEntry,
// getAllProvinciaUrbanAreas,
// getAllNation,
// getAllRoomType,
getAllCode
} from '@/api/default';
export const useStore = defineStore('user', () => {
const userInfo = ref();
const token = ref(null);
const hotelInfo = ref({
hotelId: null,
hotelAddress: null
});
const menuParams = ref({
selectedKeys: ['/inland/inlandAdd'],
openKeys: ['lkgl', '/inland/inlandAdd'],
preOpenKeys: ['lkgl'],
activeKey: '/inland/inlandAdd',
panes: [{ title: '内宾入住', key: '/inland/inlandAdd', closable: false }]
});
// const hotelId = ref(null);
const roomAll = ref([]);
// const defaultType = ref({
// countryAll: [],
// visaAll: [],
// genderAll: [],
// foreignGuestAll: [],
// internalGuestAll: [],
// plateNumberAll: [],
// reasonEntryAll: [],
// provinciaUrbanAreasAll: [],
// nationAll: [],
// roomAllType: [],
// checkInStatusAll: [],
// departmentAll: []
// });
const defaultType = ref([]);
const getUserInfo = async (param) => {
login(param).then(res => {
if (res.code == '9000') {
message.success('登录成功!');
hotelInfo.value.hotelId = param.hotelId;
hotelInfo.value.hotelAddress = param.address;
token.value = res.data;
let strings = res.data.split("."); //截取token,获取载体
userInfo.value = JSON.parse(decodeURIComponent(escape(window.atob(strings[1].replace(/-/g, "+").replace(/_/g, "/")))));
router.push({
name: 'homepage'
});
getAllCode().then(res => {
defaultType.value = res.data;
// for (let i = 0; i < res.data.length; i++) {
// switch (res.data[i].key) {
// case 1: //查询房间类型
// defaultType.value.roomAllType = res.data[i];
// break;
// case 2: //查询入住状态
// defaultType.value.checkInStatusAll = res.data[i];
// break;
// case 3: //查询所有内宾证件种类
// defaultType.value.internalGuestAll = res.data[i];
// break;
// case 4: //查询所有外宾证件种类
// defaultType.value.foreignGuestAll = res.data[i];
// break;
// case 5: //查询性别
// defaultType.value.genderAll = res.data[i];
// break;
// case 6: //查询所有车牌类型
// defaultType.value.plateNumberAll = res.data[i];
// break;
// case 7: //查询入境事由
// defaultType.value.reasonEntryAll = res.data[i];
// break;
// case 8: //查询所有签证种类
// defaultType.value.visaAll = res.data[i];
// break;
// case 9: //查询所有国家
// defaultType.value.countryAll = res.data[i];
// break;
// case 10: //查询所有民族
// defaultType.value.visaAll = res.data[i];
// break;
// case 11: //查询全国省市县
// defaultType.value.departmentAll = res.data[i];
// break;
// }
// }
})
//当前酒店下所有的房间号
getAllRoom({
hotelid: param.hotelId
}).then(res => {
roomAll.value = res.data;
});
// //查询所有国家
// getAllCountry().then(res => {
// defaultType.value.countryAll = res.data;
// });
// //查询所有签证种类
// getAllVisa().then(res => {
// defaultType.value.visaAll = res.data;
// })
// //查询性别
// getAllGender().then(res => {
// defaultType.value.genderAll = res.data;
// })
// //查询所有外宾证件种类
// getAllForeignGuest().then(res => {
// defaultType.value.foreignGuestAll = res.data;
// })
// //查询所有内宾证件种类
// getAllInternalGuest().then(res => {
// defaultType.value.internalGuestAll = res.data;
// })
// //查询所有车牌类型
// getAllPlateNumber().then(res => {
// defaultType.value.plateNumberAll = res.data;
// });
// //查询入境事由
// getAllReasonEntry().then(res => {
// defaultType.value.reasonEntryAll = res.data;
// })
// //查询省市县
// getAllProvinciaUrbanAreas().then(res => {
// defaultType.value.provinciaUrbanAreasAll = res.data;
// })
// //查询所有民族
// getAllNation().then(res => {
// defaultType.value.nationAll = res.data;
// })
// //查询所有房间类型
// getAllRoomType().then(res => {
// defaultType.value.roomAllType = res.data;
// })
}
}).catch(err => {
message.error(err.message);
})
}
const clearUserInfo = () => {
userInfo.value = {};
localStorage.removeItem('user');
};
const returnCode = key => {
if (defaultType.value.length > 0) {
let mateCode = defaultType.value.filter(item => {
return item.key == key
});
return mateCode[0].value
} else {
getCode();
}
}
const getCode = () => {
getAllCode().then(res => {
defaultType.value = res.data;
let mateCode = defaultType.value.filter(item => {
return item.key == key
});
return mateCode[0].value
})
}
const clearAll = () => {
defaultType.value = [];
roomAll.value = [];
}
const setAll = (dataCode,dataRoom) => {
defaultType.value = dataCode;
roomAll.value = dataRoom
}
return {
userInfo,
token,
hotelInfo,
menuParams,
// hotelId,
roomAll,
defaultType,
returnCode,
getUserInfo,
clearUserInfo,
clearAll,
setAll,
}
}, {
persist: true
})
\ No newline at end of file
import {
defineStore
} from 'pinia';
export const websocketStore = defineStore('websocket', () => {
const identityInformation = ref({});
return {
identityInformation
}
}, {
persist: true
})
\ No newline at end of file
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
.card {
padding: 2em;
}
#app {
width: 100%;
height: 100%;
overflow: hidden;
/* margin: 0 auto;
padding: 2rem;
text-align: center; */
}
div::-webkit-scrollbar {
width: 10px;
height: 10px;
/**/
}
div::-webkit-scrollbar-track {
background: #dfdfdf;
border-radius: 2px;
}
div::-webkit-scrollbar-thumb {
background: #bbbbbb;
border-radius: 10px;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
import {
upLoadImg
} from '@/api/user.js';
import {
upLoadArrayImage
} from '@/api/hotel.js';
// base64转file,dataurl为base64地址,filename为文件名称,自定义即可
export const dataURLtoFile = (dataurl, filename) => {
let arr = dataurl.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {
type: mime
});
}
/**路径转为文件 */
export const getImageFileFromUrl=(url, imageName)=>{
return new Promise((resolve, reject) => {
let blob = null;
let imgFile = null;
let xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.setRequestHeader("Accept", "image/png");
xhr.responseType = "blob";
xhr.onload = () => {
blob = xhr.response;
imgFile = new File([blob], imageName, { type: "image/png" });
resolve(imgFile);
};
xhr.onerror = e => {
reject(e);
};
xhr.send();
});
}
//获取当前时间 传1返回YYYY-MM-DD HH-MM-SS 传2返回YYYY-MM-DD
export const getCurrentDate = (val) => {
const nowDate = new Date();
const {
year,
month,
day,
hour,
minute,
second
} = {
year: nowDate.getFullYear(),
month: nowDate.getMonth(),
day: nowDate.getDay(),
hour: nowDate.getHours(),
minute: nowDate.getMinutes(),
second: nowDate.getSeconds()
}
const YYYYMMDD = year + '-' + month + '-' + day;
const HHMMSS = hour + ':' + minute + ':' + second;
if (val == 1) {
return YYYYMMDD + ' ' + HHMMSS;
} else if (val == 2) {
return YYYYMMDD
}
}
Date.prototype.format = function (format) {
var o = {
"M+": this.getMonth() + 1, //month
"d+": this.getDate(), //day
"h+": this.getHours(), //hour
"m+": this.getMinutes(), //minute
"s+": this.getSeconds(), //second
"q+": Math.floor((this.getMonth() + 3) / 3), //quarter
"S": this.getMilliseconds() //millisecond
}
if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
(this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length == 1 ? o[k] :
("00" + o[k]).substr(("" + o[k]).length));
return format;
};
export const ChangeDateType = (TM, TMformat) => {
let result = TM;
try {
result = TM.format(TMformat);
} catch (e) {
//TODO handle the exception
};
return result;
}
/**现场图片提交 */
export const file_img_src = (base64_img, hotelId, type) => {
const timestamp = Date.parse(new Date());
let file = dataURLtoFile(base64_img, timestamp + ".png");
let fd = new FormData();
fd.append("file", file);
fd.append("hotelId", hotelId);
fd.append("bucket", type);
return new Promise((resolve) => {
upLoadImg(fd).then((res) => {
if (res.code == 9000) {
resolve(res.data);
} else {
resolve("");
}
});
});
};
//遍历树状结构
export const treeForeach = (tree, func) => {
let node, list = [...tree]
while (node = list.shift()) {
func(node)
node.children && list.push(...node.children)
}
}
\ No newline at end of file
import {
websocketStore
} from "@/store/websocketStore.js";
const myWebsocketStore = websocketStore();
class initWebsocket {
constructor() {
this.obj = {
certificatecardid: '',
msg: '',
cardinfo: '',
cardName: '',
str: '',
devicetype: '',
statusbar: '',
certificatePhoto: ''
};
this.websocket = null;
}
connect() {
try {
var readyState = new Array("on connection", "Connection established",
"Closing connection", "Close connection");
var host = "ws://127.0.0.1:90/echo/";
this.websocket = new WebSocket(host);
this.websocket.onopen = () => {
this.obj.statusbar = readyState[this.websocket.readyState];
this.websocket.send(18601);
this.websocket.send(18402);
}
this.websocket.onmessage = (event) => {
var str = event.data;
var strsub = str;
//此处要加多种扫描仪
var deviceArr = new Array();
deviceArr[0] = "D300+";
deviceArr[1] = "D800II";
deviceArr[2] = "D120+";
deviceArr[3] = "L1250+";
deviceArr[4] = "L1250";
deviceArr[5] = "B660";
deviceArr[6] = "M110";
deviceArr[7] = "E2000";
deviceArr[8] = "CR620+";
deviceArr[9] = "DSL3100";
deviceArr[10] = "AVA5";
deviceArr[11] = "B6680";
deviceArr[12] = "AW570";
deviceArr[13] = "M1260";
deviceArr[14] = "DSL62";
deviceArr[15] = "U350II";
deviceArr[16] = "L7280+";
deviceArr[17] = "AVA5+";
deviceArr[18] = "D800II+";
deviceArr[19] = "AVA5 Plus";
if (this.IsInArray(deviceArr, str)) {
//此处可更换为自己使用的扫描仪型号
this.obj.devicetype = "scanner";
return;
}
if (strsub != "") {
str = strsub.replace(/\*/g, "\r\n");
this.obj.str = str; //传入textarea中
//console.log('Message state', websocket.readyState);
}
this.tup() //对返回信息进行处理,显示到页面
}
this.websocket.onclose = () => {
this.obj.statusbar = readyState[this.websocket.readyState];
}
setInterval(() => {
this.AutoPhotoAndRecog()
}, 1000);
} catch (exception) {
this.obj.statusbar = "Error";
}
}
//判断字符串是否在数组中方法
IsInArray(arr, val) {
let testStr = ',' + arr.join(",") + ",";
return testStr.indexOf("," + val + ",") != -1;
}
send() {
try {
this.websocket.send("181026150"); //发送护照芯片内容读取设置指令,固定指令,请勿变动
this.websocket.send("1810331"); //设置保存图片类型,18103+31 表示所有图片都保存
this.websocket.send("181041"); //是否识别识读区,请勿变动
this.websocket.send("181061"); //是否返回base64格式图片
this.websocket.send("1810731"); //哪些图片返回base64,默认所有图片都返回
} catch (exception) {
this.obj.msg = "Error sending data";
}
}
AutoPhotoAndRecog() {
var str = this.obj.devicetype;
if (str = "scanner") {
setInterval(() => {
this.getInformation()
}, 2000);
} else {
this.getInformation();
}
}
getInformation() {
if (this.websocket != null) {
this.websocket.send("11112");
}
}
tup() {
var str = this.obj.str;
//字符分割
var seek = str.split("data:image/jpeg;base64,");
var len = seek.length; //没有找到报头 此时会返回原串,长度也为1
if (len > 1) //有证件信息和图像,当只有一张图片的时候,有一个base64的头,会分割成两段,第一段为空,第二段会去掉头的图像base64串
{
var seek0 = seek[0]; //身份信息数据
//alert(seek0);
var strhead = "";
var strChipHead = "";
for (var i = 1; i < len; i++) //头像数据//头像数据 data:image/jpeg;base64,xx.... xx 表示图片的类型 01 为白光,以此类推
{
if (seek[i].length > 2) {
var strType = seek[i][0] + seek[i][1];
seek[i] = seek[i].substr(2);
if (strType == "01") //白光
{
seek[i] = "data:image/jpeg;base64," + seek[i];
} else if (strType == "02") //红外
{
seek[i] = "data:image/jpeg;base64," + seek[i];
} else if (strType == "04") //紫外
{
seek[i] = "data:image/jpeg;base64," + seek[i];
} else if (strType == "08") //版面头像
{
strhead = seek[i];
seek[i] = "data:image/jpeg;base64," + seek[i];
} else if (strType == "16") //芯片头像
{
strChipHead = seek[i];
seek[i] = "data:image/jpeg;base64," + seek[i];
}
}
}
//优先显示芯片头像
let seek1 = null;
if (strChipHead != "") {
seek1 = "data:image/jpeg;base64," + strChipHead;
this.obj.certificatePhoto = seek1;
} else {
seek1 = "data:image/jpeg;base64," + strhead;
}
if (seek0 != "") {
seek0 = seek0.replace(/\*/g, "\r\n");
this.obj.msg = "Receive information:" + seek0;
this.getcardInfo();
}
} else {
//var strsub = str.substr(1);
if (str != "") {
str = str.replace(/\*/g, "\r\n");
this.obj.msg = "Receive information:" + str;
//getcardInfo();
}
}
}
singlerecog() {
var str = this.obj.msg;
if (str == "scanner") {
this.websocket.send("1000" + this.obj.certificateType + "02");
}
this.websocket.send("18201" + this.obj.certificateType);
}
getcardInfo() {
var str = this.obj.msg;
var cardid = str.substring(str.indexOf(":") + 1, str.indexOf("\r\n")); //获取返回信息中的证件类型编号IDCardID
if (cardid == "二代证读卡") {
this.obj.cardinfo = "二代证读芯片";
myWebsocketStore.identityInformation = {};
myWebsocketStore.identityInformation = this.obj;
return;
}
var card1by1;
var cardname;
for (var i = 0; i < 80; i++) {
if (this.obj.certificateType) {
card1by1 = this.obj.certificatecardid;
}
if (card1by1 == cardid) {
cardname = this.obj.cardName;
break;
}
this.obj.msg = "证件类型:" + cardid + "\n" + "证件名称:" + cardname;
myWebsocketStore.identityInformation = this.obj;
return this.obj;
}
}
close() {
// 关闭连接
this.websocket.close()
// 销毁 websocket 实例对象
this.websocket = null;
}
}
export default initWebsocket;
\ No newline at end of file
import { useStore } from "@/store/index.js";
const userstore = useStore();
export function provincialUrbanAreas() {
let aa = userstore.returnCode(11);
for (let i = 0; i < aa.length; i++) {
if (aa[i].code.substring(2, 6) == '0000') {
aa[i]['parentCode'] = ''
}
if (aa[i].code.substring(4, 6) == '00'&&aa[i].code.substring(2, 4) != '00') {
aa[i]['parentCode'] = aa[i].code.substring(0, 2) + '0000';
} else if (aa[i].code.substring(4, 6) != '00') {
aa[i]['parentCode'] = aa[i].code.substring(0, 4) + '00';
}
}
return recursionDataTree(aa);
}
function recursionDataTree(menu) {
let result = [];
menu.forEach(item => {
delete item.children;
});
let map = {};
menu.forEach(item => {
map[item.code] = item;
});
menu.forEach(item => {
let parent = map[item.parentCode];
if (parent) {
(parent.children || (parent.children = [])).push(item);
} else {
result.push(item);
}
});
return result;
}
import axios from "axios";
import {
useStore
} from "../store";
const service = axios.create({
//根据环境变量 统一设置 域名 前缀,实际请求的路径是 baseURL + requestUrl
baseURL: '/api',
withCredentials: true, //跨域请求时发送Cookie
timeout: 20000, // 设置超时时间
});
// 请求拦截
service.interceptors.request.use(
(config) => {
const store = useStore();
// 请求前加一些需要的逻辑,如再请求头中加参数
if (store.token) {
config.headers['Authorization'] = store.token
}
//最终要返回这个配置
return config;
},
(error) => {
//请求失败时的逻辑
return Promise.reject(error);
}
);
// 响应拦截
service.interceptors.response.use(
(response) => {
//response中包含响应的所有数据包括响应头,状态等
// 前后端约定的接口回来的数据格式,接口成功或接口失败,做一些逻辑处理再返回结果
if (response.status !== 200) {
alert(response.statusText);
//最终都要返回结果
return Promise.reject(new Error(response.statusText || "Error"));
} else {
//最终都要返回结果
if (response.data.code == '9000' || response.data.constructor !== Object) {
return response.data;
} else {
return Promise.reject(response.data);
}
}
},
(error) => {
console.log("err" + error); // for debug
return Promise.reject(error);
}
);
export default service;
\ No newline at end of file
import axios from "axios";
import {
useStore
} from "../store";
const service = axios.create({
//根据环境变量 统一设置 域名 前缀,实际请求的路径是 baseURL + requestUrl
baseURL: '',
withCredentials: true, //跨域请求时发送Cookie
timeout: 10000, // 设置超时时间
});
// 请求拦截
service.interceptors.request.use(
(config) => {
const store = useStore();
// 请求前加一些需要的逻辑,如再请求头中加参数
if (store.token) {
config.headers['Authorization'] = store.token
}
//最终要返回这个配置
return config;
},
(error) => {
//请求失败时的逻辑
return Promise.reject(error);
}
);
// 响应拦截
service.interceptors.response.use(
(response) => {
//response中包含响应的所有数据包括响应头,状态等
// 前后端约定的接口回来的数据格式,接口成功或接口失败,做一些逻辑处理再返回结果
if (response.status !== 200) {
alert(response.statusText);
//最终都要返回结果
return Promise.reject(new Error(response.statusText || "Error"));
} else {
//最终都要返回结果
if (response.data.code == '9000' || response.data.constructor !== Object) {
return response.data;
} else {
return Promise.reject(response.data.message);
}
}
},
(error) => {
let status = "";
if (error.request) {
status = error.request;
} else if (error.response) {
status = error.response;
}
if (status) {
switch (status.status) {
case 400:
error.message = "请求错误(400)";
break;
case 401:
error.message = "未授权,请重新登录(401)";
router.push("/401");
break;
case 403:
error.message = "拒绝访问(403)";
break;
case 404:
error.message = "请求出错(404)";
router.push("/404");
break;
case 408:
error.message = "请求超时(408)";
break;
case 500:
error.message = "服务器错误(500)";
router.push("/a500");
break;
case 501:
error.message = "服务未实现(501)";
break;
case 502:
error.message = "网络错误(502)";
break;
case 503:
error.message = "服务不可用(503)";
break;
case 504:
error.message = "网络超时(504)";
break;
case 505:
error.message = "HTTP版本不受支持(505)";
break;
default:
error.message = `连接出错(${error.response.status})!`;
}
} else {
error.message = "连接服务器失败!";
}
// console.log("err" + error); // for debug
return Promise.reject(error);
}
);
export default service;
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<template>
<a-modal :visible="visible" :title="title" width="60%" @cancel="handleCancel" @ok="handleCancel">
<div class="roleAdd">
<div style="margin: 0px 5px">
<a-form class="form" ref="formRef" :model="formState" :labelCol="{ span: 8 }" :wrapper-col="{ span: 16 }" layout="inline" :rules="rules">
<table class="form-tables">
<tr>
<td colspan="1">
<a-form-item name="name" :label="`角色名称`">
<a-input v-model:value="formState.name" :allowClear="true" placeholder="请输入角色名称" />
</a-form-item>
</td>
<td colspan="1">
<a-form-item name="description" :label="`角色描述`">
<a-input v-model:value="formState.description" :allowClear="true" placeholder="角色描述" />
</a-form-item>
</td>
</tr>
</table>
</a-form>
</div>
<div class="titleBox">
<div style="margin: 0 auto">
<a-space :size="10">
<a-button type="primary" size="large" @click="saveInfo">
<template #icon><file-protect-outlined /></template>保存
</a-button>
<a-button type="primary" size="large" @click="() => formRef.resetFields()" v-if="operateStatus==1">
<template #icon>
<reload-outlined />
</template>清空
</a-button>
</a-space>
</div>
</div>
</div>
</a-modal>
</template>
<script setup>
import { useStore } from '@/store/index.js'
import { message } from 'ant-design-vue';
import { onMounted, reactive } from 'vue';
import { addRoles, updateRoles } from '@/api/role.js';
import { forIn } from "lodash-es";
const props = defineProps({
visible: Boolean,
title: String,
formData: {},
flogStatus: Number
});
const emit = defineEmits(["changeCancel", "changeData"]);
const handleCancel = async () => {
await emit("changeCancel");
};
const userstore = useStore();
const formRef = ref();
const formState = reactive({
name: '',
description: ''
});
const rules = {
name: [
{
required: true,
message: '请输入角色名称'
}
],
description: [
{
required: true,
message: '请输入角色描述'
}
]
};
const roles = ref([]);
const operateStatus = ref(1);
const loading = ref(false);
const saveInfo = () => {
if (operateStatus.value == 1) {
addRoles(formState).then(res => {
if (res.code == '9000') {
message.success('新增成功!');
handleCancel();
emit("changeData");
}
}).catch(error => {
message.error(error.message);
});
} else if (operateStatus.value == 2) {
updateRoles(formState).then(res => {
if (res.code == '9000') {
message.success('编辑成功!');
handleCancel();
emit("changeData");
}
}).catch(error => {
message.error(error.message);
});
}
}
// let socket = null;
// // 提交按钮的点击事件处理函数
// const send = () => {
// // 向服务器发送消息
// socket.emit('send', '')
// }
onMounted(() => {
operateStatus.value = props?.flogStatus;
if (operateStatus.value == 2) {
forIn(props?.formData, (value, key) => (formState[key] = value));
}
// //实例websocket
// socket = io('ws://127.0.0.1:90/echo/');
// // 建立连接的事件
// socket.on('connect', () => console.log('connect: websocket 连接成功!'));
// // 关闭连接的事件
// socket.on('disconnect', () => console.log('disconnect: websocket 连接关闭!'));
// // 接收到消息的事件
// socket.on('message', msg => console.log(msg));
})
// onBeforeUnmount(() => {
// // 关闭连接
// socket.close()
// // 销毁 websocket 实例对象
// socket = null;
// })
</script>
<style lang="less">
.roleAdd {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
.form {
.ant-form-item-with-help {
margin-bottom: 0px;
}
.ant-form-item-label {
flex: auto;
}
}
.form-tables {
width: 100%;
border-collapse: collapse;
tr {
width: 100%;
height: 60px;
td {
border: 1px solid #e7e7e7;
max-width: 222px;
.img-wp {
width: 186.829px;
height: 230px;
border: 1px solid #a5a5a5;
.img-div {
border-image-source: radial-gradient(
60% 60%,
transparent 0px,
transparent 100%,
#6691ef 100%
);
border-image-slice: 1;
border-width: 1px;
border-style: solid;
border-image-outset: 0px;
width: calc(100% - 40px);
height: calc(100% - 80px);
margin: 20px;
.img-span {
margin: 23px auto;
width: 14px;
line-height: 35px;
font-weight: 400;
font-size: 15px;
}
}
}
}
}
}
.titleBox {
display: flex;
justify-content: space-between;
align-items: center;
background: #fafafa;
border-radius: 0px 0px 2px 2px;
border: 1px solid #e9e9e9;
padding: 10px;
margin: 25px 5px;
}
.sign {
display: inline-block;
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
line-height: 16px;
&::before {
content: "";
display: inline-block;
width: 4px;
height: 12px;
background: #3162f5;
border-radius: 2px;
margin-right: 8px;
}
}
}
</style>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment