feat(产品)
This commit is contained in:
parent
dbd3b1f839
commit
78d6d7df1f
|
@ -1,20 +1,69 @@
|
|||
<template>
|
||||
<pb-layout
|
||||
title="分类"
|
||||
navbar="normal"
|
||||
tabbar="/pages/index/category"
|
||||
:bgStyle="bgStyle"
|
||||
opacityBgUi="bg-white"
|
||||
color="black"
|
||||
>
|
||||
<p-empty icon="/static/soldout-empty.png" text="暂无内容" />
|
||||
</pb-layout>
|
||||
<pb-layout title="产品" navbar="normal" tabbar="/pages/index/product" :bgStyle="bgStyle" opacityBgUi="bg-white"
|
||||
color="black">
|
||||
|
||||
<view v-if="StaticRange.pagination.total > 0" class="goods-list ss-m-t-20">
|
||||
<view class="ss-p-l-20 ss-p-r-20" v-for="item in state.pagination.list" :key="item.id">
|
||||
<p-goods-column size="lg" :data="item" :topRadius="10" bottomRadius="10"
|
||||
@click="peach.$router.go('/pages/goods/index', { id: item.id })" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<uni-load-more v-if="StaticRange.pagination.total > 0" :status="StaticRange.loadStatus" :content-text="{
|
||||
contentdown: '上拉加载更多'
|
||||
}" @click="loadMore" />
|
||||
<p-empty v-if="StaticRange.pagination.total === 0" icon="/static/soldout-empty.png" text="暂无产品" />
|
||||
</pb-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import peach from '@/peach'
|
||||
import _ from 'lodash'
|
||||
import { resetPagination } from '@/peach/util'
|
||||
|
||||
const bgStyle = {
|
||||
backgroundImage: '',
|
||||
backgroundColor: '',
|
||||
description: '',
|
||||
backgroundImage: '',
|
||||
backgroundColor: '',
|
||||
description: '',
|
||||
}
|
||||
|
||||
const state = ref({
|
||||
pagination: {
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNo: 1,
|
||||
pageSize: 6
|
||||
}
|
||||
})
|
||||
|
||||
function emptyList() {
|
||||
resetPagination(state.value.pagination)
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
emptyList()
|
||||
getList()
|
||||
}
|
||||
|
||||
function getList() {
|
||||
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
if (state.value.loadStatus === 'noMore') {
|
||||
return
|
||||
}
|
||||
state.value.pagination.pageNo++
|
||||
getList()
|
||||
}
|
||||
|
||||
onLoad(async (options) => {
|
||||
getList()
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
loadMore()
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
<template>
|
||||
<view class="ss-goods-wrap">
|
||||
<view v-if="size === 'lg'" class="lg-goods-card ss-flex ss-col-stretch" :style="[elStyles]" @click="onClick">
|
||||
<image class="lg-img-box" :src="peach.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image>
|
||||
<view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ss-p-t-20">
|
||||
<view>
|
||||
<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="lg-goods-title ss-line-2"
|
||||
:style="[{ color: titleColor }]">
|
||||
{{ data.title || data.name }}
|
||||
</view>
|
||||
<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
|
||||
class="lg-goods-subtitle ss-m-t-10 ss-line-1"
|
||||
:style="[{ color: subTitleColor, background: subTitleBackground }]">
|
||||
{{ data.subtitle || data.introduction }}
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="ss-flex ss-col-bottom ss-m-t-10">
|
||||
<view v-if="goodsFields.price?.show" class="lg-goods-price ss-m-r-12 ss-flex ss-col-bottom font-OPPOSANS"
|
||||
:style="[{ color: goodsFields.price.color }]">
|
||||
<text class="ss-font-24">{{ priceUnit }}</text>
|
||||
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
|
||||
</view>
|
||||
<view
|
||||
v-if="(goodsFields.original_price?.show || goodsFields.marketPrice?.show) && (data.original_price > 0 || data.marketPrice > 0)"
|
||||
class="goods-origin-price ss-flex ss-col-bottom font-OPPOSANS" :style="[{ color: originPriceColor }]">
|
||||
<text class="price-unit ss-font-20">{{ priceUnit }}</text>
|
||||
<view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="ss-m-t-8 ss-flex ss-col-center ss-flex-wrap">
|
||||
<view class="sales-text">{{ salesAndStock }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<button>详情</button>
|
||||
<button>编辑</button>
|
||||
<button>删除</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { isArray } from 'lodash';
|
||||
import { fen2yuan, formatSales, formatStock } from '@/peach/hooks/useGoods';
|
||||
|
||||
const props = defineProps({
|
||||
goodsFields: {
|
||||
type: [Array, Object],
|
||||
default() {
|
||||
return {
|
||||
price: { show: true },
|
||||
stock: { show: true },
|
||||
name: { show: true },
|
||||
introduction: { show: true },
|
||||
marketPrice: { show: true },
|
||||
salesCount: { show: true }
|
||||
}
|
||||
}
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
topRadius: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
bottomRadius: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
priceUnit: {
|
||||
type: String,
|
||||
default: '¥',
|
||||
},
|
||||
titleColor: {
|
||||
type: String,
|
||||
default: '#333',
|
||||
},
|
||||
subTitleColor: {
|
||||
type: String,
|
||||
default: '#999999',
|
||||
},
|
||||
subTitleBackground: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
const emits = defineEmits(['click'])
|
||||
|
||||
function onClick() {
|
||||
emits('click')
|
||||
}
|
||||
|
||||
const elStyles = computed(() => {
|
||||
return {
|
||||
background: props.background,
|
||||
'border-top-left-radius': props.topRadius + 'px',
|
||||
'border-top-right-radius': props.topRadius + 'px',
|
||||
'border-bottom-left-radius': props.bottomRadius + 'px',
|
||||
'border-bottom-right-radius': props.bottomRadius + 'px',
|
||||
}
|
||||
})
|
||||
|
||||
// 格式化销量、库存信息
|
||||
const salesAndStock = computed(() => {
|
||||
let text = [];
|
||||
if (props.goodsFields.salesCount?.show) {
|
||||
text.push(formatSales(props.data.sales_show_type, props.data.salesCount));
|
||||
}
|
||||
if (props.goodsFields.stock?.show) {
|
||||
text.push(formatStock(props.data.stock_show_type, props.data.stock));
|
||||
}
|
||||
return text.join(' | ');
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.lg-goods-card {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
background-color: $white;
|
||||
height: 280rpx;
|
||||
|
||||
.lg-img-box {
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.lg-goods-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
// line-height: 36rpx;
|
||||
// width: 410rpx;
|
||||
}
|
||||
|
||||
.lg-goods-subtitle {
|
||||
font-size: 24rpx;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
// line-height: 30rpx;
|
||||
// width: 410rpx;
|
||||
}
|
||||
|
||||
.lg-goods-price {
|
||||
font-size: 30rpx;
|
||||
color: $red;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
|
||||
.buy-box {
|
||||
position: absolute;
|
||||
bottom: 20rpx;
|
||||
right: 20rpx;
|
||||
z-index: 2;
|
||||
width: 120rpx;
|
||||
height: 50rpx;
|
||||
background: linear-gradient(90deg, #fe8900, #ff5e00);
|
||||
border-radius: 25rpx;
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,33 @@
|
|||
import { ref } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
/**
|
||||
* 将分转成元
|
||||
*
|
||||
* @param price 分,例如说 100 分
|
||||
* @returns {string} 元,例如说 1.00 元
|
||||
*/
|
||||
export function fen2yuan(price) {
|
||||
return (price / 100.0).toFixed(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化销量
|
||||
* @param {'exact' | string} type 格式类型:exact=精确值,其它=大致数量
|
||||
* @param {number} num 销量
|
||||
* @return {string} 格式化后的销量字符串
|
||||
*/
|
||||
export function formatSales(type, num) {
|
||||
let prefix = type !== "exact" && num < 10 ? "销量" : "已售";
|
||||
return formatNum(prefix, type, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化库存
|
||||
* @param {'exact' | any} type 格式类型:exact=精确值,其它=大致数量
|
||||
* @param {number} num 销量
|
||||
* @return {string} 格式化后的销量字符串
|
||||
*/
|
||||
export function formatStock(type, num) {
|
||||
return formatNum("库存", type, num);
|
||||
}
|
Loading…
Reference in New Issue