feat(shop): 添加文章详情页面并优化购物车样式

- 新增文章详情页面组件,用于显示文章内容
- 优化购物车页面样式,增加空购物车状态的透明背景
- 添加多个购物相关 API 接口,包括优惠券、订单等
- 更新环境配置,修改 API 基础 URL
- 调整发现页面布局,增加文章详情入口
This commit is contained in:
2025-08-13 01:37:15 +08:00
parent 1c2e00b7ba
commit 9dabda3d47
4 changed files with 381 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api/index';
import type { ShopArticle, ShopArticleParam } from './model';
/**
* 分页查询商品文章
*/
export async function pageShopArticle(params: ShopArticleParam) {
const res = await request.get<ApiResult<PageResult<ShopArticle>>>(
'/shop/shop-article/page',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询商品文章列表
*/
export async function listShopArticle(params?: ShopArticleParam) {
const res = await request.get<ApiResult<ShopArticle[]>>(
'/shop/shop-article',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加商品文章
*/
export async function addShopArticle(data: ShopArticle) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-article',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改商品文章
*/
export async function updateShopArticle(data: ShopArticle) {
const res = await request.put<ApiResult<unknown>>(
'/shop/shop-article',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除商品文章
*/
export async function removeShopArticle(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/shop/shop-article/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除商品文章
*/
export async function removeBatchShopArticle(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/shop/shop-article/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询商品文章
*/
export async function getShopArticle(id: number) {
const res = await request.get<ApiResult<ShopArticle>>(
'/shop/shop-article/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,125 @@
import type { PageParam } from '@/api/index';
/**
* 商品文章
*/
export interface ShopArticle {
// 文章ID
articleId?: number;
// 文章标题
title?: string;
// 文章类型 0常规 1视频
type?: number;
// 模型
model?: string;
// 详情页模板
detail?: string;
// 文章分类ID
categoryId?: number;
// 上级id, 0是顶级
parentId?: number;
// 话题
topic?: string;
// 标签
tags?: string;
// 封面图
image?: string;
// 封面图宽
imageWidth?: number;
// 封面图高
imageHeight?: number;
// 付费金额
price?: string;
// 开始时间
startTime?: string;
// 结束时间
endTime?: string;
// 来源
source?: string;
// 产品概述
overview?: string;
// 虚拟阅读量(仅用作展示)
virtualViews?: number;
// 实际阅读量
actualViews?: number;
// 评分
rate?: string;
// 列表显示方式(10小图展示 20大图展示)
showType?: number;
// 访问密码
password?: string;
// 可见类型 0所有人 1登录可见 2密码可见
permission?: number;
// 发布来源客户端 (APP、H5、小程序等)
platform?: string;
// 文章附件
files?: string;
// 视频地址
video?: string;
// 接受的文件类型
accept?: string;
// 经度
longitude?: string;
// 纬度
latitude?: string;
// 所在省份
province?: string;
// 所在城市
city?: string;
// 所在辖区
region?: string;
// 街道地址
address?: string;
// 点赞数
likes?: number;
// 评论数
commentNumbers?: number;
// 提醒谁看
toUsers?: string;
// 作者
author?: string;
// 推荐
recommend?: number;
// 报名人数
bmUsers?: number;
// 用户ID
userId?: number;
// 商户ID
merchantId?: number;
// 项目ID
projectId?: number;
// 语言
lang?: string;
// 关联默认语言的文章ID
langArticleId?: number;
// 是否自动翻译
translation?: string;
// 编辑器类型 0 Markdown编辑器 1 富文本编辑器
editor?: string;
// pdf文件地址
pdfUrl?: string;
// 版本号
version?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0已发布, 1待审核 2已驳回 3违规内容
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 商品文章搜索条件
*/
export interface ShopArticleParam extends PageParam {
articleId?: number;
keywords?: string;
}