|
|
|
@@ -1,62 +1,102 @@ |
|
|
|
<script setup> |
|
|
|
<script lang="ts" setup> |
|
|
|
import Contact from "../../components/contact" |
|
|
|
import { Router } from 'tarojs-router-next' |
|
|
|
import { ref } from 'vue'; |
|
|
|
import {reactive, ref} from 'vue'; |
|
|
|
import './index.scss' |
|
|
|
import {gql} from "graphql-tag"; |
|
|
|
import {PinyinHelper, GQLRequest} from "../../utils"; |
|
|
|
|
|
|
|
interface ContactData { |
|
|
|
id: number |
|
|
|
name: string |
|
|
|
isVIP: boolean |
|
|
|
flexVisit: boolean |
|
|
|
isBlock: boolean |
|
|
|
nickName: string |
|
|
|
avatar: string |
|
|
|
phone: string |
|
|
|
company: string |
|
|
|
nextVisitDate?: string |
|
|
|
firstCharPinyin: string |
|
|
|
} |
|
|
|
|
|
|
|
const state = reactive<{ |
|
|
|
isContactDataLoading: boolean; |
|
|
|
searchQuery: string; |
|
|
|
contactFullList: ContactData[]; // Using the ContactData interface |
|
|
|
contactList: ContactData[]; // Generic type for now |
|
|
|
contactGroupedList: any[]; // Generic type for now |
|
|
|
}>({ |
|
|
|
isContactDataLoading: true, |
|
|
|
searchQuery: "", |
|
|
|
contactFullList: [], |
|
|
|
contactList: [], |
|
|
|
contactGroupedList: [], |
|
|
|
}) |
|
|
|
|
|
|
|
const val = ref(''); |
|
|
|
|
|
|
|
const data = ref([ |
|
|
|
{ |
|
|
|
title: 'A', |
|
|
|
list: [ |
|
|
|
{ id: 1, name: '', isVIP: true, company: '阿姨公司', avatar: null }, |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: 'B', |
|
|
|
list: [ |
|
|
|
{ id: 2, name: '包子', isVIP: false, company: '公司', avatar: null }, |
|
|
|
{ id: 3, name: '白老师', isVIP: true, company: '', avatar: null }, |
|
|
|
{ id: 4, name: '八哥', isVIP: false, company: '', avatar: null }, |
|
|
|
{ id: 5, name: '保生', isVIP: false, company: '', avatar: null }, |
|
|
|
{ id: 6, name: '巴金', isVIP: false, company: null, avatar: null }, |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: 'G', |
|
|
|
list: [ |
|
|
|
{ id: 7, name: '高工', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 8, name: '国总', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 9, name: '宫崎骏', isVIP: false, company: null, avatar: null }, |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: 'H', |
|
|
|
list: [ |
|
|
|
{ id: 10, name: '何同学', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 11, name: '韩红', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 12, name: '洪秀权', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 13, name: '何同学', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 14, name: '韩红', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 15, name: '洪秀权', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 16, name: '何同学', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 17, name: '韩红', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 18, name: '洪秀权', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 19, name: '韩红', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 20, name: '洪秀权', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 21, name: '韩红', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 22, name: '洪秀权', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 23, name: '何同学', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 24, name: '韩红', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 25, name: '洪秀权', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 26, name: '何同学', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 27, name: '韩红', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 28, name: '洪秀权', isVIP: false, company: null, avatar: null }, |
|
|
|
{ id: 29, name: '韩红', isVIP: false, company: null, avatar: null }, |
|
|
|
] |
|
|
|
const GQL_QUERY_ALL_CONTACT = gql` |
|
|
|
query { |
|
|
|
visitors { |
|
|
|
id |
|
|
|
name |
|
|
|
nickname |
|
|
|
type |
|
|
|
visitorCompany |
|
|
|
avatar |
|
|
|
phone |
|
|
|
} |
|
|
|
} |
|
|
|
` |
|
|
|
|
|
|
|
GQLRequest.query(GQL_QUERY_ALL_CONTACT, {}) |
|
|
|
.then( result => { |
|
|
|
// console.log(result) |
|
|
|
for(let item of result.data.visitors) { |
|
|
|
state.contactFullList.push({ |
|
|
|
id: item.id, |
|
|
|
name: item.name, |
|
|
|
nickName: item.nickname, |
|
|
|
avatar: item.avatar, |
|
|
|
company: item.visitorCompany, |
|
|
|
phone: item.phone, |
|
|
|
flexVisit: "", |
|
|
|
isBlock: "", |
|
|
|
isVIP: "", |
|
|
|
firstCharPinyin: PinyinHelper.getPinyinGroupName(item.name) |
|
|
|
} as ContactData) |
|
|
|
} |
|
|
|
console.log(state.contactFullList) |
|
|
|
state.isContactDataLoading = false |
|
|
|
state.contactList = state.contactFullList |
|
|
|
generateContactGroupList() |
|
|
|
}) |
|
|
|
|
|
|
|
const onSearchValueChange = (value) => { |
|
|
|
state.contactList = [] |
|
|
|
for(const item of state.contactFullList) { |
|
|
|
if (item.name.match(value)) { |
|
|
|
state.contactList.push(item) |
|
|
|
} |
|
|
|
} |
|
|
|
]); |
|
|
|
generateContactGroupList() |
|
|
|
console.log(state.contactList) |
|
|
|
} |
|
|
|
const generateContactGroupList = () => { |
|
|
|
let contactGroupedList = [] |
|
|
|
for (const item of state.contactList) { |
|
|
|
const firstChar = item.firstCharPinyin; |
|
|
|
if (!contactGroupedList[firstChar]) { |
|
|
|
contactGroupedList[firstChar] = { title: firstChar, list: [] }; |
|
|
|
} |
|
|
|
contactGroupedList[firstChar].list.push(item); |
|
|
|
} |
|
|
|
|
|
|
|
state.contactGroupedList = Object.values(contactGroupedList).sort((a, b) => |
|
|
|
a.title.localeCompare(b.title) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
</script> |
|
|
|
|
|
|
|
@@ -70,7 +110,7 @@ const data = ref([ |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<View class="d-flex"> |
|
|
|
<nut-searchbar v-model="val" class="flex-grow-1"> |
|
|
|
<nut-searchbar placeholder="" confirm-type="search" clearable v-model="state.searchQuery" class="flex-grow-1" @change="onSearchValueChange"> |
|
|
|
<template #rightin> |
|
|
|
<Text className="fas fa-search text-black-50"/> |
|
|
|
</template> |
|
|
|
@@ -81,9 +121,14 @@ const data = ref([ |
|
|
|
</View> |
|
|
|
|
|
|
|
|
|
|
|
<view class="scroll"> |
|
|
|
<Contact :items="data"/> |
|
|
|
<view class="scroll 100vh" v-if="!state.isContactDataLoading"> |
|
|
|
<Contact :items="state.contactGroupedList"/> |
|
|
|
</view> |
|
|
|
<View v-else class="d-flex flex-column"> |
|
|
|
<NutSkeleton class="p-3" height="15px" animated avatar avatar-size="45px" row="1"/> |
|
|
|
<NutSkeleton class="p-3" height="15px" animated avatar avatar-size="45px" row="1"/> |
|
|
|
<NutSkeleton class="p-3" height="15px" animated avatar avatar-size="45px" row="1"/> |
|
|
|
</View> |
|
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
|