Commit c7fd6aad by lijiabin

【需求 17679】 feat: 优化完成积分商城页面

parent 22115883
import service from '@/utils/request/index' import service from '@/utils/request/index'
import type { BackendServicePageResult, PageSearchParams } from '@/utils/request/types' import type { BackendServicePageResult, PageSearchParams } from '@/utils/request/types'
import type { ShopItem, YaBiData } from './types' import type { ExchangeGoodsParams, ShopItemDto, ShopSearchParams, YaBiData } from './types'
/** /**
* 积分商城列表 * 积分商城列表
*/ */
export const getShopItemList = (data: PageSearchParams) => { export const getShopItemList = (data: ShopSearchParams) => {
return service.request<BackendServicePageResult<ShopItem>>({ return service.request<BackendServicePageResult<ShopItemDto>>({
url: '/api/culture/shop/item/pageList', url: '/api/culture/shop/item/pageList',
method: 'POST', method: 'POST',
data, data,
...@@ -33,3 +33,14 @@ export const getYaBiData = () => { ...@@ -33,3 +33,14 @@ export const getYaBiData = () => {
data: {}, data: {},
}) })
} }
/**
* 兑换商品
*/
export const exchangeGoods = (data: ExchangeGoodsParams) => {
return service.request({
url: '/api/culture/shop/item/exchange',
method: 'POST',
data,
})
}
import type { PageSearchParams } from '@/utils/request/types'
import { ShopGoodsTypeEnum } from '@/constants'
/**
* 请求参数类型
*/
export interface ShopSearchParams extends PageSearchParams {
region: string
itemType: ShopGoodsTypeEnum
}
/** /**
* 积分商城商品类型 * 积分商城商品类型
*/ */
export interface ShopItem { export interface ShopItemDto {
id: number id: number
description: string description: string
enable: number enable: number
...@@ -22,3 +33,12 @@ export interface ShopItem { ...@@ -22,3 +33,12 @@ export interface ShopItem {
export interface YaBiData { export interface YaBiData {
currentValue: number currentValue: number
} }
/**
* 兑换商品请求参数类型
*/
export interface ExchangeGoodsParams {
itemId: number
num: number
deliveryInfo?: string
}
...@@ -12,12 +12,14 @@ type TabsProps = { ...@@ -12,12 +12,14 @@ type TabsProps = {
type TabsEmits = { type TabsEmits = {
'update:modelValue': [TypeOfValue] 'update:modelValue': [TypeOfValue]
change: [TypeOfValue] change: [TypeOfValue]
setA: [string]
} }
const BASE_TAB_CALASSES = const BASE_TAB_CALASSES =
'tab-item cursor-pointer bg-white rounded-lg flex items-center justify-center px-4 py-2 min-w-20 h-8 transition-all duration-300 hover:shadow-md hover:bg-#D9EFFD/20 hover:text-#000/80 hover:-translate-y-0.5 active:scale-95 font-medium text-14px text-#000/55 shadow-sm' 'tab-item cursor-pointer bg-#d9effd/80 rounded-lg flex items-center justify-center px-4 py-2 min-w-20 h-8 transition-all duration-300 hover:shadow-md hover:bg-blue-100 hover:text-blue-700 hover:-translate-y-0.5 active:scale-95 font-medium text-14px text-gray-700 shadow-sm border border-blue-100'
const ACTIVE_TAB_CLASSES = ' !bg-#D9EFFD shadow-lg transform -translate-y-1 !text-#000'
const ACTIVE_TAB_CLASSES =
' !bg-gradient-to-r !from-[#3b82f6]/90 !to-[#60a5fa]/90 !shadow-lg transform -translate-y-1 !text-white !border-transparent'
// <div class="left flex gap-3"> 未设置排列方式 需要给父组件设置 flex布局 // <div class="left flex gap-3"> 未设置排列方式 需要给父组件设置 flex布局
export default function Tabs({ tabs, modelValue }: TabsProps, { emit }: SetupContext<TabsEmits>) { export default function Tabs({ tabs, modelValue }: TabsProps, { emit }: SetupContext<TabsEmits>) {
return tabs.map((tab) => ( return tabs.map((tab) => (
......
...@@ -2,85 +2,84 @@ ...@@ -2,85 +2,84 @@
* 确认兑换商品的弹窗内容 * 确认兑换商品的弹窗内容
*/ */
import { ShopGoodsTypeEnum, regionListOptions } from '@/constants' import { ShopGoodsTypeEnum, regionListOptions } from '@/constants'
import type { ShopItem } from '@/api' import type { ExchangeGoodsParams, ShopItemDto } from '@/api'
import type { SetupContext } from 'vue' import type { SetupContext } from 'vue'
import ask from '@/assets/img/culture/ask.png' import ask from '@/assets/img/culture/ask.png'
type ExchangeContentProps = { type ExchangeContentProps = {
item: ShopItem item: ShopItemDto
type: ShopGoodsTypeEnum modelValue: ExchangeGoodsParams
modelValue: {
region: string
num: number
}
} }
type ExchangeContentEvents = { type ExchangeContentEvents = {
'update:modelValue'(data: { region: string; num: number }): void 'update:modelValue'(data: ExchangeGoodsParams): void
} }
export default function ExchangeContent( export default function ExchangeContent(
{ item, modelValue, type }: ExchangeContentProps, { item, modelValue }: ExchangeContentProps,
context: SetupContext<ExchangeContentEvents>, context: SetupContext<ExchangeContentEvents>,
) { ) {
return ( return (
<div class="exchange-content py-6"> <div class="exchange-content py-6 px-4">
{/* 商品图片区域 - 同上 */} {/* 商品图片区域 */}
<div class="flex justify-center mb-8"> <div class="flex justify-center mb-8">
<div class="relative"> <div class="relative">
<div class="w-32 h-32 bg-gradient-to-br from-orange-100 to-pink-100 rounded-3xl flex items-center justify-center"> <div class="w-32 h-32 bg-gradient-to-br from-orange-100 to-pink-100 rounded-3xl flex items-center justify-center shadow-lg">
<div class="w-20 h-20 bg-white rounded-2xl flex items-center justify-center shadow-sm"> <div class="w-20 h-20 bg-white rounded-2xl flex items-center justify-center shadow-sm">
<img src={ask} alt={item.name} class="w-16 h-16 object-contain" /> <img src={ask} alt={item.name} class="w-16 h-16 object-contain" />
</div> </div>
</div> </div>
<div class="absolute -top-2 -right-2 w-7 h-7 bg-blue-500 rounded-full flex items-center justify-center"> <div class="absolute -top-2 -right-2 w-7 h-7 bg-blue-500 rounded-full flex items-center justify-center shadow-md">
<span class="text-white text-sm font-medium">6</span> <span class="text-white text-sm font-medium">6</span>
</div> </div>
</div> </div>
</div> </div>
{/* 商品信息 */} {/* 商品信息 */}
<div class="space-y-4 mb-8"> <div class="space-y-3 mb-8">
<div class="flex items-center justify-center gap-3"> <div class="flex items-center gap-3 px-4">
<div class="w-1.5 h-1.5 bg-gray-400 rounded-full"></div> <div class="w-1.5 h-1.5 bg-gray-400 rounded-full flex-shrink-0"></div>
<span class="text-gray-600 text-sm">名称:</span> <span class="text-gray-600 text-sm min-w-12">名称:</span>
<span class="font-medium text-gray-900">{item.name}</span> <span class="font-medium text-gray-900 flex-1">{item.name}</span>
</div> </div>
<div class="flex items-center justify-center gap-3"> <div class="flex items-center gap-3 px-4">
<div class="w-1.5 h-1.5 bg-orange-400 rounded-full"></div> <div class="w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0"></div>
<span class="text-gray-600 text-sm">积分:</span> <span class="text-gray-600 text-sm min-w-12">积分:</span>
<span class="font-semibold text-orange-500 text-lg">{item.price}YA币</span> <span class="font-semibold text-orange-500 text-lg">{item.price}YA币</span>
</div> </div>
</div> </div>
{/* 办公点选择和数量 */}
{item.itemType === ShopGoodsTypeEnum.REAL_GOODS && (
<div class=" rounded-2xl px-5 mx-2 space-y-4">
{/* 办公点选择 */} {/* 办公点选择 */}
{type === ShopGoodsTypeEnum.REAL_GOODS && ( <div>
<div class="mb-6"> <label class="text-gray-700 text-sm font-medium mb-2 block">办公点</label>
<div class="text-center text-gray-700 text-sm font-medium mb-4">选择办公点:</div>
<div class=" w-full">
<el-select <el-select
modelValue={modelValue.region} modelValue={modelValue.deliveryInfo}
onUpdate:modelValue={(value: string) => onUpdate:modelValue={(value: string) =>
context.emit('update:modelValue', { ...modelValue, region: value }) context.emit('update:modelValue', { ...modelValue, deliveryInfo: value })
} }
placeholder="请选择办公点" placeholder="请选择办公点"
class="w-full"
> >
{regionListOptions.map((office) => ( {regionListOptions.map((office) => (
<el-option <el-option key={office.value} label={office.label} value={office.value} />
class="text-center w-full"
key={office.value}
label={office.label}
value={office.value}
/>
))} ))}
</el-select> </el-select>
选择数量 </div>
{/* 数量选择 */}
<div>
<label class="text-gray-700 text-sm font-medium mb-2 block">选择数量</label>
<el-input-number <el-input-number
min={1}
modelValue={modelValue.num} modelValue={modelValue.num}
onUpdate:modelValue={(value: number) => onUpdate:modelValue={(value: number) =>
context.emit('update:modelValue', { ...modelValue, num: value }) context.emit('update:modelValue', { ...modelValue, num: value })
} }
placeholder="请选择数量" class="w-full"
controls-position="right"
/> />
</div> </div>
</div> </div>
...@@ -91,19 +90,15 @@ export default function ExchangeContent( ...@@ -91,19 +90,15 @@ export default function ExchangeContent(
ExchangeContent.props = { ExchangeContent.props = {
item: { item: {
type: Object as PropType<ShopItem>, type: Object as PropType<ShopItemDto>,
required: true, required: true,
}, },
modelValue: { modelValue: {
type: Object as PropType<{ region: string; num: number }>, type: Object as PropType<ExchangeGoodsParams>,
required: true,
},
type: {
type: Number,
required: true, required: true,
}, },
} }
ExchangeContent.emits = { ExchangeContent.emits = {
'update:modelValue': (value: { region: string; num: number }) => value, 'update:modelValue': (value: ExchangeGoodsParams) => value,
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment