Prechádzať zdrojové kódy

fix: 头像尺寸按规则调整

王晓东 1 mesiac pred
rodič
commit
50c2292dd9
31 zmenil súbory, kde vykonal 537 pridanie a 272 odobranie
  1. 10 3
      project.private.config.json
  2. 21 0
      src/app.less
  3. 2 36
      src/components/AgentCard/index.module.less
  4. 63 41
      src/components/AgentCard/index.tsx
  5. 14 16
      src/components/AgentPage/components/AgentActionBar/index.tsx
  6. 2 2
      src/components/ChatRecordItem/index.tsx
  7. 3 5
      src/components/DigitalCard/DigitalCardBasic.tsx
  8. 4 4
      src/components/tag-certificated/index.tsx
  9. 0 0
      src/config/default-avatar.ts
  10. BIN
      src/images/avatar-default.png
  11. 5 0
      src/images/svgs/icon-certificate-white.svg
  12. 6 7
      src/pages/agent/index.module.less
  13. 4 3
      src/pages/agent/index.tsx
  14. 2 2
      src/pages/chat-session-messages/components/VisitorSummary/index.tsx
  15. 1 1
      src/pages/chat/components/ChatGreeting/index.module.less
  16. 4 4
      src/pages/chat/components/personal-card/index.tsx
  17. 30 3
      src/pages/chat/index.tsx
  18. 1 0
      src/pages/component-library/index.config.ts
  19. 0 4
      src/pages/component-library/index.module.less
  20. 178 125
      src/pages/component-library/index.tsx
  21. 5 7
      src/pages/contact/components/contact-card/index.module.less
  22. 61 0
      src/pages/dashboard/components/AgentList/components/AgentCard/index.module.less
  23. 75 0
      src/pages/dashboard/components/AgentList/components/AgentCard/index.tsx
  24. 1 1
      src/pages/dashboard/components/AgentList/index.tsx
  25. 2 2
      src/pages/dashboard/components/VisitorCard/index.tsx
  26. 1 3
      src/pages/knowledge/components/PersonalTab/components/ScrollList.tsx
  27. 0 0
      src/pages/visiteor-detail/components/AgentCard/index.module.less
  28. 37 0
      src/pages/visiteor-detail/components/AgentCard/index.tsx
  29. 1 1
      src/pages/visiteor-detail/components/VisitorSummary/index.tsx
  30. 1 2
      src/styles/_vars.less
  31. 3 0
      tailwind.config.js

+ 10 - 3
project.private.config.json

@@ -8,12 +8,19 @@
   "condition": {
     "miniprogram": {
       "list": [
+        {
+          "name": "pages/component-library/index",
+          "pathName": "pages/component-library/index",
+          "query": "",
+          "scene": null,
+          "launchMode": "default"
+        },
         {
           "name": "pages/profile/index",
           "pathName": "pages/profile/index",
           "query": "agentId=p_cb626719d6aYig5s-agent_408",
-          "scene": null,
-          "launchMode": "default"
+          "launchMode": "default",
+          "scene": null
         },
         {
           "name": "pages/knowledge/index",
@@ -46,5 +53,5 @@
       ]
     }
   },
-  "libVersion": "3.8.12"
+  "libVersion": "3.9.0"
 }

+ 21 - 0
src/app.less

@@ -25,6 +25,9 @@
 .pingfang-SC-Medium{
   font-family: PingFangSC-Medium;
 }
+.pingfang-SC-Semibold{
+  font-family: PingFangSC-Semibold;
+}
 .global-color{
   font-weight: 400;
   font-size: 14px;
@@ -125,6 +128,7 @@
   line-height: 20px;
   transition: background-color .2s;
 }
+
 .button-rounded.actived{
   background-color: #000;
   color: #FFF;
@@ -134,11 +138,18 @@
   font-size: 14px;
   background-color: var(--color-primary);
 }
+
 .button-rounded.button-primary-light{
   font-size: 14px;
   color: var(--color-primary);
   background-color: rgba(var(--color-primary-rgb), .1);
 }
+.button-text-medium.button-primary{
+  font-size: 12px;
+}
+.button-text-medium.button-primary-light{
+  font-size: 12px;
+}
 .button-border-primary{
   border: 1px solid #327BF9;
 }
