Directorio de artículos
Efecto de interfaz
【ilustrar】
- Las imágenes de los productos en la interfaz son de Xianyu, si hay alguna infracción, contáctenos para eliminarlas.
- Con respecto a la implementación de la página de clasificación de productos, búsquela en mi serie de artículos Uniapp.
- Con respecto a la implementación de botones flotantes en la página, búsquelo en mi serie de artículos Uniapp.
Implementación de interfaz
herramienta js
La función de esta clase de herramienta es calcular la relación de aspecto de la imagen dada la dirección URL de una imagen. El propósito de calcular la relación de aspecto es permitir que la imagen se muestre en una proporción normal.
/**
* 获取uuid
*/
export default {
/**
* 获取高宽比 乘以 100%
*/
getAspectRatio(url) {
uni.getImageInfo({
src: url,
success: function(res) {
let aspectRatio = res.height * 100.0 / res.width;
// console.log("aspectRatio:" + aspectRatio);
return aspectRatio + "%";
}
});
},
}
página
página delantera
<template>
<view class="content">
<view style="display: flex;align-items: center;">
<u-search placeholder="请输入商品名称" v-model="searchForm.keyword" @search="listProductVo" :showAction="false"
:clearabled="true"></u-search>
<text class="iconfont" style="font-size: 35px;" @click="selectCategory()"></text>
</view>
<u-row customStyle="margin-top: 10px" gutter="10" align="start" v-if="productList[0].length>0&&loadData==false">
<u-col span="6" class="col" v-for="(data,index) in productList" :key="index">
<view class="productVoItem" v-for="(productVo,index1) in data" :key="index1"
@click="seeProductDetail(productVo)">
<u--image v-if="productVo.picList!=null&&productVo.picList.length>0" :showLoading="true"
:src="productVo.picList[0]" width="100%" :height="getAspectRatio(productVo.picList[0])"
radius="10" mode="widthFix"></u--image>
<!-- <u--image v-else :showLoading="true" :src="src" @click="click"></u--image> -->
<view class="productMes">
<text class="productName">【{
{productVo.name}}】</text>
<text>
{
{productVo.description==null?'':productVo.description}}
</text>
</view>
<view style="display: flex;align-items: center;">
<!-- 现价 -->
<view class="price">¥<text class="number">{
{productVo.price}}</text>/{
{productVo.unit}}</view>
<view style="width: 10px;"></view>
<!-- 原价 -->
<view class="originPrice">¥{
{productVo.originalPrice}}/{
{productVo.unit}}
</view>
</view>
<view style="display: flex;align-items: center;">
<u--image :src="productVo.avatar" width="20" height="20" shape="circle"></u--image>
<view style="width: 10px;"></view>
<view> {
{productVo.nickname}}</view>
</view>
</view>
</u-col>
</u-row>
<u-empty v-if="productList[0].length==0&&loadData==false" mode="data" texColor="#ffffff" iconSize="180"
iconColor="#D7DEEB" text="所选择的分类没有对应的商品,请重新选择" textColor="#D7DEEB" textSize="18" marginTop="30">
</u-empty>
<view style="margin-top: 20px;" v-if="loadData==true">
<u-skeleton :loading="true" :animate="true" rows="10"></u-skeleton>
</view>
<!-- 浮动按钮 -->
<FloatButton @click="cellMyProduct()">
<u--image :src="floatButtonPic" shape="circle" width="60px" height="60px"></u--image>
</FloatButton>
</view>
</template>
<script>
import FloatButton from "@/components/FloatButton/FloatButton.vue";
import {
listProductVo
} from "@/api/market/prodct.js";
import pictureApi from "@/utils/picture.js";
export default {
components: {
FloatButton
},
onShow: function() {
let categoryNameList = uni.getStorageSync("categoryNameList");
if (categoryNameList) {
this.categoryNameList = categoryNameList;
this.searchForm.productCategoryId = uni.getStorageSync("productCategoryId");
this.searchForm.keyword = this.getCategoryLayerName(this.categoryNameList);
uni.removeStorageSync("categoryNameList");
uni.removeStorageSync("productCategoryId");
this.listProductVo();
}
},
data() {
return {
title: 'Hello',
// 浮动按钮的图片
floatButtonPic: require("@/static/cellLeaveUnused.png"),
searchForm: {
// 商品搜索关键词
keyword: "",
productCategoryId: undefined
},
productList: [
[],
[]
],
loadData: false,
}
},
onLoad() {
},
created() {
this.listProductVo();
},
methods: {
/**
* 查询商品vo集合
*/
listProductVo() {
this.loadData = true;
listProductVo(this.searchForm).then(res => {
this.loadData = false;
// console.log("listProductVo:" + JSON.stringify(res))
let productVoList = res.rows;
this.productList = [
[],
[]
];
for (var i = 0; i < productVoList.length; i++) {
if (i % 2 == 0) {
// 第一列数据
this.productList[0].push(productVoList[i]);
} else {
// 第二列数据
this.productList[1].push(productVoList[i]);
}
}
})
},
/**
* 跳转到卖闲置页面
*/
cellMyProduct() {
console.log("我要卖闲置");
uni.navigateTo({
url: "/pages/sellMyProduct/sellMyProduct"
})
},
/**
* 获取高宽比 乘以 100%
*/
getAspectRatio(url) {
return pictureApi.getAspectRatio(url);
},
/**
* 选择分类
*/
selectCategory() {
uni.navigateTo({
url: "/pages/sellMyProduct/selectCategory"
})
},
/**
* 获取商品名称
*/
getCategoryLayerName() {
let str = '';
for (let i = 0; i < this.categoryNameList.length - 1; i++) {
str += this.categoryNameList[i] + '/';
}
return str + this.categoryNameList[this.categoryNameList.length - 1];
},
/**
* 查看商品的详情
*/
seeProductDetail(productVo) {
// console.log("productVo:"+JSON.stringify(productVo))
uni.navigateTo({
url: "/pages/product/detail?productVo=" + encodeURIComponent(JSON.stringify(productVo))
})
}
}
}
</script>
<style lang="scss">
.content {
padding: 20rpx;
.col {
width: 50%;
}
.productVoItem {
margin-bottom: 20px;
.productMes {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
/* 显示2行 */
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
.productName {
font-weight: bold;
}
}
.price {
color: #ff0000;
font-weight: bold;
.number {
font-size: 22px;
}
}
.originPrice {
color: #A2A2A2;
font-size: 15px;
// 给文字添加中划线
text-decoration: line-through;
}
}
}
</style>
Deje que el texto muestre solo dos líneas.
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
/* 显示2行 */
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
Objeto de entrega de salto de ruta
Debido a que se ha consultado mucha información sobre el producto en la página de inicio. Cuando hace clic para ver los detalles del producto, no es necesario volver a consultar mucha información. Puede transferir directamente la información conocida sobre el producto a la nueva página. a través del enrutamiento Cuando necesita prestar atención, antes de pasar un objeto como parámetro, el objeto debe codificarse.
uni.navigateTo({
url: "/pages/product/detail?productVo=" + encodeURIComponent(JSON.stringify(productVo))
})
Mostrar elementos en dos columnas
En primer lugar, los productos consultados se dividen en dos grupos.
let productVoList = res.rows;
this.productList = [
[],
[]
];
for (var i = 0; i < productVoList.length; i++) {
if (i % 2 == 0) {
// 第一列数据
this.productList[0].push(productVoList[i]);
} else {
// 第二列数据
this.productList[1].push(productVoList[i]);
}
}
Luego, simplemente use el diseño de filas y columnas en el diseño, es decir, use una fila y dos columnas para mostrar la información del producto.
Utilice un guión para tachar el precio original.
// 给文字添加中划线
text-decoration: line-through;
extremo posterior
mercancías
controlador
/**
* 查询商品Vo列表
*/
@PreAuthorize("@ss.hasPermi('market:product:list')")
@PostMapping("/listProductVo")
@ApiOperation("获取商品列表")
public TableDataInfo listProductVo(@RequestBody ProductVo productVo) {
startPage();
if (productVo.getProductCategoryId() != null) {
// --if-- 当分类不为空的时候,只按照分类来搜索
productVo.setKeyword(null);
}
List<ProductVo> list = productService.selectProductVoList(productVo);
return getDataTable(list);
}
servicio
/**
* 查询商品Vo列表
*
* @param productVo
* @return
*/
@Override
public List<ProductVo> selectProductVoList(ProductVo productVo) {
// List<ProductVo> productVoList = new ArrayList<>();
List<ProductVo> productVoList = baseMapper.selectProductVoList(productVo);
///设置每个商品的图片
// 获取所有商品的id
List<Long> productIdList = productVoList.stream().map(item -> {
return item.getId();
}).collect(Collectors.toList());
// 查询出所有商品的图片
if (productIdList.size() > 0) {
List<Picture> pictureList = pictureService.selectPictureListByItemIdListAndType(productIdList, PictureType.PRODUCT.getType());
Map<Long, List<String>> itemIdAndPicList = new HashMap<>();
for (Picture picture : pictureList) {
if (!itemIdAndPicList.containsKey(picture.getItemId())) {
List<String> picList = new ArrayList<>();
picList.add(picture.getAddress());
itemIdAndPicList.put(picture.getItemId(), picList);
} else {
itemIdAndPicList.get(picture.getItemId()).add(picture.getAddress());
}
}
// 给每个商品设置图片
for (ProductVo vo : productVoList) {
vo.setPicList(itemIdAndPicList.get(vo.getId()));
}
}
return productVoList;
}
mapeador
void starNumDiffOne(@Param("productId") Long productId);
SQL
<select id="selectProductVoList" parameterType="ProductVo" resultMap="ProductVoResult">
SELECT
p.id,
p.NAME,
p.description,
p.original_price,
p.price,
p.product_category_id,
pc.NAME AS productCategoryName,
p.user_id,
u.user_name as username,
u.nick_name as nickname,
u.avatar as avatar,
p.reviewer_id,
u1.user_name as reviewerUserName,
p.fineness,
p.unit,
p.STATUS,
p.is_contribute,
p.functional_status,
p.brand_id,
b.NAME AS brandName
FROM
product AS p
LEFT JOIN product_category AS pc ON p.product_category_id = pc.id
LEFT JOIN brand AS b ON p.brand_id = b.id
LEFT JOIN sys_user AS u ON p.user_id = u.user_id
LEFT JOIN sys_user AS u1 ON p.reviewer_id = u1.user_id
<where>
<if test="keyword != null and keyword != ''">and p.name like concat('%', #{keyword}, '%')</if>
<if test="keyword != null and keyword != ''">or p.description like concat('%', #{keyword}, '%')</if>
<if test="productCategoryId != null and productCategoryId != ''">and p.product_category_id =
#{productCategoryId}
</if>
</where>
</select>
Otros artículos sobre el mismo proyecto.
Para ver otros artículos sobre este proyecto, consulte la introducción del proyecto [Easy Mini Program Project], la visualización de la página del mini programa y la colección de series de artículos.