Jelajahi Sumber

feat: add dashboard page

王晓东 2 minggu lalu
induk
melakukan
1b4ca7e39e
49 mengubah file dengan 573 tambahan dan 123 penghapusan
  1. 1 1
      .env.development
  2. 1 1
      .env.production
  3. 1 1
      package.json
  4. 2 2
      project.config.json
  5. 1 1
      project.private.config.json
  6. 5 2
      src/app.config.ts
  7. 23 0
      src/app.less
  8. 28 0
      src/components/DigitalCard/DigitalCardBasic.tsx
  9. 7 0
      src/components/icon/IconArrowDownRounded/index.tsx
  10. 3 0
      src/images/svgs/IconArrowDownRounded.svg
  11. 3 0
      src/images/svgs/Iconly/Regular/Bold/IconArrowDownRounded.svg
  12. 0 3
      src/images/svgs/icon-right-arrow.svg
  13. 0 68
      src/pages/analysis/index.module.less
  14. 0 15
      src/pages/analysis/index.tsx
  15. 1 1
      src/pages/component-library/components/comp-item/compItem.tsx
  16. 1 1
      src/pages/component-library/components/comp-item/index.module.less
  17. 1 1
      src/pages/component-library/index.tsx
  18. 42 0
      src/pages/dashboard/components/DataCard/index.tsx
  19. 73 0
      src/pages/dashboard/components/Picker/PickerSingleColumn.tsx
  20. 37 0
      src/pages/dashboard/components/VisitorCard/index.tsx
  21. 0 0
      src/pages/dashboard/index.config.ts
  22. 0 0
      src/pages/dashboard/index.module.less
  23. 80 0
      src/pages/dashboard/index.tsx
  24. 3 3
      src/pages/index/index.tsx
  25. 1 1
      src/pages/login/index.tsx
  26. 2 2
      src/service/agent.ts
  27. 3 3
      src/service/bot.ts
  28. 3 3
      src/service/knowledge.ts
  29. 2 2
      src/service/storage.ts
  30. 2 2
      src/service/system.ts
  31. 1 1
      src/service/user.ts
  32. 238 0
      src/service/visitor.ts
  33. 2 2
      src/xiaolanbenlib/api/auth.ts
  34. 0 0
      src/xiaolanbenlib/api/index.ts
  35. 2 2
      src/xiaolanbenlib/api/upload.ts
  36. 0 0
      src/xiaolanbenlib/constant.ts
  37. 1 1
      src/xiaolanbenlib/hooks/data/useAuth.tsx
  38. 0 0
      src/xiaolanbenlib/module/alioss/Base64.js
  39. 0 0
      src/xiaolanbenlib/module/alioss/crypto.js
  40. 0 0
      src/xiaolanbenlib/module/alioss/hmac.js
  41. 1 1
      src/xiaolanbenlib/module/alioss/index.ts
  42. 0 0
      src/xiaolanbenlib/module/alioss/sha1.js
  43. 0 1
      src/xiaolanbenlib/module/axios.js
  44. 0 0
      src/xiaolanbenlib/module/sign.js
  45. 0 0
      src/xiaolanbenlib/utils/auth.ts
  46. 0 0
      src/xiaolanbenlib/utils/event.ts
  47. 0 0
      src/xiaolanbenlib/utils/link.ts
  48. 1 1
      src/xiaolanbenlib/utils/upload.ts
  49. 1 1
      tailwind.config.js

+ 1 - 1
.env.development

@@ -2,7 +2,7 @@
 TARO_APP_ID="wxede8ad263e6161b6"
 TARO_APP_BASE_URL="https://dev-api.xiaolvye.cn/"
 TARO_APP_NAME_TEXT="小蓝本"
-TARO_APP_NAME="bluenote"
+TARO_APP_NAME="xiaolanben"
 # 产品故事
 TARO_APP_STORY_URL="https://mp.weixin.qq.com/s?__biz=MzkzMDc0OTU0Nw==&mid=2247483671&idx=1&sn=27749d28c6e2e96e69735df477dd1597&chksm=c274cc13f50345059f716fc795d66fbafbfdc195334b8ea68f240bc8e06b1be37b81ffd3e580"
 TARO_APP_AGREEMENT_URL="https://dev-h5.xiaolvye.cn/agreement"

+ 1 - 1
.env.production

@@ -1,7 +1,7 @@
 TARO_APP_ID="wxede8ad263e6161b6"
 TARO_APP_BASE_URL="https://dev-api.xiaolvye.cn/"
 TARO_APP_NAME_TEXT="小蓝本"
-TARO_APP_NAME="bluenote"
+TARO_APP_NAME="xiaolanben"
 # 产品故事
 TARO_APP_STORY_URL="https://mp.weixin.qq.com/s?__biz=MzkzMDc0OTU0Nw==&mid=2247483671&idx=1&sn=27749d28c6e2e96e69735df477dd1597&chksm=c274cc13f50345059f716fc795d66fbafbfdc195334b8ea68f240bc8e06b1be37b81ffd3e580"
 TARO_APP_AGREEMENT_URL="https://dev-h5.xiaolvye.cn/agreement"

+ 1 - 1
package.json

@@ -1,5 +1,5 @@
 {
-  "name": "bluenote",
+  "name": "bluebook",
   "version": "1.0.0",
   "private": true,
   "description": "blue note",

+ 2 - 2
project.config.json

@@ -1,7 +1,7 @@
 {
   "miniprogramRoot": "dist/",
-  "projectname": "bluenote",
-  "description": "bluenote",
+  "projectname": "bluebook",
+  "description": "bluebook",
   "appid": "wxede8ad263e6161b6",
   "setting": {
     "urlCheck": true,

+ 1 - 1
project.private.config.json

@@ -1,5 +1,5 @@
 {
-  "projectname": "bluenote",
+  "projectname": "bluebook",
   "setting": {
     "compileHotReLoad": true,
     "urlCheck": false,

+ 5 - 2
src/app.config.ts

@@ -2,12 +2,12 @@ export default defineAppConfig({
   pages: [
     'pages/index/index',
     'pages/login/index',
+    'pages/dashboard/index',
     'pages/contact/index',
     'pages/knowledge/index',
     'pages/knowledge-item/index',
     'pages/knowledge-item-editor/index',
     'pages/member/index',
-    'pages/analysis/index',
     'pages/profile/index',
     'pages/agent/index',
     'pages/editor-pages/editor-personality/index',
@@ -57,6 +57,7 @@ export default defineAppConfig({
     selectedColor: '#000000',
     backgroundColor: '#f5f5f2',
     list: [
+      
       {
         pagePath: 'pages/index/index',
         selectedIconPath: 'images/tabbar/home-actived.png',
@@ -69,6 +70,7 @@ export default defineAppConfig({
         iconPath: 'images/tabbar/contact.png',
         text: '联系人'
       },
+      
       {
         pagePath: 'pages/knowledge/index',
         selectedIconPath: 'images/tabbar/contact-actived.png',
@@ -77,11 +79,12 @@ export default defineAppConfig({
       },
       
       {
-        pagePath: 'pages/analysis/index',
+        pagePath: 'pages/dashboard/index',
         selectedIconPath: 'images/tabbar/analysis-actived.png',
         iconPath: 'images/tabbar/analysis.png',
         text: '数据'
       },
+
       {
         pagePath: 'pages/member/index',
         selectedIconPath: 'images/tabbar/vip-actived.png',

+ 23 - 0
src/app.less

@@ -307,4 +307,27 @@
   border-top-width: 1px;
   border-top: 1px solid #FFFFFF;
   backdrop-filter: blur(38px);
+}
+
+
+/* 保持和之前相同,仅需确保以下类名存在 */
+.picker-modal {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  background: #fff;
+  z-index: 1000;
+}
+
+.picker-header {
+  display: flex;
+  justify-content: space-between;
+  padding: 15px;
+  border-bottom: 1px solid #f5f5f5;
+}
+
+.picker-item {
+  text-align: center;
+  line-height: 50px;
 }

+ 28 - 0
src/components/DigitalCard/DigitalCardBasic.tsx

@@ -0,0 +1,28 @@
+import { View } from "@tarojs/components";
+import TagCertificated from "@/components/tag-certificated";
+export interface DigitalCardBasicProps {
+  certificated?: boolean
+  name: string
+  position: string
+  company: string
+}
+
+const DigitalCardBasic = ({name, position, company, certificated }: DigitalCardBasicProps) => {
+  
+  return <View className="flex items-start">
+              <View className="flex flex-col flex-1">
+                <View className="flex items-end gap-8">
+                  <View className="text-24 font-medium leading-32">{name}</View>
+                  <View className="text-12 leading-20">{position}</View>
+                </View>
+                <View className="flex items-center gap-2">
+                  <View className="text-12 leading-20 truncate max-w-[188px]">
+                    {company}
+                  </View>
+                  {certificated && <TagCertificated />}
+                </View>
+              </View>
+            </View>
+}
+
+export default DigitalCardBasic;

+ 7 - 0
src/components/icon/IconArrowDownRounded/index.tsx

@@ -0,0 +1,7 @@
+import { Image } from '@tarojs/components'
+import Icon from '@/images/svgs/IconArrowDownRounded.svg'
+export default () => {
+  return (
+    <Image src={Icon} mode="widthFix" style={{width: '12px', height: '12px'}}></Image>
+  )
+}

+ 3 - 0
src/images/svgs/IconArrowDownRounded.svg

@@ -0,0 +1,3 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.4345 8.31539C5.4055 8.28714 5.2815 8.18047 5.1795 8.0811C4.538 7.49854 3.488 5.97881 3.1675 5.18339C3.116 5.06259 3.007 4.75718 3 4.59401C3 4.43765 3.036 4.2886 3.109 4.14637C3.211 3.96907 3.3715 3.82684 3.561 3.7489C3.6925 3.69873 4.086 3.6208 4.093 3.6208C4.5235 3.54286 5.223 3.5 5.996 3.5C6.7325 3.5 7.4035 3.54286 7.8405 3.60667C7.8475 3.61398 8.3365 3.69191 8.504 3.77716C8.81 3.93351 9 4.23892 9 4.56576V4.59401C8.9925 4.80687 8.8025 5.25451 8.7955 5.25451C8.4745 6.00706 7.476 7.49172 6.8125 8.08841C6.8125 8.08841 6.642 8.25645 6.5355 8.32952C6.3825 8.4435 6.193 8.5 6.0035 8.5C5.792 8.5 5.595 8.43619 5.4345 8.31539Z" fill="black" fill-opacity="0.25"/>
+</svg>

+ 3 - 0
src/images/svgs/Iconly/Regular/Bold/IconArrowDownRounded.svg

@@ -0,0 +1,3 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.4345 8.31539C5.4055 8.28714 5.2815 8.18047 5.1795 8.0811C4.538 7.49854 3.488 5.97881 3.1675 5.18339C3.116 5.06259 3.007 4.75718 3 4.59401C3 4.43765 3.036 4.2886 3.109 4.14637C3.211 3.96907 3.3715 3.82684 3.561 3.7489C3.6925 3.69873 4.086 3.6208 4.093 3.6208C4.5235 3.54286 5.223 3.5 5.996 3.5C6.7325 3.5 7.4035 3.54286 7.8405 3.60667C7.8475 3.61398 8.3365 3.69191 8.504 3.77716C8.81 3.93351 9 4.23892 9 4.56576V4.59401C8.9925 4.80687 8.8025 5.25451 8.7955 5.25451C8.4745 6.00706 7.476 7.49172 6.8125 8.08841C6.8125 8.08841 6.642 8.25645 6.5355 8.32952C6.3825 8.4435 6.193 8.5 6.0035 8.5C5.792 8.5 5.595 8.43619 5.4345 8.31539Z" fill="black" fill-opacity="0.25"/>
+</svg>

+ 0 - 3
src/images/svgs/icon-right-arrow.svg

@@ -1,3 +0,0 @@
-<svg width="9" height="14" viewBox="0 0 9 14" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M1.65685 12.6569L7.31371 7L1.65685 1.34315" stroke="black" stroke-opacity="0.45" stroke-width="2"/>
-</svg>

+ 0 - 68
src/pages/analysis/index.module.less

@@ -1,68 +0,0 @@
-
-.dashboardScoreBar{
-  box-shadow: 0px 0px 12px 0px rgba(#6A685E, .03); 
-}
-.dashboardScore{
-  color: #000;
-  font-family: Poppins;
-  font-size: 36px;
-  font-weight: 500;
-  line-height: 44px;
-  text-align: center;
-  font-weight: 500;
-}
-.dashboardSubText{
-  color: rgba(0, 0, 0, 0.45);
-  text-align: center;
-  font-size: 12px;
-  font-style: normal;
-  font-weight: 400;
-  line-height: 20px;
-}
-.chatList{
-  display: flex;
-  flex-wrap: wrap;
-  gap: 8px;
-  justify-content: space-around;
-  align-items: center;
-  padding-bottom: 40px;
-}
-.chatItem{
-  display: flex;
-  flex-direction: column;
-  width: 155px;
-  box-sizing: border-box;
-  padding: 36px 24px 16px;
-  background-color: white;
-  border-radius: 20px;
-  box-shadow: 0px 4px 12px 0px rgba(#6A685E, .03); 
-}
-.turnRow{
-  display: flex;
-  align-items: center;
-  gap: 2px;
-  padding: 36px 0 4px;
-  line-height: 32px;
-}
-.turnNum{
-  font-size: 24px;
-  line-height: 32px;
-  color: #000;
-}
-.turnText{
-  font-size: 20px;
-  line-height: 28px;
-}
-.datetime{
-  font-size: 12px;
-  line-height: 22px;
-  padding-bottom: 12px;
-  color: rgba(#000, .45);
-}
-.userName{
-  border-top: 1px dashed rgba(#000, .1);
-  padding-top: 12px;
-  font-size: 12px;
-  line-height: 22px;
-  color: rgba(#000, .45);
-}

+ 0 - 15
src/pages/analysis/index.tsx

@@ -1,15 +0,0 @@
-import { View, Text, Image } from "@tarojs/components";
-import Taro, { useDidShow } from "@tarojs/taro";
-import NavBarNormal from "@/components/nav-bar-normal/index";
-import PageCustom from "@/components/page-custom/index";
-
-export default () => {
-  
-  return (
-    <PageCustom>
-      <NavBarNormal leftColumn={()=> <Text>数据分析</Text>}>
-      </NavBarNormal>
-      <View className="p-20">暂无数据</View>
-    </PageCustom>
-  );
-};

+ 1 - 1
src/pages/component-library/components/comp-item/compItem.tsx

@@ -11,7 +11,7 @@ export const CompType = {
   image: style.compIconImage,
   email: style.compIconEmail,
   tel: style.compIconTel,
-  bluenote: style.compIconBluenote,
+  bluebook: style.compIconBluebook,
   wechat: style.compIconWechat,
   shiping: style.compIconShiping,
   tiktok: style.compIconTiktok,

+ 1 - 1
src/pages/component-library/components/comp-item/index.module.less

@@ -54,7 +54,7 @@
   .compIcon();
   background-image: url(https://cdn.wehome.cn/cmn/png/107/META-H8UKVHWU-KIGP3BIL7M5AYC6XHNUA2-74CYVI2M-A91.png);
 }
-.compIconBluenote{
+.compIconBluebook{
   .compIcon();
   background-image: url(https://cdn.wehome.cn/cmn/png/87/META-H8UKVHWU-1JNUXQBKDFMDLDZZ7BUW3-O6MEE2AM-JL.png);
 }

+ 1 - 1
src/pages/component-library/index.tsx

@@ -21,7 +21,7 @@ export default () => {
     {type: CompType.image, num: 0, text: '图片/视频'},
     {type: CompType.tel, num: 0, text: '电话'},
     {type: CompType.local, num: 0, text: '地图'},
-    {type: CompType.bluenote, num: 0, text: '小蓝本'},
+    {type: CompType.bluebook, num: 0, text: '小蓝本'},
   ])
   
   const [wechatWidget, setWechatWidget] = useState([

+ 42 - 0
src/pages/dashboard/components/DataCard/index.tsx

@@ -0,0 +1,42 @@
+import { View } from "@tarojs/components";
+import IconArrowThin from "@/components/icon/icon-arrow-thin";
+export interface IndexProps {
+  text: string;
+  unitText: string;
+  value: number;
+  onClick?: () => void;
+  arrow?: boolean;
+}
+
+export default function Index({
+  text,
+  unitText,
+  value,
+  onClick,
+  arrow,
+}: IndexProps) {
+  const handleClick = () => {
+    onClick?.();
+  };
+  return (
+    <View
+      className="flex p-12 rounded-8 bg-gray-3 text-black"
+      onClick={handleClick}
+    >
+      <View className="flex-1">
+        <View className="flex items-center mb-8 font-medium">{text}</View>
+        <View className="flex items-center">
+          <View className="flex items-end flex-1 gap-2">
+            <View className="text-22 font-bold leading-22">{value}</View>
+            <View className="text-10 font-medium leading-14">{unitText}</View>
+          </View>
+        </View>
+      </View>
+      {arrow && (
+        <View className="flex-center">
+          <IconArrowThin />
+        </View>
+      )}
+    </View>
+  );
+}

+ 73 - 0
src/pages/dashboard/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;

+ 37 - 0
src/pages/dashboard/components/VisitorCard/index.tsx

@@ -0,0 +1,37 @@
+import { View, Text } from "@tarojs/components";
+import DigitalCardBasic from "@/components/DigitalCard/DigitalCardBasic";
+
+export interface IndexProps {
+  data: {
+    certificated?: boolean
+    name: string
+    position: string
+    company: string
+    agentName: string
+    visitNum: number
+    chatNum: number
+    disLikeNum: number
+    visitTime: number
+  }
+}
+
+const Index = ({ data }: IndexProps) => {
+  
+  return <View className="bg-white rounded-12 p-12">
+  <View className="flex items-start gap-12">
+    <View className="flex items-start bg-pink rounded-full overflow-hidden">
+      <View className="w-56 h-56 bg-gray-3 rounded-full"></View>
+    </View>
+    <View className="flex flex-col gap-8">
+      <DigitalCardBasic name={data.name} position={data.position} company={data.company} certificated />
+      <View className="text-14 font-medium leading-22">第 <Text className="text-yellow">{data.visitNum}</Text> 次访问了你的智能体【{data.agentName}】</View>
+      <View className="flex-center text-12 leading-20">
+        <View className="flex-1"><Text className="text-primary">{data.chatNum}</Text> 轮对话</View>
+        <View className="text-gray-45 leading-20">5小时前</View>
+      </View>
+    </View>
+  </View>
+</View>
+}
+
+export default Index;

+ 0 - 0
src/pages/analysis/index.config.ts → src/pages/dashboard/index.config.ts


+ 0 - 0
src/pages/dashboard/index.module.less


+ 80 - 0
src/pages/dashboard/index.tsx

@@ -0,0 +1,80 @@
+import { View, Text, } from "@tarojs/components";
+import Taro, { useDidShow } from "@tarojs/taro";
+import NavBarNormal from "@/components/nav-bar-normal/index";
+import PageCustom from "@/components/page-custom/index";
+import IconArrowDownRounded from '@/components/icon/IconArrowDownRounded';
+import DataCard from './components/DataCard'
+import VisitorCard from "./components/VisitorCard";
+import  PickerSingleColumn from "./components/Picker/PickerSingleColumn";
+import { useState } from "react";
+
+export default () => {
+  
+  
+  // 当前选中的值
+  const options = ['张三', '李四']
+  // 是否显示选择器
+  const [showPicker, setShowPicker] = useState(false)
+
+  // 当前选中的值
+  const [selected, setSelected] = useState(options[0])
+
+  const handleChange = (value: string) => {
+    setSelected(value)
+  }
+
+  return (
+    <PageCustom>
+      <NavBarNormal leftColumn={()=> <Text>数据分析</Text>}>
+      </NavBarNormal>
+      <View className="w-full pt-8 px-16 pb-40">
+        
+        
+        <PickerSingleColumn 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>
+        
+
+        <View className="grid grid-cols-2 gap-8 bg-white rounded-12 p-12 mb-12">
+          <DataCard text="今日访问次数" unitText="次" value={588} />
+          <DataCard text="今日对话人数" unitText="人" value={588} />
+          <DataCard text="累计访问次数" unitText="次" value={588} />
+          <DataCard text="累计对话人数" unitText="人" value={588} />
+          <DataCard text="好评" unitText="条" value={20} arrow />
+          <DataCard text="待处理差评" unitText="条" value={2} arrow />
+        </View>
+
+        <View className="mb-8 text-14 leading-22 font-medium">访问详情</View>
+        <View className="flex flex-col gap-8">
+          <VisitorCard data={{
+              name: '洪三',
+              company: '北京茗视光眼科医院管理有限公司',
+              position: 'CEO',
+              agentName: '张医生',
+              chatNum: 10,
+              visitNum: 7,
+              disLikeNum: 2,
+              visitTime: 5
+            }}></VisitorCard>
+          
+          <VisitorCard data={{
+              name: '李四',
+              company: '北京茗视光眼科医院管理有限公司',
+              position: '商务经理',
+              agentName: '张医生',
+              chatNum: 10,
+              visitNum: 7,
+              disLikeNum: 2,
+              visitTime: 5
+            }}></VisitorCard>
+        </View>
+      </View>
+      
+    </PageCustom>
+  );
+};

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

@@ -5,9 +5,9 @@ import style from "./index.module.less";
 import NavBarNormal from "@/components/nav-bar-normal/index";
 import LogoImage from '@/images/logo.png'
 import PageCustom from "@/components/page-custom/index";
-import { UserInfoResponse } from '@/lib/api/auth'
-import { onLogout, useIsLogin } from '@/lib/hooks/data/useAuth'
-import refreshUserId, { clearUserInfo, getOpenIdAsync } from '@/lib/utils/auth'
+import { UserInfoResponse } from '@/xiaolanbenlib/api/auth'
+import { onLogout, useIsLogin } from '@/xiaolanbenlib/hooks/data/useAuth'
+import refreshUserId, { clearUserInfo, getOpenIdAsync } from '@/xiaolanbenlib/utils/auth'
 
 import WelcomeTips from './components/welcome/index'
 

+ 1 - 1
src/pages/login/index.tsx

@@ -2,7 +2,7 @@ import NavBarNormal from "@/components/nav-bar-normal/index";
 import { View,Text, Image, Checkbox, Button } from "@tarojs/components";
 import PageCustom from "@/components/page-custom/index";
 import LogoImage from '@/images/logo.png'
-import { useLogin } from '@/lib/hooks/data/useAuth'
+import { useLogin } from '@/xiaolanbenlib/hooks/data/useAuth'
 
 
 import { useState } from "react";

+ 2 - 2
src/service/agent.ts

@@ -1,7 +1,7 @@
 import {
   bluebookAiAgent,
-} from '@/lib/api/index'
-import request from '@/lib/module/axios.js'
+} from '@/xiaolanbenlib/api/index'
+import request from '@/xiaolanbenlib/module/axios.js'
 import { TAgentDetail, TComponentItem } from '@/types/agent'
 
 

+ 3 - 3
src/service/bot.ts

@@ -1,8 +1,8 @@
-import { bluebookAiAgent } from "@/lib/api/index";
+import { bluebookAiAgent } from "@/xiaolanbenlib/api/index";
 import Taro from "@tarojs/taro";
-import { getHeaders } from "@/lib/module/axios.js";
+import { getHeaders } from "@/xiaolanbenlib/module/axios.js";
 import JsonChunkParser from "@/utils/jsonChunkParser";
-import request from "@/lib/module/axios.js";
+import request from "@/xiaolanbenlib/module/axios.js";
 import type { TMessage } from "@/types/bot";
 
 export type TMessageHistories = {

+ 3 - 3
src/service/knowledge.ts

@@ -1,8 +1,8 @@
-import { bluebookAiAgent } from "@/lib/api/index";
+import { bluebookAiAgent } from "@/xiaolanbenlib/api/index";
 import Taro from "@tarojs/taro";
-import { getHeaders } from "@/lib/module/axios.js";
+import { getHeaders } from "@/xiaolanbenlib/module/axios.js";
 import JsonChunkParser from "@/utils/jsonChunkParser";
-import request from "@/lib/module/axios.js";
+import request from "@/xiaolanbenlib/module/axios.js";
 import type { TKnowledgeListItem, TQAListItem } from "@/types/knowledge";
 
 

+ 2 - 2
src/service/storage.ts

@@ -1,8 +1,8 @@
 // 我的音色库&形象库
 import {
   bluebookAiAgent,
-} from '@/lib/api/index'
-import request from '@/lib/module/axios.js'
+} from '@/xiaolanbenlib/api/index'
+import request from '@/xiaolanbenlib/module/axios.js'
 import Taro from '@tarojs/taro'
 
 import {FileTypes} from '@/consts'

+ 2 - 2
src/service/system.ts

@@ -1,8 +1,8 @@
 // 系统配置
 import {
   bluebookAiAgent,
-} from '@/lib/api/index'
-import request from '@/lib/module/axios.js'
+} from '@/xiaolanbenlib/api/index'
+import request from '@/xiaolanbenlib/module/axios.js'
 
 
 

+ 1 - 1
src/service/user.ts

@@ -1,4 +1,4 @@
-import request from '@/lib/module/axios.js'
+import request from '@/xiaolanbenlib/module/axios.js'
 import { TEntityUser } from '@/types/index'
 
 

+ 238 - 0
src/service/visitor.ts

@@ -0,0 +1,238 @@
+import {
+  bluebookAiAgent,
+} from '@/xiaolanbenlib/api/index'
+import request from '@/xiaolanbenlib/module/axios.js'
+
+
+
+// 编辑差评记录的答案消息--编辑后则自动标识为已处理
+export const editVisitorDislikeAnswer = (data: {
+  "agentId": string,
+  "answer": string,
+  "visitorId": string,
+  "links": string[],
+  "msgId": string,
+  "pics": string[],
+  "question": string
+}) => {
+  return request.put(`${bluebookAiAgent}api/v1/my/visitor/dislike/message/answer`, data)
+}
+
+// 删除指定的差评待处理记录
+export const deleteVisitorDislikeAnswer = (data: {
+  "agentId": string,
+  "visitorId": string,
+  "msgId": string,
+}) => {
+  return request.delete(`${bluebookAiAgent}api/v1/my/visitor/dislike/message`, {params: data})
+}
+
+// 获取未处理的差评记录列表
+export type TVisitorDislikeMessagesResponse = {
+  "data": [
+    [
+      {
+        "agentId": string,
+        "visitorId": string,
+        "content": string,
+        "dislikeReason": string,
+        "isDislike": false,
+        "isLike": false,
+        "isStreaming": false,
+        "msgId": number,
+        "msgTime": "2025-05-15T09:20:38.928Z",
+        "msgUk": string,
+        "originalAgentId": string,
+        "role": string
+      }
+    ]
+  ],
+  "nextId": string,
+  "totalCount": number
+}
+
+export const getVisitorDislikeMessages = (data: {
+  "agentId": string,
+  "beginId": string,
+  "pageSize": number,
+}) => {
+  return request.get<TVisitorDislikeMessagesResponse>(`${bluebookAiAgent}api/v1/my/visitor/dislike/message`, {params: data})
+}
+
+
+// 访客访问详情--访客信息
+export type TVisotorInfoResponse = {
+  "agentId": string,
+  "agentStatus": string,
+  "avatarUrl": string,
+  "chatRound": number,
+  "dislikeCnt": number,
+  "isEnt": false,
+  "lastChatTime": "2025-05-21T07:09:45.814Z",
+  "myAgentId": string,
+  "myAgentName": string,
+  "name": string,
+  "position": string,
+  "visitTimes": number,
+  "visitorId": number
+}
+export const getVisitorInfo = (data: {
+  "visitorId": string,
+  "beginId": string,
+}) => {
+  return request.get<TVisotorInfoResponse>(`${bluebookAiAgent}api/v1/my/visitor/info`, {params: data})
+}
+
+// 获取好评记录列表--包含已读未读
+export type TVisitorLikeMessagesResponse = {
+  "data": [
+    {
+      "agentId": string,
+      "visitorId": string,
+      "content": string,
+      "dislikeReason": string,
+      "isDislike": false,
+      "isLike": false,
+      "isStreaming": false,
+      "msgId": number,
+      "msgTime": "2025-05-21T07:09:45.820Z",
+      "msgUk": string,
+      "originalAgentId": string,
+      "role": string
+    }
+  ],
+  "nextId": string,
+  "totalCount": number
+}
+export const getVisitorLikeMessages = (data: {
+  "visitorId": string,
+  "beginId": string,
+}) => {
+  return request.get<TVisitorLikeMessagesResponse>(`${bluebookAiAgent}api/v1/my/visitor/like/messages`, {params: data})
+}
+
+// 访客数据列表--列表会按我的智能体明细展示
+export type TVisitorListResponse = {
+  "data": [
+    {
+      "agentId": string,
+      "agentStatus": string,
+      "avatarUrl": string,
+      "chatRound": number,
+      "dislikeCnt": number,
+      "isEnt": false,
+      "lastChatTime": "2025-05-21T07:09:45.823Z",
+      "myAgentId": string,
+      "myAgentName": string,
+      "name": string,
+      "position": string,
+      "visitTimes": number,
+      "visitorId": number
+    }
+  ],
+  "nextId": string,
+  "totalCount": number
+}
+export const getVisitorList = (data: {
+  "agentId": string,
+  "startId": string,
+  "pageSize": string,
+}) => {
+  return request.get<TVisitorListResponse>(`${bluebookAiAgent}api/v1/my/visitor/list`, {params: data})
+}
+
+
+// 访客访问详情--访客聊天记录
+export type TVisitorMessagesResponse = {
+  "data": [
+    {
+      "agentId": string,
+      "visitorId": string,
+      "content": string,
+      "dislikeReason": string,
+      "isDislike": false,
+      "isLike": false,
+      "isStreaming": false,
+      "msgId": number,
+      "msgTime": "2025-05-21T07:09:45.826Z",
+      "msgUk": string,
+      "originalAgentId": string,
+      "role": string
+    }
+  ],
+  "nextId": string,
+  "totalCount": number
+}
+export const getVisitorMessages = (data: {
+  "visitorId": string,
+  "startId": string,
+  "beginId": string,
+  "pageSize": string,
+}) => {
+  return request.get<TVisitorListResponse>(`${bluebookAiAgent}api/v1/my/visitor/messages`, {params: data})
+}
+
+// 访客聊天记录 获取指定 msgId 前后各N条;用于查看好差评记录的访客详情
+export type TVisitorMessagesByMsgIdResponse = [
+  {
+    "agentId": string,
+    "visitorId": string,
+    "content": string,
+    "dislikeReason": string,
+    "isDislike": false,
+    "isLike": false,
+    "isStreaming": false,
+    "msgId": number,
+    "msgTime": "2025-05-21T07:09:45.828Z",
+    "msgUk": string,
+    "originalAgentId": string,
+    "role": string
+  }
+]
+export const getVisitorMessagesByMsgId = (data: {
+  "visitorId": string,
+  "agentId": string,
+  "msgId": string,
+  "size": number,
+}) => {
+  return request.get<TVisitorMessagesByMsgIdResponse>(`${bluebookAiAgent}api/v1/my/visitor/messages/byMsgId`, {params: data})
+}
+
+
+// 访问数据汇总
+export type TVisitorSummaryResponse = {
+  sumChatUv?: number// 总聊天UV ,
+  sumPv?: number// 总PV ,
+  sumUv?: number// 总UV ,
+  todayChatUv?: number// 今日聊天UV ,
+  todayPv?: number// 今日PV ,
+  todayUv?: number// 今日UV ,
+  unprocessedDislikeCnt?: number// 未处理差评记录数 ,
+  unreadLikeCnt?: number// 未查看点赞记录数
+}
+export const getVisitorSummary = (data: {
+  "agentId": string,
+}) => {
+  return request.get<TVisitorSummaryResponse>(`${bluebookAiAgent}api/v1/my/visitor/summary`, {params: data})
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 2 - 2
src/lib/api/auth.ts → src/xiaolanbenlib/api/auth.ts

@@ -2,8 +2,8 @@ import {
   bluebookBaseConst,
   getUserCenterParams,
   usercenterbase,
-} from '@/lib/api/index'
-import request from '@/lib/module/axios.js'
+} from '@/xiaolanbenlib/api/index'
+import request from '@/xiaolanbenlib/module/axios.js'
 
 export interface loginWithoutAuthorizeProps {
   autoPwd: number // "密码是否由系统自动生成(0不是,1是)",

+ 0 - 0
src/lib/api/index.ts → src/xiaolanbenlib/api/index.ts


+ 2 - 2
src/lib/api/upload.ts → src/xiaolanbenlib/api/upload.ts

@@ -1,5 +1,5 @@
-import { blueServiceBaseConst } from '@/lib/api/index'
-import request from '@/lib/module/axios.js'
+import { blueServiceBaseConst } from '@/xiaolanbenlib/api/index'
+import request from '@/xiaolanbenlib/module/axios.js'
 
 export const getOssConfig = (params) =>
   request.post(

+ 0 - 0
src/lib/constant.ts → src/xiaolanbenlib/constant.ts


+ 1 - 1
src/lib/hooks/data/useAuth.tsx → src/xiaolanbenlib/hooks/data/useAuth.tsx

@@ -1,4 +1,4 @@
-import { IS_LOGIN_STORAGE_KEY } from '@/lib/constant'
+import { IS_LOGIN_STORAGE_KEY } from '@/xiaolanbenlib/constant'
 import { ButtonProps } from '@tarojs/components'
 import Taro, { useDidShow } from '@tarojs/taro'
 import { useCallback, useEffect, useState } from 'react'

+ 0 - 0
src/lib/module/alioss/Base64.js → src/xiaolanbenlib/module/alioss/Base64.js


+ 0 - 0
src/lib/module/alioss/crypto.js → src/xiaolanbenlib/module/alioss/crypto.js


+ 0 - 0
src/lib/module/alioss/hmac.js → src/xiaolanbenlib/module/alioss/hmac.js


+ 1 - 1
src/lib/module/alioss/index.ts → src/xiaolanbenlib/module/alioss/index.ts

@@ -1,4 +1,4 @@
-import { getOssConfig } from '@/lib/api/upload'
+import { getOssConfig } from '@/xiaolanbenlib/api/upload'
 import Taro from '@tarojs/taro'
 import Base64 from './Base64'
 import Crypto from './crypto'

+ 0 - 0
src/lib/module/alioss/sha1.js → src/xiaolanbenlib/module/alioss/sha1.js


+ 0 - 1
src/lib/module/axios.js → src/xiaolanbenlib/module/axios.js

@@ -21,7 +21,6 @@ export const getHeaders = async (config) => {
   const openId = Taro.getStorageInfoSync(OPEN_ID_STORAGE_KEY)
   config.headers.openId = `${openId}`
   await sign(config)
-  console.log(config,1111)
   return config
 };
 

+ 0 - 0
src/lib/module/sign.js → src/xiaolanbenlib/module/sign.js


+ 0 - 0
src/lib/utils/auth.ts → src/xiaolanbenlib/utils/auth.ts


+ 0 - 0
src/lib/utils/event.ts → src/xiaolanbenlib/utils/event.ts


+ 0 - 0
src/lib/utils/link.ts → src/xiaolanbenlib/utils/link.ts


+ 1 - 1
src/lib/utils/upload.ts → src/xiaolanbenlib/utils/upload.ts

@@ -1,4 +1,4 @@
-import uploadFileToAlioss from '@/lib/module/alioss'
+import uploadFileToAlioss from '@/xiaolanbenlib/module/alioss'
 import Taro from '@tarojs/taro'
 
 const IMAGE_LIMIT = 50 * 1024 * 1024 // 50MB = 52428800 bytes

+ 1 - 1
tailwind.config.js

@@ -40,7 +40,7 @@ module.exports = {
       'orange': '#FD561F',
       'red': '#EE4949',
       'green': '#31BE59',
-      'yellow': '#ffc82c',
+      'yellow': '#EE9E49',
       'gray': '#f6f6f6',
       'gray-page': '#f6f6f6',
       'gray-dark': '#273444',