< ?xml version = "1.0" encoding = "UTF-8" ?>
< ! DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
< mapper namespace = "com.java1234.mapper.ProductMapper" > < resultMap id = "productResult" type = "com.java1234.entity.Product" > < association property = "type" column = "typeId" select = "com.java1234.mapper.SmallTypeMapper.findById" > < /association> < /resultMap> < select id = "list" parameterType = "Map" resultMap = "productResult" > select * from t_product< where> < if test = "name!=null and name!='' " > and name like concat( '%' ,< /if> < /where> < if test = "start!=null and pageSize!=null " > limit < /if> < /select> < select id = "getTotal" parameterType = "Map" resultType = "Long" > select count( *) from t_product< where> < if test = "name!=null and name!='' " > and name like concat( '%' ,< /if> < /where> < /select> < insert id = "add" parameterType = "com.java1234.entity.Product" > insert into t_product values( null,< /insert> < update id = "update" parameterType = "com.java1234.entity.Product" > update t_product< set> < if test = "name!=null and name!=''" > name = < /if> < if test = "price!=null" > price = < /if> < if test = "stock!=null" > stock = < /if> < if test = "type!=null and type.id!=null" > typeId = < /if> < if test = "proPic!=null and proPic!=''" > proPic = < /if> < if test = "description!=null and description!=''" > description = < /if> < if test = "productIntroImgs!=null and productIntroImgs!=''" > productIntroImgs = < /if> < if test = "productParaImgs!=null and productParaImgs!=''" > productParaImgs = < /if> < if test = "swiperPic!=null and swiperPic!=''" > swiperPic = < /if> < if test = "swiperSort!=null" > swiperSort = < /if> < /set> where id = < /update> < select id = "findById" parameterType = "Integer" resultMap = "productResult" > select * from t_product where id = < /select> < /mapper>
package com.java1234.controller.admin; import com.java1234.entity.*;
import com.java1234.service.IProductService;
import com.java1234.util.DateUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /*** 管理端-商品Controller控制器* @author java1234_小锋* @site www.java1234.com* @company 南通小锋网络科技有限公司* @create 2022 -02-14 6 :54*/
@RestController
@RequestMapping( "/admin/product" )
public class AdminProductController { @Autowiredprivate IProductService productService; @Value( "${productImagesFilePath} " ) private String productImagesFilePath; @Value( "${swiperImagesFilePath} " ) private String swiperImagesFilePath; /*** 根据条件分页查询* @param pageBean* @return*/@RequestMapping( "/list" ) public R list( @RequestBody PageBean pageBean) { System.out.println( pageBean) ; Map< String,Object> map = new HashMap<> ( ) ; map.put( "name" ,pageBean.getQuery( ) .trim( )) ; map.put( "start" ,pageBean.getStart( )) ; map.put( "pageSize" ,pageBean.getPageSize( )) ; List< Product> productList = productService.list( map) ; Long total = productService.getTotal( map) ; Map< String,Object> resultMap = new HashMap<> ( ) ; resultMap.put( "productList" ,productList) ; resultMap.put( "total" ,total) ; return R.ok( resultMap) ; } /*** 更新热门状态* @param id * @param hot* @return*/@GetMapping( "/updateHot/{id}/state/{hot}" ) public R updateHot( @PathVariable( value = "id" ) Integer id,@PathVariable( value = "hot" ) boolean hot) { Product product = productService.getById( id) ; product.setHot( hot) ; if( hot) { product.setHotDateTime( new Date( )) ; } else{ product.setHotDateTime( null) ; } productService.saveOrUpdate( product) ; return R.ok( ) ; } /*** 更新swiper状态* @param id * @param swiper* @return*/@GetMapping( "/updateSwiper/{id}/state/{swiper}" ) public R updateSwiper( @PathVariable( value = "id" ) Integer id,@PathVariable( value = "swiper" ) boolean swiper) { Product product = productService.getById( id) ; product.setSwiper( swiper) ; productService.saveOrUpdate( product) ; return R.ok( ) ; } /*** 删除* @param id * @return*/@GetMapping( "/delete/{id}" ) public R delete( @PathVariable( value = "id" ) Integer id ) { productService.removeById( id) ; return R.ok( ) ; } /*** 添加或修改* @param product* @return*/@RequestMapping( "/save" ) public R save( @RequestBody Product product) { System.out.println( "product" +product) ; if( product.getId( ) == null || product.getId( ) == -1) { productService.add( product) ; } else{ productService.update( product) ; } return R.ok( ) ; } /*** 上传商品大类图片* @param file * @return* @throws Exception*/@RequestMapping( "/uploadImage" ) public Map< String,Object> uploadImage( MultipartFile file ) throws Exception{ Map< String,Object> resultMap = new HashMap<> ( ) ; if( ! file.isEmpty( )) { //获取文件名String originalFilename = file.getOriginalFilename( ) ; String suffixName = originalFilename.substring( originalFilename.lastIndexOf( "." )) ; String newFileName = DateUtil.getCurrentDateStr( ) + suffixName; FileUtils.copyInputStreamToFile( file.getInputStream( ) ,new File( productImagesFilePath+newFileName)) ; resultMap.put( "code" ,0) ; resultMap.put( "msg" ,"上传成功" ) ; Map< String,Object> dataMap = new HashMap<> ( ) ; dataMap.put( "title" ,newFileName) ; dataMap.put( "src" ,"/image/product/" +newFileName) ; resultMap.put( "data" ,dataMap) ; } return resultMap; } /*** 上传swiper幻灯图片* @param file * @return* @throws Exception*/@RequestMapping( "/uploadSwiperImage" ) public Map< String,Object> uploadSwiperImage( MultipartFile file ) throws Exception{ Map< String,Object> resultMap = new HashMap<> ( ) ; if( ! file.isEmpty( )) { //获取文件名String originalFilename = file.getOriginalFilename( ) ; String suffixName = originalFilename.substring( originalFilename.lastIndexOf( "." )) ; String newFileName = DateUtil.getCurrentDateStr( ) + suffixName; FileUtils.copyInputStreamToFile( file.getInputStream( ) ,new File( swiperImagesFilePath+newFileName)) ; resultMap.put( "code" ,0) ; resultMap.put( "msg" ,"上传成功" ) ; Map< String,Object> dataMap = new HashMap<> ( ) ; dataMap.put( "title" ,newFileName) ; dataMap.put( "src" ,"/image/swiper/" +newFileName) ; resultMap.put( "data" ,dataMap) ; } return resultMap; }
}
server:port: 8080 servlet:context-path: /spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_java1234_mall_v3?serverTimezone= Asia/Shanghaiusername: rootpassword: 123456 mybatis-plus:global-config:db-config:id-type: auto configuration:map-underscore-to-camel-case: false auto-mapping-behavior: full log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:mybatis/mapper/*.xmlweixin:jscode2sessionUrl: https://api.weixin.qq.com/sns/jscode2sessionappid: wx8a1b5168c6b661afsecret: 56cd2d8dbc9d5ebcc759e48a62131be0weixinpayconfig:appid: wx8a1b5168c6b661afmch_id: 换成你的key: jrBXpy1VPNY0FCFI42EBShLom7KMaRBaurl: https://api.mch.weixin.qq.com/pay/unifiedordernotify_url: https://2c23-222-184-165-54.ngrok.io/weixinpay/notifyUrlbigTypeImagesFilePath: D://java1234-mall-v3/bigTypeImgs/productImagesFilePath: D://java1234-mall-v3/productImgs/swiperImagesFilePath: D://java1234-mall-v3/swiperImgs/
< template> < el-dialogmodel-value= "swiperImageDialogVisible" title = "幻灯设置" width = "30%" @close= "handleClose" center> < el-formref = "formRef" :model= "form" label-width= "100px" style = "text-align: center" :rules= "rules" > < el-form-item label = "排列序号" prop = "swiperSort" > < el-input v-model= "form.swiperSort" style = "width: 100px" /> < /el-form-item> < el-upload:headers= "headers" class = "avatar-uploader" :action= "getServerUrl()+'/admin/product/uploadSwiperImage'" :show-file-list= "false" :on-success= "handleAvatarSuccess" :before-upload= "beforeAvatarUpload" > < img v-if= "imageUrl" :src= "imageUrl" class = "avatar" /> < el-icon v-else class = "avatar-uploader-icon" > < Plus /> < /el-icon> < /el-upload> < /el-form> < template < span class = "dialog-footer" > < el-button type = "primary" @click= "handleConfirm" > 确认更换< /el-button> < /span> < /template> < /el-dialog>
< /template> < script setup> import { defineEmits, defineProps, ref, watch} from "vue" ;
import axios,{ getServerUrl} from "@/util/axios" ;
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue' const tableData = ref( [ ] ) const props = defineProps( { imageDialogValue:{ type:Object,default:( ) = > { } ,required:true} }
) const headers = ref( { token:window.sessionStorage.getItem( "token" )
} ) const rules = ref( { swiperSort:[ { required: true,message:'请输入排列序号' } ,{ type:'number' ,message: '排序序号必须是数值类型' ,transform: ( value) = > Number( value) } ]
} ) const form = ref( { id:-1,swiperPic:'' ,swiperSort:0
} ) const formRef = ref( null) const imageUrl = ref( "" ) watch( ( ) = > props.imageDialogValue,( ) = > { form.value = props.imageDialogValue; imageUrl.value = getServerUrl( ) +'/image/swiper/' +form.value.swiperPic} ,{ deep:true,immediate:true}
) const emits = defineEmits( [ 'update:modelValue' ,'initProductList' ] ) const handleClose = ( ) = > { emits( 'update:modelValue' ,false)
} const handleAvatarSuccess = ( res) = > { imageUrl.value = getServerUrl( ) +res.data.srcform.value.swiperPic = res.data.title;
} const beforeAvatarUpload = ( file) = > { const isJPG = file.type == = 'image/jpeg' const isLt2M = file.size / 1024 / 1024 < 2 if ( ! isJPG) { ElMessage.error( '图片必须是jpg格式' ) } if ( ! isLt2M) { ElMessage.error( '图片大小不能超过2M!' ) } return isJPG && isLt2M
} const handleConfirm = async( ) = > { formRef.value.validate( async( valid) = > { if( valid) { let result = await axios.post( "admin/product/save" ,form.value) ; let data = result.data; if( data.code== 0 ) { ElMessage.success( "执行成功!" ) formRef.value.resetFields( ) ; emits( "initProductList" ) handleClose( ) ; } else{ ElMessage.error( data.msg) ; } } } ) ; } < /script> < style> .avatar-uploader .el-upload { border: 1px dashed border-radius: 6px; cursor: pointer; position: relative; overflow: hidden;
}
.avatar-uploader .el-upload:hover { border-color:
}
.el-icon.avatar-uploader-icon { font-size: 28px; color: width: 178px; height: 178px; text-align: center;
}
.avatar { width: 178px; height: 178px; display: block;
} < /style>
< template> < el-card> < el-row :gutter= "20" class = "header" > < el-col :span= "7" > < el-input placeholder = "请输入商品名称..." clearable v-model= "queryForm.query" > < /el-input> < /el-col> < el-button type = "primary" :icon= "Search" @click= "initProductList" > 搜索< /el-button> < el-button type = "primary" @click= "handleDialogValue()" > 添加商品< /el-button> < /el-row> < el-table :data= "tableData" stripe style = "width: 100%" > < el-table-column prop = "name" label = "商品名称" width = "200" fixed/> < el-table-column prop = "image" label = "商品图片" width = "150" align = "center" > < template v-slot= "scope" > < img :src= "getServerUrl()+'/image/product/'+scope.row.proPic" width = "80" height = "80" /> < /template> < /el-table-column> < el-table-column prop = "price" label = "商品价格" width = "100" /> < el-table-column prop = "stock" label = "商品库存" width = "200" /> < el-table-column prop = "type" label = "商品类别" width = "200" :formatter= "typeNameFormatter" /> < el-table-column prop = "hot" label = "热卖?" width = "100" align = "center" > < template v-slot= "{row}" > < el-switch v-model= "row.hot" @change= "hotChangeHandle(row)" > < /el-switch> < /template> < /el-table-column> < el-table-column prop = "swiper" label = "首页幻灯?" width = "100" align = "center" > < template v-slot= "{row}" > < el-switch v-model= "row.swiper" @change= "swiperChangeHandle(row)" > < /el-switch> < /template> < /el-table-column> < el-table-column prop = "swiperPic" label = "幻灯图片" width = "150" align = "center" > < template v-slot= "scope" > < img :src= "getServerUrl()+'/image/swiper/'+scope.row.swiperPic" width = "150" height = "75" /> < /template> < /el-table-column> < el-table-column prop = "swiperSort" label = "幻灯排序" width = "150" align = "center" /> < el-table-column prop = "description" label = "商品描述" width = "400" /> < el-table-column prop = "action" label = "操作" width = "500" fixed = "right" > < template v-slot= "scope" > < el-button type = "success" @click= "handleImageDialogValue(scope.row)" > 更换图片< /el-button> < el-button type = "primary" @click= "handleSwiperImageDialogValue(scope.row)" > 幻灯设置< /el-button> < el-button type = "primary" :icon= "Edit" @click= "handleDialogValue(scope.row)" > < /el-button> < el-button type = "danger" :icon= "Delete" @click= "handleDelete(scope.row.id)" > < /el-button> < el-button type = "primary" :icon= "Edit" @click= "handleDialogValue(scope.row)" > 轮播图设置< /el-button> < /template> < /el-table-column> < /el-table> < el-paginationv-model:currentPage= "queryForm.pageNum" :page-sizes= "[10, 20, 30, 40,50]" :page-size= "queryForm.pageSize" :small= "small" :disabled= "disabled" :background= "background" layout = "total, sizes, prev, pager, next, jumper" :total= "total" @size-change= "handleSizeChange" @current-change= "handleCurrentChange" > < /el-pagination> < /el-card> < Dialog v-model= "dialogVisible" :dialogTitle= "dialogTitle" @initProductList= "initProductList" :dialogValue= "dialogValue" /> < ImageDialog v-model= "imageDialogVisible" :imageDialogValue= "imageDialogValue" @initProductList= "initProductList" > < /ImageDialog> < SwiperImageDialog v-model= "swiperImageDialogVisible" :imageDialogValue= "imageDialogValue" @initProductList= "initProductList" > < /SwiperImageDialog>
< /template> < script setup> import { Search,Edit,Delete } from '@element-plus/icons-vue'
import { ref } from 'vue'
import axios,{ getServerUrl } from '@/util/axios'
import Dialog from './components/dialog'
import ImageDialog from './components/imageDialog'
import SwiperImageDialog from './components/swiperImageDialog'
import { ElMessageBox,ElMessage} from 'element-plus' const queryForm = ref( { query:'' ,pageNum:1,pageSize:10
} ) const total = ref( 0 ) const tableData = ref( [
] ) const dialogValue = ref( { } )
const dialogVisible = ref( false)
const dialogTitle = ref( '' ) const imageDialogVisible = ref( false) const imageDialogValue = ref( { } ) const swiperImageDialogVisible = ref( false) const initProductList = async( ) = > { console.log( 'xxx' ) const res = await axios.post( "admin/product/list" ,queryForm.value) ; tableData.value = res.data.productList; total.value = res.data.total;
} initProductList( ) ; const handleSizeChange = ( pageSize) = > { queryForm.value.pageNum = 1 ; queryForm.value.pageSize = pageSize; initProductList( ) ;
} const handleCurrentChange = ( pageNum) = > { queryForm.value.pageNum = pageNum; initProductList( ) ;
} const handleImageDialogValue = ( row) = > { imageDialogValue.value = JSON.parse( JSON.stringify( row)) imageDialogVisible.value = true
} const handleSwiperImageDialogValue = ( row) = > { imageDialogValue.value = JSON.parse( JSON.stringify( row)) swiperImageDialogVisible.value = true
} const handleDialogValue = ( row) = > { if( row) { dialogValue.value = JSON.parse( JSON.stringify( row)) ; dialogTitle.value = "商品修改" } else{ dialogValue.value = { bigType:{ id:"" } } dialogTitle.value = "商品添加" } dialogVisible.value = true;
} const handleDelete = ( id) = > { ElMessageBox.confirm( '您确定要删除这条记录吗?' ,'系统提示' ,{ confirmButtonText: '确定' ,cancelButtonText: '取消' ,type: 'warning' ,} ) .then( async( ) = > { console.log( "id=" +id) let res = await axios.get( "admin/product/delete/" +id) ; if( res.data.code== 0 ) { ElMessage( { type: 'success' ,message: '删除成功!' ,} ) ; initProductList( ) ; } else{ ElMessage( { type: 'error' ,message: res.data.msg,} ) ; } } ) .catch(( ) = > { } )
} const typeNameFormatter = ( row) = > { return row.type.name
} const hotChangeHandle = async( row) = > { let res = await axios.get( "admin/product/updateHot/" +row.id+"/state/" +row.hot) ; if( res.data.code== 0 ) { ElMessage( { type:'success' ,message:'执行成功!' ,} ) } else{ ElMessage( { type: 'error' ,message: res.data.msg,} ) initProductList( ) ; }
} const swiperChangeHandle = async( row) = > { let res = await axios.get( "admin/product/updateSwiper/" +row.id+"/state/" +row.swiper) ; if( res.data.code== 0 ) { ElMessage( { type:'success' ,message:'执行成功!' ,} ) } else{ ElMessage( { type: 'error' ,message: res.data.msg,} ) initProductList( ) ; }
} < /script> < style lang = "scss" scoped> .header{ padding-bottom: 16px; box-sizing: border-box;
} .el-pagination{ padding-top: 15px; box-sizing: border-box;
} < /style>