agent-mine.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <script setup lang="ts">
  2. import {
  3. getBroker,
  4. getDesignerStatistics,
  5. getFollowStatistics,
  6. getYearTarget,
  7. } from '../../../core/libs/requests'
  8. import { NetImages } from '../../../core/libs/net-images'
  9. import { useUserStore } from '../../../store'
  10. import { storeToRefs } from 'pinia'
  11. import qrCode from '@designer-hub/assets/src/libs/assets/qrCode'
  12. import Card from '@designer-hub/app/src/components/card.vue'
  13. import SectionHeading from '@designer-hub/app/src/components/section-heading.vue'
  14. import { getFollowUpPage } from '@/core/libs/agent-requests'
  15. import { locationIcon } from '@designer-hub/assets/src/svgs'
  16. import { dayjs } from 'wot-design-uni'
  17. import PageHelperEvo from '@/components/page-helper-evo.vue'
  18. import ListHelperEvo from '@/components/list-helper-evo.vue'
  19. const userStore = useUserStore()
  20. const { userInfo } = storeToRefs(userStore)
  21. const { data: agent, run: setAgent } = useRequest(() =>
  22. getBroker({ brokerId: String(userInfo.value.userId) }),
  23. )
  24. const { data: yearTarget, run: setYearTarget } = useRequest(() => getYearTarget())
  25. const { data: designerData, run: setDesignerData } = useRequest(() => getDesignerStatistics())
  26. const { data: followData, run: setFollowData } = useRequest(() => getFollowStatistics())
  27. const designerDataList = computed(() =>
  28. designerData.value
  29. ?.filter((it: any) => it.type !== 2)
  30. .map((it: any, index: number) => ({
  31. title: it.typeName,
  32. value: it.quantity ?? 0,
  33. subTitle: index === 0 ? designerData.value[1].typeName : '占比',
  34. subValue:
  35. index === designerData.value[1].quantity
  36. ? 0
  37. : `${((it.quantity / designerData.value[0].quantity) * 100).toFixed(0)}%`,
  38. })),
  39. )
  40. const bgClass = [
  41. 'bg-gradient-to-r from-[#fef3ee] to-[#f0f4f9]',
  42. 'bg-gradient-to-r from-[#fef8ee] to-[#f0f4f9]',
  43. 'bg-gradient-to-r from-[#eef4fe] to-[#f0f4f9]',
  44. 'bg-gradient-to-r from-[#faf2ff] to-[#f0f4f9]',
  45. ]
  46. const units = [
  47. // { },
  48. // 单位、 换算率
  49. // { unit: '万', rate: 1 },
  50. // { unit: '万', rate: 1 },
  51. // { unit: '次', rate: 1 },
  52. // { unit: '次', rate: 1 },
  53. { unit: '', rate: 1 },
  54. { unit: '', rate: 1 },
  55. { unit: '', rate: 1 },
  56. { unit: '', rate: 1 },
  57. ]
  58. const toSettings = () => {
  59. uni.navigateTo({ url: '/pages/mine/agent/settings/index' })
  60. }
  61. const toInvite = () => {
  62. uni.navigateTo({ url: '/pages/mine/agent/invite/index' })
  63. }
  64. onMounted(async () => {
  65. await setAgent()
  66. await Promise.all([setYearTarget(), setDesignerData(), setFollowData()])
  67. })
  68. </script>
  69. <template>
  70. <div>
  71. <div class="aspect-[0.96/1] absolute left-0 right-0 top--1">
  72. <wd-img
  73. width="100%"
  74. height="100%"
  75. :src="NetImages.AgentMineHeaderBg"
  76. custom-class="vertical-bottom"
  77. ></wd-img>
  78. </div>
  79. <!-- <wd-navbar
  80. fixed
  81. safeAreaInsetTop
  82. custom-class="bg-transparent!"
  83. :bordered="false"
  84. placeholder
  85. v-bind="navBarProps"
  86. ></wd-navbar> -->
  87. <div class="p-4 flex flex-col gap-4 relative">
  88. <div class="flex items-center px-4 mb-4" @click="toSettings">
  89. <wd-img
  90. round
  91. width="56"
  92. height="56"
  93. custom-class="border border-solid border-white"
  94. :src="agent?.headImgUrl"
  95. />
  96. <div class="mx-4 flex-1">
  97. <div class="text-white text-lg font-normal font-['PingFang_SC'] leading-normal">
  98. {{ agent?.brokerName }}
  99. </div>
  100. <div class="text-white text-xs font-normal font-['PingFang_SC'] leading-relaxed">
  101. ID:{{ agent?.inviteCode }}
  102. </div>
  103. </div>
  104. <div class="flex flex-col items-center" @click.stop="toInvite">
  105. <div class="w-[29px] h-[29px] relative">
  106. <wd-img width="28" height="28" :src="qrCode"></wd-img>
  107. </div>
  108. <div class="text-white text-[10px] font-normal font-['PingFang_SC'] leading-relaxed">
  109. 邀请码
  110. </div>
  111. </div>
  112. </div>
  113. <Card>
  114. <SectionHeading title="本年目标" size="base"></SectionHeading>
  115. <div class="flex flex-col gap-2.5 mt-3">
  116. <template v-for="(it, i) in yearTarget" :key="i">
  117. <div class="rounded-lg flex items-center p-4 gap-6" :class="bgClass[i]">
  118. <div>
  119. <div class="w-[45px] h-[45px] rounded-full border-4 border-[#ffe2d0]">
  120. <div style="width: 50px; height: 50px">
  121. <wd-circle
  122. :model-value="
  123. it.thisYearComplete && it.target
  124. ? Number((Number(it.thisYearComplete) / Number(it.target)).toFixed(0)) *
  125. 100
  126. : 0
  127. "
  128. :size="50"
  129. :color="['#FF7742', '#FFAA42', '#4271FF', '#C131FF'][i]"
  130. :clockwise="false"
  131. >
  132. <div class="flex flex-col items-center">
  133. <div
  134. class="w-[29.20px] h-[18.39px] text-black text-sm font-medium font-['D-DIN-PRO']"
  135. >
  136. {{
  137. it.thisYearComplete && it.target
  138. ? (
  139. Number(Number(it.thisYearComplete) / Number(it.target)) * 100
  140. ).toFixed(1)
  141. : 0
  142. }}%
  143. </div>
  144. <div
  145. class="w-[22.71px] h-[10.82px] text-black/60 text-[7px] font-normal font-['PingFang_SC']"
  146. >
  147. 达成率
  148. </div>
  149. </div>
  150. </wd-circle>
  151. </div>
  152. </div>
  153. </div>
  154. <div class="flex-1">
  155. <div class="text-black/60 text-xs font-normal font-['PingFang_SC']">
  156. {{ it.typeName }}
  157. </div>
  158. <div class="flex items-center gap-1">
  159. <div class="text-black/90 text-lg font-medium font-['D-DIN-PRO'] leading-normal">
  160. <!-- 6000 -->
  161. <!-- {{ it.target / 10000 }}-->
  162. {{ it.target / units[i].rate }}
  163. </div>
  164. <div class="text-black text-xs font-normal font-['PingFang_SC']">
  165. {{ units[i].unit }}
  166. </div>
  167. </div>
  168. <div class="flex items-center gap-1">
  169. <div class="text-black/60 text-xs font-normal font-['PingFang_SC']">差值</div>
  170. <div class="text-[#ff2d2d] text-xs font-medium font-['D-DIN-PRO'] leading-normal">
  171. <!-- 3000 -->
  172. {{ (it.target - (it.thisYearComplete ?? 0)) / units[i].rate }}
  173. </div>
  174. <div
  175. class="text-[#ff2d2d] text-[10px] font-medium font-['D-DIN-PRO'] leading-normal"
  176. >
  177. {{ units[i].unit }}
  178. </div>
  179. </div>
  180. </div>
  181. <div class="">
  182. <div class="text-black/60 text-xs font-normal font-['PingFang_SC']">当年完成</div>
  183. <div class="flex items-center gap-1">
  184. <div class="text-black/90 text-lg font-medium font-['D-DIN-PRO'] leading-normal">
  185. <!-- 6000 -->
  186. {{ (it.thisYearComplete ?? 0) / units[i].rate }}
  187. </div>
  188. <div class="text-black text-xs font-normal font-['PingFang_SC']">
  189. {{ units[i].unit }}
  190. </div>
  191. </div>
  192. <div class="flex items-center gap-1">
  193. <div class="text-black/60 text-xs font-normal font-['PingFang_SC']">本月</div>
  194. <div class="text-[#0FC187] text-xs font-medium font-['D-DIN-PRO'] leading-normal">
  195. <!-- 3000 -->
  196. {{ (it.thisMonthComplete ?? 0) / units[i].rate }}
  197. </div>
  198. <div
  199. class="text-[#0FC187] text-[10px] font-medium font-['D-DIN-PRO'] leading-normal"
  200. >
  201. {{ units[i].unit }}
  202. </div>
  203. </div>
  204. </div>
  205. </div>
  206. </template>
  207. </div>
  208. </Card>
  209. <Card>
  210. <SectionHeading title="设计师数据" size="base"></SectionHeading>
  211. <div class="mt-3">
  212. <ListHelperEvo
  213. v-if="designerDataList?.length"
  214. :items="designerDataList"
  215. content-class="grid grid-cols-3 gap-2.5"
  216. >
  217. <template #default="{ item }">
  218. <div class="bg-[#f6f7ff] rounded-lg aspect-[1/1] flex flex-col justify-around p-2.5">
  219. <div class="text-black/60 text-xs font-normal font-['PingFang_SC'] leading-none">
  220. {{ item.title }}
  221. </div>
  222. <div class="text-black/90 text-lg font-bold font-['D-DIN_Exp'] leading-normal">
  223. {{ item.value }}
  224. </div>
  225. <div class="flex items-center gap-1">
  226. <div class="text-black/40 text-xs font-normal font-['PingFang_SC'] leading-none">
  227. {{ item.subTitle }}
  228. </div>
  229. <div class="text-[#ff2d2d] text-xs font-normal font-['D-DIN_Exp'] leading-normal">
  230. {{ item.subValue }}
  231. </div>
  232. </div>
  233. </div>
  234. </template>
  235. </ListHelperEvo>
  236. <!-- <template v-for="(it, i) in designerData" :key="i"></template>-->
  237. </div>
  238. </Card>
  239. <Card>
  240. <SectionHeading title="跟进数据" size="base"></SectionHeading>
  241. <div class="mt-3 grid grid-cols-3 gap-2.5">
  242. <template v-for="(it, i) in followData" :key="i">
  243. <div class="bg-[#f6f7ff] rounded-lg aspect-[1/1] flex flex-col justify-around p-2.5">
  244. <div class="text-black/60 text-xs font-normal font-['PingFang_SC'] leading-none">
  245. {{ it.typeName }}
  246. </div>
  247. <div class="text-black/90 text-lg font-bold font-['D-DIN_Exp'] leading-normal">
  248. {{ it.quantity ?? 0 }}
  249. </div>
  250. <div class="flex items-center gap-1">
  251. <div class="text-black/40 text-xs font-normal font-['PingFang_SC'] leading-none">
  252. 年新增
  253. </div>
  254. <div class="text-[#ff2d2d] text-xs font-normal font-['D-DIN_Exp'] leading-normal">
  255. {{ it.thisYearQuantity ?? 0 }}
  256. </div>
  257. </div>
  258. </div>
  259. </template>
  260. </div>
  261. </Card>
  262. <PageHelperEvo :request="getFollowUpPage" :query="{ brokerId: userInfo.userId }">
  263. <template #default="{ source }">
  264. <div class="flex flex-col gap-4">
  265. <template v-for="(it, index) in source?.list" :key="index">
  266. <div class="bg-white rounded-2xl shadow pl-[15px] py-[15px] flex-col gap-2 flex">
  267. <div class="flex items-center justify-between">
  268. <div
  269. class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-relaxed"
  270. >
  271. {{ dayjs(it.followTime).format('YYYY-MM-DD HH:mm') }}
  272. </div>
  273. <div
  274. class="text-white text-xs font-normal font-['PingFang_SC'] leading-none pa-[8px]"
  275. :class="`${{ 1: 'bg-[#2357E9]', 2: 'bg-[#f8b344]' }[it.followType]}`"
  276. style="border-top-left-radius: 15px; border-bottom-left-radius: 5px"
  277. >
  278. <div class="flex items-center gap-1">
  279. <div class="w-1 h-1 bg-white rounded-full border"></div>
  280. <!-- 线下拜访 -->
  281. {{ it.followTypeName }}
  282. </div>
  283. </div>
  284. </div>
  285. <div
  286. class="text-black/60 text-sm font-normal font-['PingFang_SC'] leading-normal mr-[15px] mt-[29px]"
  287. >
  288. <!-- 和周老师在工作碰了环球项目,选了瓷砖款式,后天客户交定金,订单金额初步为
  289. 304958 -->
  290. {{ it.remark }}
  291. </div>
  292. <div class="mt-[15px] flex gap-2.5">
  293. <template v-for="(src, index) in it?.imgUrl?.split(',')" :key="index">
  294. <wd-img
  295. custom-class="rounded-lg overflow-hidden"
  296. width="70"
  297. height="70"
  298. :src="src"
  299. />
  300. </template>
  301. </div>
  302. <div class="flex items-center justify-between mt-[19px]">
  303. <div
  304. class="h-[25px] px-1.5 bg-[#f4f4f4] rounded-md justify-center items-center gap-1 inline-flex"
  305. >
  306. <wd-img width="15px" height="15px" :src="locationIcon"></wd-img>
  307. <div
  308. class="text-black/40 text-[10px] font-normal font-['PingFang_SC'] leading-[25px]"
  309. >
  310. <!-- 一间空间设计工作室 -->
  311. {{ it?.address.address }}
  312. </div>
  313. </div>
  314. <div
  315. class="text-black/90 text-sm font-normal font-['PingFang_SC'] leading-relaxed mr-[15px]"
  316. >
  317. 渠道:{{ it?.brokerName }}
  318. </div>
  319. </div>
  320. </div>
  321. </template>
  322. </div>
  323. </template>
  324. </PageHelperEvo>
  325. </div>
  326. </div>
  327. </template>