B074-详情富文本 服务上下架 高级查询 分页 查看详情

news2024/12/23 17:58:56

目录

      • 服务详情修改优化
        • ProductServiceImpl
        • Product.vue
      • 详情数据-富文本-vue-quill-editor
        • 使用步骤
        • 测试
        • 图片的访问方式
        • 富文本集成fastDfs
      • 后台服务上下架(批量)
        • 前端开始
        • 后端完成
          • ProductController
          • ProductServiceImpl
          • ProductMapper
      • 前台展示上架
        • 前端开始
        • 后端完成
          • ProductQuery
          • ProductController
          • ProductMapper
          • 测试
        • 前端展示列表和图片
          • product.html
      • 服务高级查询
      • 分页
      • 查看详情
        • 跳转详情页
        • 数据展示后台接口
          • ProductController
          • ProductMapper
        • 前台展示
          • 导入vue和axios
          • 获取数据.js
          • 展示数据
            • 图片展示
            • 详情
            • 名称,售价,原价,销量
            • 切换图片js

服务详情修改优化

在这里插入图片描述

ProductServiceImpl

product后端保存操作修改

    @Override
    public void update(Product product) {
        ProductDetail detail = product.getDetail();
        if(detail !=null){
            if(detail.getId() !=null){
                productDetailMapper.update(detail);
            }else{
                productDetailMapper.save(detail);
            }
        }

        productMapper.update(product);
    }

Product.vue

显示新增界面清除页面缓存

			//显示新增界面
			handleAdd: function () {
				this.fileList = [];//清楚页面缓存数据
				this.productFormVisible = true;//显示新增弹出框
				this.productForm = {
					id: null,
					name: '',
					resources: '',
					saleprice: 0,
					costprice: 0,
					detail:{
						id:null,
						intro:'',
						orderNotice:''
					}
				};
			},

详情数据-富文本-vue-quill-editor

使用步骤

见文档

测试

在这里插入图片描述
在这里插入图片描述

图片的访问方式

1.链接访问,
2.页面本地存储二进制字节码,base64加密,长度很长不好保存到数据库,

富文本集成fastDfs

修改页面本地存储为链接存储,步骤见文档
结果:
在这里插入图片描述

后台服务上下架(批量)

前端开始

页面加两个按钮,未选置灰,绑定事件,传id数组到后端,

<el-form-item>
	<el-button type="success" @click="onsale" :disabled="this.sels.length===0">上架</el-button>
</el-form-item>
<el-form-item>
	<el-button type="warning" @click="offsale" :disabled="this.sels.length===0">下架</el-button>
</el-form-item>
		sels: [],//列表选中行
		onsale(){
			var ids = this.sels.map(item => item.id);
			//获取选中的行
			if(!this.sels || this.sels.length  <1){
				this.$message({ message: '老铁,你不选中数据,臣妾上架不了啊....',type: 'error'});
				return;
			}
			this.$confirm('确认上架选中记录吗?', '温馨提示', {
				type: 'warning'
			}).then(() => {
				this.listLoading = true;
				this.$http.post('/product/onsale',ids).then((res) => {
					this.listLoading = false;
					if(res.data.success){
						this.$message({
							message: '上架成功',
							type: 'success'
						});
					}else{
						this.$message({
							message: res.data.message,
							type: 'error'
						});
					}
					this.getProducts();
				});
			}).catch(() => {

			});
		},
		offsale(){
			var ids = this.sels.map(item => item.id);
			//获取选中的行
			if(!this.sels || this.sels.length  <1){
				this.$message({ message: '老铁,你不选中数据,臣妾下架不了啊....',type: 'error'});
				return;
			}
			this.$confirm('确认下架选中记录吗?', '提示', {
				type: 'warning'
			}).then(() => {
				this.listLoading = true;
				this.$http.post('/product/offsale',ids).then((res) => {
					this.listLoading = false;
					if(res.data.success){
						this.$message({
							message: '下架成功',
							type: 'success'
						});
					}else{
						this.$message({
							message: res.data.message,
							type: 'error'
						});
					}
					this.getProducts();
				});
			}).catch(() => {

			});
		}

后端完成

ProductController
    /**
     * 批量上架
     */
    @PostMapping("/onsale")
    public AjaxResult onsale(@RequestBody List<Long> ids){
        try {
            productService.onOrOffSale(ids,1);//flag:0下架 1上架
            return AjaxResult.me();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setMessage("上架失败!"+e.getMessage());
        }
    }

    /**
     * 批量下架
     */
    @PostMapping("/offsale")
    public AjaxResult offsale(@RequestBody List<Long> ids){
        try {
            productService.onOrOffSale(ids,0);//flag:0下架 1上架
            return AjaxResult.me();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setMessage("下架失败!"+e.getMessage());
        }
    }
ProductServiceImpl
    @Override
    public void onOrOffSale(List<Long> ids, int flag) {
        //1.判断是上架还是下架
        Map<String,Object> map = new HashMap<>();
        map.put("ids", ids);
        if(flag == 1){
            //1.1 调整状态
            //1.2时间
            map.put("onSaleTime",new Date());
            productMapper.onSale(map);
        }else{
            //1.1 调整状态
            //1.2时间
            map.put("offSaleTime",new Date());
            productMapper.offSale(map);
        }
    }
ProductMapper
    <!--void onSale(Map<String, Object> map);-->
    <update id="onSale" >
        UPDATE t_product set state=1, onsaletime=#{onSaleTime} where id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </update>


    <!--void offSale(Map<String, Object> map);-->
    <update id="offSale" >
        UPDATE t_product set state=0, offsaletime=#{offSaleTime} where id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </update>

前台展示上架

前端开始

index修改栏目名称,拷贝search为product,修改引入路径,index支持跳转到product,product修改栏目名称并支持跳转到index,
拷贝success为adoutUs,修改引入路径,index支持跳转到adoutUs,adoutUs修改页面内容,

product引入vue和axios,用div包住body里的内容,写vue实例,

后端完成

ProductQuery
@Data
public class ProductQuery extends BaseQuery {
    //查询上下架的标识
    private Integer state;
}
ProductController
    /**
     * 前端主站使用的接口,只查询上架的
     */
    @PostMapping("/list")
    public PageList<Product> queryWebPage(@RequestBody ProductQuery productQuery){
        productQuery.setState(1);
        return productService.queryPage(productQuery);
    }
ProductMapper
    <!--Integer queryCount(ProductQuery productQuery);-->
    <select id="queryCount" parameterType="ProductQuery" resultType="integer">
        SELECT count(*) FROM t_product
        <include refid="whereSql"/>
    </select>

    <!--List<Product> queryData(ProductQuery productQuery)-->
    <select id="queryData" resultType="Product" parameterType="ProductQuery">
        SELECT * FROM t_product
        <include refid="whereSql"/>
        limit #{start},#{pageSize}
    </select>

    <!--Where条件-->
    <sql id="whereSql">
        <where>
            <if test="keyword != null and keyword != ''">
                AND name LIKE concat("%",#{keyword},"%")
            </if>
            <if test="state != null">
                AND state = #{state}
            </if>
        </where>
    </sql>
测试

注释掉拦截器,然后可以免登录用swagger测试

前端展示列表和图片

调整入参获取数据,遍历,按照规格渲染到页面

fastDfs传800×800可以自定转430×430,350×350,60×60,

product.html
<ul class="am-avg-sm-2 am-avg-md-3 am-avg-lg-4 boxes">
	<li v-for="product in pageList.rows">
		<div class="i-pic limit">
			<img :src="baseFastUrl + product.resources.split(',')[0] + imgSuffix" />
			<p class="title fl">【官方旗舰店】{{product.name}}</p>
			<p class="price fl">
				<b>¥</b>
				<strong>{{product.saleprice}}</strong>
			</p>
			<p class="number fl">
				销量<span>{{product.salecount}}</span>
			</p>
		</div>
	</li>
</ul>
<script type="text/javascript">
    new Vue({
        el: "#productDiv",
        data: {
            baseFastUrl: "http://115.159.217.249:8888/",
            imgSuffix: "_350x350.jpg",
            pageList: {
                total: 0,
                rows: []
            },
            queryParams: {
                pageSize: 12,
                currentPage: 1,
                keyword: '',
            }
        },
        methods: {
            getProducts() {
                this.$http.post("/product/list", this.queryParams)
                    .then(result => {
                        result = result.data;//pageList  rows  total
                        console.log(result);
                        if (result) {
                            this.pageList = result;
                        }
                    })
                    .catch(result => {
                        console.log(result);
                        alert("系统错误!");
                    })
            }
        },
        mounted() {
            this.getProducts();
        }
    })
</script>

服务高级查询

元素绑定

<div class="search-bar pr">
	<a name="index_none_header_sysc" href="#"></a>
	<form>
		<input id="searchInput" name="index_none_header_sysc" v-model="queryParams.keyword" type="text" placeholder="搜索" autocomplete="off">
		<input id="ai-topsearch" class="submit am-btn" @click="search" value="搜索" index="1" type="button">
	</form>
</div>

方法绑定

search() {
		this.queryParams.currentPage = 1;//定为到第一页
		this.getProducts();
	},

分页

页数计算与展示,不同页查询,左右箭头分页查询并限制不超过第一页和最后页,

<!--分页 -->
<ul class="am-pagination am-pagination-right">
	<!--class="am-disabled"-->
	<li>
		<a href="javascript:;" @click="handCurrentPage(queryParams.currentPage -1)">&laquo;</a>
	</li>

	<li v-for="page in countPage">
		<a href="javascript:;" @click="handCurrentPage(page)">
			{{page}}
		</a>
	</li>

	<li><a href="javascript:;" @click="handCurrentPage(queryParams.currentPage +1)">&raquo;</a></li>
</ul>
	computed: {
		countPage() {
			//向上取整
			return Math.ceil(this.pageList.total / this.queryParams.pageSize);
		}
	},
		handCurrentPage(page) {//动态分页
			if (page == 0) {
				this.queryParams.currentPage = 1;//定位到第一页
			} else if (page >= this.countPage) {
				this.queryParams.currentPage = this.countPage;//定位到最后页
			} else {
				this.queryParams.currentPage = page;//定位到所选页
			}
			this.getProducts();
		},

查看详情

跳转详情页

<li v-for="product in pageList.rows" @click="goDetail(product.id)">
	goDetail(productId) {//跳转到详情页
		//当前窗体打开
		//location.href = "http://localhost/productDetail.html?productId=" + productId;
		window.open("http://localhost/productDetail.html?productId=" + productId);
	},

数据展示后台接口

ProductController
    @GetMapping("/{id}")
    @ApiOperation(value = "查询一条服务数据",notes = "需要传入id")
    public Product getById(@PathVariable("id") Long id){
        return productService.getById(id);
    }
ProductMapper
    <resultMap id="ProductMap" type="Product">
        <!--基础属性-->
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="resources" property="resources"/>
        <result column="saleprice" property="saleprice"/>
        <result column="costprice" property="costprice"/>
        <result column="offsaletime" property="offsaletime"/>
        <result column="onsaletime" property="onsaletime"/>
        <result column="state" property="state"/>
        <result column="createtime" property="createtime"/>
        <result column="salecount" property="salecount"/>

        <association property="detail" javaType="ProductDetail">
            <id column="did" property="id"/>
            <result column="intro" property="intro"/>
            <result column="orderNotice" property="orderNotice"/>
        </association>
    </resultMap>

    <!--Product loadById(Long id);-->
    <select id="loadById" resultMap="ProductMap">
        SELECT
            p.*, d.id did,
            d.intro,
            d.orderNotice
        FROM
            t_product p
        LEFT JOIN t_product_detail d ON p.id = d.product_id
        WHERE
            p.id =  #{id}
    </select>

前台展示

导入vue和axios
获取数据.js
<script type="text/javascript">
    new Vue({
        el:"#productDetailDiv",
        data:{
            product:{},
            fastDfsUrl:"http://115.159.217.249:8888",
            midimgSuffix:"_350x350.jpg",
            smallimgSuffix:"_60x60.jpg",
            resources:[]
        },
        mounted(){
            let productId = parseUrlParams2Obj(location.href).productId;
            this.$http.get("/product/"+productId)
                .then(result=>{
                    this.product = result.data;
                    if(this.product.resources){
                        this.resources = this.product.resources.split(',');
                    }
                })
                .catch(result=>{
                    console.log(result);
                    alert("系统错误");
                })
        }
    });
</script>
展示数据
图片展示
		<div class="tb-booth tb-pic tb-s310">
			<a :href="fastDfsUrl+resources[0]">
				<img :src="fastDfsUrl+resources[0]+midimgSuffix" alt="细节展示放大镜特效" :rel="fastDfsUrl+resources[0]" class="jqzoom" />
			</a>
		</div>
		<ul class="tb-thumb" id="thumblist">
			<li v-for="(resource,index) in resources">
				<div class="tb-pic tb-s40 tb-selected" v-if="index==0">
					<a href="#"><img :src="fastDfsUrl+resource+smallimgSuffix" :mid="fastDfsUrl+resource+midimgSuffix" :big="fastDfsUrl+resource"></a>
				</div>
				<div class="tb-pic tb-s40" v-else>
					<a href="#"><img :src="fastDfsUrl+resource+smallimgSuffix" :mid="fastDfsUrl+resource+midimgSuffix" :big="fastDfsUrl+resource"></a>
				</div>
			</li>
		</ul>
详情
		<div class="am-tab-panel am-fade am-in am-active">
			<div class="J_Brand">
				<div class="attr-list-hd tm-clear">
					<h4>服务简介:</h4></div>
				<div class="clear"></div>
				<div v-html="product.detail.intro" v-if="product.detail">
				</div>
				<div class="clear"></div>
			</div>
			<div class="details">
				<div class="attr-list-hd after-market-hd">
					<h4>预定须知</h4>
				</div>
				<div class="twlistNews">
					<div v-html="product.detail.orderNotice" v-if="product.detail">
					</div>
				</div>
			</div>
			<div class="clear"></div>
		</div>
名称,售价,原价,销量

切换图片js
<script type="text/javascript">
	// 切换图片js
	$(document).ready(function() {
		$(".jqzoom").imagezoom();
		$("#thumblist").on("click","#thumblist li a", function() {
			$(this).parents("li").addClass("tb-selected").siblings().removeClass("tb-selected");
			$(".jqzoom").attr('src', $(this).find("img").attr("mid"));
			$(".jqzoom").attr('rel', $(this).find("img").attr("big"));
		});
		/*$("#thumblist li a").click(function() {
			$(this).parents("li").addClass("tb-selected").siblings().removeClass("tb-selected");
			$(".jqzoom").attr('src', $(this).find("img").attr("mid"));
			$(".jqzoom").attr('rel', $(this).find("img").attr("big"));
		});*/
	});
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/785979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【雕爷学编程】Arduino动手做(171)---micro:bit 开发板3

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#xff0c;这…

Jmeter 如何并发执行 Python 脚本

目录 1. 前言 2. Python 实现文件上传 3. Jmeter 并发执行 4. 最后 1. 前言 JMeter 是一个开源性能测试工具&#xff0c;它可以帮助我们更轻松地执行性能测试&#xff0c;并使测试结果更加可靠。Python 是一种广泛使用的编程语言&#xff0c;它可以用于开发各种软件和应用…

ResultMap结果集映射

为了解决属性名和字段名不相同的问题 example&#xff1a;MyBatis-CRUD: Mybatis做增删改查 使用resultmap前查询password时为空&#xff0c;因为属性名与字段名不相同 做结果集映射&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <!…

自己动手写一个编译器

一、概述 本文将参考《自己动手写编译器这本书》&#xff0c;自己写一个编译器&#xff0c;但是因为本人水平有限。文章中比较晦涩的内容&#xff0c;自己也没弄明白。因此&#xff0c;本文仅在实践层跑一遍流程。具体的原理还需要大家自行探索。 TinyC 编译器可将 TinyC 源程序…

JavaScript 判断先后两个数组增加和减少的元素

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

错误解决:Failed to create Spark client for Spark session

错误解决&#xff1a;Failed to create Spark client for Spark session "Failed to create Spark client for Spark session"的错误通常表示无法为Spark会话创建Spark客户端。这可能是由于以下一些常见问题导致的&#xff1a; Spark配置错误&#xff1a;请检查Spar…

SAMStable-Diffusion集成进化!分割、生成一切!AI绘画新玩法

自SAM「分割一切」模型推出之后&#xff0c;二创潮就开始了&#xff0c;有想法有行动&#xff01;飞桨AI Studio开发者会唱歌的炼丹师就创作出SAM进化版&#xff0c;将SAM、Stable Diffusion集成&#xff0c;实现「分割」、「生成」能力二合一&#xff0c;并部署为应用&#xf…

vue项目入口和个文件之间的关系

vue项目入口和个文件之间的关系 1、代码的执行顺序和引入关系 1、代码的执行顺序和引入关系

新星计划打卡学习:VUE3引入element-plus

目录 1、安装element-plus 2、安装按需导入插件 3、修改配置文件 4、添加页面内容 5、保存并重启项目 1、安装element-plus 官网说要想使用element-plus需要先进行安装&#xff0c;并给出了三种安装方式&#xff0c;我选择了第三种。 报错了&#xff1a; 解决的办法&…

PostgreSQL 设置时区,时间/日期函数汇总

文章目录 前言查看时区修改时区时间/日期操作符和函数时间/日期操作符日期/时间函数&#xff1a;extract&#xff0c;date_part函数支持的field 数据类型格式化函数用于日期/时间格式化的模式&#xff1a; 扩展 前言 本文基于 PostgreSQL 12.6 版本&#xff0c;不同版本的函数…

人才公寓水电表改造解决方案

随着社会经济的不断发展&#xff0c;人才公寓作为吸引和留住人才的重要配套设施&#xff0c;其水电表改造问题越来越受到人们的关注。本文将从以下几个方面探讨人才公寓水电表改造解决方案。 一、现状分析 目前&#xff0c;人才公寓的水电表普遍存在以下几个问题&#xff1a; …

Jenkins从配置到实战(二) - Jenkins如何在多台机器上自动化构建

前言 jenkins除了支持在本机上进行项目构建&#xff0c;还可以将构建任务分发到其他远程服务器上去执行&#xff0c;可以实现在不同平台和架构的机器上来完成项目的自动化构建任务&#xff0c;也能减轻jenkins服务器的压力。本文章就主要介绍下此流程。 准备工作 准备两台机…

2.02 分类功能实现后台实现

三级分类效果图&#xff1a; 一 实现一级分类查询 步骤1&#xff1a;使用逆向工程生成创建实体类和对应的mapper 实体类&#xff1a;Categorymapper: CategoryMapper和CategoryMapper.xml步骤2&#xff1a; import com.one.pojo.Category; import java.util.List; public int…

视频讲解Codeforces Round 887 (Div. 2)(A--C)

文章目录 A. Desorting1、板书2、代码 B. Fibonaccharsis1、板书2、代码 C. Ntarsis Set1、板书2、代码 视频讲解Codeforces Round 887 (Div. 2)&#xff08;A–C&#xff09; A. Desorting 1、板书 2、代码 #include<bits/stdc.h> #define endl \n #define INF 0x3f…

Linux6.13 Docker LNMP项目搭建

文章目录 计算机系统5G云计算第四章 LINUX Docker LNMP项目搭建一、项目环境1.环境描述2.容器ip地址规划3.任务需求 二、部署过程1.部署构建 nginx 镜像2.部署构建 mysql 镜像3.部署构建 php 镜像4.验证测试 计算机系统 5G云计算 第四章 LINUX Docker LNMP项目搭建 一、项目…

功能测试也可以发现数据库相关的性能问题

很多同学认为功能测试和性能测试是严格分开的&#xff0c;功能测试人员无法发现性能问题。其实不是这样的&#xff0c;功能测试人员在验证功能时也可以发现性能问题&#xff1b;一些功能反而在功能测试环境不好验证&#xff0c;需要在性能环境上测试。 今天咱们就说一下测试涉及…

Spring Security 身份验证的基本类/架构

目录 1、SecurityContextHolder 核心类 2、SecurityContext 接口 3、Authentication 用户认证信息接口 4、GrantedAuthority 拥有权限接口 5、AuthenticationManager 身份认证管理器接口 6、ProviderManager 身份认证管理器的实现 7、AuthenticationProvider 特定类型的…

西北乱跑娃 -- CSS动态旋转果冻效果

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>旋转果冻</title> <style> #myDIV {margin: 250px;width: 250px;height: 250px;background: orange;position: relative;font-size: 20px;animation: anima…

【前缀和】LeetCode 560. 和为k的字数组

文章目录 题目描述方法1 暴力方法2 暴力优化方法3 前缀和方法4 前缀和优化 题目描述 力扣560题&#xff0c;链接&#xff1a;https://leetcode.cn/problems/subarray-sum-equals-k 方法1 暴力 暴力法&#xff0c;三重for循环&#xff0c;时间复杂度 O ( N 3 ) O(N^3) O(N3)&a…

[回馈]ASP.NET Core MVC开发实战之商城系统(二)

经过一段时间的准备&#xff0c;新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始&#xff0c;在之前的文章中&#xff0c;讲解了商城系统的整体功能设计&#xff0c;页面布局设计&#xff0c;环境搭建&#xff0c;系统配置&#xff0c;及首页商品类型&#xff0c;bann…