Merge branch 'yongpxu-dev' into yongpxu-dev2

This commit is contained in:
超级老白兔
2025-09-16 17:53:14 +08:00
7 changed files with 289 additions and 117 deletions

1
Cunkebao/.gitignore vendored
View File

@@ -4,3 +4,4 @@ build/
yarn.lock yarn.lock
.env .env
.DS_Store .DS_Store
dist/*

View File

@@ -1,50 +1,50 @@
{ {
"_charts-DsEZaGAW.js": { "_charts-B449e2xS.js": {
"file": "assets/charts-DsEZaGAW.js", "file": "assets/charts-B449e2xS.js",
"name": "charts", "name": "charts",
"imports": [ "imports": [
"_ui-YC29IQHT.js", "_ui-DDu9FCjt.js",
"_vendor-Bq99rrm8.js" "_vendor-0WYR1k4q.js"
] ]
}, },
"_ui-D0C0OGrH.css": { "_ui-D0C0OGrH.css": {
"file": "assets/ui-D0C0OGrH.css", "file": "assets/ui-D0C0OGrH.css",
"src": "_ui-D0C0OGrH.css" "src": "_ui-D0C0OGrH.css"
}, },
"_ui-YC29IQHT.js": { "_ui-DDu9FCjt.js": {
"file": "assets/ui-YC29IQHT.js", "file": "assets/ui-DDu9FCjt.js",
"name": "ui", "name": "ui",
"imports": [ "imports": [
"_vendor-Bq99rrm8.js" "_vendor-0WYR1k4q.js"
], ],
"css": [ "css": [
"assets/ui-D0C0OGrH.css" "assets/ui-D0C0OGrH.css"
] ]
}, },
"_utils-Ft3ushmX.js": { "_utils-DC06x9DY.js": {
"file": "assets/utils-Ft3ushmX.js", "file": "assets/utils-DC06x9DY.js",
"name": "utils", "name": "utils",
"imports": [ "imports": [
"_vendor-Bq99rrm8.js" "_vendor-0WYR1k4q.js"
] ]
}, },
"_vendor-Bq99rrm8.js": { "_vendor-0WYR1k4q.js": {
"file": "assets/vendor-Bq99rrm8.js", "file": "assets/vendor-0WYR1k4q.js",
"name": "vendor" "name": "vendor"
}, },
"index.html": { "index.html": {
"file": "assets/index-d8oC2PBC.js", "file": "assets/index-DzNmnMYg.js",
"name": "index", "name": "index",
"src": "index.html", "src": "index.html",
"isEntry": true, "isEntry": true,
"imports": [ "imports": [
"_vendor-Bq99rrm8.js", "_vendor-0WYR1k4q.js",
"_ui-YC29IQHT.js", "_ui-DDu9FCjt.js",
"_utils-Ft3ushmX.js", "_utils-DC06x9DY.js",
"_charts-DsEZaGAW.js" "_charts-B449e2xS.js"
], ],
"css": [ "css": [
"assets/index-D8Ews0CA.css" "assets/index-QrS4Cvyc.css"
] ]
} }
} }

View File

@@ -11,13 +11,13 @@
</style> </style>
<!-- 引入 uni-app web-view SDK必须 --> <!-- 引入 uni-app web-view SDK必须 -->
<script type="text/javascript" src="/websdk.js"></script> <script type="text/javascript" src="/websdk.js"></script>
<script type="module" crossorigin src="/assets/index-d8oC2PBC.js"></script> <script type="module" crossorigin src="/assets/index-DzNmnMYg.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vendor-Bq99rrm8.js"> <link rel="modulepreload" crossorigin href="/assets/vendor-0WYR1k4q.js">
<link rel="modulepreload" crossorigin href="/assets/ui-YC29IQHT.js"> <link rel="modulepreload" crossorigin href="/assets/ui-DDu9FCjt.js">
<link rel="modulepreload" crossorigin href="/assets/utils-Ft3ushmX.js"> <link rel="modulepreload" crossorigin href="/assets/utils-DC06x9DY.js">
<link rel="modulepreload" crossorigin href="/assets/charts-DsEZaGAW.js"> <link rel="modulepreload" crossorigin href="/assets/charts-B449e2xS.js">
<link rel="stylesheet" crossorigin href="/assets/ui-D0C0OGrH.css"> <link rel="stylesheet" crossorigin href="/assets/ui-D0C0OGrH.css">
<link rel="stylesheet" crossorigin href="/assets/index-D8Ews0CA.css"> <link rel="stylesheet" crossorigin href="/assets/index-QrS4Cvyc.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@@ -1,5 +1,4 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useCkChatStore } from "@/store/module/ckchat/ckchat";
import { Form, Input, Button, Toast, Checkbox } from "antd-mobile"; import { Form, Input, Button, Toast, Checkbox } from "antd-mobile";
import { import {
EyeInvisibleOutline, EyeInvisibleOutline,
@@ -7,7 +6,6 @@ import {
UserOutline, UserOutline,
} from "antd-mobile-icons"; } from "antd-mobile-icons";
import { useUserStore } from "@/store/module/user"; import { useUserStore } from "@/store/module/user";
import { useWebSocketStore } from "@/store/module/websocket/websocket";
import { loginWithPassword, loginWithCode, sendVerificationCode } from "./api"; import { loginWithPassword, loginWithCode, sendVerificationCode } from "./api";
import style from "./login.module.scss"; import style from "./login.module.scss";
@@ -19,7 +17,6 @@ const Login: React.FC = () => {
const [countdown, setCountdown] = useState(0); const [countdown, setCountdown] = useState(0);
const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
const [agreeToTerms, setAgreeToTerms] = useState(false); const [agreeToTerms, setAgreeToTerms] = useState(false);
const { setUserInfo } = useCkChatStore.getState();
const { login, login2 } = useUserStore(); const { login, login2 } = useUserStore();
// 倒计时效果 // 倒计时效果
@@ -75,13 +72,9 @@ const Login: React.FC = () => {
: loginWithCode(loginParams); : loginWithCode(loginParams);
response.then(res => { response.then(res => {
const { member, kefuData, deviceTotal } = res; const { member, deviceTotal } = res;
// 清空WebSocket连接状态 // 清空WebSocket连接状态
useWebSocketStore.getState().clearConnectionState();
login(res.token, member, deviceTotal); login(res.token, member, deviceTotal);
const { self, token } = kefuData;
login2(token.access_token);
setUserInfo(self);
}); });
}; };

View File

@@ -84,16 +84,6 @@ const Mine: React.FC = () => {
bgColor: "#fff7e6", bgColor: "#fff7e6",
iconColor: "#fa8c16", iconColor: "#fa8c16",
}, },
{
id: "ckb",
title: "触客宝",
description: "触客宝",
icon: <PhoneOutlined />,
count: 0,
path: "/ckbox/weChat",
bgColor: "#fff7e6",
iconColor: "#fa8c16",
},
]; ];
// 加载统计数据 // 加载统计数据

View File

@@ -218,6 +218,63 @@
} }
} }
} }
// 点赞和评论交互区域
.interactionArea {
margin-top: 8px;
padding: 8px 12px;
background-color: #f7f7f7;
border-radius: 4px;
font-size: 13px;
.likeArea {
display: flex;
align-items: center;
margin-bottom: 4px;
.likeIcon {
color: #ff6b6b;
margin-right: 6px;
font-size: 12px;
}
.likeList {
color: #576b95;
span {
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
}
.commentArea {
.commentItem {
margin-bottom: 2px;
line-height: 1.4;
.commentUser {
color: #576b95;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
.commentSeparator {
color: #666;
}
.commentContent {
color: #333;
}
}
}
}
} }
} }

View File

@@ -10,16 +10,47 @@ import {
import { InfiniteScroll } from "antd-mobile"; import { InfiniteScroll } from "antd-mobile";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
// 评论数据类型
interface CommentItem {
commentArg: number;
commentId1: number;
commentId2: number;
commentTime: number;
content: string;
nickName: string;
wechatId: string;
}
// 点赞数据类型
interface LikeItem {
createTime: number;
nickName: string;
wechatId: string;
}
// 朋友圈实体数据类型
interface MomentEntity {
content: string;
createTime: number;
lat: number;
lng: number;
location: string;
objectType: number;
picSize: number;
resUrls: string[];
snsId: string;
urls: string[];
userName: string;
}
// 朋友圈数据类型定义 // 朋友圈数据类型定义
interface FriendsCircleItem { interface FriendsCircleItem {
id: string; commentList: CommentItem[];
avatar: string; createTime: number;
username: string; likeList: LikeItem[];
content: string; momentEntity: MomentEntity;
images?: string[]; snsId: string;
time: string; type: number;
likes?: number;
comments?: number;
} }
// API响应类型 // API响应类型
@@ -39,60 +70,83 @@ interface PaginationParams {
// 模拟朋友圈数据 // 模拟朋友圈数据
const mockFriendsCircleData: FriendsCircleItem[] = [ const mockFriendsCircleData: FriendsCircleItem[] = [
{ {
id: "1", commentList: [
avatar: "", {
username: "我的朋友圈", commentArg: 2,
content: "", commentId1: 0,
time: "", commentId2: 35,
commentTime: 1758011325,
content: "测试评论",
nickName: "老坑爹- 解放双手,释放时间",
wechatId: "wxid_480es52qsj2812",
},
],
createTime: 1757258659,
likeList: [
{
createTime: 1757315556,
nickName: "老坑爹- 解放双手,释放时间",
wechatId: "wxid_480es52qsj2812",
},
],
momentEntity: {
content: "没看到血月[旺柴]",
createTime: 1757258659,
lat: 0,
lng: 0,
location: "",
objectType: 1,
picSize: 0,
resUrls: [
"https://ac-weremote-s2.oss-cn-shenzhen.aliyuncs.com/weremote/chat-logs/5E2C38F5A275450D935F3ECEC076124E/aa6d4c2f7b1fe24d04d34f4f409883e6/sns/wxid_480es52qsj2812/-3705790026851937712/-3705790026851937712-14740954047910318662.jpg",
],
snsId: "-3705790026851937712",
urls: ["/sns/3/3/snst_14740954047910318662"],
userName: "wxid_dlhi90odctcl22",
},
snsId: "-3705790026851937712",
type: 1,
}, },
{ {
id: "2", commentList: [],
avatar: "", createTime: 1757258600,
username: "朋友圈广场", likeList: [],
content: "", momentEntity: {
time: "", content:
"🎉🎊🎈欢迎小伙伴加入单群聊客宝地盘思慕斯蛋糕的小伙伴们的支持与信任!!!",
createTime: 1757258600,
lat: 0,
lng: 0,
location: "",
objectType: 1,
picSize: 0,
resUrls: ["/public/assets/face/1.png"],
snsId: "-3705790026851937713",
urls: ["/sns/3/3/snst_14740954047910318663"],
userName: "wxid_dlhi90odctcl23",
},
snsId: "-3705790026851937713",
type: 1,
}, },
{ {
id: "3", commentList: [],
avatar: "/public/assets/face/1.png", createTime: 1757258500,
username: "老坑爹-解放双手,释放时间", likeList: [],
content: momentEntity: {
"🎉🎊🎈欢迎小伙伴加入单群聊客宝地盘思慕斯蛋糕的小伙伴们的支持与信任!!!", content: "一整年卡1好的产品有用户的好评是买卖说的再多不如用户的有说服力",
images: ["/public/assets/face/1.png"], createTime: 1757258500,
time: "2025年9月16日 13:48", lat: 0,
likes: 0, lng: 0,
comments: 0, location: "",
}, objectType: 1,
{ picSize: 0,
id: "4", resUrls: ["/public/assets/face/1.png"],
avatar: "/public/assets/face/1.png", snsId: "-3705790026851937714",
username: "老坑爹-解放双手,释放时间", urls: ["/sns/3/3/snst_14740954047910318664"],
content: "一整年卡1好的产品有用户的好评是买卖说的再多不如用户的有说服力", userName: "wxid_dlhi90odctcl24",
images: ["/public/assets/face/1.png"], },
time: "2025年9月16日 11:33", snsId: "-3705790026851937714",
likes: 0, type: 1,
comments: 0,
},
{
id: "5",
avatar: "/public/assets/face/1.png",
username: "老坑爹-解放双手,释放时间",
content:
"两个小时637朵卡今天的努力也是给我自己最好的礼物🎁坚持就是胜利第二年开干。",
images: ["/public/assets/face/1.png"],
time: "2025年9月16日 11:03",
likes: 0,
comments: 0,
},
{
id: "6",
avatar: "/public/assets/face/1.png",
username: "老坑爹-解放双手,释放时间",
content: "老坑爹如果不幸苦,没有品质保障,客户会无限复购?",
images: ["/public/assets/face/1.png"],
time: "2025年9月16日 10:33",
likes: 0,
comments: 0,
}, },
]; ];
@@ -118,9 +172,9 @@ const FriendsCircle: React.FC = () => {
const { pageNum, pageSize, type } = params; const { pageNum, pageSize, type } = params;
const startIndex = (pageNum - 1) * pageSize; const startIndex = (pageNum - 1) * pageSize;
// 使用原有的模拟数据 // 使用模拟数据
const allData = mockFriendsCircleData.slice(2); // 排除前两个特殊项 const allData = mockFriendsCircleData;
const typeData = type === "my" ? allData.slice(0, 2) : allData.slice(2); const typeData = type === "my" ? allData.slice(0, 1) : allData;
const paginatedData = typeData.slice(startIndex, startIndex + pageSize); const paginatedData = typeData.slice(startIndex, startIndex + pageSize);
return { return {
@@ -222,26 +276,57 @@ const FriendsCircle: React.FC = () => {
console.log("评论:", id); console.log("评论:", id);
}; };
// 格式化时间戳
const formatTime = (timestamp: number) => {
const date = new Date(timestamp * 1000);
return date.toLocaleString("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
});
};
// 获取用户昵称
const getUserNickName = (item: FriendsCircleItem) => {
// 优先从点赞列表或评论列表中获取昵称
if (item.likeList.length > 0) {
return item.likeList[0].nickName;
}
if (item.commentList.length > 0) {
return item.commentList[0].nickName;
}
return item.momentEntity.userName;
};
const renderNormalItem = (item: FriendsCircleItem, isNotMy?: boolean) => { const renderNormalItem = (item: FriendsCircleItem, isNotMy?: boolean) => {
const nickName = getUserNickName(item);
const content = item.momentEntity.content;
const images = item.momentEntity.resUrls;
const time = formatTime(item.createTime);
const likesCount = item.likeList.length;
const commentsCount = item.commentList.length;
return ( return (
<div className={styles.circleItem}> <div className={styles.circleItem}>
{isNotMy && ( {isNotMy && (
<div className={styles.avatar}> <div className={styles.avatar}>
<Avatar size={36} shape="square" src={item.avatar} /> <Avatar size={36} shape="square" src="/public/assets/face/1.png" />
</div> </div>
)} )}
<div className={styles.itemWrap}> <div className={styles.itemWrap}>
<div className={styles.itemHeader}> <div className={styles.itemHeader}>
<div className={styles.userInfo}> <div className={styles.userInfo}>
<div className={styles.username}>{item.username}</div> <div className={styles.username}>{nickName}</div>
</div> </div>
</div> </div>
<div className={styles.itemContent}> <div className={styles.itemContent}>
<div className={styles.contentText}>{item.content}</div> <div className={styles.contentText}>{content}</div>
{item.images && item.images.length > 0 && ( {images && images.length > 0 && (
<div className={styles.imageContainer}> <div className={styles.imageContainer}>
{item.images.map((image, index) => ( {images.map((image, index) => (
<img <img
key={index} key={index}
src={image} src={image}
@@ -251,28 +336,74 @@ const FriendsCircle: React.FC = () => {
</div> </div>
)} )}
<div className={styles.blueLink}></div> {images && images.length > 0 && (
<div className={styles.blueLink}></div>
)}
</div> </div>
<div className={styles.itemFooter}> <div className={styles.itemFooter}>
<div className={styles.timeInfo}>{item.time}</div> <div className={styles.timeInfo}>{time}</div>
<div className={styles.actions}> <div className={styles.actions}>
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<HeartOutlined />} icon={<HeartOutlined />}
onClick={() => handleLike(item.id)} onClick={() => handleLike(item.snsId)}
className={styles.actionButton} className={styles.actionButton}
/> >
{likesCount > 0 && <span>{likesCount}</span>}
</Button>
<Button <Button
type="text" type="text"
size="small" size="small"
icon={<MessageOutlined />} icon={<MessageOutlined />}
onClick={() => handleComment(item.id)} onClick={() => handleComment(item.snsId)}
className={styles.actionButton} className={styles.actionButton}
/> >
{commentsCount > 0 && <span>{commentsCount}</span>}
</Button>
</div> </div>
</div> </div>
{/* 点赞和评论区域 */}
{(item.likeList.length > 0 || item.commentList.length > 0) && (
<div className={styles.interactionArea}>
{/* 点赞列表 */}
{item.likeList.length > 0 && (
<div className={styles.likeArea}>
<HeartOutlined className={styles.likeIcon} />
<span className={styles.likeList}>
{item.likeList.map((like, index) => (
<span key={like.wechatId}>
{like.nickName}
{index < item.likeList.length - 1 && "、"}
</span>
))}
</span>
</div>
)}
{/* 评论列表 */}
{item.commentList.length > 0 && (
<div className={styles.commentArea}>
{item.commentList.map(comment => (
<div
key={`${comment.wechatId}-${comment.commentTime}`}
className={styles.commentItem}
>
<span className={styles.commentUser}>
{comment.nickName}
</span>
<span className={styles.commentSeparator}>: </span>
<span className={styles.commentContent}>
{comment.content}
</span>
</div>
))}
</div>
)}
</div>
)}
</div> </div>
</div> </div>
); );
@@ -284,7 +415,7 @@ const FriendsCircle: React.FC = () => {
{myCircleData.length > 0 ? ( {myCircleData.length > 0 ? (
<> <>
{myCircleData.map(item => ( {myCircleData.map(item => (
<div key={item.id} className={styles.itemWrapper}> <div key={item.snsId} className={styles.itemWrapper}>
{renderNormalItem(item, false)} {renderNormalItem(item, false)}
</div> </div>
))} ))}
@@ -317,7 +448,7 @@ const FriendsCircle: React.FC = () => {
{squareData.length > 0 ? ( {squareData.length > 0 ? (
<> <>
{squareData.map(item => ( {squareData.map(item => (
<div key={item.id} className={styles.itemWrapper}> <div key={item.snsId} className={styles.itemWrapper}>
{renderNormalItem(item, true)} {renderNormalItem(item, true)}
</div> </div>
))} ))}