feat: 添加权限查询模块UI
This commit is contained in:
parent
cfa564f458
commit
216e29873d
@ -286,6 +286,71 @@
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/access-permission-inquiry",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/access-right-detection",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/add-permission-group",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/delivery-status",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/permission-query",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/release-record",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/send-permission",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/viewing-delivery-records",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/access-authority/access-authority",
|
||||
"type": "page",
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
}
|
||||
</route>
|
||||
|
||||
<!-- 门禁管理 -->
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 开局引导 -->
|
||||
@ -16,7 +17,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 数据统计 -->
|
||||
<view class="stats-section">
|
||||
<view class="stats-section" @click="handleStatsClick">
|
||||
<view class="stats-item">
|
||||
<text class="number">0</text>
|
||||
<text class="label">团队人员</text>
|
||||
@ -33,7 +34,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 同步提示 -->
|
||||
<view class="sync-tip">
|
||||
<view class="sync-tip" @click="handleSyncClick">
|
||||
<view class="dot"></view>
|
||||
<text class="text">您有6个人员、15条信息未同步到设备</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
@ -101,6 +102,18 @@
|
||||
desc: '广告、欢迎词发布到屏幕'
|
||||
}
|
||||
]
|
||||
|
||||
const handleStatsClick = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/personnel-passage/traffic-record/traffic-record'
|
||||
})
|
||||
}
|
||||
|
||||
const handleSyncClick = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/personnel-passage/AccessManage/permission-query'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@ -0,0 +1,168 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="权限查询" />
|
||||
<view class="inquiry-container">
|
||||
<!-- 查询表单 -->
|
||||
<view class="inquiry-form">
|
||||
<!-- 查询方式 -->
|
||||
<view class="form-item">
|
||||
<text class="label">人员查询方式</text>
|
||||
<view class="select" @click="handleSelectType">
|
||||
<text>按姓名</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 姓名输入 -->
|
||||
<view class="form-item">
|
||||
<text class="label">人员姓名</text>
|
||||
<input class="input" type="text" placeholder="请输入" placeholder-class="placeholder" />
|
||||
</view>
|
||||
|
||||
<!-- 门禁范围 -->
|
||||
<view class="form-item">
|
||||
<text class="label">门禁点范围</text>
|
||||
<view class="select" @click="handleSelectDoor">
|
||||
<text class="placeholder">全选</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 下发状态 -->
|
||||
<view class="form-item">
|
||||
<text class="label">下发状态</text>
|
||||
<view class="select" @click="handleSelectStatus">
|
||||
<text class="placeholder">全选</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="bottom-buttons">
|
||||
<button class="reset-btn">重置</button>
|
||||
<button class="query-btn">查询</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TopNavigation from '@/components/TopNavigation/TopNavigation.vue'
|
||||
|
||||
const handleSelectType = () => {
|
||||
// 处理选择查询方式
|
||||
}
|
||||
|
||||
const handleSelectDoor = () => {
|
||||
// 处理选择门禁点
|
||||
}
|
||||
|
||||
const handleSelectStatus = () => {
|
||||
// 处理选择状态
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.inquiry-container {
|
||||
min-height: 100vh;
|
||||
padding: 0 16px;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.inquiry-form {
|
||||
margin-top: 12px;
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px;
|
||||
margin-bottom: 1px;
|
||||
background-color: #fff;
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.input {
|
||||
flex: 1;
|
||||
height: 20px;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.select {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-buttons {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
height: 44px;
|
||||
font-size: 16px;
|
||||
border-radius: 22px;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.reset-btn {
|
||||
color: #666;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.query-btn {
|
||||
color: #fff;
|
||||
background-color: #2b5cff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,180 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="通行权限检测" />
|
||||
<view class="detection-container">
|
||||
<!-- 检测说明 -->
|
||||
<view class="detection-banner">
|
||||
<image class="banner-img" src="/static/images/bg_no_device.webp" mode="aspectFit" />
|
||||
<view class="detection-info">
|
||||
<image class="info-icon" src="/static/images/icon_white_tip.png" mode="aspectFit" />
|
||||
<view class="info-content">
|
||||
<text class="info-title">可检测以下两类问题:</text>
|
||||
<text class="info-item">1. 人员无法通行?</text>
|
||||
<text class="info-item">2.通行记录识别为陌生人?抓拍图不是该人员?</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 检测表单 -->
|
||||
<view class="detection-form">
|
||||
<!-- 姓名输入 -->
|
||||
<view class="form-item">
|
||||
<text class="label">姓名</text>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="请输入完整姓名"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 门禁选择 -->
|
||||
<view class="form-item">
|
||||
<text class="label">门禁</text>
|
||||
<view class="select" @click="handleSelectDoor">
|
||||
<text class="placeholder">请选择</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 开始检测按钮 -->
|
||||
<button class="start-btn" @click="handleStartDetection">开始检测</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TopNavigation from '@/components/TopNavigation/TopNavigation.vue'
|
||||
|
||||
const handleSelectDoor = () => {
|
||||
// 处理选择门禁
|
||||
}
|
||||
|
||||
const handleStartDetection = () => {
|
||||
// 处理开始检测
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.detection-container {
|
||||
min-height: 100vh;
|
||||
padding: 0 16px;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.detection-banner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
margin-top: 16px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.banner-img {
|
||||
width: 100%;
|
||||
aspect-ratio: 1/1;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.detection-info {
|
||||
display: flex;
|
||||
// width: 100%;
|
||||
padding: 10px;
|
||||
background-color: #f8f9fc;
|
||||
border-radius: 8px;
|
||||
|
||||
.info-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-top: 2px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
.info-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detection-form {
|
||||
margin-top: 12px;
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 16px;
|
||||
margin-bottom: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.label {
|
||||
min-width: 60px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.input {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.select {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 40px;
|
||||
|
||||
.placeholder {
|
||||
margin-right: 8px;
|
||||
margin-left: auto;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.start-btn {
|
||||
width: 100%;
|
||||
height: 44px;
|
||||
margin-top: 24px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background: #2b5cff;
|
||||
border-radius: 22px;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,303 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="添加权限组" />
|
||||
<scroll-view
|
||||
class="group-container"
|
||||
:scroll-y="true"
|
||||
:style="{ height: 'calc(100vh - var(--status-bar-height) - 44px)' }"
|
||||
>
|
||||
<!-- 配置名称 -->
|
||||
<view class="form-item input-item">
|
||||
<view class="form-header">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
<text>配置名称</text>
|
||||
</view>
|
||||
</view>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="name"
|
||||
@input="nameLength = name.length"
|
||||
placeholder="必填"
|
||||
placeholder-class="placeholder"
|
||||
maxlength="20"
|
||||
/>
|
||||
<text class="count">{{ nameLength }}/20</text>
|
||||
</view>
|
||||
|
||||
<!-- 配置描述 -->
|
||||
<view class="form-item input-item">
|
||||
<view class="form-header">
|
||||
<text class="form-label">配置描述</text>
|
||||
</view>
|
||||
<textarea
|
||||
class="textarea"
|
||||
v-model="desc"
|
||||
@input="descLength = desc.length"
|
||||
placeholder="描述权限配置的范围,例如:1幢1单元门口机出入口"
|
||||
placeholder-class="placeholder"
|
||||
maxlength="50"
|
||||
/>
|
||||
<text class="count">{{ descLength }}/50</text>
|
||||
</view>
|
||||
|
||||
<!-- 人员配置方式 -->
|
||||
<view class="form-item select-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
<text>人员配置方式</text>
|
||||
</view>
|
||||
<view class="form-value">
|
||||
<text>按人员/组织</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 人员范围 -->
|
||||
<view class="form-item select-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
<text>人员范围</text>
|
||||
</view>
|
||||
<view class="form-value">
|
||||
<text class="placeholder">必选</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 门禁范围 -->
|
||||
<view class="form-item select-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
<text>门禁范围</text>
|
||||
</view>
|
||||
<view class="form-value">
|
||||
<text class="placeholder">必选</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 门禁通行时间 -->
|
||||
<view class="form-item select-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
<text>门禁通行时间</text>
|
||||
</view>
|
||||
<view class="form-value">
|
||||
<text>全天时段有效</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提示说明 -->
|
||||
<view class="tips">
|
||||
<view class="tips-header">
|
||||
<image class="icon" src="/static/images/icon_gray_tip.png" mode="aspectFit" />
|
||||
<text class="title">提示</text>
|
||||
</view>
|
||||
<view class="tips-content">
|
||||
<view class="tips-list">
|
||||
<view class="tip-item">
|
||||
<text>1.</text>
|
||||
<text>
|
||||
通行时间仅型号为DS-K1T、D1或HST-AU开头的门禁设备有效,其余型号仅支持全天时段有效;
|
||||
</text>
|
||||
</view>
|
||||
<view class="tip-item">
|
||||
<text>2.</text>
|
||||
<text>
|
||||
通过角色配置[一键开门]、[密码开门]菜单权限,可远程/蓝牙/密码打开此配置范围内的门禁;
|
||||
</text>
|
||||
</view>
|
||||
<view class="tip-item">
|
||||
<text>3.</text>
|
||||
<text>一键开门不受通行时间、门禁状态的限制,可全天开门。</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部占位,防止保存按钮遮挡内容 -->
|
||||
<view style="height: 76px"></view>
|
||||
</scroll-view>
|
||||
<!-- 底部按钮 -->
|
||||
<button class="save-btn">保存</button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import TopNavigation from '@/components/TopNavigation/TopNavigation.vue'
|
||||
|
||||
const nameLength = ref(0)
|
||||
const descLength = ref(0)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.group-container {
|
||||
box-sizing: border-box;
|
||||
padding: 12px 16px;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
position: relative;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.input-item {
|
||||
.form-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
|
||||
.required {
|
||||
margin-right: 4px;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
margin-left: 4px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.input,
|
||||
.textarea {
|
||||
display: block; // 确保是块级元素
|
||||
width: auto; // 让宽度自动计算
|
||||
padding: 8px;
|
||||
// margin-right: 10px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
background-color: #f8f9fc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.count {
|
||||
position: absolute;
|
||||
right: 26px;
|
||||
bottom: 26px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.select-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.form-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
|
||||
.required {
|
||||
margin-right: 4px;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
.form-value {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
|
||||
.arrow {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
padding: 16px;
|
||||
margin-top: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.tips-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.tips-content {
|
||||
.tips-list {
|
||||
padding-left: 4px;
|
||||
clear: both;
|
||||
|
||||
.tip-item {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: #666;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
text:last-child {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
position: fixed;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
left: 16px;
|
||||
height: 44px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background-color: #2b5cff;
|
||||
border-radius: 8px;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
278
src/pages/personnel-passage/AccessManage/delivery-status.vue
Normal file
278
src/pages/personnel-passage/AccessManage/delivery-status.vue
Normal file
@ -0,0 +1,278 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="下发状态" />
|
||||
<view class="status-container">
|
||||
<!-- 人员信息 -->
|
||||
<view class="person-info">
|
||||
<text class="name">HikMall_30013234</text>
|
||||
<text class="company">19104656的互联</text>
|
||||
|
||||
<!-- 门禁信息 -->
|
||||
<view class="door-info">
|
||||
<text class="label">门禁</text>
|
||||
<text class="value">DS-K(L40959329)</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 下发状态列表 -->
|
||||
<view class="status-list">
|
||||
<!-- 人员信息 -->
|
||||
<view class="status-item">
|
||||
<checkbox class="checkbox" :checked="false" />
|
||||
<view class="item-content">
|
||||
<text class="title">人员信息</text>
|
||||
</view>
|
||||
<text class="status success">已下发</text>
|
||||
</view>
|
||||
|
||||
<!-- 人脸 -->
|
||||
<view class="status-item">
|
||||
<checkbox class="checkbox" :checked="false" />
|
||||
<view class="item-content">
|
||||
<text class="title">人脸</text>
|
||||
<image class="icon" src="/static/images/icon_face.png" mode="aspectFit" />
|
||||
</view>
|
||||
<text class="status success">已下发</text>
|
||||
</view>
|
||||
|
||||
<!-- 指纹 -->
|
||||
<view class="status-item">
|
||||
<checkbox class="checkbox" :checked="false" />
|
||||
<view class="item-content">
|
||||
<text class="title">指纹1</text>
|
||||
<image class="icon" src="/static/images/icon_fingerprint.png" mode="aspectFit" />
|
||||
<text class="error-msg">设备离线,请稍后重试</text>
|
||||
</view>
|
||||
<text class="status error">下发失败</text>
|
||||
</view>
|
||||
|
||||
<!-- 密码 -->
|
||||
<view class="status-item">
|
||||
<checkbox class="checkbox" :checked="false" />
|
||||
<view class="item-content">
|
||||
<text class="title">密码</text>
|
||||
<image class="icon" src="/static/images/icon_password.png" mode="aspectFit" />
|
||||
<text class="password">7****9</text>
|
||||
</view>
|
||||
<text class="status success">已下发</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 状态说明 -->
|
||||
<view class="status-desc">
|
||||
<view class="desc-header">
|
||||
<image class="info-icon" src="/static/images/icon_info.png" mode="aspectFit" />
|
||||
<text class="title">状态说明</text>
|
||||
</view>
|
||||
<view class="desc-list">
|
||||
<text class="desc-item">1、下发中:已配置权限,正在同步到门禁点;</text>
|
||||
<text class="desc-item">2、删除中:已删除权限,正在同步到门禁点;</text>
|
||||
<text class="desc-item">3、待下发:已配置权限,未同步到门禁点,不可通行;</text>
|
||||
<text class="desc-item">4、已下发:已配置权限,并已同步到门禁点,可通行;</text>
|
||||
<text class="desc-item">5、下发失败:已配置权限,同步到门禁点失败,不可通行;</text>
|
||||
<text class="desc-item">6、待重新下发:更新信息,待将信息同步到门禁点,可通行;</text>
|
||||
<text class="desc-item">7、待删除:已删除权限,未同步到门禁点,可通行。</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="bottom-buttons">
|
||||
<button class="record-btn" @click="handleRecordBtnClick">查看记录</button>
|
||||
<button class="publish-btn">立即下发</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TopNavigation from '@/components/TopNavigation/TopNavigation.vue'
|
||||
|
||||
const handleRecordBtnClick = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/personnel-passage/AccessManage/viewing-delivery-records'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.status-container {
|
||||
min-height: 100vh;
|
||||
padding: 12px 16px;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.person-info {
|
||||
padding: 16px;
|
||||
margin-bottom: 10px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.name {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.company {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.door-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px;
|
||||
margin-top: 12px;
|
||||
background-color: #f8f9fc;
|
||||
border-radius: 8px;
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.status-list {
|
||||
margin-bottom: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid #f5f6fa;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
margin-right: 8px;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
.item-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.error-msg {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.password {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 14px;
|
||||
|
||||
&.success {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&.error {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status-desc {
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.desc-header {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.info-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.desc-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
.desc-item {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-buttons {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
background-color: #fff;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
height: 44px;
|
||||
font-size: 16px;
|
||||
border-radius: 8px;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.record-btn {
|
||||
color: #666;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.publish-btn {
|
||||
color: #fff;
|
||||
background-color: #2b5cff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
364
src/pages/personnel-passage/AccessManage/permission-query.vue
Normal file
364
src/pages/personnel-passage/AccessManage/permission-query.vue
Normal file
@ -0,0 +1,364 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="权限查询" />
|
||||
<scroll-view
|
||||
class="query-container"
|
||||
:scroll-y="true"
|
||||
:style="{ height: 'calc(100vh - var(--status-bar-height) - 44px)' }"
|
||||
>
|
||||
<!-- 搜索提示卡片 -->
|
||||
<view class="search-tip">
|
||||
<text>人员无法通行?</text>
|
||||
<text class="check-btn" @click="handleCheckClick">去检测</text>
|
||||
</view>
|
||||
|
||||
<!-- 权限查询入口 -->
|
||||
<view class="query-entry" @click="handleQueryClick">
|
||||
<text class="entry-title">通行权限查询</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
|
||||
<!-- 人员列表 -->
|
||||
<view class="person-list">
|
||||
<view class="person-item" v-for="person in personList" :key="person.id">
|
||||
<view class="person-info">
|
||||
<text class="person-name">{{ person.name }}</text>
|
||||
<text class="person-id">{{ person.id }}</text>
|
||||
</view>
|
||||
<text class="company">{{ person.company }}</text>
|
||||
<view class="validity">
|
||||
<text class="label">有效时间:</text>
|
||||
<text class="value">{{ person.validityPeriod }}</text>
|
||||
</view>
|
||||
<view class="access-info">
|
||||
<view class="door-info">
|
||||
<image class="icon" src="/static/images/icon_door.png" mode="aspectFit" />
|
||||
<text>门禁点:{{ person.doorPoint }}</text>
|
||||
</view>
|
||||
<view class="time-info">
|
||||
<image class="icon" src="/static/images/icon_time.png" mode="aspectFit" />
|
||||
<text>通行时间:</text>
|
||||
<view class="time-tag">{{ person.accessTime }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="auth-types" @click="() => handlePersonItemClick(person)">
|
||||
<view class="type-item" v-for="type in person.authTypes" :key="type.name">
|
||||
<image class="type-icon" :src="type.icon" mode="aspectFit" />
|
||||
<text>{{ type.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<image class="item-arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="bottom-buttons">
|
||||
<button class="btn add-btn" @click="handleAddBtnClick">添加权限组</button>
|
||||
<button class="btn publish-btn" @click="handlePublishBtnClick">下发权限</button>
|
||||
<button class="btn record-btn" @click="handleRecordBtnClick">下发记录</button>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TopNavigation from '@/components/TopNavigation/TopNavigation.vue'
|
||||
|
||||
interface AuthType {
|
||||
name: string
|
||||
icon: string
|
||||
}
|
||||
|
||||
interface Person {
|
||||
id: string
|
||||
name: string
|
||||
company: string
|
||||
validityPeriod: string
|
||||
doorPoint: string
|
||||
accessTime: string
|
||||
authTypes: AuthType[]
|
||||
}
|
||||
|
||||
const personList = ref<Person[]>([
|
||||
{
|
||||
id: 'CY01068968',
|
||||
name: 'HikMall_30013234',
|
||||
company: '19104656的互联',
|
||||
validityPeriod: '永久有效',
|
||||
doorPoint: 'DS-K(L40959329)',
|
||||
accessTime: '全天时段有效',
|
||||
authTypes: [
|
||||
{ name: '人员', icon: '/static/images/icon_person.png' },
|
||||
{ name: '人脸', icon: '/static/images/icon_face.png' },
|
||||
{ name: '指纹', icon: '/static/images/icon_fingerprint.png' },
|
||||
{ name: '密码', icon: '/static/images/icon_password.png' }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'CY01069559',
|
||||
name: '4',
|
||||
company: '19104656的互联/test',
|
||||
validityPeriod: '2000-01-01至2037-12-31',
|
||||
doorPoint: 'DS-K(L40959329)',
|
||||
accessTime: '全天时段有效',
|
||||
authTypes: [
|
||||
{ name: '人员', icon: '/static/images/icon_person.png' },
|
||||
{ name: '指纹', icon: '/static/images/icon_fingerprint.png' }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'CY01069559',
|
||||
name: '4',
|
||||
company: '19104656的互联/test',
|
||||
validityPeriod: '2000-01-01至2037-12-31',
|
||||
doorPoint: 'DS-K(L40959329)',
|
||||
accessTime: '全天时段有效',
|
||||
authTypes: [
|
||||
{ name: '人员', icon: '/static/images/icon_person.png' },
|
||||
{ name: '指纹', icon: '/static/images/icon_fingerprint.png' }
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
const handleCheckClick = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/personnel-passage/AccessManage/access-right-detection'
|
||||
})
|
||||
}
|
||||
|
||||
const handleQueryClick = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/personnel-passage/AccessManage/access-permission-inquiry'
|
||||
})
|
||||
}
|
||||
|
||||
const handlePersonItemClick = (person: Person) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/personnel-passage/AccessManage/delivery-status?id=${person.id}`
|
||||
})
|
||||
}
|
||||
|
||||
// 添加权限组
|
||||
const handleAddBtnClick = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/personnel-passage/AccessManage/add-permission-group'
|
||||
})
|
||||
}
|
||||
|
||||
// 下发权限
|
||||
const handlePublishBtnClick = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/personnel-passage/AccessManage/send-permission'
|
||||
})
|
||||
}
|
||||
|
||||
// 下发记录
|
||||
const handleRecordBtnClick = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/personnel-passage/AccessManage/release-record'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.query-container {
|
||||
box-sizing: border-box;
|
||||
padding: 0 16px;
|
||||
padding-bottom: 76px;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.search-tip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px;
|
||||
margin-top: 12px;
|
||||
background-color: #fff7f2;
|
||||
border-radius: 8px;
|
||||
|
||||
.check-btn {
|
||||
padding: 2px 8px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.query-entry {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px;
|
||||
margin-top: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.entry-title {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.person-list {
|
||||
margin-top: 12px;
|
||||
|
||||
.person-item {
|
||||
position: relative;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.person-info {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
margin-bottom: 4px;
|
||||
|
||||
.person-name {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.person-id {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.company {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.validity {
|
||||
margin-bottom: 12px;
|
||||
font-size: 14px;
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.access-info {
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
background-color: #f8f9fc;
|
||||
border-radius: 8px;
|
||||
|
||||
.door-info,
|
||||
.time-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.time-tag {
|
||||
padding: 2px 8px;
|
||||
margin-left: 4px;
|
||||
font-size: 12px;
|
||||
color: #2b5cff;
|
||||
background-color: #eef4ff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-types {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
||||
.type-item {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
|
||||
.type-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-arrow {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-buttons {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
padding-top: 12px;
|
||||
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #eee;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
height: 44px;
|
||||
font-size: 14px;
|
||||
|
||||
// &::after {
|
||||
// border: 1px solid #eee;
|
||||
// border-radius: 0;
|
||||
// }
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
color: #2b5cff;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.publish-btn {
|
||||
color: #2b5cff;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.record-btn {
|
||||
color: #2b5cff;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
186
src/pages/personnel-passage/AccessManage/release-record.vue
Normal file
186
src/pages/personnel-passage/AccessManage/release-record.vue
Normal file
@ -0,0 +1,186 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="下发记录" />
|
||||
<scroll-view
|
||||
class="record-container"
|
||||
:scroll-y="true"
|
||||
:style="{ height: 'calc(100vh - var(--status-bar-height) - 44px)' }"
|
||||
>
|
||||
<view class="record-list">
|
||||
<view class="record-item" v-for="record in records" :key="record.time">
|
||||
<view class="record-header">
|
||||
<view class="title-wrap">
|
||||
<text class="title">{{ record.title }}</text>
|
||||
<text class="time">{{ record.time }}</text>
|
||||
</view>
|
||||
<view class="status-wrap" @click="handleRecordClick(record)">
|
||||
<text class="status">{{ record.status }}</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="record-stats">
|
||||
<view class="stat-item">
|
||||
<text class="value">{{ record.success }}</text>
|
||||
<text class="label">成功</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="value">{{ record.fail }}</text>
|
||||
<text class="label">失败</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="value">{{ record.total }}</text>
|
||||
<text class="label">总数</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TopNavigation from '@/components/TopNavigation/TopNavigation.vue'
|
||||
|
||||
interface Record {
|
||||
title: string
|
||||
time: string
|
||||
status: string
|
||||
success: number
|
||||
fail: number
|
||||
total: number
|
||||
}
|
||||
|
||||
const records = ref<Record[]>([
|
||||
{
|
||||
title: '系统自动操作下发',
|
||||
time: '2025-01-16 14:01:41',
|
||||
status: '已完成',
|
||||
success: 0,
|
||||
fail: 4,
|
||||
total: 4
|
||||
},
|
||||
{
|
||||
title: '杨操作下发',
|
||||
time: '2025-01-16 09:47:06',
|
||||
status: '已完成',
|
||||
success: 0,
|
||||
fail: 4,
|
||||
total: 4
|
||||
},
|
||||
{
|
||||
title: '系统自动操作下发',
|
||||
time: '2025-01-16 06:01:13',
|
||||
status: '已完成',
|
||||
success: 0,
|
||||
fail: 8,
|
||||
total: 8
|
||||
},
|
||||
{
|
||||
title: '系统自动操作下发',
|
||||
time: '2025-01-15 06:01:12',
|
||||
status: '已完成',
|
||||
success: 0,
|
||||
fail: 8,
|
||||
total: 8
|
||||
},
|
||||
{
|
||||
title: '系统自动操作下发',
|
||||
time: '2025-01-14 15:42:37',
|
||||
status: '已完成',
|
||||
success: 0,
|
||||
fail: 4,
|
||||
total: 4
|
||||
}
|
||||
])
|
||||
|
||||
const handleRecordClick = (record: Record) => {
|
||||
// 处理记录点击
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.record-container {
|
||||
padding: 12px 16px;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.record-list {
|
||||
.record-item {
|
||||
padding: 16px;
|
||||
margin-right: 32px;
|
||||
margin-bottom: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.record-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.title-wrap {
|
||||
.title {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
|
||||
.status {
|
||||
font-size: 14px;
|
||||
color: #2b5cff;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.record-stats {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 12px;
|
||||
background-color: #f8f9fc;
|
||||
border-radius: 8px;
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
|
||||
.value {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
214
src/pages/personnel-passage/AccessManage/send-permission.vue
Normal file
214
src/pages/personnel-passage/AccessManage/send-permission.vue
Normal file
@ -0,0 +1,214 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="下发权限">
|
||||
<template #right>
|
||||
<view class="timing-btn" @click="handleTimingClick">
|
||||
<image class="icon" src="/static/images/icon_timing.png" mode="aspectFit" />
|
||||
<text>定时下发</text>
|
||||
</view>
|
||||
</template>
|
||||
</TopNavigation>
|
||||
|
||||
<view class="send-container">
|
||||
<!-- 下发选项 -->
|
||||
<view class="form-item">
|
||||
<text class="label">下发方式</text>
|
||||
<view class="select">
|
||||
<text>普通下发</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">门禁范围</text>
|
||||
<view class="select">
|
||||
<text>全选</text>
|
||||
<image class="arrow" src="/static/images/icon_black_right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提示说明 -->
|
||||
<view class="tips">
|
||||
<view class="tips-header">
|
||||
<image class="icon" src="/static/images/icon_gray_tip.png" mode="aspectFit" />
|
||||
<text class="title">提示</text>
|
||||
</view>
|
||||
<view class="tips-content">
|
||||
<view class="tips-list">
|
||||
<view class="tip-item">
|
||||
<text>1.</text>
|
||||
<text>仅可选择已配置过通行权限的门禁进行下发;</text>
|
||||
</view>
|
||||
<view class="tip-item">
|
||||
<text>2.</text>
|
||||
<text>下发信息过多,会影响人员通行体验,建议避开人流量较大时间,错峰下发;</text>
|
||||
</view>
|
||||
<view class="tip-item">
|
||||
<text>3.</text>
|
||||
<text>
|
||||
设备数据与平台数据不一致时,可选择[全量下发],将删除设备本地数据后,重新下发平台数据;
|
||||
</text>
|
||||
</view>
|
||||
<view class="tip-item">
|
||||
<text>4.</text>
|
||||
<text>
|
||||
通行时间仅型号为DS-K1T、D1或HST-AU开头的门禁设备有效,其余型号仅支持全天时段有效。
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="extra-tips">
|
||||
<text>
|
||||
新添加或修改权限组需点击[立即下发],将配置的通行凭证下发到对应门禁点成功后,可生效通行权限;
|
||||
</text>
|
||||
<text>
|
||||
若权限组已按照组织/分组/楼幢进行人员配置,则后续在对应的组织/分组/楼幢中加入人员,将自动下发新增的通行凭证,无需手动下发。
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<button class="send-btn">立即下发</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TopNavigation from '@/components/TopNavigation/TopNavigation.vue'
|
||||
|
||||
const handleTimingClick = () => {
|
||||
// 处理定时下发点击
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.send-container {
|
||||
min-height: 100vh;
|
||||
padding: 12px 16px;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.timing-btn {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
padding: 4px 8px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.select {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
|
||||
.arrow {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.tips-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.tips-content {
|
||||
.tips-list {
|
||||
padding-left: 4px;
|
||||
|
||||
.tip-item {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: #666;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
text:last-child {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.extra-tips {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: #666;
|
||||
background-color: #f5f6fa;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
position: fixed;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
left: 16px;
|
||||
height: 44px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background-color: #2b5cff;
|
||||
border-radius: 8px;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,220 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom',
|
||||
disableScroll: false
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="查看记录" />
|
||||
<view class="records-container">
|
||||
<!-- 人员信息 -->
|
||||
<view class="person-info">
|
||||
<text class="name">HikMall_30013234</text>
|
||||
<text class="company">19104656的互联</text>
|
||||
|
||||
<!-- 门禁信息 -->
|
||||
<view class="door-info">
|
||||
<text class="label">门禁</text>
|
||||
<text class="value">DS-K(L40959329)</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 记录列表 -->
|
||||
<view class="records-list">
|
||||
<!-- 记录项 -->
|
||||
<view class="record-item" v-for="(item, index) in records" :key="index">
|
||||
<text class="time">{{ item.time }}</text>
|
||||
<view class="record-content">
|
||||
<view class="content-header">
|
||||
<text class="title">{{ item.title }}</text>
|
||||
<text :class="['status', item.status === '下发失败' ? 'error' : 'success']">
|
||||
{{ item.status }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="operation-info">
|
||||
<image class="icon" src="/static/images/icon_operation.png" mode="aspectFit" />
|
||||
<text class="label">权限操作:</text>
|
||||
<text class="value">{{ item.operation }}</text>
|
||||
</view>
|
||||
|
||||
<view v-if="item.error" class="error-info">
|
||||
<image class="icon" src="/static/images/icon_info.png" mode="aspectFit" />
|
||||
<text class="label">失败原因:</text>
|
||||
<text class="value">{{ item.error }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TopNavigation from '@/components/TopNavigation/TopNavigation.vue'
|
||||
|
||||
const records = [
|
||||
{
|
||||
time: '2025-01-16 06:01:13',
|
||||
title: '指纹1',
|
||||
status: '下发失败',
|
||||
operation: '下发权限',
|
||||
error: '设备离线,请稍后重试'
|
||||
},
|
||||
{
|
||||
time: '2025-01-15 06:01:12',
|
||||
title: '指纹1',
|
||||
status: '下发失败',
|
||||
operation: '下发权限',
|
||||
error: '设备离线,请稍后重试'
|
||||
},
|
||||
{
|
||||
time: '2025-01-14 06:01:17',
|
||||
title: '指纹1',
|
||||
status: '下发失败',
|
||||
operation: '下发权限',
|
||||
error: '设备离线,请稍后重试'
|
||||
},
|
||||
{
|
||||
time: '2025-01-13 11:22:18',
|
||||
title: '人员信息',
|
||||
status: '下发成功',
|
||||
operation: '下发权限'
|
||||
},
|
||||
{
|
||||
time: '2025-01-15 06:01:12',
|
||||
title: '指纹1',
|
||||
status: '下发失败',
|
||||
operation: '下发权限',
|
||||
error: '设备离线,请稍后重试'
|
||||
},
|
||||
{
|
||||
time: '2025-01-15 06:01:12',
|
||||
title: '指纹1',
|
||||
status: '下发失败',
|
||||
operation: '下发权限',
|
||||
error: '设备离线,请稍后重试'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.records-container {
|
||||
min-height: 100vh;
|
||||
padding: 12px 16px;
|
||||
background-color: #f5f6fa;
|
||||
}
|
||||
|
||||
.person-info {
|
||||
padding: 16px;
|
||||
margin-bottom: 10px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.name {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.company {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.door-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px;
|
||||
margin-top: 12px;
|
||||
background-color: #f8f9fc;
|
||||
border-radius: 8px;
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.records-list {
|
||||
.record-item {
|
||||
margin-bottom: 12px;
|
||||
|
||||
.time {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.record-content {
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.content-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 14px;
|
||||
|
||||
&.success {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.error {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operation-info,
|
||||
.error-info {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -14,7 +14,7 @@
|
||||
<view class="password-card">
|
||||
<view class="help-icon">
|
||||
<text>通行帮助</text>
|
||||
<image src="/static/images/personnelPassage/icon_tip.png" mode="aspectFit" />
|
||||
<image src="/static/images/icon_white_tip.png" mode="aspectFit" />
|
||||
</view>
|
||||
|
||||
<view class="password-display">
|
||||
|
||||
BIN
src/static/images/icon_gray_tip.png
Normal file
BIN
src/static/images/icon_gray_tip.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
8
src/types/uni-pages.d.ts
vendored
8
src/types/uni-pages.d.ts
vendored
@ -35,6 +35,14 @@ interface NavigateToOptions {
|
||||
"/pages/attendance/attendance-add-group/attendance-time" |
|
||||
"/pages/attendance/attendance-add-group/outside-rules" |
|
||||
"/pages/attendance/attendance-add-group/special-date-set" |
|
||||
"/pages/personnel-passage/AccessManage/access-permission-inquiry" |
|
||||
"/pages/personnel-passage/AccessManage/access-right-detection" |
|
||||
"/pages/personnel-passage/AccessManage/add-permission-group" |
|
||||
"/pages/personnel-passage/AccessManage/delivery-status" |
|
||||
"/pages/personnel-passage/AccessManage/permission-query" |
|
||||
"/pages/personnel-passage/AccessManage/release-record" |
|
||||
"/pages/personnel-passage/AccessManage/send-permission" |
|
||||
"/pages/personnel-passage/AccessManage/viewing-delivery-records" |
|
||||
"/pages/personnel-passage/access-authority/access-authority" |
|
||||
"/pages/personnel-passage/one-click-open-door/one-click-open-door" |
|
||||
"/pages/personnel-passage/password-open-door/password-open-door" |
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user