优化流量池列表样式:重构样式文件,增加卡片样式和布局,提升视觉效果和用户体验;更新组件逻辑,简化代码结构,增强可维护性。
This commit is contained in:
@@ -1,65 +1,175 @@
|
||||
.listWrap {
|
||||
padding: 12px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.cardContent {
|
||||
/* 美团风格卡片样式 */
|
||||
.cardCompact {
|
||||
margin: 0 0 12px 0;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.cardBody {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* 左侧图片区域 */
|
||||
.imageBox {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
}
|
||||
.checkbox {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.cardWrap {
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||
margin-bottom: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin-bottom: 12px;
|
||||
/* 右侧内容区域 */
|
||||
.contentArea {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 标题行 */
|
||||
.titleRow {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.3;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
margin: 6px 0 4px 0;
|
||||
/* 右侧标签区域 */
|
||||
.rightTags {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.count {
|
||||
font-size: 13px;
|
||||
color: #1677ff;
|
||||
.deliveryTag {
|
||||
background: #fff7e6;
|
||||
color: #d46b08;
|
||||
font-size: 10px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #ffd591;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
.timeTag {
|
||||
color: #ff6b35;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
/* 评分和销售信息 */
|
||||
.ratingRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.rating {
|
||||
color: #ff6b35;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sales {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
/* 配送信息 */
|
||||
.deliveryInfo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 11px;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
/* 中间标签 */
|
||||
.middleTag {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
margin: 16px 0;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.pagination button {
|
||||
background: #f5f5f5;
|
||||
border: none;
|
||||
.highScoreTag {
|
||||
background: linear-gradient(135deg, #ff6b35, #ff8c42);
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
padding: 4px 12px;
|
||||
color: #1677ff;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.pagination button:disabled {
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
/* 底部按钮区域 */
|
||||
.bottomActions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.dineInBtn {
|
||||
background: transparent;
|
||||
border: 1px solid #52c41a;
|
||||
color: #52c41a;
|
||||
font-size: 11px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.couponBtn {
|
||||
background: linear-gradient(135deg, #ff6b35, #ff8c42);
|
||||
color: white;
|
||||
font-size: 11px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.couponText {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,8 @@ import {
|
||||
SearchOutlined,
|
||||
ReloadOutlined,
|
||||
PlusOutlined,
|
||||
RightOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Input, Button, Pagination, Card, Tag } from "antd";
|
||||
import { Input, Button, Pagination, Card } from "antd";
|
||||
import styles from "./index.module.scss";
|
||||
import { Empty } from "antd-mobile";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@@ -57,6 +56,31 @@ const TrafficPoolList: React.FC = () => {
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const handleRefresh = () => {
|
||||
setPage(1);
|
||||
// 触发数据重新获取
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const params = {
|
||||
page: 1,
|
||||
pageSize,
|
||||
keyword: search,
|
||||
};
|
||||
|
||||
const res: PackageList = await getPackage(params);
|
||||
setList(res?.list || []);
|
||||
setTotal(res?.total || 0);
|
||||
} catch (error) {
|
||||
console.error("获取列表失败:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
@@ -114,7 +138,7 @@ const TrafficPoolList: React.FC = () => {
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => setPage(1)}
|
||||
onClick={handleRefresh}
|
||||
loading={loading}
|
||||
size="large"
|
||||
icon={<ReloadOutlined />}
|
||||
@@ -140,127 +164,68 @@ const TrafficPoolList: React.FC = () => {
|
||||
) : (
|
||||
<div>
|
||||
{list.map(item => (
|
||||
<Card
|
||||
<div
|
||||
key={item.id}
|
||||
className={styles.cardCompact}
|
||||
onClick={() => {
|
||||
// 进入分组管理
|
||||
navigate(`/mine/traffic-pool/group/${item.id}`);
|
||||
}}
|
||||
>
|
||||
<div style={{ display: "flex", alignItems: "flex-start" }}>
|
||||
{/* 分组图标 */}
|
||||
<div className={styles.cardBody}>
|
||||
{/* 左侧图片区域(优先展示 pic,缺省时使用假头像) */}
|
||||
<div
|
||||
style={{
|
||||
width: "48px",
|
||||
height: "48px",
|
||||
borderRadius: "8px",
|
||||
background: getGroupColor(item.type),
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
fontSize: item.type === 0 ? "18px" : "24px",
|
||||
fontWeight: item.type === 0 ? "bold" : "normal",
|
||||
color: item.type === 0 ? "#333" : "inherit",
|
||||
marginRight: "12px",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
className={styles.imageBox}
|
||||
style={{ background: getGroupColor(item.type) }}
|
||||
>
|
||||
{getGroupIcon(item.type, item.name)}
|
||||
</div>
|
||||
|
||||
{/* 分组信息 */}
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<div
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
fontWeight: "bold",
|
||||
marginBottom: "4px",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
color: "#666",
|
||||
marginBottom: "8px",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
}}
|
||||
>
|
||||
{item.description}
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
fontSize: "14px",
|
||||
color: "#333",
|
||||
marginBottom: "4px",
|
||||
}}
|
||||
>
|
||||
{item.num}人
|
||||
</div>
|
||||
|
||||
{/* RFM数据 */}
|
||||
{item.RFM > 0 ? (
|
||||
<div
|
||||
{item.pic ? (
|
||||
<img
|
||||
src={item.pic}
|
||||
alt={item.name}
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
color: "#666",
|
||||
marginBottom: "4px",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "cover",
|
||||
}}
|
||||
>
|
||||
RFM: {item.RFM} | R:{item.R} F:{item.F} M:{item.M}
|
||||
</div>
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
<span
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
color: "#999",
|
||||
marginBottom: "4px",
|
||||
fontSize: 24,
|
||||
fontWeight: "bold",
|
||||
color: "#333",
|
||||
}}
|
||||
>
|
||||
暂无RFM数据
|
||||
</div>
|
||||
{getGroupIcon(item.type, item.name)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* 标签和创建时间 */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Tag
|
||||
color={item.type === 4 ? "purple" : "blue"}
|
||||
style={{ fontSize: "10px", padding: "2px 6px" }}
|
||||
>
|
||||
{item.type === 4 ? "自定义" : "系统分组"}
|
||||
</Tag>
|
||||
<div style={{ fontSize: "10px", color: "#999" }}>
|
||||
{item.createTime}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右侧箭头 */}
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "8px",
|
||||
color: "#ccc",
|
||||
fontSize: "16px",
|
||||
}}
|
||||
>
|
||||
<RightOutlined />
|
||||
{/* 右侧仅展示选中字段 */}
|
||||
<div className={styles.contentArea}>
|
||||
{/* 标题与人数 */}
|
||||
<div className={styles.titleRow}>
|
||||
<div className={styles.title}>{item.name}</div>
|
||||
<div className={styles.timeTag}>共{item.num}人</div>
|
||||
</div>
|
||||
|
||||
{/* RFM 汇总 */}
|
||||
<div className={styles.ratingRow}>
|
||||
<span className={styles.rating}>RFM:{item.RFM}</span>
|
||||
<span className={styles.sales}>
|
||||
R:{item.R} F:{item.F} M:{item.M}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* 类型与创建时间 */}
|
||||
<div className={styles.deliveryInfo}>
|
||||
<span>
|
||||
类型: {item.type === 0 ? "自定义" : "系统分组"}
|
||||
</span>
|
||||
<span>创建:{item.createTime}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user