Browse Source

feat: contact,contact-us ui

王晓东 1 week ago
parent
commit
f32de02253

+ 1 - 0
src/app.config.ts

@@ -17,6 +17,7 @@ export default defineAppConfig({
     'pages/chat/index',
     'pages/chat/index',
     'pages/agent-gen/index',
     'pages/agent-gen/index',
     'pages/editor-contact/index',
     'pages/editor-contact/index',
+    'pages/contact-us/index',
     
     
     'pages/test/index',
     'pages/test/index',
     'pages/component-library/index',
     'pages/component-library/index',

+ 73 - 0
src/components/Picker/PickerSingleColumn.tsx

@@ -0,0 +1,73 @@
+import { View, PickerView, PickerViewColumn  } from "@tarojs/components"
+import Taro from "@tarojs/taro"
+
+export interface IndexProps {
+  options: string[]
+  headerTitle?: string
+  selected: string
+  showPicker: boolean
+  setShowPicker: (show:boolean) => void
+  onChange: (value: string) => void
+  children: JSX.Element|JSX.Element[]
+}
+
+const Index = ({selected, showPicker, setShowPicker,onChange, options, headerTitle = '请选择', children }: IndexProps) => {
+  
+  
+  
+  
+
+  // 处理选择变化
+  const handleChange = (e:any) => {
+    const { value } = e.detail
+    onChange(options[value[0]])
+  }
+
+  // 确认选择
+  const handleConfirm = () => {
+    setShowPicker(false)
+    Taro.showToast({
+      title: `已选择: ${selected}`,
+      icon: 'none'
+    })
+  }
+  return <View>
+    {children}
+    {showPicker && (
+            <View className='picker-modal'>
+              <View className='picker-header'>
+                <View className='picker-cancel' onClick={() => setShowPicker(false)}>
+                  取消
+                </View>
+                <View className='picker-title'>{headerTitle}</View>
+                <View 
+                  className='picker-confirm' 
+                  onClick={handleConfirm}
+                  style={{ color: '#317CFA' }} // 直接修改确认按钮颜色
+                >
+                  确定
+                </View>
+              </View>
+
+              {/* 单列 PickerView */}
+              <PickerView
+                className='picker-view'
+                indicatorStyle='height: 50px;' // 选中项高亮样式
+                style='width: 100%; height: 300px;'
+                onChange={handleChange}
+                value={[options.indexOf(selected)]} // 初始选中项索引
+              >
+                <PickerViewColumn>
+                  {options.map((item) => (
+                    <View key={item} className='picker-item'>
+                      {item}
+                    </View>
+                  ))}
+                </PickerViewColumn>
+              </PickerView>
+            </View>
+          )}
+  </View>
+}
+
+export default Index;

+ 24 - 0
src/components/form/FormItem.tsx

@@ -0,0 +1,24 @@
+import { Text, View } from "@tarojs/components";
+interface Iprops {
+  labelText?: string,
+  required?: boolean
+  labelRenderer?: JSX.Element
+  children: JSX.Element
+}
+
+export default function Index({labelText, required, labelRenderer, children}:Iprops) {
+  const renderLabel = ()=> {
+    if(labelRenderer){
+      return labelRenderer
+    }
+    return <View className="text-14 font-medium text-black leading-28">
+        {labelText} {required && <Text className="text-red">*</Text>}
+      </View>
+  }
+  return (
+    <View className="flex flex-col gap-6  w-full">
+      {renderLabel()}
+      {children}
+    </View>
+  );
+}

+ 2 - 2
src/components/search-bar/index.module.less

@@ -1,5 +1,5 @@
 .searchBarContainer{
 .searchBarContainer{
-  padding: 13px 16px;
+  padding: 10px 16px;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 8px;
   gap: 8px;
@@ -18,7 +18,7 @@
   font-family: PingFang SC;
   font-family: PingFang SC;
   font-size: 14px;
   font-size: 14px;
   font-weight: 400;
   font-weight: 400;
-  line-height: 22px;
+  line-height: 20px;
   text-align: left;
   text-align: left;
   flex: 1;
   flex: 1;
   padding: 0;
   padding: 0;

+ 1 - 1
src/components/search-bar/index.tsx

@@ -14,7 +14,7 @@ export default function Index({value, onChange, onClear}: Props) {
   return (
   return (
     <View className={style.searchBarContainer}>
     <View className={style.searchBarContainer}>
       <Image src={IconSearch} className={style.searchBarIcon}></Image>
       <Image src={IconSearch} className={style.searchBarIcon}></Image>
-      <Input value={value} onInput={(e:any)=> onChange(e.target.value)} placeholderTextColor='rgba(0,0,0,.4)' type='text' placeholder='搜索关键词...' className={style.searchBarInput}  />
+      <Input value={value} onInput={(e:any)=> onChange(e.target.value)} placeholderTextColor='#A1A7BA' type='text' placeholder='搜索智能体' className={style.searchBarInput}  />
       {/* {value && <View className={`iconfont icon-a-icon_24_edit1  ${style.searchBarClearButton}`} onClick={handleClear}></View>} */}
       {/* {value && <View className={`iconfont icon-a-icon_24_edit1  ${style.searchBarClearButton}`} onClick={handleClear}></View>} */}
       {value && <Image src={IconClear} className={`${style.searchBarClearButton}`} onClick={handleClear}></Image>}
       {value && <Image src={IconClear} className={`${style.searchBarClearButton}`} onClick={handleClear}></Image>}
       
       

+ 91 - 59
src/components/slide-delete/index.js

@@ -4,20 +4,31 @@ Component({
    */
    */
   properties: {
   properties: {
     pid: {
     pid: {
-      type: Number,
-      value: 0,
+      type: String,
+      value: '',
       observer(newVal) {
       observer(newVal) {
-        if(newVal) {
-          this.setData({
-              animate: true
-          }, () => {
+        console.log("on pid:", newVal, typeof newVal);
+        if (newVal) {
+          this.setData(
+            {
+              animate: true,
+            },
+            () => {
               this.setData({
               this.setData({
-                  translateX: 0
-              })
-          })
+                translateX: 0,
+              });
+            }
+          );
         }
         }
-      }
-    }
+      },
+    },
+    pinned: {
+      type: Boolean,
+      value: false,
+      observer(newVal) {
+        console.log("onTop changed:", newVal, typeof newVal);
+      },
+    },
   },
   },
 
 
   /**
   /**
@@ -25,7 +36,7 @@ Component({
    */
    */
   data: {
   data: {
     translateX: 0,
     translateX: 0,
-    animate: false
+    animate: false,
   },
   },
 
 
   /**
   /**
@@ -37,44 +48,51 @@ Component({
      */
      */
     handleTouchStart(e) {
     handleTouchStart(e) {
       // touch事件初始时,组件禁掉transition动画
       // touch事件初始时,组件禁掉transition动画
-      this.setData({
-        animate: false
-      }, () => {
-        this.touchStartX = e.touches[0].pageX
-        this.touchStartY = e.touches[0].pageY
-        this.startX = this.data.translateX      // 组件初始位置
-        this.direction = null                   // 记录手指滑动方向 X:左右滑动; Y:上下滑动
-      })
+      this.setData(
+        {
+          animate: false,
+        },
+        () => {
+          this.touchStartX = e.touches[0].pageX;
+          this.touchStartY = e.touches[0].pageY;
+          this.startX = this.data.translateX; // 组件初始位置
+          this.direction = null; // 记录手指滑动方向 X:左右滑动; Y:上下滑动
+        }
+      );
     },
     },
 
 
     /**
     /**
      * 处理touchmove事件
      * 处理touchmove事件
      */
      */
     handleTouchMove: function (e) {
     handleTouchMove: function (e) {
-      this.touchMoveX = e.touches[0].pageX
-      this.touchMoveY = e.touches[0].pageY
-      this.moveX = this.touchMoveX - this.touchStartX
+      this.touchMoveX = e.touches[0].pageX;
+      this.touchMoveY = e.touches[0].pageY;
+      this.moveX = this.touchMoveX - this.touchStartX;
 
 
       // 竖直移动距离超过了左右移动距离
       // 竖直移动距离超过了左右移动距离
-      if(Math.abs(this.touchMoveY - this.touchStartY) > Math.abs(this.moveX)) {
-        this.direction = 'Y'
-        return
+      if (Math.abs(this.touchMoveY - this.touchStartY) > Math.abs(this.moveX)) {
+        this.direction = "Y";
+        return;
       }
       }
-      this.direction = 'X'
+      this.direction = "X";
 
 
       // 以下两种情况不进行移动:1. 在最右边时向右滑动; 2. 在最左边时向左滑动
       // 以下两种情况不进行移动:1. 在最右边时向右滑动; 2. 在最左边时向左滑动
-      if((this.startX === 0 && this.moveX > 0) || (this.startX === -this.actionWidth && this.moveX < 0)) {
-        return
-      } else if(Math.abs(this.moveX) >= this.actionWidth) {
+      if (
+        (this.startX === 0 && this.moveX > 0) ||
+        (this.startX === -this.actionWidth && this.moveX < 0)
+      ) {
+        return;
+      } else if (Math.abs(this.moveX) >= this.actionWidth) {
         // 移动超出删除按钮的宽度时取按钮宽度作为移动距离
         // 移动超出删除按钮的宽度时取按钮宽度作为移动距离
-        this.moveX = this.moveX < 0 ? -this.actionWidth : this.actionWidth
+        this.moveX = this.moveX < 0 ? -this.actionWidth : this.actionWidth;
         this.setData({
         this.setData({
-          translateX: this.moveX
-        })
-      } else {  // 其他情况:手指滑动多少就位移多少
+          translateX: this.moveX,
+        });
+      } else {
+        // 其他情况:手指滑动多少就位移多少
         this.setData({
         this.setData({
-          translateX: this.touchMoveX - this.touchStartX + this.startX
-        })
+          translateX: this.touchMoveX - this.touchStartX + this.startX,
+        });
       }
       }
     },
     },
 
 
@@ -83,45 +101,59 @@ Component({
      */
      */
     handleTouchEnd: function (e) {
     handleTouchEnd: function (e) {
       // 非左右滑动时不进行任何操作
       // 非左右滑动时不进行任何操作
-      if(this.direction !== 'X') {
-        return
+      if (this.direction !== "X") {
+        return;
       }
       }
-      let translateX = 0
+      let translateX = 0;
       // 移动超出右滑最大位移
       // 移动超出右滑最大位移
-      if(this.moveX + this.startX >= 0) {
-        translateX = 0
-      } else if(this.moveX + this.startX <= -this.actionWidth) {
+      if (this.moveX + this.startX >= 0) {
+        translateX = 0;
+      } else if (this.moveX + this.startX <= -this.actionWidth) {
         // 移动超出左滑最大位移
         // 移动超出左滑最大位移
-        translateX = -this.actionWidth
-      } else if((this.startX === 0 && Math.abs(this.moveX) < this.actionWidth / 2) || (this.startX === -this.actionWidth && Math.abs(this.moveX) > this.actionWidth / 2)) {
+        translateX = -this.actionWidth;
+      } else if (
+        (this.startX === 0 && Math.abs(this.moveX) < this.actionWidth / 2) ||
+        (this.startX === -this.actionWidth &&
+          Math.abs(this.moveX) > this.actionWidth / 2)
+      ) {
         // 以下两种情况都滑动到右边起点(即删除按钮隐藏的状态):
         // 以下两种情况都滑动到右边起点(即删除按钮隐藏的状态):
         // 1. 从右边起点左滑但未超过最大位移的一半,回退到右边起点
         // 1. 从右边起点左滑但未超过最大位移的一半,回退到右边起点
         // 2. 从左边起点右滑且超过最大位移的一半,继续滑到到右边起点
         // 2. 从左边起点右滑且超过最大位移的一半,继续滑到到右边起点
-        translateX = 0
+        translateX = 0;
       } else {
       } else {
-        translateX = -this.actionWidth
+        translateX = -this.actionWidth;
       }
       }
-      this.setData({
-          animate: true
-      }, () => {
+      this.setData(
+        {
+          animate: true,
+        },
+        () => {
+          console.log(translateX, 3333);
+          if (translateX === -60) {
+            this.triggerEvent("action", {
+              type: e.currentTarget.dataset.type,
+              id: this.data.pid,
+            });
+          }
           this.setData({
           this.setData({
-              translateX
-          })
-      })
+            translateX,
+          });
+        }
+      );
     },
     },
 
 
     /**
     /**
      * 组件操作事件(此示例只有删除事件,可根据需要增加其他事件)
      * 组件操作事件(此示例只有删除事件,可根据需要增加其他事件)
      */
      */
     handleAction({ currentTarget: { dataset: data } }) {
     handleAction({ currentTarget: { dataset: data } }) {
-      this.triggerEvent('action', {
+      this.triggerEvent("action", {
         type: data.type,
         type: data.type,
-        id: this.data.pid
-      })
-    }
+        id: this.data.pid,
+      });
+    },
   },
   },
 
 
   ready() {
   ready() {
-    this.actionWidth = 60
-  }
-})
+    this.actionWidth = 60;
+  },
+});

+ 5 - 3
src/components/slide-delete/index.wxml

@@ -3,13 +3,15 @@
         bindtouchstart="handleTouchStart"
         bindtouchstart="handleTouchStart"
         bindtouchmove="handleTouchMove"
         bindtouchmove="handleTouchMove"
         bindtouchend="handleTouchEnd"
         bindtouchend="handleTouchEnd"
+        data-type="slide"
         style="transform: translateX({{translateX * 2}}rpx)"
         style="transform: translateX({{translateX * 2}}rpx)"
   >
   >
       <slot/>
       <slot/>
   </view>
   </view>
   <view class="action-wrap">
   <view class="action-wrap">
-      <view class="action del" bindtap="handleAction" data-type="del">
-          <text>删除</text>
-      </view>
+    <view wx:if="{{pinned}}" class="action cancel" bindtap="handleAction" data-type="unpin">
+        <text>取消置顶</text>
+    </view>
+    <view wx:else class="action pinned" bindtap="handleAction" data-type="pin"><text>置顶</text></view>
   </view>
   </view>
 </view>
 </view>

+ 11 - 1
src/components/slide-delete/index.wxss

@@ -10,6 +10,7 @@
 
 
 .wrap .content.animate {
 .wrap .content.animate {
   transition: transform 0.3s;
   transition: transform 0.3s;
+  background: #F6F8FB;
 }
 }
 
 
 .wrap .action-wrap {
 .wrap .action-wrap {
@@ -27,7 +28,16 @@
   height: 100%;
   height: 100%;
   justify-content: center;
   justify-content: center;
   align-items: center;
   align-items: center;
-  background: #E66671;
+  color: white;
+  background: #327BF9;
+}
+.wrap .action.cancel {
+  display: flex;
+  width: 120rpx;
+  height: 100%;
+  justify-content: center;
+  align-items: center;
+  background: #FF4747;
 }
 }
 
 
 .wrap .action text {
 .wrap .action text {

+ 5 - 0
src/pages/contact-us/index.config.ts

@@ -0,0 +1,5 @@
+export default definePageConfig({
+  navigationBarTitleText: '开场提问引导',
+  "usingComponents": {},
+  navigationStyle: 'custom'
+})

+ 2 - 0
src/pages/contact-us/index.module.less

@@ -0,0 +1,2 @@
+
+

+ 124 - 0
src/pages/contact-us/index.tsx

@@ -0,0 +1,124 @@
+import { useState } from "react";
+import { View } from "@tarojs/components";
+
+import PageCustom from "@/components/page-custom/index";
+import NavBarNormal from "@/components/nav-bar-normal/index";
+import WemetaInput from "@/components/wemeta-input/index";
+import WemetaTextarea from "@/components/wemeta-textarea";
+import FormItem from '@/components/form/FormItem'
+import Taro, { useUnload } from "@tarojs/taro";
+import { useCharacterStore } from "@/store/characterStore";
+import { useComponentStore } from "@/store/componentStore";
+import  PickerSingleColumn from "@/components/Picker/PickerSingleColumn";
+import IconArrowDownRounded from '@/components/icon/IconArrowDownRounded';
+
+export default function Index() {
+
+  
+  // 当前选中的值
+  const options = ['销售人员', '客服与售后支持', '市场与商务合作人员', '新员工 / 培训岗位', '管理者 / 内容运营者']
+  // 是否显示选择器
+  const [showPicker, setShowPicker] = useState(false)
+
+  // 当前选中的值
+  const [selected, setSelected] = useState(options[0])
+
+  const handleChange = (value: string) => {
+    setSelected(value)
+  }
+
+  const [value, setValue] = useState({
+    job: "",
+    department: "",
+    company: "",
+  });
+
+  const onChange = (key: string, v: string) => {
+    value[key] = v;
+    setValue({
+      ...value,
+    });
+  };
+
+  const handleSave = async () => {
+    if (
+      !value.job?.length &&
+      !value.department?.length &&
+      !value.company?.length
+    ) {
+      return;
+    }
+    
+    // const c = {
+    //   data: {
+    //     job: value.job,
+    //     department: value.department,
+    //     company: value.company,
+    //   },
+    //   enabled: currentComponent?.enabled ?? true,
+    //   id: currentComponent?.id,
+    //   name: currentComponent?.name ?? "商务名片",
+    //   characterProfileId:
+    //     currentComponent?.characterProfileId ?? character?.profileId,
+    //   type: "businessCard",
+    // };
+
+    // await saveComponent(c);
+  };
+
+  
+
+  return (
+    <PageCustom>
+      <NavBarNormal
+        backText="联系我们"
+      ></NavBarNormal>
+      <View className="flex flex-col items-center w-full gap-16 p-16 pb-140">
+        <FormItem labelText="您的姓名" required>
+          <WemetaInput
+              value={value.job}
+              onInput={(value: string) => onChange("job", value)}
+              placeholder="请输入"
+            />
+        </FormItem>
+        <FormItem labelText="联系方式" required>
+          <WemetaInput
+              value={value.job}
+              onInput={(value: string) => onChange("job", value)}
+              placeholder="请输入您的手机号/微信号"
+            />
+        </FormItem>
+        <FormItem labelText="公司信息" required>
+          <WemetaInput
+              value={value.job}
+              onInput={(value: string) => onChange("job", value)}
+              placeholder="请输入公司名称"
+            />
+        </FormItem>
+        <FormItem labelText="您的岗位" required>
+          <PickerSingleColumn headerTitle="您的岗位" options={options} selected={selected} onChange={handleChange} showPicker={showPicker} setShowPicker={setShowPicker}>
+            <View className="flex items-center gap-2 bg-white rounded-12 p-12 mb-16" onClick={() => setShowPicker(true)}>
+              <View className="flex-1 text-14 leading-22 text-gray-45">{selected}</View>
+              <View className="flex-center">
+                <IconArrowDownRounded/>
+              </View>
+            </View>
+          </PickerSingleColumn>
+        </FormItem>
+        <FormItem labelText="需求详情">
+          <WemetaTextarea
+            value={value.job}
+            onInput={(value: string) => onChange("job", value)}
+            placeholder="请输入"
+          />
+        </FormItem>
+
+      </View>
+      <View className="bottom-bar">
+        <View className="pt-12 px-20">
+          <View className={`button-rounded button-primary`}>保存</View>
+        </View>
+      </View>
+    </PageCustom>
+  );
+}

+ 10 - 16
src/pages/contact/components/contact-card/index.module.less

@@ -1,43 +1,37 @@
 .contactCard{
 .contactCard{
   display: flex;
   display: flex;
-  padding: 20px;
+  padding: 16px;
   align-items: center;
   align-items: center;
-  gap: 20px;
-  align-self: stretch;
-  border-radius: 20px;
-  background: white;
+  gap: 8px;
   color: #262626;
   color: #262626;
   font-family: "PingFang SC";
   font-family: "PingFang SC";
-  box-shadow: 0 4px 12px rgba(#6A685E, .03);
 }
 }
 
 
 .avatar{
 .avatar{
   display: flex;
   display: flex;
-  width: 72px;
-  height: 72px;
+  width: 48px;
+  height: 48px;
   justify-content: center;
   justify-content: center;
   align-items: center;
   align-items: center;
   border-radius: 100%;
   border-radius: 100%;
   overflow: hidden;
   overflow: hidden;
-  border: 1px solid rgba(0, 0, 0, 0.04);
 }
 }
 .infoColumn{
 .infoColumn{
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
-  gap: 10;
+  gap: 4px;
 }
 }
 .nameRow{
 .nameRow{
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 4px;
   gap: 4px;
   font-style: normal;
   font-style: normal;
-  letter-spacing: 0.8px;
 }
 }
 .nickName{
 .nickName{
-  font-size: 18px;
+  font-size: 14px;
   font-style: normal;
   font-style: normal;
-  font-weight: 600;
-  line-height: 26px;
+  font-weight: 500;
+  line-height: 20px;
 }
 }
 .nameMarkup{
 .nameMarkup{
   display: flex;
   display: flex;
@@ -53,9 +47,9 @@
 }
 }
 
 
 .subInfo{
 .subInfo{
-  color: rgba(0, 0, 0, 0.65);
+  color: #777E95;
   font-size: 12px;
   font-size: 12px;
   font-style: normal;
   font-style: normal;
   font-weight: 400;
   font-weight: 400;
-  line-height: 20px;
+  line-height: 16px;
 }
 }

+ 19 - 19
src/pages/contact/components/contact-card/index.tsx

@@ -12,27 +12,27 @@ interface Props {
 const Index = ({data, deleteable, refresh, fromContact}: Props)=> {
 const Index = ({data, deleteable, refresh, fromContact}: Props)=> {
   const handleClick = (data: IContactModel)=>{
   const handleClick = (data: IContactModel)=>{
     console.log(data, fromContact)
     console.log(data, fromContact)
-    if(fromContact){
-      Taro.navigateTo({url: '/pages/profile/index?fromContact=true&profileId='+data.contactProfileId})
-      return   
-    }
-    Taro.navigateTo({url: '/pages/profile/index?profileId='+data.contactProfileId})
+    // if(fromContact){
+    //   Taro.navigateTo({url: '/pages/profile/index?fromContact=true&profileId='+data.contactProfileId})
+    //   return   
+    // }
+    // Taro.navigateTo({url: '/pages/profile/index?profileId='+data.contactProfileId})
   }
   }
   const handleLongPress = (e, profileId: string) => {
   const handleLongPress = (e, profileId: string) => {
-    console.log("longpress");
-    if(!deleteable){
-      return;
-    }
-    e.stopPropagation();
-    Taro.showModal({
-      content: "😭 确认删除该联系人吗?",
-      async success(result) {
-        if (result.confirm) {
-          await delContact(profileId);
-          refresh();
-        }
-      },
-    });
+    // console.log("longpress");
+    // if(!deleteable){
+    //   return;
+    // }
+    // e.stopPropagation();
+    // Taro.showModal({
+    //   content: "😭 确认删除该联系人吗?",
+    //   async success(result) {
+    //     if (result.confirm) {
+    //       await delContact(profileId);
+    //       refresh();
+    //     }
+    //   },
+    // });
   };
   };
 
 
   return (
   return (

+ 7 - 0
src/pages/contact/index.module.less

@@ -1,3 +1,10 @@
 .page{
 .page{
   padding: 28px;
   padding: 28px;
+}
+.contactContent{
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  overflow: hidden;
+  border-top: 1px solid #EAECF5;
 }
 }

+ 45 - 25
src/pages/contact/index.tsx

@@ -15,7 +15,22 @@ import PageCustom from "@/components/page-custom/index";
 
 
 export default function Index() {
 export default function Index() {
   const [searchValue, setSearchValue] = useState("");
   const [searchValue, setSearchValue] = useState("");
-  const [list, setList] = useState<IContactModel[]>([]);
+  const [list, setList] = useState<IContactModel[]>([
+    {
+      avatar:
+        "https://cdn.wehome.cn/cmn/png/53/META-H8UKWHWU-2JNUAG2BARJF55VHU9QS3-YBQGHDAM-IW.png",
+      name: "孙海涛",
+      contactProfileId: "id1",
+      pinned: true,
+    },
+    {
+      avatar:
+        "https://cdn.wehome.cn/cmn/png/53/META-H8UKWHWU-2JNUAG2BARJF55VHU9QS3-YBQGHDAM-IW.png",
+      name: "殷海清",
+      contactProfileId: "id2",
+      pinned: false,
+    },
+  ]);
 
 
   const fetcher = async ([_url, page, pageSize]) => {
   const fetcher = async ([_url, page, pageSize]) => {
     const res = await getContactList({ page, pageSize });
     const res = await getContactList({ page, pageSize });
@@ -73,34 +88,39 @@ export default function Index() {
     loadMore();
     loadMore();
   });
   });
 
 
-  useEffect(() => {
-    if (data?.length) {
-      setList((prevdata) => {
-        return [...prevdata, ...data];
-      });
-    }
-  }, [data]);
+  // useEffect(() => {
+  //   if (data?.length) {
+  //     setList((prevdata) => {
+  //       return [...prevdata, ...data];
+  //     });
+  //   }
+  // }, [data]);
 
 
   reportPageVisit();
   reportPageVisit();
 
 
-  const handleHello = (e:any)=> {
-    console.log(e)
-  }
+  const handleHello = (e: any) => {
+    console.log(e);
+  };
 
 
   const renderContent = () => {
   const renderContent = () => {
     if (list?.length) {
     if (list?.length) {
       return list.map((item) => (
       return list.map((item) => (
         // @ts-ignore
         // @ts-ignore
-        <slide-delete pid={item.contactProfileId} onAction={handleHello}>
-          <ContactCard
-            refresh={resetFetchList}
-            deleteable
-            key={item.contactProfileId}
-            data={item}
-            fromContact
-          ></ContactCard>
+        <slide-delete
+          pid={item.contactProfileId}
+          pinned={item.pinned}
+          onAction={handleHello}
+        >
+          <View className={`${item.pinned ? "bg-gray" : "bg-white"}`}>
+            <ContactCard
+              refresh={resetFetchList}
+              deleteable
+              key={item.contactProfileId}
+              data={item}
+              fromContact
+            ></ContactCard>
+          </View>
         </slide-delete>
         </slide-delete>
-        
       ));
       ));
     }
     }
     return (
     return (
@@ -115,17 +135,17 @@ export default function Index() {
 
 
   return (
   return (
     <PageCustom>
     <PageCustom>
-      <NavBarNormal leftColumn={()=> <Text>联系人</Text>}></NavBarNormal>
-      <View className="flex flex-col gap-20 w-full">
-        <View className="px-8">
+      <NavBarNormal leftColumn={() => <Text className="text-16 font-medium">联系人</Text>}></NavBarNormal>
+      <View className="flex flex-col w-full">
+        <View className="px-16 pb-12">
           <SearchBar
           <SearchBar
             value={searchValue}
             value={searchValue}
             onChange={(e) => handleSearchBarChanged(e)}
             onChange={(e) => handleSearchBarChanged(e)}
             onClear={() => handleClear()}
             onClear={() => handleClear()}
           ></SearchBar>
           ></SearchBar>
         </View>
         </View>
-        
-        <View className="flex flex-col w-full overflow-hidden">{renderContent()}</View>
+
+        <View className={style.contactContent}>{renderContent()}</View>
       </View>
       </View>
     </PageCustom>
     </PageCustom>
   );
   );

+ 2 - 2
src/pages/knowledge-item/index.tsx

@@ -48,10 +48,10 @@ export default function Index() {
           <View className="flex rounded-12 p-16 gap-16 bg-white">
           <View className="flex rounded-12 p-16 gap-16 bg-white">
             <View className="flex-1">
             <View className="flex-1">
               <View className="text-14 font-medium leading-22 text-black pb-2">
               <View className="text-14 font-medium leading-22 text-black pb-2">
-                个人知识
+                精准QA模式
               </View>
               </View>
               <View className="text-12 leading-20 text-gray-45">
               <View className="text-12 leading-20 text-gray-45">
-                使用你上传的内容(如文档、链接等)作为智能体回答的知识基础。
+                知识转问答,助力AI更高效作答
               </View>
               </View>
             </View>
             </View>
 
 

+ 150 - 0
src/pages/knowledge/components/CompanyTab/index.tsx

@@ -0,0 +1,150 @@
+import { Image, View } from "@tarojs/components";
+import RoundedLabel from "../rounded-label";
+import IconFilterFeeds from "@/components/icon/IconFilterFeeds";
+import IconFilterBatch from "@/components/icon/IconFilterBatch";
+import IconFilterList from "@/components/icon/IconFilterList";
+
+import IconFIleTxt from "@/components/icon/IconFIleTxt";
+import IconFIlePDF from "@/components/icon/IconFIlePDF";
+import IconFIleXLSX from "@/components/icon/IconFIleXLSX";
+
+import FigureList from "@/components/list/figure-list";
+import FigureListItem from "@/components/list/figure-list-item";
+
+import Popup from "@/components/popup/popup";
+import WemetaSwitch from "@/components/wemeta-switch";
+import { useEffect, useState } from "react";
+
+import ViewStyleChat from '../view-style/ViewStyleChat'
+import ViewStyleList from '../view-style/ViewStyleList'
+
+import  PickerSingleColumn from "@/components/Picker/PickerSingleColumn";
+import IconArrowDownRounded from '@/components/icon/IconArrowDownRounded';
+
+type TListStyle = "chat" | "list";
+
+const Index = () => {
+  
+  const [checked, setChecked] = useState(false);
+  const [showPopup, setShowPopup] = useState(false);
+  const [listStyle, setListStyle] = useState<TListStyle>("chat");
+
+  const handleListStyleChange = (listStyle: TListStyle) => {
+    setListStyle(listStyle);
+  };
+
+
+  // 当前选中的值
+  const options = ['北京茗视光眼科医院管理有限公司', '杭州小蓝本有限公司']
+  // 是否显示选择器
+  const [showPicker, setShowPicker] = useState(false)
+
+  // 当前选中的值
+  const [selected, setSelected] = useState(options[0])
+
+  const handleChange = (value: string) => {
+    setSelected(value)
+  }
+
+  
+
+  useEffect(() => {
+    console.log("hellow");
+  }, []);
+
+  return (
+    <>
+      <View className="pt-12">
+        <View className="rounded-container-header"></View>
+        <View className="px-16 pb-20">
+          <View className="pb-8">
+            <PickerSingleColumn options={options} selected={selected} onChange={handleChange} showPicker={showPicker} setShowPicker={setShowPicker}>
+              <View className="flex items-center gap-2 bg-gray-3 rounded-12 p-12 mb-16" onClick={() => setShowPicker(true)}>
+                <View className="flex-1 text-14 leading-22 text-gray-45">{selected}</View>
+                <View className="flex-center">
+                  <IconArrowDownRounded/>
+                </View>
+              </View>
+            </PickerSingleColumn>
+          </View>
+          <View className="flex items-center">
+            
+            <View className="flex-1 text-12 leading-20 text-gray-45">
+              共102个文件
+            </View>
+            <View className="flex items-center">
+              {listStyle === "chat" ? (
+                <RoundedLabel
+                  onClick={() => setShowPopup(true)}
+                  text="信息流"
+                  icon={IconFilterFeeds}
+                ></RoundedLabel>
+              ) : (
+                <>
+                  <RoundedLabel
+                    onClick={() => {
+                      console.log("batch");
+                    }}
+                    text="批量"
+                    icon={IconFilterBatch}
+                  ></RoundedLabel>
+                  <RoundedLabel
+                    text="列表"
+                    icon={IconFilterList}
+                  ></RoundedLabel>
+                </>
+              )}
+            </View>
+          </View>
+        </View>
+        <View className="px-16">
+          {listStyle === "chat" ? <ViewStyleChat/> : <ViewStyleList />}
+        </View>
+      </View>
+      
+      <Popup setShow={setShowPopup} show={showPopup} title="展示样式">
+        <View
+          className={`rounded-card ${
+            listStyle === "chat" ? "rounded-card-actived" : ""
+          }`}
+          onClick={() => {
+            handleListStyleChange("chat");
+          }}
+        >
+          <View className="border-bottom1-gray mb-12">
+            <View className="mb-8 text-14 font-medium leading-22">
+              对话信息流
+            </View>
+            <View className="mb-12 text-12 leading-20 text-gray-45">
+              以对话形式展示,模拟自然的对话流程。
+            </View>
+          </View>
+          <View className="flex items-center">
+            <View className="flex-1 text-14 font-medium leading-22">
+              仅显示 AI 助手信息
+            </View>
+            <WemetaSwitch
+              checked={checked}
+              onChange={(checked) => setChecked(checked)}
+            ></WemetaSwitch>
+          </View>
+        </View>
+        <View
+          className={`rounded-card ${
+            listStyle === "list" ? "rounded-card-actived" : ""
+          }`}
+          onClick={() => {
+            handleListStyleChange("list");
+          }}
+        >
+          <View className="mb-8 text-14 font-medium leading-22">列表形式</View>
+          <View className="mb-12 text-12 leading-20 text-gray-45">
+            将知识点以简洁列表呈现,清晰快速地提供信息。
+          </View>
+        </View>
+      </Popup>
+    </>
+  );
+};
+
+export default Index;

+ 29 - 7
src/pages/knowledge/index.tsx

@@ -3,29 +3,51 @@
  */
  */
 
 
 import { View } from "@tarojs/components";
 import { View } from "@tarojs/components";
-
+import { useState } from "react";
 import PageCustom from "@/components/page-custom/index";
 import PageCustom from "@/components/page-custom/index";
 import NavBarNormal from "@/components/nav-bar-normal/index";
 import NavBarNormal from "@/components/nav-bar-normal/index";
 import WemetaTabs from "@/components/wemeta-tabs/index";
 import WemetaTabs from "@/components/wemeta-tabs/index";
 import PersonalTab from './components/personal-tab'
 import PersonalTab from './components/personal-tab'
+import CompanyTab from './components/CompanyTab'
+import Taro from "@tarojs/taro";
+
+
 
 
 
 
 export default function Index() {
 export default function Index() {
   
   
+
+  
+
   const tabList = [
   const tabList = [
     {
     {
       key: "1",
       key: "1",
       label: "个人知识",
       label: "个人知识",
-      children: <View><PersonalTab /></View> ,
+      children: <View>
+        {/* <View className="flex flex-col pt-56 items-center">
+          <View className="data-empty"></View>
+          <View className="text-12 text-gray-45 text-center leading-24 mt-12">
+            暂无数据
+          </View>
+        </View> */}
+        <PersonalTab />
+      </View> ,
     },
     },
     {
     {
       key: "2",
       key: "2",
       label: "企业知识",
       label: "企业知识",
-      children: (
-        <>
-          <View className="pt-12"></View>
-        </>
-      ),
+      children: <View>
+          <View className="flex-center pt-40">
+            <View className="text-center text-14 leading-28 text-gray-45 mb-44 w-172">
+              <View className="text-center text-16 leading-24 font-medium text-black">绑定企业,知识自动到位</View>
+              <View>访问公司统一知识内容</View>
+              <View>一键同步到你的智能体</View>
+              <View>提升回复效率与专业度</View>
+              <View className="button-rounded button-primary" onClick={()=> Taro.navigateTo({url: '/pages/contact-us/index'})}>联系我们</View>
+            </View>
+          </View>
+          {/* <CompanyTab/> */}
+      </View>,
     },
     },
   ];
   ];
   return (
   return (

+ 1 - 1
src/service/bot.ts

@@ -14,7 +14,7 @@ export type TMessageHistories = {
 // 获取与指定智能体的历史会话记录--按智能体维度倒序返回
 // 获取与指定智能体的历史会话记录--按智能体维度倒序返回
 type TGetMessageHistoriesParams = {
 type TGetMessageHistoriesParams = {
   agentId: string;
   agentId: string;
-  beginId?: string; // 起始ID, 如果未传入则获取最新的N条
+  startId?: string; // 起始ID, 如果未传入则获取最新的N条
   pageSize: number;
   pageSize: number;
 };
 };
 export const getMessageHistories = (data: TGetMessageHistoriesParams) => {
 export const getMessageHistories = (data: TGetMessageHistoriesParams) => {

+ 4 - 4
src/service/visitor.ts

@@ -53,7 +53,7 @@ export type TVisitorDislikeMessagesResponse = {
 
 
 export const getVisitorDislikeMessages = (data: {
 export const getVisitorDislikeMessages = (data: {
   "agentId": string,
   "agentId": string,
-  "beginId": string,
+  "startId": string,
   "pageSize": number,
   "pageSize": number,
 }) => {
 }) => {
   return request.get<TVisitorDislikeMessagesResponse>(`${bluebookAiAgent}api/v1/my/visitor/dislike/message`, {params: data})
   return request.get<TVisitorDislikeMessagesResponse>(`${bluebookAiAgent}api/v1/my/visitor/dislike/message`, {params: data})
@@ -78,7 +78,7 @@ export type TVisotorInfoResponse = {
 }
 }
 export const getVisitorInfo = (data: {
 export const getVisitorInfo = (data: {
   "visitorId": string,
   "visitorId": string,
-  "beginId": string,
+  "startId": string,
 }) => {
 }) => {
   return request.get<TVisotorInfoResponse>(`${bluebookAiAgent}api/v1/my/visitor/info`, {params: data})
   return request.get<TVisotorInfoResponse>(`${bluebookAiAgent}api/v1/my/visitor/info`, {params: data})
 }
 }
@@ -106,7 +106,7 @@ export type TVisitorLikeMessagesResponse = {
 }
 }
 export const getVisitorLikeMessages = (data: {
 export const getVisitorLikeMessages = (data: {
   "visitorId": string,
   "visitorId": string,
-  "beginId": string,
+  "startId": string,
 }) => {
 }) => {
   return request.get<TVisitorLikeMessagesResponse>(`${bluebookAiAgent}api/v1/my/visitor/like/messages`, {params: data})
   return request.get<TVisitorLikeMessagesResponse>(`${bluebookAiAgent}api/v1/my/visitor/like/messages`, {params: data})
 }
 }
@@ -166,7 +166,7 @@ export type TVisitorMessagesResponse = {
 export const getVisitorMessages = (data: {
 export const getVisitorMessages = (data: {
   "visitorId": string,
   "visitorId": string,
   "startId": string,
   "startId": string,
-  "beginId": string,
+  "startId": string,
   "pageSize": string,
   "pageSize": string,
 }) => {
 }) => {
   return request.get<TVisitorListResponse>(`${bluebookAiAgent}api/v1/my/visitor/messages`, {params: data})
   return request.get<TVisitorListResponse>(`${bluebookAiAgent}api/v1/my/visitor/messages`, {params: data})

+ 1 - 0
src/types/index.ts

@@ -162,6 +162,7 @@ export interface IContactModel {
    company?: string;
    company?: string;
    contactProfileId: string;
    contactProfileId: string;
    createdAt?: string;
    createdAt?: string;
+   onTop?:string
    /**
    /**
     * 职位
     * 职位
     */
     */