Parcourir la source

通行记录

tags/AL.0.8.0_20240113_base
yuan il y a 1 an
Parent
révision
b8e8b000dd
3 fichiers modifiés avec 193 ajouts et 38 suppressions
  1. +33
    -25
      src/components/notification/index.vue
  2. +29
    -13
      src/pages/index/index.vue
  3. +131
    -0
      src/stores/pass-records.ts

+ 33
- 25
src/components/notification/index.vue Voir le fichier

@@ -2,15 +2,17 @@
import './index.scss' import './index.scss'
import { BjxHelper } from "../../utils"; import { BjxHelper } from "../../utils";



/** /**
* props: todayPassTime: Json Array * props: todayPassTime: Json Array
* example: [["YYYY-MM-DD hh:mm:ss"], ["YYYY-MM-DD hh:mm:ss"]] * example: [["YYYY-MM-DD hh:mm:ss"], ["YYYY-MM-DD hh:mm:ss"]]
*/ */
const props = defineProps(['avatar', 'name', 'company', 'is-vip', 'pass-date', 'pass-time', 'today-pass-time'])
let lastName = BjxHelper.getBJXFirstChar(props.name)
let isVIP = JSON.parse(props.isVip)
let todayPassJsonObject = JSON.parse(props.todayPassTime)
const props = defineProps(['item'])
const item = props.item.passRecords[0]
const otherItems = props.item.passRecords.slice(1)
console.log(item.userName, otherItems.length , otherItems)
let lastName = BjxHelper.getBJXFirstChar(item.userName)
// let isVIP = props.isVip
// let todayPassJsonObject = JSON.parse(props.todayPassTime)


</script> </script>


@@ -21,61 +23,67 @@ let todayPassJsonObject = JSON.parse(props.todayPassTime)
<view class="card-body"> <view class="card-body">
<view class="d-flex flex-row"> <view class="d-flex flex-row">
<view class="pr-3 h6"> <view class="pr-3 h6">
<nut-avatar size="normal" color="white" :bg-color="BjxHelper.mbString2RgbHex(lastName)">
<view>
<view v-if="lastName">{{lastName}}</view>
<NutBadge :value="item.isVIP?'VIP':''">
<NutAvatar size="normal" color="white" :bg-color="BjxHelper.mbString2RgbHex(item.userName)" class="overflow-hidden">
<img v-if="item.faceUrl" :src="item.faceUrl" />
<view v-else-if="BjxHelper.getBJXFirstChar(item.userName)">{{BjxHelper.getBJXFirstChar(item.userName)}}</view>
<view v-else> <view v-else>
<Text className='fa fa-user'/>
<Text className='fas fa-user fa-lg'/>
</view> </view>
</view>
</nut-avatar>
</NutAvatar>
</NutBadge>

</view> </view>
<view>
<view class="flex-grow-1">
<view class="d-flex flex-row"> <view class="d-flex flex-row">
<view v-if="props.name" class="name">{{props.name}}</view>
<view v-if="item.userName" class="name">{{item.userName}}</view>
<view v-else> <view v-else>
<view class="text-black-50 name"> <view class="text-black-50 name">
<Text className='text-info fas fa-exclamation-circle'/> 无姓名 <Text className='text-info fas fa-exclamation-circle'/> 无姓名
</view> </view>
</view> </view>
<view class="pl-2">
<view v-if="isVIP" class="badge badge-pill badge-danger">VIP</view>
<view v-else></view>
</view>
</view> </view>
<view class="company text-black-50"> <view class="company text-black-50">
<view v-if="props.company">{{props.company}}</view>
<view v-if="item.company">{{item.company}}</view>
<view v-else> <view v-else>
<Text className='text-info fas fa-exclamation-circle'/> 无公司信息 <Text className='text-info fas fa-exclamation-circle'/> 无公司信息
</view> </view>
</view> </view>
</view> </view>
<view class="pr-4 d-flex justify-content-end">
<h5 class="pt-3" v-if="item.isBlock" style="line-height: unset !important;">
<view class="badge badge-pill badge-light text-danger">
<Text className="fas fa-ban text-danger"></Text>
被阻止人员
</view>
</h5>
<view v-else></view>
</view>
</view> </view>
</view> </view>


<view class="card-footer bg-white"> <view class="card-footer bg-white">
<view v-if="todayPassJsonObject.length === 0">
<view v-if="otherItems.length === 0">
<nut-collapse> <nut-collapse>
<nut-collapse-item name="name1" :title="'来访时间:'+ props.passDate" :value="props.passTime" :border=false>
<nut-collapse-item name="name1" :title="'来访时间:'+ item.date" :value="item.time" :border=false>
<template #icon> </template> <template #icon> </template>
</nut-collapse-item> </nut-collapse-item>
</nut-collapse> </nut-collapse>
</view> </view>
<view v-else> <view v-else>
<nut-collapse> <nut-collapse>
<nut-collapse-item name="name1" :title="'来访时间:'+ props.passDate" :value="props.passTime" :border=false>
<view v-for="(passTime, index) in todayPassJsonObject" :key="passTime">
<nut-collapse-item name="name1" :title="'来访时间:'+ item.date" :value="item.time" :border=false>
<view v-for="(passTime, index) in otherItems" :key="passTime.id">
<view class="d-flex"> <view class="d-flex">
<view class="flex-grow-1"> <view class="flex-grow-1">
<view v-if="index === 0">当日还有 {{todayPassJsonObject.length}} 次记录</view>
<view v-if="index === 0">当日还有 {{otherItems.length}} 次记录</view>
<view v-else></view> <view v-else></view>
</view> </view>
<view> {{ passTime }} </view>
<view> {{ passTime.time }} </view>
</view> </view>
</view> </view>
</nut-collapse-item> </nut-collapse-item>
</nut-collapse> </nut-collapse>

</view> </view>


</view> </view>


+ 29
- 13
src/pages/index/index.vue Voir le fichier

@@ -1,4 +1,4 @@
<script setup>
<script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { View, Text } from '@tarojs/components' import { View, Text } from '@tarojs/components'


@@ -9,14 +9,20 @@ import {useDidShow, useLoad} from "@tarojs/taro";
import { Date } from '@nutui/icons-vue-taro'; import { Date } from '@nutui/icons-vue-taro';
import Notification from "../../components/notification"; import Notification from "../../components/notification";
import {weappAuth} from "../../utils"; import {weappAuth} from "../../utils";
import {useContactsStore} from "../../stores/contacts";
import {GroupedPassRecords, usePassRecordsStore} from "../../stores/pass-records";


const state = reactive<{ const state = reactive<{
isPageDataLoading: boolean, isPageDataLoading: boolean,
isAuthError: boolean, isAuthError: boolean,
groupedPassRecords: GroupedPassRecords[],
}>({ }>({
isPageDataLoading: true, isPageDataLoading: true,
isAuthError: false
isAuthError: false,
groupedPassRecords: []
}) })
const passRecords = usePassRecordsStore()



init() init()