@@ -409,4 +420,14 @@
   background: linear-gradient( rgba(#fff, .45) 1%, rgba(#fff, 0) 100%);
 }
 
+.certification-container{
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(#31BE59, .1);
+  width: 20px;
+  height: 16px;
+  border-radius: 4px;
+}
+
 

+ 2 - 36
src/components/AgentCard/index.module.less

@@ -1,45 +1,11 @@
-.contactCard{
-  display: flex;
-  align-items: center;
-  gap: 12px;
-  align-self: stretch;;
-  font-family: "PingFang SC";
-  display: flex;
-  align-items: flex-start;
-  gap: 8px;
-  color: #262626;
-}
-
-.avatar{
-  display: flex;
-  width: 55px;
-  height: 55px;
-  justify-content: center;
-  align-items: center;
-  border-radius: 55px;
-  overflow: hidden;
-  flex-shrink: 0;
-  border: 1px solid rgba(0, 0, 0, 0.04);
-}
 
-.avatarContainer{
-  position: relative;
-  width: 48px;
-  height: 48px;
-}
-.avatar{
-  position: relative;
-  width: 48px;
-  height: 48px;
-  border-radius: 100%;
-  flex-shrink: 0;
-  overflow: hidden;
-}
 .infoColumn{
   width: 100%;
   display: flex;
   flex-direction: column;
+  justify-content: center;
   gap: 4px;
+  min-height: 40px;
 }
 .nameRow{
   display: flex;

+ 63 - 41
src/components/AgentCard/index.tsx

@@ -1,52 +1,74 @@
-import { View, Image } from '@tarojs/components'
+import { View } from "@tarojs/components";
 import IconCertificateColor from "@/components/icon/icon-certificate-color";
-import style from './index.module.less'
-import { TContactItem } from '@/types/contact'
-import { TAgent } from '@/types/agent'
-import { AvatarMedia } from '../AvatarMedia';
+import style from "./index.module.less";
+import { TContactItem } from "@/types/contact";
+import { TAgent } from "@/types/agent";
+import { AvatarMedia } from "@/components/AvatarMedia";
 interface Props {
-  data: TContactItem|TAgent
-  onClick?: (data: TContactItem|TAgent)=>void
-  renderRight?: ()=> JSX.Element | JSX.Element[]
-  className?: string
-  truncate?: boolean
-  showPositionAndEntNamePlaceholder?: boolean // 是否显示企业名称与职位名称占位
+  data: TContactItem | TAgent;
+  onClick?: (data: TContactItem | TAgent) => void;
+  renderRight?: () => JSX.Element | JSX.Element[];
+  className?: string;
+  truncate?: boolean;
+  showPositionAndEntNamePlaceholder?: boolean; // 是否显示企业名称与职位名称占位
 }
-const Index = ({onClick, data, showPositionAndEntNamePlaceholder = false, truncate=true, className, renderRight}: Props)=> {
-  const hasEntName = !!data.entName?.length
-  const hasPosition = !!!!data.position?.length
-  const truncateClassName = truncate ? 'truncate':''
-  const renderEntNameAndPosition = ()=> {
-    if(showPositionAndEntNamePlaceholder){
-      return <><View className={`max-w-156 ${truncateClassName}`}>{hasEntName ? data.entName : '暂无企业名称'}</View>
-        <View className='px-4'>|</View>
-        <View className={truncateClassName}>{!!data.position?.length ? data.position : '暂无职位名称'}</View>
-        </>
-    }
-    return <>{hasEntName && <View className={`max-w-156 ${truncateClassName}`}>{data.entName}</View>}
-        {(hasPosition && hasEntName) && <View className='px-4'>|</View>}
-        {hasPosition && <View className='truncate'>{data.position}</View>}
-    </>
-  }
-
+const Index = ({
+  onClick,
+  data,
+  className,
+  renderRight,
+}: Props) => {
+  const hasEntName = !!data.entName?.length;
+  const hasPosition = !!!!data.position?.length;
+  const renderEntNameAndPosition = () => {
+    return (
+      <>
+        {hasEntName && (
+          <View className={`max-w-156 truncate`}>
+            {data.entName}
+          </View>
+        )}
+        {hasPosition && hasEntName && <View className="px-4">|</View>}
+        {hasPosition && <View className="truncate">{data.position}</View>}
+      </>
+    );
+  };
   return (
-    <View className={`${style.contactCard} bg-white rounded-12 ${className}`} onClick={()=>{onClick?.(data)}}>
-      <View className={style.avatar}>
-        <AvatarMedia source={data.avatarUrl ?? ''} className='w-[55px] h-[55px]' mode="aspectFill" />
+    <View
+      className={`flex items-start gap-8 bg-white rounded-12 ${className}`}
+      onClick={() => {
+        onClick?.(data);
+      }}
+    >
+      <View className="w-42 h-42 shrink-0 overflow-hidden truncate">
+        <AvatarMedia
+          source={data.avatarUrl ?? ""}
+          className="w-42 h-42"
+          mode="aspectFill"
+        />
       </View>
-      <View className={`${style.infoColumn} ${truncateClassName}`}>
-        <View className={`${style.nameRow} ${truncateClassName}`}>
-          <View className={`${style.nickName} ${truncateClassName}`}>{data.name}</View>
+      <View className={`flex flex-col flex-1 justify-center min-h-42 truncate`}>
+        <View className="text-14 leading-22 font-pingfangSCSemibold font-semibold truncate">
+          {data.name}
         </View>
-        {(hasPosition || hasEntName) && <View className={`flex flex-col w-full gap-8 ${truncateClassName}`}>
-          <View className={`flex items-center flex-1 ${style.subInfo} ${truncateClassName}`}>
-            {renderEntNameAndPosition()}{data.isEnt && <View className={style.certificationContainer}><IconCertificateColor></IconCertificateColor></View>}
+        {(hasPosition || hasEntName) && (
+          <View className={`flex flex-col w-full gap-8 truncate`}>
+            <View
+              className={`flex items-center flex-1 text-12 leading-20 text-gray-45 truncate`}
+            >
+              {renderEntNameAndPosition()}
+              {data.isEnt && (
+                <View className={style.certificationContainer}>
+                  <IconCertificateColor></IconCertificateColor>
+                </View>
+              )}
+            </View>
           </View>
-        </View>}
+        )}
       </View>
       {renderRight && renderRight()}
     </View>
-  )
-}
+  );
+};
 
-export default Index
+export default Index;

+ 14 - 16
src/components/AgentPage/components/AgentActionBar/index.tsx

@@ -1,5 +1,5 @@
 import { useState } from "react";
-import { View } from "@tarojs/components";
+import { View, Text } from "@tarojs/components";
 import style from "./index.module.less";
 import TagCertificated from "@/components/tag-certificated";
 import IconSwapBlack from "@/components/icon/icon-swap-black";
@@ -70,8 +70,8 @@ export default ({agent, isVisitor}: IProps) => {
     }
   }
 
-  const renderValue = (value?: string | null)=> {
-    return value?.length ? value :  '-'
+  const renderValue = (value: string | null | undefined, defaultValue: string)=> {
+    return value?.length ? value :  <Text className="text-12 text-black-50">{defaultValue}</Text>
   }
 
   // 允许更多操作,非企业智能体且非访问者身份
@@ -86,13 +86,13 @@ export default ({agent, isVisitor}: IProps) => {
         <View className={style.topBar}>
           <View className="px-8 mb-16">
             <View className="flex items-start mb-24">
-              <View className="flex flex-col flex-1">
+              <View className="flex flex-col flex-1 gap-8">
                 <View className="flex items-end gap-8">
-                  <View className="text-24 font-medium leading-32 truncate max-w-180">{agent?.name}</View>
-                  <View className="text-12 leading-20">{agent?.position ?? ''}</View>
+                  <View className="text-24 font-medium leading-22 truncate max-w-180">{agent?.name}</View>
+                  <View className="text-12 leading-20 text-black-60">{agent?.position ?? '暂未填职业'}</View>
                 </View>
-                <View className="flex items-center gap-2">
-                  <View className="text-12 leading-20 truncate max-w-[188px]">
+                <View className="flex items-center gap-4">
+                  <View className="text-12 leading-20 text-black-60 truncate max-w-[188px]">
                     {agent?.entName ?? '暂未填写企业'}
                   </View>
                   {agent?.isEnt && <TagCertificated />}
@@ -111,7 +111,7 @@ export default ({agent, isVisitor}: IProps) => {
               {/* 和TA聊聊 */}
               <View className="flex-1">
                 <View
-                  className="button-rounded button-primary"
+                  className="button-rounded button-text-medium button-primary"
                   onClick={handleClick}
                 >
                   <IconChatWhite />
@@ -157,23 +157,21 @@ export default ({agent, isVisitor}: IProps) => {
               </View>}
             </View>
           </View>
-
+          
+          {/* 联系方式 */}
           <View className="rounded-12 bg-white p-20">
-            <View className="text-14 leading-22 font-medium border-b border-b-gray h-34 mb-22">
-              联系方式
-            </View>
             <View className="flex flex-col gap-20 text-12 leading-20">
               <View className="flex items-center gap-12">
                 <ContactIcon type="phone" actived={!!agent?.mobile}/>
-                <View>{renderValue(agent?.mobile)}</View>
+                <View>{renderValue(agent?.mobile, '暂未填写手机号')}</View>
               </View>
               <View className="flex items-center gap-12">
                 <ContactIcon type="mail" actived={!!agent?.email}/>
-                <View>{renderValue(agent?.email)}</View>
+                <View>{renderValue(agent?.email, '暂未填写邮箱')}</View>
               </View>
               <View className="flex items-center gap-12">
                 <ContactIcon type="location" actived={!!agent?.address}/>
-                <View>{renderValue(agent?.address)}</View>
+                <View>{renderValue(agent?.address, '暂未填写地址')}</View>
               </View>
             </View>
           </View>

+ 2 - 2
src/components/ChatRecordItem/index.tsx

@@ -105,12 +105,12 @@ export default ({ visitorId, sessionId, showMoreButton = false }: IProps) => {
     <View className="w-full">
       <View className={` bg-white rounded-12 overflow-hidden`}>
         <View className="p-16 relative">
-          <View className="text-14 text-title font-medium leading-22 mb-8 font-pingfangSCMedium">
+          <View className="text-14 text-dark font-medium leading-22 mb-8 font-pingfangSCMedium">
             {question?.content}
           </View>
           {!!answer?.content?.length && (
             <View
-              className="p-16 text-title rounded-8 relative max-h-[360px] overflow-hidden"
+              className="p-16 text-dark text-12 leading-18 rounded-8 relative max-h-[360px] overflow-hidden"
               style={{ backgroundColor: "#F4F9FF" }}
             >
               {renderAnswerContent(answer)}

+ 3 - 5
src/components/DigitalCard/DigitalCardBasic.tsx

@@ -23,13 +23,11 @@ const DigitalCardBasic = ({
   }
   return (
     <View className="flex items-start">
-      <View className="flex flex-col flex-1 justify-center min-h-40 gap-4">
-        <View className="flex">
-          <View className="text-16 max-w-120 font-medium leading-24 font-pingfangSCMedium">{name}</View>
-        </View>
+      <View className="flex flex-col flex-1 justify-center min-h-40">
+        <View className="text-16 font-medium leading-24 font-pingfangSCMedium">{name}</View>
         {/* inline-flex flex-nowrap break-normal items-center */}
         {(hasPosition || hasEntName) && <View className="text-12 leading-20 text-gray-45 gap-4">
-          {entName || ''}{renderPosition()}{!!certificated && <View className="inline-block transform translate-y-2">&nbsp;<IconCertificateColor /></View>}
+          {entName || ''}{renderPosition()}{!!certificated && <>&nbsp;<View className="certification-container transform translate-y-2"><IconCertificateColor /></View></>}
         </View>}
       </View>
     </View>

+ 4 - 4
src/components/tag-certificated/index.tsx

@@ -1,9 +1,9 @@
-import IconCertificateColor from "@/components/icon/icon-certificate-color";
-import { View } from "@tarojs/components";
+import IconCertificateWhiteSvg from "@/images/svgs/icon-certificate-white.svg";
+import { Image, View } from "@tarojs/components";
 export default () => {
   return (
-    <View className="flex-center text-green bg-green bg-opacity-10 px-4 py-2 gap-2 rounded-4">
-      <IconCertificateColor/>
+    <View className="flex-center text-white bg-green px-4 py-2 gap-2 rounded-4">
+      <Image src={IconCertificateWhiteSvg} className="w-12 h-12"></Image>
       <View className="text-10">已认证</View>
     </View>
   )

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
src/config/default-avatar.ts


BIN
src/images/avatar-default.png


+ 5 - 0
src/images/svgs/icon-certificate-white.svg

@@ -0,0 +1,5 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M10.1996 4.57293L10.5597 4.93293C10.8448 5.21293 10.9999 5.59293 10.9999 5.99293C11.0049 6.39293 10.8498 6.77343 10.5697 7.05793C10.5664 7.0616 10.5631 7.06482 10.5597 7.06805C10.5581 7.06966 10.5564 7.07127 10.5547 7.07293L10.1996 7.42793C10.0595 7.56793 9.97951 7.75793 9.97951 7.95843V8.47293C9.97951 9.30293 9.30427 9.97843 8.47397 9.97843H7.95878C7.75871 9.97843 7.56864 10.0579 7.42859 10.1979L7.06846 10.5579C6.77335 10.8534 6.38821 10.9979 6.00307 10.9979C5.61793 10.9979 5.23279 10.8534 4.93769 10.5634L4.57255 10.1979C4.4325 10.0579 4.24243 9.97843 4.04236 9.97843H3.52717C2.69687 9.97843 2.02163 9.30293 2.02163 8.47293V7.95843C2.02163 7.75793 1.9416 7.56793 1.80155 7.42293L1.44142 7.06793C0.856206 6.48343 0.851204 5.52793 1.43642 4.93843L1.80155 4.57293C1.9416 4.43293 2.02163 4.24293 2.02163 4.03793V3.52793C2.02163 2.69793 2.69687 2.02343 3.52717 2.02343H4.04236C4.24243 2.02343 4.4325 1.94293 4.57255 1.80293L4.93268 1.44293C5.5179 0.853433 6.47324 0.853433 7.06346 1.43843L7.42859 1.80293C7.56864 1.94293 7.75871 2.02343 7.95878 2.02343H8.47397C9.30427 2.02343 9.97951 2.69793 9.97951 3.52793V4.04343C9.97951 4.24293 10.0595 4.43293 10.1996 4.57293ZM5.15275 4.71298C5.15275 4.47298 4.95768 4.27798 4.71759 4.27798C4.47751 4.27798 4.27744 4.47298 4.27744 4.71298C4.27744 4.95848 4.47751 5.15298 4.71759 5.15298C4.95768 5.15298 5.15275 4.95848 5.15275 4.71298Z" fill="white"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.73953 1.80008L5.99976 0.0603027L4.25998 1.80008H1.79977V4.26028L0.0600586 6L1.79977 7.73972V10.2001H4.26014L5.99976 11.9397L7.73937 10.2001H10.1998V7.73968L11.9395 6L10.1998 4.26032V1.80008H7.73953Z" fill="white"/>
+<path d="M3.87873 5.54558L5.57579 7.24264L8.12137 4.69706" stroke="#31BE59" stroke-width="0.84"/>
+</svg>

+ 6 - 7
src/pages/agent/index.module.less

@@ -1,11 +1,10 @@
 .tabContainer{
-  display: flex;
   position: fixed;
-  top: 12px;
+  top: 0;
   left: 0;
-  z-index: 400;
-  padding: 0 16px;
-  width: 100%;
-  box-sizing: border-box;
-  align-items: center;
+  right: 0;
+  z-index: 10;
+  background: var(--color-bg-primary) url(https://cdn.wehome.cn/cmn/png/104/META-H8UKWHWU-8HXWA0PE7HXUV4QMQUBV2-4TSKCVCM-AD.png) no-repeat;
+  background-size: 100%;
+  background-position: top left;
 }

+ 4 - 3
src/pages/agent/index.tsx

@@ -11,6 +11,7 @@ import { useDidShow, useRouter } from "@tarojs/taro";
 import { useComponentStore } from "@/store/componentStore";
 import { useUserStore } from "@/store/userStore";
 import { useAppStore } from "@/store/appStore";
+import style from './index.module.less'
 
 export default function Index() {
   const [tabIndex, setTabIndex] = useState('1');
@@ -53,12 +54,12 @@ export default function Index() {
     <PageCustom>
       <NavBarNormal>创建</NavBarNormal>
       <View className="px-16 w-full flex flex-col gap-20">
-        <View className="fixed top-0 left-0 right-0 z-10" 
+        <View className={style.tabContainer} 
         style={{
-          paddingTop: headerHeight + 12,
+          paddingTop: headerHeight,
         }}
         >
-          <View className="flex flex-center px-16">
+          <View className="flex flex-center px-16 pb-12">
             <TabBarButtons
               current={tabIndex}
               list={tabList}

+ 2 - 2
src/pages/chat-session-messages/components/VisitorSummary/index.tsx

@@ -9,12 +9,12 @@ const VisitorSummary = ({ data }: IndexProps) => {
   return (
     <View className="w-full p-16">
       <View className="flex items-start gap-12">
-        <AvatarMedia source={data.avatarUrl ?? ''} roundedFull className='w-48 h-48 shrink-0' mode="aspectFill" />
+        <AvatarMedia source={data.avatarUrl ?? ''} roundedFull className='w-50 h-50 shrink-0' mode="aspectFill" />
         <View className="flex flex-col gap-8">
           <View className="flex items-start">
             <View className="flex flex-col flex-1">
               <View className="flex items-end gap-8">
-                <View className="text-14 font-semibold leading-20">{data.name}</View>
+                <View className="text-20 font-semibold font-pingfangSCSemibold leading-30">{data.name}</View>
               </View>
               <View className="text-12 leading-20">
                 <Text className="text-gray-45 leading-20">{data.lastChatTime}</Text>

+ 1 - 1
src/pages/chat/components/ChatGreeting/index.module.less

@@ -2,8 +2,8 @@
   position: absolute;
   bottom: 16px;
   left: 16px;
-  right: 16px;
   z-index: 1;
+  width: 280px;
   padding: 12px 16px 16px;
   background: #FFFFFF;
   border-radius: 0 10px 10px 10px;

+ 4 - 4
src/pages/chat/components/personal-card/index.tsx

@@ -14,12 +14,12 @@ export default ({haveBg, agent}:IProps) => {
   const entStyle = haveBg ? 'text-white' : 'text-black-45'
   const renderContent = () => {
     return <>
-        <View className="rounded-full overflow-hidden w-28 h-28">
-          <AvatarMedia source={agent?.avatarLogo || ''} className='w-28 h-28'></AvatarMedia>
+        <View className="rounded-full overflow-hidden w-36 h-36 shrink-0">
+          <AvatarMedia source={agent?.avatarLogo || ''} className='w-36 h-36'></AvatarMedia>
         </View>
-        <View className="flex flex-col flex-1 gap-4">
+        <View className="flex flex-col flex-1 gap-6">
           <View className="flex items-center gap-4">
-            <View className={`text-12 font-medium leading-12 ${nameStyle}`}>{agent?.name}</View>
+            <View className={`text-14 font-medium leading-14 ${nameStyle}`}>{agent?.name}</View>
             {agent?.isEnt && <View className="text-12 leading-12"><IconCertificateColor/></View>}
           </View>
           {agent?.entName && <View className="flex items-center gap-2">

+ 30 - 3
src/pages/chat/index.tsx

@@ -26,6 +26,7 @@ import { getMessageHistories } from "@/service/bot";
 
 import RecommendQuestions from "./components/RecommendQuestions";
 import { useKeyboard } from "./components/keyboard";
+import { useAppStore } from "@/store/appStore";
 
 export default function Index() {
   const router = useRouter();
@@ -36,6 +37,7 @@ export default function Index() {
   }
 
   const { fetchAgent, fetchAgentProfile } = useAgentStore();
+  const bottomSafeHeight = useAppStore( state => state.bottomSafeHeight)
 
   const agent = useAgentStore((state) => {
     if (isVisitor === "true") {
@@ -45,6 +47,7 @@ export default function Index() {
   });
   const scrollViewRef = useRef<any>(null);
   const messageList = useTextChat((state) => state.list);
+  const [inputContainerHeight,setInputContainerHeight]= useState(0)
 
   const { keyboardHeight, marginTopOffset, triggerHeightUpdate } = useKeyboard(
     scrollViewRef,
@@ -52,6 +55,13 @@ export default function Index() {
     "#scrollView"
   );
 
+  // 输入框容器
+  // 针对没有 safeArea?.bottom 的手机,需要额外增加 12 高度
+  let inputContainerBottomOffset = 0
+  if(bottomSafeHeight <= 0){
+    inputContainerBottomOffset = 12
+  }
+
   const { destroy, setScrollTop, genSessionId, setAutoScroll } = useTextChat();
   const scrollTop = useTextChat((state) => state.scrollTop);
   // const autoScroll = useTextChat((state) => state.autoScroll);
@@ -212,6 +222,21 @@ export default function Index() {
     };
   }, [haveBg]);
 
+  useEffect(()=> {
+    const query = Taro.createSelectorQuery();
+    // 输入框高度
+    query
+      .select('#inputContainer')
+      .boundingClientRect((rect: any) => {
+        if (rect) {
+          
+          // console.log('ScrollView height:', rect.height)
+          setInputContainerHeight(rect.height - bottomSafeHeight);
+        }
+      })
+      .exec();
+  }, [agent])
+
   return (
     <PageCustom
       fullPage
@@ -272,13 +297,15 @@ export default function Index() {
             {agent && <RecommendQuestions agent={agent} />}
           </View>
         </ScrollView>
-        <View className="w-full h-54">
-          {/* 输入框高度占位块,todo: 改成动态获取输入框块高度 */}
+        <View className="w-full h-60" style={{
+          height: inputContainerHeight,
+        }}>
         </View>
         <View
           className="bottom-bar px-16 pt-12 z-50"
+          id="inputContainer"
           style={{
-            bottom: `${keyboardHeight}px`,
+            bottom: `${keyboardHeight + inputContainerBottomOffset}px`,
           }}
         >
           <View className="bg-[#F5FAFF]">

+ 1 - 0
src/pages/component-library/index.config.ts

@@ -1,5 +1,6 @@
 export default definePageConfig({
   navigationBarTitleText: '添加自定义组件',
   "usingComponents": {},
+  navigationStyle: 'custom',
   backgroundColor: '#f5f5f2',
 })

+ 0 - 4
src/pages/component-library/index.module.less

@@ -1,7 +1,3 @@
-.container{
-  padding: 16px;
-  min-height: 100vh;
-}
 .compComtainer{
   display: flex;
   flex-direction: column;

+ 178 - 125
src/pages/component-library/index.tsx

@@ -1,171 +1,224 @@
 import { View } from "@tarojs/components";
+import NavBarNormal from "@/components/NavBarNormal/index";
+import PageCustom from "@/components/page-custom/index";
 import style from "./index.module.less";
 import CompItem, { CompType } from "./components/comp-item/compItem";
 import Taro from "@tarojs/taro";
 
 import { useComponentStore } from "@/store/componentStore";
-import { generateRandomId } from '@/utils/index'
+import { generateRandomId } from "@/utils/index";
 
 import CardList from "@/components/list/card-list";
 import CardListItem from "@/components/list/card-list-item";
 import { useState } from "react";
 import { EComponentType } from "@/consts/enum";
 import { TComponentItem } from "@/types/agent";
-import { createComponentData } from './components/createComponentData'
+import { createComponentData } from "./components/createComponentData";
 import { useAgentStore } from "@/store/agentStore";
 
 type TWidget = {
-  type: EComponentType,
-  typeStyle: string,
-  num: number,
-  text: string,
-}
+  type: EComponentType;
+  typeStyle: string;
+  num: number;
+  text: string;
+};
 export default () => {
-  const { loading, insertComponent, setLoading} = useComponentStore()
-  const { agent, editAgentWebsite, fetchAgent } = useAgentStore()
-  
-
+  const { loading, insertComponent, setLoading } = useComponentStore();
+  const { agent, editAgentWebsite, fetchAgent } = useAgentStore();
 
   const [commonWidget, setCommonWidget] = useState<TWidget[]>([
-    {type: EComponentType.title , typeStyle: CompType.title, num: 0, text: '章节标题'},
-    {type: EComponentType.text , typeStyle: CompType.text, num: 0, text: '文本内容'},
-    {type: EComponentType.link , typeStyle: CompType.link, num: 0, text: '链接'},
-    {type: EComponentType.media , typeStyle: CompType.image, num: 0, text: '图片/视频'},
-    {type: EComponentType.tel , typeStyle: CompType.tel, num: 0, text: '电话'},
-    {type: EComponentType.address , typeStyle: CompType.local, num: 0, text: '地图'},
-    {type: EComponentType.bluebook , typeStyle: CompType.bluebook, num: 0, text: '小蓝本'},
-  ])
-  
+    {
+      type: EComponentType.title,
+      typeStyle: CompType.title,
+      num: 0,
+      text: "章节标题",
+    },
+    {
+      type: EComponentType.text,
+      typeStyle: CompType.text,
+      num: 0,
+      text: "文本内容",
+    },
+    {
+      type: EComponentType.link,
+      typeStyle: CompType.link,
+      num: 0,
+      text: "链接",
+    },
+    {
+      type: EComponentType.media,
+      typeStyle: CompType.image,
+      num: 0,
+      text: "图片/视频",
+    },
+    { type: EComponentType.tel, typeStyle: CompType.tel, num: 0, text: "电话" },
+    {
+      type: EComponentType.address,
+      typeStyle: CompType.local,
+      num: 0,
+      text: "地图",
+    },
+    {
+      type: EComponentType.bluebook,
+      typeStyle: CompType.bluebook,
+      num: 0,
+      text: "小蓝本",
+    },
+  ]);
+
   const [wechatWidget, setWechatWidget] = useState<TWidget[]>([
-    {type: EComponentType.wechatArticle , typeStyle: CompType.wechat, num: 0, text: '微信公众号文章'},
-    {type: EComponentType.shiping , typeStyle: CompType.shiping, num: 0, text: '视频号'},
-    {type: EComponentType.miniProgram , typeStyle: CompType.miniProgram, num: 0, text: '小程序'},
-    {type: EComponentType.shipingVideo , typeStyle: CompType.shipingVideo, num: 0, text: '视频号视频'},
-  ])
+    {
+      type: EComponentType.wechatArticle,
+      typeStyle: CompType.wechat,
+      num: 0,
+      text: "微信公众号文章",
+    },
+    {
+      type: EComponentType.shiping,
+      typeStyle: CompType.shiping,
+      num: 0,
+      text: "视频号",
+    },
+    {
+      type: EComponentType.miniProgram,
+      typeStyle: CompType.miniProgram,
+      num: 0,
+      text: "小程序",
+    },
+    {
+      type: EComponentType.shipingVideo,
+      typeStyle: CompType.shipingVideo,
+      num: 0,
+      text: "视频号视频",
+    },
+  ]);
 
   const handleChange = (num: number, type: string) => {
-    console.log(num, type)
-    setCommonWidget(prevArr => 
-      prevArr.map(item => 
-        item.type === type ? { ...item, num } : item
-      )
+    console.log(num, type);
+    setCommonWidget((prevArr) =>
+      prevArr.map((item) => (item.type === type ? { ...item, num } : item))
     );
   };
   const handleWechatWidgeChange = (num: number, type: string) => {
-    console.log(num, type)
-    setWechatWidget(prevArr => 
-      prevArr.map(item => 
-        item.type === type ? { ...item, num } : item
-      )
+    console.log(num, type);
+    setWechatWidget((prevArr) =>
+      prevArr.map((item) => (item.type === type ? { ...item, num } : item))
     );
   };
 
-  const getComponents = (widgets: TWidget[])=> {
-    let list = widgets.filter( w => w.num > 0)
-    .reduce((prev:EComponentType[], current)=> {
-        let arr:EComponentType[] = []
-        for(let i=0; i<current.num; i++){
-          arr.push(current.type)
+  const getComponents = (widgets: TWidget[]) => {
+    let list = widgets
+      .filter((w) => w.num > 0)
+      .reduce((prev: EComponentType[], current) => {
+        let arr: EComponentType[] = [];
+        for (let i = 0; i < current.num; i++) {
+          arr.push(current.type);
         }
-        prev.push(...arr)
-      return prev
-    }, [])
+        prev.push(...arr);
+        return prev;
+      }, []);
 
-    const results = list.map(item => {
-      
-      let data  = createComponentData(item)
-      if(data === null){
-        console.warn('没有对应的组件')
-        return null
+    const results = list.map((item) => {
+      let data = createComponentData(item);
+      if (data === null) {
+        console.warn("没有对应的组件");
+        return null;
       }
-      data.id = generateRandomId()
+      data.id = generateRandomId();
 
       return {
-          type: item,
-          data,
-          enabled: true
-      }
-    })
-    return results.filter(item => !!item)
-  }
+        type: item,
+        data,
+        enabled: true,
+      };
+    });
+    return results.filter((item) => !!item);
+  };
 
   const handleSubmit = async () => {
-    if(loading){
-      return
+    if (loading) {
+      return;
     }
-    const a = getComponents(commonWidget) as TComponentItem[]
-    const b = getComponents(wechatWidget) as TComponentItem[]
-    
+    const a = getComponents(commonWidget) as TComponentItem[];
+    const b = getComponents(wechatWidget) as TComponentItem[];
+
     // 统一增加 index 值
-    const results =  [...a, ...b].map( (item, index) => {
-      item.data.index = index
-      return item
-    })
-    console.log(results)
-    if(!agent?.agentId){
-      return 
+    const results = [...a, ...b].map((item, index) => {
+      item.data.index = index;
+      return item;
+    });
+    console.log(results);
+    if (!agent?.agentId) {
+      return;
     }
-    setLoading(true)
-    const inserted  = await insertComponent(results)
-    setLoading(false)
-    if(!inserted){
-      return 
+    setLoading(true);
+    const inserted = await insertComponent(results);
+    setLoading(false);
+    if (!inserted) {
+      return;
     }
-    console.log(inserted)
-    const result = await editAgentWebsite(agent.agentId, inserted)
-    if(result){
-      await fetchAgent(agent.agentId)
-      Taro.navigateBack()
+    console.log(inserted);
+    const result = await editAgentWebsite(agent.agentId, inserted);
+    if (result) {
+      await fetchAgent(agent.agentId);
+      Taro.navigateBack();
     }
-  }
-  
+  };
+
   return (
-    <View className={`global-gray-bg ${style.container}`}>
-      <View className={style.compComtainer}>
-        <View className={style.title}>通用组件</View>
-        <CardList>
-          {commonWidget.map((item)=> {
-            return <CardListItem>
-            <View className="px-16 py-16">
-              <CompItem
-                num={item.num}
-                onChange={handleChange}
-                typeStyle={item.typeStyle}
-                type={item.type}
-              >
-                {item.text}
-              </CompItem>
-            </View>
-          </CardListItem>
-          })}
-        </CardList>
-      </View>
+    <PageCustom>
+      <NavBarNormal>添加组件</NavBarNormal>
+      <View className='p-16 w-full'>
+        <View className={style.compComtainer}>
+          <View className={style.title}>通用组件</View>
+          <CardList>
+            {commonWidget.map((item) => {
+              return (
+                <CardListItem>
+                  <View className="px-16 py-16">
+                    <CompItem
+                      num={item.num}
+                      onChange={handleChange}
+                      typeStyle={item.typeStyle}
+                      type={item.type}
+                    >
+                      {item.text}
+                    </CompItem>
+                  </View>
+                </CardListItem>
+              );
+            })}
+          </CardList>
+        </View>
 
-      <View className={`${style.compComtainer} mb-130`}>
-        <View className={style.title}>微信组件</View>
-        <CardList>
-          {wechatWidget.map((item)=> {
-            return <CardListItem>
-            <View className="px-16 py-16">
-              <CompItem
-                num={item.num}
-                onChange={handleWechatWidgeChange}
-                typeStyle={item.typeStyle}
-                type={item.type}
-              >
-                {item.text}
-              </CompItem>
-            </View>
-          </CardListItem>
-          })}
-        </CardList>
-      </View>
+        <View className={`${style.compComtainer} mb-130`}>
+          <View className={style.title}>微信组件</View>
+          <CardList>
+            {wechatWidget.map((item) => {
+              return (
+                <CardListItem>
+                  <View className="px-16 py-16">
+                    <CompItem
+                      num={item.num}
+                      onChange={handleWechatWidgeChange}
+                      typeStyle={item.typeStyle}
+                      type={item.type}
+                    >
+                      {item.text}
+                    </CompItem>
+                  </View>
+                </CardListItem>
+              );
+            })}
+          </CardList>
+        </View>
 
-      <View className="bottom-bar">
-        <View className="px-20 pt-12" onClick={handleSubmit}>
-          <View className="button-rounded-big">添加组件</View>
+        <View className="bottom-bar">
+          <View className="px-20 pt-12" onClick={handleSubmit}>
+            <View className="button-rounded-big">添加组件</View>
+          </View>
         </View>
       </View>
-    </View>
+    </PageCustom>
   );
 };

+ 5 - 7
src/pages/contact/components/contact-card/index.module.less

@@ -9,13 +9,13 @@
 }
 .avatarContainer{
   position: relative;
-  width: 48px;
-  height: 48px;
+  width: 44px;
+  height: 44px;
 }
 .avatar{
   position: relative;
-  width: 48px;
-  height: 48px;
+  width: 44px;
+  height: 44px;
   border-radius: 100%;
   flex-shrink: 0;
   overflow: hidden;
@@ -24,12 +24,10 @@
   width: 100%;
   display: flex;
   flex-direction: column;
-  gap: 4px;
 }
 .nameRow{
   display: flex;
   align-items: center;
-  gap: 4px;
   font-style: normal;
 }
 .nickName{
@@ -67,7 +65,7 @@
   font-family: PingFangSC-Regular;
   font-style: normal;
   font-weight: 400;
-  line-height: 16px;
+  line-height: 20px;
 }
 .lastMsg {
   .subInfo();

+ 61 - 0
src/pages/dashboard/components/AgentList/components/AgentCard/index.module.less

@@ -0,0 +1,61 @@
+.contactCard{
+  display: flex;
+  align-items: center;
+  align-items: flex-start;
+  gap: 8px;
+}
+
+.infoColumn{
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  gap: 4px;
+  min-height: 40px;
+}
+.nameRow{
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  font-style: normal;
+}
+.nickName{
+  font-size: 14px;
+  font-style: normal;
+  font-weight: 500;
+  line-height: 20px;
+}
+.tipCnt{
+  position: absolute;
+  z-index: 1;
+  top: 6px;
+  right: 0px;
+  font-size: 0px;
+  height: 8px;
+  width: 8px;
+  border-radius: 8px;
+  background: #FF4747;
+  border: 1px solid white;
+}
+.certificationContainer{
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(#31BE59, .1);
+  width: 20px;
+  height: 16px;
+  border-radius: 4px;
+  // align-self: flex-start;
+}
+
+.subInfo{
+  color: #414A64;
+  font-size: 12px;
+  font-style: normal;
+  font-weight: 400;
+  line-height: 16px;
+}
+.lastMsg {
+  .subInfo();
+  color: #A1A7BA;
+}

+ 75 - 0
src/pages/dashboard/components/AgentList/components/AgentCard/index.tsx

@@ -0,0 +1,75 @@
+import { View, Image } from "@tarojs/components";
+import IconCertificateColor from "@/components/icon/icon-certificate-color";
+import style from "./index.module.less";
+import { TContactItem } from "@/types/contact";
+import { TAgent } from "@/types/agent";
+import { AvatarMedia } from "@/components/AvatarMedia";
+interface Props {
+  data: TContactItem | TAgent;
+  onClick?: (data: TContactItem | TAgent) => void;
+  renderRight?: () => JSX.Element | JSX.Element[];
+  className?: string;
+  truncate?: boolean;
+  showPositionAndEntNamePlaceholder?: boolean; // 是否显示企业名称与职位名称占位
+}
+const Index = ({
+  onClick,
+  data,
+  className,
+  renderRight,
+}: Props) => {
+  const hasEntName = !!data.entName?.length;
+  const hasPosition = !!!!data.position?.length;
+  const renderEntNameAndPosition = () => {
+    return (
+      <>
+        {hasEntName && (
+          <View className={`max-w-156 truncate`}>
+            {data.entName}
+          </View>
+        )}
+        {hasPosition && hasEntName && <View className="px-4">|</View>}
+        {hasPosition && <View className="truncate">{data.position}</View>}
+      </>
+    );
+  };
+
+  return (
+    <View
+      className={`flex items-start gap-8 bg-white rounded-12 ${className}`}
+      onClick={() => {
+        onClick?.(data);
+      }}
+    >
+      <View className="w-42 h-42 shrink-0 overflow-hidden truncate">
+        <AvatarMedia
+          source={data.avatarUrl ?? ""}
+          className="w-42 h-42"
+          mode="aspectFill"
+        />
+      </View>
+      <View className={`flex flex-col flex-1 justify-center min-h-42 truncate`}>
+        <View className="text-14 leading-22 font-pingfangSCSemibold font-semibold truncate">
+          {data.name}
+        </View>
+        {(hasPosition || hasEntName) && (
+          <View className={`flex flex-col w-full gap-8 truncate`}>
+            <View
+              className={`flex items-center flex-1 text-12 leading-20 text-gray-45 truncate`}
+            >
+              {renderEntNameAndPosition()}
+              {data.isEnt && (
+                <View className={style.certificationContainer}>
+                  <IconCertificateColor></IconCertificateColor>
+                </View>
+              )}
+            </View>
+          </View>
+        )}
+      </View>
+      {renderRight && renderRight()}
+    </View>
+  );
+};
+
+export default Index;

+ 1 - 1
src/pages/dashboard/components/AgentList/index.tsx

@@ -6,7 +6,7 @@ import { useEffect, useState } from "react";
 import { useAgentStore } from "@/store/agentStore";
 import WemetaRadio from "@/components/WemetaRadio/index";
 import { TAgent } from "@/types/agent";
-import AgentCard from "@/components/AgentCard/index";
+import AgentCard from "./components/AgentCard";
 
 interface IProps {
   currentAgent: TAgent|null

+ 2 - 2
src/pages/dashboard/components/VisitorCard/index.tsx

@@ -20,8 +20,8 @@ const Index = ({ data }: IndexProps) => {
     <View className="bg-white rounded-12 p-12" onClick={handleClick}>
       <View className="flex items-start gap-12">
         <View className="flex items-star rounded-full overflow-hidden">
-          <View className="w-40 h-40 bg-gray-3 rounded-full shrink-0">
-            <AvatarMedia source={data.avatarUrl || ''} mode="aspectFill" className="w-40 h-40 bg-gray-3 rounded-full"></AvatarMedia>
+          <View className="w-44 h-44 bg-gray-3 rounded-full shrink-0">
+            <AvatarMedia source={data.avatarUrl || ''} mode="aspectFill" className="w-44 h-44 bg-gray-3 rounded-full"></AvatarMedia>
           </View>
         </View>
         <View className="flex flex-col flex-1 gap-4">

+ 1 - 3
src/pages/knowledge/components/PersonalTab/components/ScrollList.tsx

@@ -139,9 +139,7 @@ const Index = ({ types, setTotalCount }: IProps) => {
       }}
     >
       {list.length <= 0 ? (
-        <View className="pt-46">
-          <EmptyData type={"plane"} />
-        </View>
+        <EmptyData type={'search'} />
       ) : (
         <></>
       )}

+ 0 - 0
src/pages/visiteor-detail/components/AgentCard/index.module.less


+ 37 - 0
src/pages/visiteor-detail/components/AgentCard/index.tsx

@@ -0,0 +1,37 @@
+import { View } from '@tarojs/components'
+import IconCertificateColor from "@/components/icon/icon-certificate-color";
+import { TAgent } from '@/types/agent'
+import { AvatarMedia } from '@/components/AvatarMedia';
+interface Props {
+  data: TAgent
+  onClick?: (data: TAgent)=>void
+  renderRight?: ()=> JSX.Element | JSX.Element[]
+  className?: string
+}
+const Index = ({onClick, data, className, renderRight}: Props)=> {
+  const hasEntName = !!data.entName?.length
+  const hasPosition = !!data.position?.length
+  const renderPosition = ()=> {
+    return <>
+        {(hasPosition && hasEntName) && <>&nbsp;|&nbsp;</>}
+        {hasPosition && <>{data.position}</>}
+    </>
+  }
+
+  return (
+    <View className={`flex items-center gap-8 ${className}`} onClick={()=>{onClick?.(data)}}>
+      <View className='shrink-0 self-start w-50 h-50'>
+        <AvatarMedia source={data.avatarUrl ?? ''} className='w-50 h-50' mode="aspectFill" />
+      </View>
+      <View className={`flex flex-col m-h-50`}>
+        <View className="text-20 font-semibold font-pingfangSCSemibold leading-30">{data.name}</View>
+        {(hasPosition || hasEntName) && <View className="text-12 leading-20 text-gray-45 gap-4">
+          {data.entName || ''}{renderPosition()}{!!data.isEnt && <View className="certification-container  transform translate-y-2"><IconCertificateColor /></View>}
+        </View>}
+      </View>
+      {renderRight && renderRight()}
+    </View>
+  )
+}
+
+export default Index

+ 1 - 1
src/pages/visiteor-detail/components/VisitorSummary/index.tsx

@@ -5,7 +5,7 @@ import IconPhone from '@/images/svgs/dashboard/IconPhone.svg'
 import IconCopy from '@/images/svgs/dashboard/IconCopy.svg'
 import IconTime from '@/images/svgs/dashboard/IconTime.svg'
 import IconMark from '@/images/svgs/dashboard/IconMark.svg'
-import AgentCard from "@/components/AgentCard/index";
+import AgentCard from "../AgentCard";
 export interface IndexProps {
   data: TVisitorAgent;
 }

+ 1 - 2
src/styles/_vars.less

@@ -12,5 +12,4 @@
 @kwaiUrl: 'https://cdn.wehome.cn/cmn/png/111/META-H8UK0IWU-LIGPDI0B88LDCAMAO6LN3-YN8VVI2M-U61.png';
 @bilibiliUrl: 'https://cdn.wehome.cn/cmn/png/29/META-H8UKVHWU-KIGP3BIL7M5AYC6XHNUA2-ZQYTVI2M-491.png';
 @qqUrl: 'https://cdn.wehome.cn/cmn/png/64/META-H8UKWHWU-6NNPBTA0CSOODDVD47MV3-C5XKEO2M-8I.png';
-@sinaUrl: 'https://cdn.wehome.cn/cmn/png/80/META-H8UKWHWU-6NNPBTA0CSOODDVD47MV3-YS739U2M-UY.png';
-
+@sinaUrl: 'https://cdn.wehome.cn/cmn/png/80/META-H8UKWHWU-6NNPBTA0CSOODDVD47MV3-YS739U2M-UY.png';

+ 3 - 0
tailwind.config.js

@@ -38,6 +38,8 @@ module.exports = {
       'black-9': '#999999',
       'black-25': 'rgba(0, 0, 0, 0.25)',
       'black-45': 'rgba(0, 0, 0, 0.45)',
+      'black-50': 'rgba(0, 0, 0, 0.5)',
+      'black-60': 'rgba(0, 0, 0, 0.6)',
       'black-65': 'rgba(0, 0, 0, 0.65)',
       'title': '#111A34',
       'harsh': '#F94F17',
@@ -69,6 +71,7 @@ module.exports = {
     extend: {
       fontFamily: {
         pingfangSCMedium: ['PingFangSC-Medium'],
+        pingfangSCSemibold: ['PingFangSC-Semibold'],
       },
       lineHeight: {
         '0': '0px',

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov