| @@ -27,6 +27,8 @@ declare module 'vue' { | |||
| NutEmpty: typeof import('@nutui/nutui-taro')['Empty'] | |||
| NutForm: typeof import('@nutui/nutui-taro')['Form'] | |||
| NutFormItem: typeof import('@nutui/nutui-taro')['FormItem'] | |||
| NutGrid: typeof import('@nutui/nutui-taro')['Grid'] | |||
| NutGridItem: typeof import('@nutui/nutui-taro')['GridItem'] | |||
| NutInput: typeof import('@nutui/nutui-taro')['Input'] | |||
| NutNavbar: typeof import('@nutui/nutui-taro')['Navbar'] | |||
| NutRow: typeof import('@nutui/nutui-taro')['Row'] | |||
| @@ -8,7 +8,8 @@ export default defineAppConfig({ | |||
| 'pages/settings/index', | |||
| 'pages/login/index', | |||
| 'pages/web-view/index', | |||
| 'pages/contact-pass-records/index' | |||
| 'pages/contact-pass-records/index', | |||
| 'pages/contact-edit-logs/index' | |||
| ], | |||
| window: { | |||
| backgroundTextStyle: 'light', | |||
| @@ -32,7 +33,7 @@ export default defineAppConfig({ | |||
| pagePath: 'pages/invite/index', | |||
| selectedIconPath: 'images/calendar-plus-solid-397ef5.png', | |||
| iconPath: 'images/calendar-plus-regular-797979.png', | |||
| text: '新邀约' | |||
| text: '邀约' | |||
| }, | |||
| { | |||
| pagePath: 'pages/contact/index', | |||
| @@ -8,10 +8,10 @@ | |||
| color: #0056b3 !important; | |||
| } | |||
| .card-hover-gray { | |||
| background-color: #EEE; | |||
| background-color: #EEE !important; | |||
| } | |||
| .card-hover-white { | |||
| background-color: #FFF; | |||
| background-color: #FFF !important; | |||
| } | |||
| .btn-secondary:hover { | |||
| @@ -18,7 +18,7 @@ const contacts = useContactsStore() | |||
| const goContactInfoPage = () => { | |||
| console.log(item) | |||
| const contactData = contacts.getContactById(item.userId) | |||
| Router.toContactEdit({ data: contactData }) | |||
| if (contactData) Router.toContactEdit({ data: contactData }) | |||
| } | |||
| </script> | |||
| @@ -57,7 +57,7 @@ const goContactInfoPage = () => { | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="pr-4 d-flex justify-content-end"> | |||
| <view class="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> | |||
| @@ -0,0 +1,6 @@ | |||
| export default definePageConfig({ | |||
| navigationBarTitleText: '', | |||
| usingComponents: {}, | |||
| navigationStyle: 'custom', | |||
| disableScroll: true | |||
| }) | |||
| @@ -0,0 +1,20 @@ | |||
| page { | |||
| height: 100%; | |||
| } | |||
| .nut-navbar { | |||
| background: transparent; | |||
| } | |||
| .scroll { | |||
| flex: 1; | |||
| overflow: scroll; | |||
| } | |||
| .save-button { | |||
| font-size: 36px | |||
| } | |||
| .nut-action-sheet__item { | |||
| color: red !important; | |||
| } | |||
| @@ -0,0 +1,182 @@ | |||
| <script setup lang="ts"> | |||
| import { reactive } from 'vue' | |||
| import { View } from '@tarojs/components' | |||
| import './index.scss' | |||
| import {weappAuth} from "../../utils"; | |||
| import { | |||
| GroupedContactPassRecords, | |||
| useContactPassRecordsStore | |||
| } from "../../stores/contact-pass-records"; | |||
| import {Router} from "tarojs-router-next"; | |||
| import { BjxHelper } from "../../utils"; | |||
| import {ContactEditLog, useContactEditLogsStore} from "../../stores/contact-edit-logs"; | |||
| const contactData = Router.getData() | |||
| console.log("contactData", contactData) | |||
| const state = reactive<{ | |||
| isPageDataLoading: boolean, | |||
| isAuthError: boolean, | |||
| contactEditLogs: ContactEditLog[], | |||
| }>({ | |||
| isPageDataLoading: true, | |||
| isAuthError: false, | |||
| contactEditLogs: [], | |||
| }) | |||
| const editLogs = useContactEditLogsStore() | |||
| init() | |||
| function init() { | |||
| state.isAuthError = false | |||
| state.isPageDataLoading = true | |||
| console.log("contactData", contactData) | |||
| weappAuth().then(r => { | |||
| console.log(r) | |||
| editLogs.loadContactEditLogsFromServer(contactData.id).then( editLogs => { | |||
| state.isPageDataLoading = false | |||
| state.contactEditLogs = editLogs | |||
| // console.log(state.groupedPassRecords) | |||
| }) | |||
| .catch(error => { | |||
| console.log("error", error) | |||
| state.isAuthError = true | |||
| state.isPageDataLoading = false | |||
| }) | |||
| }).catch(e => { | |||
| console.log("error", e) | |||
| state.isAuthError = true | |||
| state.isPageDataLoading = false | |||
| }) | |||
| } | |||
| const onAuthErrorRefresh = () => { | |||
| init() | |||
| } | |||
| // const onPullDownRefresh = () => { | |||
| // console.log("onPullDownRefresh") | |||
| // state.isRefresherTriggered = false | |||
| // } | |||
| function onPullDownRefresh (e) { | |||
| console.log("onPullDownRefresh", e) | |||
| // state.isRefresherTriggered = false | |||
| } | |||
| const goBack = () => { | |||
| Router.back() | |||
| } | |||
| </script> | |||
| <template> | |||
| <view class="h-100 d-flex flex-column"> | |||
| <BackgroundBasic/> | |||
| <NutNavbar title=""></NutNavbar> | |||
| <view class="p-3 d-flex"> | |||
| <view class="flex-grow-1"> | |||
| <view class="h3"> | |||
| <view class="fas fa-chevron-left text-primary" @tap="goBack()" hover-class="btn-hover-primary"/> | |||
| 编辑记录 | |||
| </view> | |||
| <view class="text-black-50">此联系人的最近编辑记录</view> | |||
| </view> | |||
| <view class="d-flex align-items-end"> | |||
| <View></View> | |||
| </view> | |||
| </view> | |||
| <View v-if="state.isAuthError"> | |||
| <nut-empty description="连接出现问题,请稍后重试"> | |||
| <div style="margin-top: 10px"> | |||
| <nut-button type="default" @tap="onAuthErrorRefresh">刷新</nut-button> | |||
| </div> | |||
| </nut-empty> | |||
| </View> | |||
| <View class="scroll 100vh" v-else> | |||
| <view class="scroll 100vh" v-if="!state.isPageDataLoading"> | |||
| <Scroll-View style="height: 100vh" :scrollY="true"> | |||
| <view v-for="item in state.contactEditLogs" class="border m-3 p-3 bg-light"> | |||
| <view class="d-flex flex-row"> | |||
| <view class="pr-3"> | |||
| <NutAvatar size="normal" color="white" :bg-color="BjxHelper.mbString2RgbHex(item.userName)" class="overflow-hidden"> | |||
| <view v-if="BjxHelper.getBJXFirstChar(item.userName)">{{BjxHelper.getBJXFirstChar(item.userName)}}</view> | |||
| <view v-else> | |||
| <Text className='fas fa-user fa-lg'/> | |||
| </view> | |||
| </NutAvatar> | |||
| </view> | |||
| <view class="d-flex align-items-center text-black-50"> | |||
| <view> | |||
| <view class="font-weight-bold">{{item.userName + ' ' + item.methodDesc + ' ' + item.paramsDesc}}</view> | |||
| <view class="text-black-50 small">{{item.datetime}}</view> | |||
| </view> | |||
| </view> | |||
| </View> | |||
| </view> | |||
| <view v-if="state.contactEditLogs.length >= 100" class="pl-5 pr-5 pt-5 pb-3 text-black-50"> | |||
| <nut-divider> 仅显示最近 100 条记录 </nut-divider> | |||
| </view> | |||
| <view v-else-if="state.contactEditLogs.length === 0" class="pl-5 pr-5 pt-5 pb-3 text-black-50"> | |||
| <nut-divider> 没有编辑记录 </nut-divider> | |||
| </view> | |||
| <view v-else class="container pt-5 pb-3"> | |||
| <view class="row"> | |||
| <view class="col"/> | |||
| <view class="col text-center text-black-50"> | |||
| <nut-divider> 没有更多了 </nut-divider> | |||
| </view> | |||
| <view class="col"/> | |||
| </view> | |||
| </view> | |||
| </Scroll-View> | |||
| </view> | |||
| <View v-else class="skeleton"> | |||
| <NutSkeleton v-for="_ in 10" class="pl-4 pt-4 pb-4 pr-5" height="20px" width="60vw" animated avatar avatar-size="50px" row="2"/> | |||
| </View> | |||
| </View> | |||
| </view> | |||
| <!-- <view class="p-4">--> | |||
| <!-- <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">使用电话号码登录</button>--> | |||
| <!-- </view>--> | |||
| <!-- <Counter/>--> | |||
| <!-- <nut-cell title="展示弹出层" is-link @click="show = true"></nut-cell>--> | |||
| <!-- <nut-popup :style="{ padding: '30px 50px' }" v-model:visible="show">正文</nut-popup>--> | |||
| <!-- <View><Text>{{state.msg}}</Text></View>--> | |||
| <!-- <nut-button type="primary" @click="handleClick(state.msg2)">点我</nut-button>--> | |||
| <!-- <Add color="red" />--> | |||
| <!-- <div class="alert alert-primary" role="alert">--> | |||
| <!-- A simple primary alert—check it out!--> | |||
| <!-- </div>--> | |||
| <!-- <h1>Example heading <span class="badge bg-secondary">New</span></h1>--> | |||
| <!-- <button type="button" class="btn btn-primary">--> | |||
| <!-- Notifications <span class="badge text-bg-secondary">4</span>--> | |||
| <!-- </button>--> | |||
| <!-- <button type="button" class="btn btn-primary position-relative">--> | |||
| <!-- Inbox--> | |||
| <!-- <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">--> | |||
| <!-- 99+--> | |||
| <!-- <span class="visually-hidden">unread messages</span>--> | |||
| <!-- </span>--> | |||
| <!-- </button>--> | |||
| <!-- </view>--> | |||
| </template> | |||
| @@ -32,15 +32,16 @@ const onSaveClicked = () => { | |||
| }).catch(error => { | |||
| Taro.hideLoading() | |||
| if (error) { | |||
| const errorMessage = (typeof error === "string")? error : "服务器错误,请稍后重试" | |||
| Taro.showToast({ | |||
| title: error, | |||
| title: errorMessage, | |||
| icon: 'none', | |||
| duration: 2000 | |||
| }) | |||
| } | |||
| else { | |||
| Taro.showToast({ | |||
| title: '网络异常,请稍候重试', | |||
| title: '网络异常,请稍后重试', | |||
| icon: 'none', | |||
| duration: 2000 | |||
| }) | |||
| @@ -70,7 +71,7 @@ const onBlockConfirm = (item) => { | |||
| }).catch(error => { | |||
| Taro.hideLoading() | |||
| Taro.showToast({ | |||
| title: '网络异常,请稍候重试', | |||
| title: '网络异常,请稍后重试', | |||
| icon: 'none', | |||
| duration: 2000 | |||
| }) | |||
| @@ -81,8 +82,8 @@ const onClickPassRecords = () => { | |||
| Router.toContactPassRecords({ data: contactData }) | |||
| } | |||
| const onClickEditRecords = () => { | |||
| Router.toContactEdit({ data: contactData }) | |||
| const onClickEditLogs = () => { | |||
| Router.toContactEditLogs({ data: contactData }) | |||
| } | |||
| const onDeleteConfirm = (item) => { | |||
| @@ -99,7 +100,7 @@ const onDeleteConfirm = (item) => { | |||
| }).catch(error => { | |||
| Taro.hideLoading() | |||
| Taro.showToast({ | |||
| title: '网络异常,请稍候重试', | |||
| title: '网络异常,请稍后重试', | |||
| icon: 'none', | |||
| duration: 2000 | |||
| }) | |||
| @@ -141,7 +142,7 @@ const onDeleteConfirm = (item) => { | |||
| </view> | |||
| <view hover-class="card-hover-gray"> | |||
| <nut-cell title="编辑记录" sub-title="本联系人在公司中的所有信息修改记录" @tap="onClickEditRecords"> | |||
| <nut-cell title="编辑记录" sub-title="此联系人的信息修改记录" @tap="onClickEditLogs"> | |||
| <template #desc> | |||
| <Text className="fas fa-chevron-right"/> | |||
| </template> | |||
| @@ -29,7 +29,7 @@ const onSaveClicked = () => { | |||
| }).catch(error => { | |||
| Taro.hideLoading() | |||
| Taro.showToast({ | |||
| title: '网络异常,请稍候重试', | |||
| title: '网络异常,请稍后重试', | |||
| icon: 'none', | |||
| duration: 2000 | |||
| }) | |||
| @@ -125,6 +125,9 @@ const goBack = () => { | |||
| <view v-if="passRecords.passRecords.length >= 100" class="pl-5 pr-5 pt-5 pb-3 text-black-50"> | |||
| <nut-divider> 仅显示最近 100 条记录 </nut-divider> | |||
| </view> | |||
| <view v-else-if="passRecords.passRecords.length === 0" class="pl-5 pr-5 pt-5 pb-3 text-black-50"> | |||
| <nut-divider> 没有到访记录 </nut-divider> | |||
| </view> | |||
| <view v-else class="container pt-5 pb-3"> | |||
| <view class="row"> | |||
| @@ -11,4 +11,15 @@ page { | |||
| overflow: scroll; | |||
| } | |||
| .nut-grid-item__content { | |||
| padding: 0; | |||
| display:unset; | |||
| } | |||
| .nut-grid-item__content--border { | |||
| border-right-width: unset; | |||
| border-bottom-width: unset; | |||
| } | |||
| .nut-grid-item__content--surround { | |||
| border-top-width: unset; | |||
| border-left-width: unset; | |||
| } | |||
| @@ -1,11 +1,208 @@ | |||
| <template> | |||
| <view class="index"> | |||
| <text>我是邀约页面!</text> | |||
| </view> | |||
| </template> | |||
| <script lang="ts" setup> | |||
| import Contact from "../../components/contact" | |||
| import { Router } from 'tarojs-router-next' | |||
| import {reactive, ref} from 'vue'; | |||
| import './index.scss' | |||
| import { useContactsStore, ContactData } from '../../stores/contacts' | |||
| import { registerRouterBackListener } from 'tarojs-router-next' | |||
| import {BjxHelper} from "../../utils"; | |||
| import {gql} from "graphql-tag"; | |||
| import {PinyinHelper, GQLRequest, weappAuth} from "../../utils"; | |||
| import {useAuthStore} from "../../stores/auth"; | |||
| // defineExpose({ | |||
| // loadContactsFromServer, | |||
| // }); | |||
| const state = reactive<{ | |||
| isAuthError: boolean, | |||
| isContactDataLoadError: boolean, | |||
| isContactDataLoading: boolean, | |||
| searchQuery: string, | |||
| normalContacts: ContactData[], | |||
| flexContacts: ContactData[], // Generic type for now | |||
| }>({ | |||
| isAuthError: false, | |||
| isContactDataLoadError: false, | |||
| isContactDataLoading: true, | |||
| searchQuery: "", | |||
| normalContacts: [], | |||
| flexContacts: [] | |||
| }) | |||
| const contacts = useContactsStore() | |||
| <script> | |||
| export default { | |||
| name: 'Invite' | |||
| init() | |||
| function init() { | |||
| state.isAuthError = false | |||
| state.isContactDataLoadError = false | |||
| state.isContactDataLoading = true | |||
| weappAuth() | |||
| .then(r => { | |||
| contacts.loadContactsFromServer().then( | |||
| contactList => { | |||
| console.log("contactList", contactList) | |||
| generateContactGroupList(contactList) | |||
| state.isContactDataLoading = false | |||
| }) | |||
| .catch(e => { | |||
| state.isAuthError = false | |||
| state.isContactDataLoadError = true | |||
| state.isContactDataLoading = false | |||
| }) | |||
| }) | |||
| .catch(e=> { | |||
| console.log("error", e) | |||
| state.isAuthError = true | |||
| state.isContactDataLoadError = false | |||
| state.isContactDataLoading = false | |||
| }) | |||
| registerRouterBackListener((to, from) => { | |||
| if ((from.url === "/pages/contact-new/index" && to.url === "/pages/invite/index") | |||
| || (from.url === "/pages/contact-edit/index" && to.url === "/pages/invite/index") | |||
| ) { | |||
| generateContactGroupList(contacts.allContacts) | |||
| } | |||
| }) | |||
| } | |||
| const onAuthErrorRefresh = () => { | |||
| init() | |||
| } | |||
| const onContactDataLoadErrorRefresh = () => { | |||
| state.isContactDataLoadError = false | |||
| state.isContactDataLoading = true | |||
| contacts.loadContactsFromServer().then( | |||
| contactList => { | |||
| console.log("contactList", contactList) | |||
| generateContactGroupList(contactList) | |||
| state.isContactDataLoading = false | |||
| }) | |||
| .catch(e => { | |||
| state.isContactDataLoadError = true | |||
| state.isContactDataLoading = false | |||
| }) | |||
| } | |||
| const generateContactGroupList = (contactList: ContactData[]) => { | |||
| state.normalContacts = [] | |||
| state.flexContacts = [] | |||
| for (const item of contactList) { | |||
| if (item.flexVisit === true) state.flexContacts.push(item) | |||
| else state.normalContacts.push(item) | |||
| } | |||
| } | |||
| const goToContactNewPage = () => { | |||
| Router.toContactNew() | |||
| } | |||
| const goToContactEditPage = (item) => { | |||
| Router.toContactEdit({ data: item }) | |||
| } | |||
| </script> | |||
| <template> | |||
| <view class="h-100 d-flex flex-column"> | |||
| <BackgroundBasic/> | |||
| <NutNavbar title=""></NutNavbar> | |||
| <view class="pl-3 pt-3 pr-3 h3 d-flex"> | |||
| <view class="flex-grow-1"> | |||
| 我的邀约 | |||
| </view> | |||
| </view> | |||
| <View class="scroll 100vh"> | |||
| <View class="mt-3 p-3"> | |||
| <View class="border bg-white p-3 d-flex flex-column" hover-class="card-hover-gray" @tap="goToContactNewPage()" > | |||
| <View class="d-flex justify-content-center"> | |||
| <Image :src="require('./invite.jpeg')" class="p-3" mode='heightFix' style="height: 15vh"/> | |||
| </View> | |||
| <View class="d-flex justify-content-center"> | |||
| <View class="fas fa-plus-circle text-black-50" style="font-size: 120%"> 新邀约</View> | |||
| </View> | |||
| </View> | |||
| </View> | |||
| <View v-if="!state.isContactDataLoading"> | |||
| <View v-if="state.isAuthError"> | |||
| <nut-empty description="连接出现问题,请稍后重试"> | |||
| <div style="margin-top: 10px"> | |||
| <nut-button type="default" @tap="onAuthErrorRefresh">刷新</nut-button> | |||
| </div> | |||
| </nut-empty> | |||
| </View> | |||
| <View v-else-if="state.isContactDataLoadError"> | |||
| <nut-empty description="连接出现问题,请稍后重试"> | |||
| <div style="margin-top: 10px"> | |||
| <nut-button type="default" @tap="onContactDataLoadErrorRefresh">刷新</nut-button> | |||
| </div> | |||
| </nut-empty> | |||
| </View> | |||
| <View v-else> | |||
| <View class="h4 p-3">来访联系人</View> | |||
| <View class="container-fluid"> | |||
| <View class="row w-100"> | |||
| <View style="width: 25vw" v-for="item in state.normalContacts"> | |||
| <View class="m-2 p-3 border" hover-class="card-hover-gray" @tap="goToContactEditPage(item)"> | |||
| <View class="d-flex justify-content-center"> | |||
| <NutBadge :value="item.isVIP?'VIP':''"> | |||
| <NutAvatar size="normal" color="white" :bg-color="BjxHelper.mbString2RgbHex(item.name)" class="overflow-hidden"> | |||
| <img v-if="item.avatar" :src="item.avatar" /> | |||
| <view v-else-if="BjxHelper.getBJXFirstChar(item.name)">{{BjxHelper.getBJXFirstChar(item.name)}}</view> | |||
| <view v-else> | |||
| <Text className='fas fa-user fa-lg'/> | |||
| </view> | |||
| </NutAvatar> | |||
| </NutBadge> | |||
| </View> | |||
| <View class="d-flex justify-content-center small b pt-2 text-nowrap overflow-hidden"> | |||
| {{item.name}} | |||
| </View> | |||
| </View> | |||
| </View> | |||
| </View> | |||
| </View> | |||
| <View class="h4 p-3">可随时来访联系人</View> | |||
| <View class="container-fluid"> | |||
| <View class="row w-100"> | |||
| <View style="width: 25vw" v-for="item in state.flexContacts"> | |||
| <View class="m-2 p-3 border" hover-class="card-hover-gray" @tap="goToContactEditPage(item)"> | |||
| <View class="d-flex justify-content-center"> | |||
| <NutBadge :value="item.isVIP?'VIP':''"> | |||
| <NutAvatar size="normal" color="white" :bg-color="BjxHelper.mbString2RgbHex(item.name)" class="overflow-hidden"> | |||
| <img v-if="item.avatar" :src="item.avatar" /> | |||
| <view v-else-if="BjxHelper.getBJXFirstChar(item.name)">{{BjxHelper.getBJXFirstChar(item.name)}}</view> | |||
| <view v-else> | |||
| <Text className='fas fa-user fa-lg'/> | |||
| </view> | |||
| </NutAvatar> | |||
| </NutBadge> | |||
| </View> | |||
| <View class="d-flex justify-content-center small b pt-2 text-nowrap overflow-hidden"> | |||
| {{item.name}} | |||
| </View> | |||
| </View> | |||
| </View> | |||
| </View> | |||
| </View> | |||
| </View> | |||
| </View> | |||
| <View v-else class="d-flex flex-column"> | |||
| <NutSkeleton v-for="_ in 10" class="p-3" height="15px" animated avatar avatar-size="50px" row="1"/> | |||
| </View> | |||
| </View> | |||
| </view> | |||
| </template> | |||
| @@ -0,0 +1,88 @@ | |||
| // 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 dayjs from "dayjs"; | |||
| import {PassRecords} from "./pass-records"; | |||
| export interface ContactEditLog { | |||
| userName: string | |||
| method: string | |||
| methodDesc: string | |||
| datetime: string | |||
| params: string | |||
| paramsDesc: string | |||
| } | |||
| export const useContactEditLogsStore = defineStore('contact-edit-logs', () => { | |||
| const editLogs: Ref<UnwrapRef<ContactEditLog[]>> = ref([]) | |||
| const GQL_QUERY_CONTACT_EDIT_LOGS = gql` | |||
| query ($visitorId: ID, $limit: Int ) { | |||
| visitorLogs(visitorId: $visitorId, limit: $limit) { | |||
| userName | |||
| param | |||
| method | |||
| operateTime | |||
| } | |||
| } | |||
| ` | |||
| function loadContactEditLogsFromServer (visitorId: number) { | |||
| return new Promise((resolve, reject) => { | |||
| const items: ContactEditLog[] = [] | |||
| const limit = 100 | |||
| console.log("visitorId", visitorId) | |||
| return GQLRequest.query(GQL_QUERY_CONTACT_EDIT_LOGS, {visitorId, limit}) | |||
| .then(result => { | |||
| if (result.code == 500) { | |||
| reject("Network Error") | |||
| } else { | |||
| console.log(result) | |||
| for (let item of result.data.visitorLogs) { | |||
| // console.log(item) | |||
| items.push({ | |||
| userName: item.userName, | |||
| method: item.method, | |||
| methodDesc: methodToDesc(item.method), | |||
| datetime: dayjs(item.operateTime, "YYYY-MM-DDTHH:mm:ss").format("YYYY年MM月DD日 HH:mm:ss"), | |||
| params: item.param, | |||
| paramsDesc: paramsToDesc(item.method, item.param) | |||
| } as ContactEditLog) | |||
| } | |||
| editLogs.value = items.sort((a, b) => a.datetime.localeCompare(b.datetime)).reverse(); | |||
| console.log("editLogs", editLogs.value) | |||
| resolve(editLogs.value) | |||
| } | |||
| }).catch(e => { | |||
| reject(e) | |||
| }) | |||
| }) | |||
| } | |||
| function methodToDesc(method: string) { | |||
| if (method === "updateVisitor") return "更新了" | |||
| else if (method === "createVisitor") return "创建了" | |||
| else if (method === "deleteVisitor") return "删除了" | |||
| else return method | |||
| } | |||
| function paramsToDesc(method: string, params: string) { | |||
| if (method === "updateVisitor" || method === "createVisitor") { | |||
| if (params.indexOf("resourceId") !== -1) return "访客照片和信息" | |||
| else if (params.indexOf('isBlock":true') !== -1) return "阻止状态" | |||
| else if (params.indexOf('isBlock":false') !== -1) return "取消阻止状态" | |||
| else return "访客信息" | |||
| } | |||
| else if (method === "deleteVisitor" ) { | |||
| return "此访客" | |||
| } | |||
| else return params | |||
| } | |||
| return { loadContactEditLogsFromServer } | |||
| }) | |||
| @@ -36,8 +36,8 @@ export const useContactItemStore = defineStore('contact-item', () => { | |||
| } | |||
| const CREATE_VISITOR = gql` | |||
| mutation CreateVisitor($name: String!, $nickName: String, $phone: String, $company: String, $isVIP: Boolean, $flexVisit: Boolean, $resourceId: Long ) { | |||
| createVisitor( input: { | |||
| mutation CreateVisitor($staffId: ID!, $name: String!, $nickName: String, $phone: String, $company: String, $isVIP: Boolean, $flexVisit: Boolean, $resourceId: ID ) { | |||
| createVisitor( staffId: $staffId, input: { | |||
| name: $name, | |||
| nickname: $nickName, | |||
| phone: $phone, | |||
| @@ -50,8 +50,8 @@ export const useContactItemStore = defineStore('contact-item', () => { | |||
| ` | |||
| const UPDATE_VISITOR = gql` | |||
| mutation UpdateVisitor($id: Long!, $name: String!, $nickName: String, $phone: String, $company: String, $isVIP: Boolean, $flexVisit: Boolean, $resourceId: Long ) { | |||
| updateVisitor( input: { | |||
| mutation UpdateVisitor($staffId: ID!, $id: ID!, $name: String!, $nickName: String, $phone: String, $company: String, $isVIP: Boolean, $flexVisit: Boolean, $resourceId: ID ) { | |||
| updateVisitor( staffId: $staffId, input: { | |||
| id: $id, | |||
| name: $name, | |||
| nickname: $nickName, | |||
| @@ -65,14 +65,14 @@ export const useContactItemStore = defineStore('contact-item', () => { | |||
| ` | |||
| const DELETE_VISITOR = gql` | |||
| mutation DeleteVisitor($id: Long! ) { | |||
| deleteVisitor( id: $id ) | |||
| mutation DeleteVisitor( $staffId: ID!, $id: ID! ) { | |||
| deleteVisitor( staffId: $staffId, id: $id ) | |||
| } | |||
| ` | |||
| const CHANGE_BLOCK_STATUS = gql` | |||
| mutation UpdateVisitor($id: Long!, $isBlock: Boolean ) { | |||
| updateVisitor( input: { | |||
| mutation UpdateVisitor( $staffId: ID!, $id: ID!, $isBlock: Boolean ) { | |||
| updateVisitor( staffId: $staffId, input: { | |||
| id: $id, | |||
| isBlock: $isBlock | |||
| } ) | |||
| @@ -86,13 +86,15 @@ export const useContactItemStore = defineStore('contact-item', () => { | |||
| const company = contact.value.company | |||
| const isVIP = contact.value.isVIP | |||
| const flexVisit = contact.value.flexVisit | |||
| const staffId = Session.get("staff").id | |||
| return new Promise((resolve, reject) => { | |||
| if (contactNewAvatar.value !== "") { | |||
| uploadFace().then(r => { | |||
| console.log(r) | |||
| const resourceId = r.data.resourceId | |||
| GQLRequest.query(CREATE_VISITOR, { name, nickName, phone, company, isVIP, flexVisit, resourceId }) | |||
| GQLRequest.query(CREATE_VISITOR, { staffId, name, nickName, phone, company, isVIP, flexVisit, resourceId }) | |||
| .then(r=> resolve(r)) | |||
| .catch(e=> reject(e)) | |||
| }).catch(e => { | |||
| @@ -100,7 +102,7 @@ export const useContactItemStore = defineStore('contact-item', () => { | |||
| }) | |||
| } | |||
| else { | |||
| GQLRequest.query(CREATE_VISITOR, { name, nickName, phone, company, isVIP, flexVisit }) | |||
| GQLRequest.query(CREATE_VISITOR, { staffId, name, nickName, phone, company, isVIP, flexVisit }) | |||
| .then(r=> resolve(r)) | |||
| .catch(e=> reject(e)) | |||
| } | |||
| @@ -117,14 +119,14 @@ export const useContactItemStore = defineStore('contact-item', () => { | |||
| const company = contact.value.company | |||
| const isVIP = contact.value.isVIP | |||
| const flexVisit = contact.value.flexVisit | |||
| const staffId = Session.get("staff").id | |||
| return new Promise((resolve, reject) => { | |||
| if (contactNewAvatar.value !== "") { | |||
| uploadFace().then(r => { | |||
| console.log(r) | |||
| const resourceId = r.data.resourceId | |||
| GQLRequest.query(UPDATE_VISITOR, {id, name, nickName, phone, company, isVIP, flexVisit, resourceId }) | |||
| GQLRequest.query(UPDATE_VISITOR, {staffId, id, name, nickName, phone, company, isVIP, flexVisit, resourceId }) | |||
| .then(r=> resolve(r)) | |||
| .catch(e=> reject(e)) | |||
| }).catch(e => { | |||
| @@ -132,7 +134,7 @@ export const useContactItemStore = defineStore('contact-item', () => { | |||
| }) | |||
| } | |||
| else { | |||
| GQLRequest.query(UPDATE_VISITOR, {id, name, nickName, phone, company, isVIP, flexVisit }) | |||
| GQLRequest.query(UPDATE_VISITOR, {staffId, id, name, nickName, phone, company, isVIP, flexVisit }) | |||
| .then(r=> resolve(r)) | |||
| .catch(e=> reject(e)) | |||
| } | |||
| @@ -141,13 +143,16 @@ export const useContactItemStore = defineStore('contact-item', () => { | |||
| function setBlockStatus(isBlock: Boolean) { | |||
| const id = contact.value.id | |||
| return GQLRequest.query(CHANGE_BLOCK_STATUS, { id, isBlock }) | |||
| const staffId = Session.get("staff").id | |||
| return GQLRequest.query(CHANGE_BLOCK_STATUS, { staffId, id, isBlock }) | |||
| } | |||
| function deleteVisitor() { | |||
| const id = contact.value.id | |||
| const staffId = Session.get("staff").id | |||
| return GQLRequest.query(DELETE_VISITOR, { id }) | |||
| return GQLRequest.query(DELETE_VISITOR, { staffId, id }) | |||
| } | |||
| function uploadFace() { | |||
| @@ -78,10 +78,7 @@ export const useContactsStore = defineStore('contacts', () => { | |||
| function getContactById(id: number) { | |||
| for(const contact of allContacts.value) { | |||
| console.log(contact) | |||
| if (contact.id === id) { | |||
| return contact | |||
| } | |||
| if (contact.id === id) return contact | |||
| } | |||
| return undefined | |||
| } | |||
| @@ -75,7 +75,7 @@ export const usePassRecordsStore = defineStore('pass-records', () => { | |||
| if (result.code == 500) { | |||
| reject("Network Error") | |||
| } else { | |||
| console.log(result) | |||
| // console.log(result) | |||
| const resultGroups = ['passRecords8', 'passRecords9'] | |||
| for (let groupName of resultGroups) { | |||
| for (let item of result.data[groupName]) { | |||
| @@ -100,7 +100,7 @@ export const usePassRecordsStore = defineStore('pass-records', () => { | |||
| passRecords.value = items.sort((a, b) => a.recognizedTime.localeCompare(b.recognizedTime)).reverse(); | |||
| // console.log(passRecords.value) | |||
| generatePassRecordsGroupList(passRecords.value) | |||
| console.log(groupedPassRecords.value) | |||
| // console.log(groupedPassRecords.value) | |||
| resolve(groupedPassRecords.value) | |||
| } | |||
| }).catch(e => { | |||