@@ -25,7 +31,17 @@ function init() {
state.isPageDataLoading = true state.isPageDataLoading = true
weappAuth().then(r => { weappAuth().then(r => {
console.log(r) console.log(r)
state.isPageDataLoading = false
passRecords.loadPassRecordsFromServer().then( passRecords => {
state.isPageDataLoading = false
state.groupedPassRecords = passRecords
console.log("aaa",state.groupedPassRecords )
// console.log(state.groupedPassRecords)
})
.catch(error => {
console.log("error", error)
state.isAuthError = true
state.isPageDataLoading = false
})
}).catch(e => { }).catch(e => {
console.log("error", e) console.log("error", e)
state.isAuthError = true state.isAuthError = true
@@ -92,19 +108,19 @@ const onAuthErrorRefresh = () => {
<View class="scroll 100vh" v-else> <View class="scroll 100vh" v-else>
<view class="scroll 100vh" v-if="!state.isPageDataLoading"> <view class="scroll 100vh" v-if="!state.isPageDataLoading">
<Scroll-View :scroll-y="true"> <Scroll-View :scroll-y="true">
<Notification name="" company="小明科技2" is-vip="true" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>
<Notification name="王远" company="joydata科技" is-vip="true" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='[]'/>
<Notification name="华雨" company="joydata科技" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21"]'/>
<Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>
<Notification v-for="item in state.groupedPassRecords" :item="item"/>
<!-- <Notification name="王远" company="joydata科技" is-vip="true" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='[]'/>-->
<!-- <Notification name="华雨" company="joydata科技" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21"]'/>-->
<!-- <Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>-->


<Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>
<Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>
<Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>
<!-- <Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>-->
<!-- <Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>-->
<!-- <Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>-->




<Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>
<Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>
<Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>
<!-- <Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>-->
<!-- <Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>-->
<!-- <Notification name="邸为荣" company="" is-vip="false" pass-date="2023-12-25" pass-time="22:22:22" today-pass-time='["22:22:21","22:22:20"]'/>-->


<view class="container pt-5 pb-3"> <view class="container pt-5 pb-3">
<view class="row"> <view class="row">


+ 131
- 0
src/stores/pass-records.ts Voir le fichier

@@ -0,0 +1,131 @@
// https://pinia.esm.dev/introduction.html
import { defineStore } from 'pinia'
import {GQLRequest, PinyinHelper, Session} from "../utils";
import {gql} from "graphql-tag";
import {ref, Ref, UnwrapRef} from "vue";
import Taro from "@tarojs/taro";
import moment from "moment";

export interface PassRecords {
key: string
id: number
userName: string
userId: number
faceUrl: string
recognizedTime: string
createTime: Date
type: number
company: string
isVIP: boolean
isBlock: boolean
date: string
time: string
}

export interface GroupedPassRecords {
key: string
passRecords: PassRecords[]
}

export const usePassRecordsStore = defineStore('pass-records', () => {

const passRecords: Ref<UnwrapRef<PassRecords[]>> = ref([])
const groupedPassRecords: Ref<UnwrapRef<GroupedPassRecords[]>> = ref([])

const GQL_QUERY_30_DAYS_PASS_RECORDS = gql`
query ($startDate: Date, $endDate: Date ) {
passRecords8: visitorPassRecords(type: 8, startDate: $startDate, endDate: $endDate) {
id
userName
userId
faceUrl
recognizedTime
createTime
type
visitor {
isVip
isBlock
visitorCompany
}
}
passRecords9: visitorPassRecords(type: 9, startDate: $startDate, endDate: $endDate) {
id
userName
userId
faceUrl
recognizedTime
createTime
type
visitor {
isVip
isBlock
visitorCompany
}
}
}
`

function loadPassRecordsFromServer () {
return new Promise((resolve, reject) => {
const items: PassRecords[] = []
const startDate = moment().subtract(30, "days" ).format("YYYY-MM-DD")
const endDate = moment().add(1, "days").format("YYYY-MM-DD")
console.log(startDate, endDate)
return GQLRequest.query(GQL_QUERY_30_DAYS_PASS_RECORDS, {startDate, endDate})
.then(result => {
if (result.code == 500) {
reject("Network Error")
} else {
console.log(result)
const resultGroups = ['passRecords8', 'passRecords9']
for (let groupName of resultGroups) {
for (let item of result.data[groupName]) {
// console.log(item)
items.push({
key: moment(item.recognizedTime, "YYYY-MM-DDTHH:mm:ss").format("YYYY-MM-DD")+item.userId,
id: item.id,
userName: item.userName,
userId: item.userId,
faceUrl: item.faceUrl,
recognizedTime: item.recognizedTime,
createTime: item.createTime,
type: item.type,
company: item.visitor ? item.visitor.visitorCompany : "",
isVIP: item.visitor ? item.visitor.isVip: false,
isBlock: item.visitor ? item.visitor.isBlock : false,
date: moment(item.recognizedTime, "YYYY-MM-DDTHH:mm:ss").format("YYYY-MM-DD"),
time: moment(item.recognizedTime, "YYYY-MM-DDTHH:mm:ss").format("HH:mm:ss"),
} as PassRecords)
}
}
passRecords.value = items.sort((a, b) => a.recognizedTime.localeCompare(b.recognizedTime)).reverse();
// console.log(passRecords.value)
generatePassRecordsGroupList(passRecords.value)
console.log(groupedPassRecords.value)
resolve(groupedPassRecords.value)
}
}).catch(e => {
reject(e)
})
})
}

const generatePassRecordsGroupList = (passRecords: PassRecords[]) => {
let passRecordsGroupedList = []
for (const item of passRecords) {
const key = item.key;
if (!passRecordsGroupedList[key]) {
passRecordsGroupedList[key] = { key: key, passRecords: [] };
}
passRecordsGroupedList[key].passRecords.push(item);
}

groupedPassRecords.value = Object.values(passRecordsGroupedList)
}

const getGroupedList = () => {
return groupedPassRecords.value
}

return { loadPassRecordsFromServer, getGroupedList}
})

Chargement…
Annuler
Enregistrer