微信小程序,访客邀约
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

213 lines
7.3 KiB

  1. <script lang="ts" setup>
  2. import Contact from "../../components/contact"
  3. import { Router } from 'tarojs-router-next'
  4. import {reactive, ref} from 'vue';
  5. import './index.scss'
  6. import { useContactsStore, ContactData } from '../../stores/contacts'
  7. import { registerRouterBackListener } from 'tarojs-router-next'
  8. import {BjxHelper} from "../../utils";
  9. import {gql} from "graphql-tag";
  10. import {PinyinHelper, GQLRequest, weappAuth} from "../../utils";
  11. import {useAuthStore} from "../../stores/auth";
  12. // defineExpose({
  13. // loadContactsFromServer,
  14. // });
  15. const state = reactive<{
  16. isAuthError: boolean,
  17. isContactDataLoadError: boolean,
  18. isContactDataLoading: boolean,
  19. searchQuery: string,
  20. normalContacts: ContactData[],
  21. flexContacts: ContactData[], // Generic type for now
  22. }>({
  23. isAuthError: false,
  24. isContactDataLoadError: false,
  25. isContactDataLoading: true,
  26. searchQuery: "",
  27. normalContacts: [],
  28. flexContacts: []
  29. })
  30. const contacts = useContactsStore()
  31. init()
  32. function init() {
  33. state.isAuthError = false
  34. state.isContactDataLoadError = false
  35. state.isContactDataLoading = true
  36. weappAuth()
  37. .then(r => {
  38. contacts.loadContactsFromServer().then(
  39. contactList => {
  40. console.log("contactList", contactList)
  41. generateContactGroupList(contactList)
  42. state.isContactDataLoading = false
  43. })
  44. .catch(e => {
  45. state.isAuthError = false
  46. state.isContactDataLoadError = true
  47. state.isContactDataLoading = false
  48. })
  49. })
  50. .catch(e=> {
  51. console.log("error", e)
  52. state.isAuthError = true
  53. state.isContactDataLoadError = false
  54. state.isContactDataLoading = false
  55. })
  56. registerRouterBackListener((to, from) => {
  57. if ((from.url === "/pages/contact-new/index" && to.url === "/pages/index/index")
  58. || (from.url === "/pages/contact-edit/index" && to.url === "/pages/index/index")
  59. ) {
  60. generateContactGroupList(contacts.allContacts)
  61. }
  62. })
  63. }
  64. const onAuthErrorRefresh = () => {
  65. init()
  66. }
  67. const onContactDataLoadErrorRefresh = () => {
  68. state.isContactDataLoadError = false
  69. state.isContactDataLoading = true
  70. contacts.loadContactsFromServer().then(
  71. contactList => {
  72. console.log("contactList", contactList)
  73. generateContactGroupList(contactList)
  74. state.isContactDataLoading = false
  75. })
  76. .catch(e => {
  77. state.isContactDataLoadError = true
  78. state.isContactDataLoading = false
  79. })
  80. }
  81. const generateContactGroupList = (contactList: ContactData[]) => {
  82. state.normalContacts = []
  83. state.flexContacts = []
  84. for (const item of contactList) {
  85. if (item.flexVisit === true) state.flexContacts.push(item)
  86. else state.normalContacts.push(item)
  87. }
  88. }
  89. const goToContactNewPage = () => {
  90. Router.toContactNew()
  91. }
  92. const goToContactEditPage = (item) => {
  93. Router.toContactEdit({ data: item })
  94. }
  95. </script>
  96. <template>
  97. <view class="h-100 d-flex flex-column">
  98. <BackgroundBasic/>
  99. <NutNavbar title=""></NutNavbar>
  100. <view class="pl-3 pt-3 pr-3 h3 d-flex">
  101. <view class="flex-grow-1">
  102. 我的邀约
  103. </view>
  104. </view>
  105. <View class="scroll 100vh w-100">
  106. <View class="mt-3 p-3">
  107. <View class="border bg-white p-3 d-flex flex-column" hover-class="card-hover-gray" @tap="goToContactNewPage()" >
  108. <View class="d-flex justify-content-center">
  109. <Image :src="require('./invite.jpeg')" class="p-3" mode='heightFix' style="height: 15vh"/>
  110. </View>
  111. <View class="d-flex justify-content-center">
  112. <View class="fas fa-plus-circle text-black-50" style="font-size: 120%"> 新邀约</View>
  113. </View>
  114. </View>
  115. </View>
  116. <View v-if="!state.isContactDataLoading">
  117. <View v-if="state.isAuthError">
  118. <nut-empty description="连接出现问题,请稍后重试">
  119. <div style="margin-top: 10px">
  120. <nut-button type="default" @tap="onAuthErrorRefresh">刷新</nut-button>
  121. </div>
  122. </nut-empty>
  123. </View>
  124. <View v-else-if="state.isContactDataLoadError">
  125. <nut-empty description="连接出现问题,请稍后重试">
  126. <div style="margin-top: 10px">
  127. <nut-button type="default" @tap="onContactDataLoadErrorRefresh">刷新</nut-button>
  128. </div>
  129. </nut-empty>
  130. </View>
  131. <View v-else>
  132. <View class="h4 p-3">来访联系人</View>
  133. <View class="w-100 d-flex flex-wrap">
  134. <View style="width: 25vw" v-for="item in state.normalContacts">
  135. <View class="m-2 p-3 border" hover-class="card-hover-gray" @tap="goToContactEditPage(item)">
  136. <View class="d-flex justify-content-center">
  137. <NutBadge :value="item.isBlock?'阻止':''">
  138. <NutBadge :value="item.isVIP?'VIP':''">
  139. <NutAvatar size="normal" color="white" :bg-color="BjxHelper.mbString2RgbHex(item.name)" class="overflow-hidden">
  140. <img v-if="item.avatar" :src="item.avatar" />
  141. <view v-else-if="BjxHelper.getBJXFirstChar(item.name)">{{BjxHelper.getBJXFirstChar(item.name)}}</view>
  142. <view v-else>
  143. <Text className='fas fa-user fa-lg'/>
  144. </view>
  145. </NutAvatar>
  146. </NutBadge>
  147. </NutBadge>
  148. </View>
  149. <View class="d-flex justify-content-center small b pt-2 text-nowrap overflow-hidden">
  150. {{item.name}}
  151. </View>
  152. </View>
  153. </View>
  154. </View>
  155. <View class="h4 p-3">可随时来访联系人</View>
  156. <View class="w-100 d-flex flex-wrap">
  157. <View style="width: 25vw" v-for="item in state.flexContacts">
  158. <View class="m-2 p-3 border" hover-class="card-hover-gray" @tap="goToContactEditPage(item)">
  159. <View class="d-flex justify-content-center">
  160. <NutBadge :value="item.isBlock?'阻止':''">
  161. <NutBadge :value="item.isVIP?'VIP':''">
  162. <NutAvatar size="normal" color="white" :bg-color="BjxHelper.mbString2RgbHex(item.name)" class="overflow-hidden">
  163. <img v-if="item.avatar" :src="item.avatar" />
  164. <view v-else-if="BjxHelper.getBJXFirstChar(item.name)">{{BjxHelper.getBJXFirstChar(item.name)}}</view>
  165. <view v-else>
  166. <Text className='fas fa-user fa-lg'/>
  167. </view>
  168. </NutAvatar>
  169. </NutBadge>
  170. </NutBadge>
  171. </View>
  172. <View class="d-flex justify-content-center small b pt-2 text-nowrap overflow-hidden">
  173. {{item.name}}
  174. </View>
  175. </View>
  176. </View>
  177. </View>
  178. </View>
  179. </View>
  180. <View v-else class="d-flex flex-column pt-5">
  181. <View class="row w-100 pt-4">
  182. <View style="width: 25vw" v-for="_ in 20" class="pb-5 skeleton-avatar d-flex justify-content-center">
  183. <NutSkeleton class="p-3" height="15px" animated avatar avatar-size="50px" row="0"/>
  184. </View>
  185. </View>
  186. </View>
  187. </View>
  188. </view>
  189. </template>