Browse Source
- 新增文章详情页面组件,用于显示文章内容 - 优化购物车页面样式,增加空购物车状态的透明背景 - 添加多个购物相关 API 接口,包括优惠券、订单等 - 更新环境配置,修改 API 基础 URL - 调整发现页面布局,增加文章详情入口master
4 changed files with 381 additions and 0 deletions
@ -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)); |
||||
|
} |
@ -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; |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
export default definePageConfig({ |
||||
|
navigationBarTitleText: '商品文章管理', |
||||
|
navigationBarTextStyle: 'black' |
||||
|
}) |
@ -0,0 +1,151 @@ |
|||||
|
import {useState} from "react"; |
||||
|
import Taro, {useDidShow} from '@tarojs/taro' |
||||
|
import {Button, Cell, CellGroup, Space, Empty, ConfigProvider, Divider} from '@nutui/nutui-react-taro' |
||||
|
import {Dongdong, ArrowRight, CheckNormal, Checked} from '@nutui/icons-react-taro' |
||||
|
import {View} from '@tarojs/components' |
||||
|
import {ShopUserAddress} from "@/api/shop/shopUserAddress/model"; |
||||
|
import {listShopUserAddress, removeShopUserAddress, updateShopUserAddress} from "@/api/shop/shopUserAddress"; |
||||
|
|
||||
|
const Address = () => { |
||||
|
const [list, setList] = useState<ShopUserAddress[]>([]) |
||||
|
const [address, setAddress] = useState<ShopUserAddress>() |
||||
|
|
||||
|
const reload = () => { |
||||
|
listShopUserAddress({ |
||||
|
userId: Taro.getStorageSync('UserId') |
||||
|
}) |
||||
|
.then(data => { |
||||
|
setList(data || []) |
||||
|
// 默认地址
|
||||
|
setAddress(data.find(item => item.isDefault)) |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
Taro.showToast({ |
||||
|
title: '获取地址失败', |
||||
|
icon: 'error' |
||||
|
}); |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const onDefault = async (item: ShopUserAddress) => { |
||||
|
if (address) { |
||||
|
await updateShopUserAddress({ |
||||
|
...address, |
||||
|
isDefault: false |
||||
|
}) |
||||
|
} |
||||
|
await updateShopUserAddress({ |
||||
|
id: item.id, |
||||
|
isDefault: true |
||||
|
}) |
||||
|
Taro.showToast({ |
||||
|
title: '设置成功', |
||||
|
icon: 'success' |
||||
|
}); |
||||
|
reload(); |
||||
|
} |
||||
|
|
||||
|
const onDel = async (id?: number) => { |
||||
|
await removeShopUserAddress(id) |
||||
|
Taro.showToast({ |
||||
|
title: '删除成功', |
||||
|
icon: 'success' |
||||
|
}); |
||||
|
reload(); |
||||
|
} |
||||
|
|
||||
|
const selectAddress = async (item: ShopUserAddress) => { |
||||
|
if (address) { |
||||
|
await updateShopUserAddress({ |
||||
|
...address, |
||||
|
isDefault: false |
||||
|
}) |
||||
|
} |
||||
|
await updateShopUserAddress({ |
||||
|
id: item.id, |
||||
|
isDefault: true |
||||
|
}) |
||||
|
setTimeout(() => { |
||||
|
Taro.navigateBack() |
||||
|
},500) |
||||
|
} |
||||
|
|
||||
|
useDidShow(() => { |
||||
|
reload() |
||||
|
}); |
||||
|
|
||||
|
if (list.length == 0) { |
||||
|
return ( |
||||
|
<ConfigProvider> |
||||
|
<div className={'h-full flex flex-col justify-center items-center'} style={{ |
||||
|
height: 'calc(100vh - 300px)', |
||||
|
}}> |
||||
|
<Empty |
||||
|
style={{ |
||||
|
backgroundColor: 'transparent' |
||||
|
}} |
||||
|
description="您还没有地址哦" |
||||
|
/> |
||||
|
<Space> |
||||
|
<Button onClick={() => Taro.navigateTo({url: '/user/address/add'})}>新增地址</Button> |
||||
|
<Button type="success" fill="dashed" |
||||
|
onClick={() => Taro.navigateTo({url: '/user/address/wxAddress'})}>获取微信地址</Button> |
||||
|
</Space> |
||||
|
</div> |
||||
|
</ConfigProvider> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<CellGroup> |
||||
|
<Cell |
||||
|
onClick={() => Taro.navigateTo({url: '/user/address/wxAddress'})} |
||||
|
> |
||||
|
<div className={'flex justify-between items-center w-full'}> |
||||
|
<div className={'flex items-center gap-3'}> |
||||
|
<Dongdong className={'text-green-600'}/> |
||||
|
<div>获取微信地址</div> |
||||
|
</div> |
||||
|
<ArrowRight className={'text-gray-400'}/> |
||||
|
</div> |
||||
|
</Cell> |
||||
|
</CellGroup> |
||||
|
{list.map((item, _) => ( |
||||
|
<Cell.Group> |
||||
|
<Cell className={'flex flex-col gap-1'} onClick={() => selectAddress(item)}> |
||||
|
<View> |
||||
|
<View className={'font-medium text-sm'}>{item.name} {item.phone}</View> |
||||
|
</View> |
||||
|
<View className={'text-xs'}> |
||||
|
{item.province} {item.city} {item.region} {item.address} |
||||
|
</View> |
||||
|
</Cell> |
||||
|
<Cell |
||||
|
align="center" |
||||
|
title={ |
||||
|
<View className={'flex items-center gap-1'} onClick={() => onDefault(item)}> |
||||
|
{item.isDefault ? <Checked className={'text-green-600'} size={16}/> : <CheckNormal size={16}/>} |
||||
|
<View className={'text-gray-400'}>默认地址</View> |
||||
|
</View> |
||||
|
} |
||||
|
extra={ |
||||
|
<> |
||||
|
<View className={'text-gray-400'} onClick={() => onDel(item.id)}> |
||||
|
删除 |
||||
|
</View> |
||||
|
<Divider direction={'vertical'}/> |
||||
|
<View className={'text-gray-400'} |
||||
|
onClick={() => Taro.navigateTo({url: '/user/address/add?id=' + item.id})}> |
||||
|
修改 |
||||
|
</View> |
||||
|
</> |
||||
|
} |
||||
|
/> |
||||
|
</Cell.Group> |
||||
|
))} |
||||
|
</> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default Address; |
Loading…
Reference in new issue