商品管理幻灯图片更换实现
<?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('%',#{name},'%')</if></where><if test="start!=null and pageSize!=null ">limit #{start},#{pageSize}</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('%',#{name},'%')</if></where></select><insert id="add" parameterType="com.java1234.entity.Product">insert into t_product values(null,#{name},#{price},#{stock},#{proPic},#{hot},#{swiper},#{swiperPic},#{swiperSort},#{type.id},null,#{productIntroImgs},#{productParaImgs},#{description});</insert><update id="update" parameterType="com.java1234.entity.Product">update t_product<set><if test="name!=null and name!=''">name=#{name},</if><if test="price!=null">price=#{price},</if><if test="stock!=null">stock=#{stock},</if><if test="type!=null and type.id!=null">typeId=#{type.id},</if><if test="proPic!=null and proPic!=''">proPic=#{proPic},</if><if test="description!=null and description!=''">description=#{description},</if><if test="productIntroImgs!=null and productIntroImgs!=''">productIntroImgs=#{productIntroImgs},</if><if test="productParaImgs!=null and productParaImgs!=''">productParaImgs=#{productParaImgs},</if><if test="swiperPic!=null and swiperPic!=''">swiperPic=#{swiperPic},</if><if test="swiperSort!=null">swiperSort=#{swiperSort},</if></set>where id=#{id}</update><select id="findById" parameterType="Integer" resultMap="productResult">select * from t_product where id=#{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: 8080servlet: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: 123456mybatis-plus:global-config:db-config:id-type: auto #id生成规则:数据库id自增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: 56cd2d8dbc9d5ebcc759e48a62131be0#微信支付配置# appid# mch_id 商户号# key 商户的key【API密匙】# url api请求地址# notify_url 服务器异步通知页面路径weixinpayconfig: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 #footer><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 < 2if (!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 #d9d9d9;border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;
}
.avatar-uploader .el-upload:hover {border-color: #409eff;
}
.el-icon.avatar-uploader-icon {font-size: 28px;color: #8c939d;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>
相关文章:
商品管理幻灯图片更换实现
<?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.ProductMappe…...
tomcat下载与使用教程
1. tomcat下载 官网:https://tomcat.apache.org/ 镜像地址:https://mirrors.huaweicloud.com/apache/tomcat/ 1、选择一个版本下载,官网下载速度缓慢,推荐镜像 2、对压缩包进行解压,无需进行安装,解压放…...
通过 Elasticsearch 和 Go 使用混合搜索进行地鼠狩猎
作者:CARLY RICHMOND,LAURENT SAINT-FLIX 就像动物和编程语言一样,搜索也经历了不同实践的演变,很难在其中做出选择。 在本系列的最后一篇博客中,Carly Richmond 和 Laurent Saint-Flix 将关键字搜索和向量搜索结合起…...
【LIUNX】配置缓存DNS服务
配置缓存DNS服务 A.安装bind bind-utils1.尝试修改named.conf配置文件2.测试nslookup B.修改named.conf配置文件1.配置文件2.再次测试 缓存DNS服务器:只提供域名解析结果的缓存功能,目的在于提高数据查询速度和效率,但是没有自己控制的区域地…...
Arduino驱动A01NYUB防水超声波传感器(超声波传感器)
目录 1、传感器特性 2、控制器和传感器连线图 3、通信协议 4、驱动程序 A01NYUB超声波测距传感器是一款通过发射和接收机械波来感应物体距离的电子传感器。该款产品具有监测距离远、范围广、防水等优点,且具有一定的穿透能力(烟雾、粉尘等)。该产品带有可拆卸式喇叭口,安…...
curl(八)时间和环境变量以及配置
一 时间 ① --connect-timeout 连接超时时间 ② -m | --max-time 数据最大传输时间 -m: 限制curl 完成时间(overall time limit)-m,--max-time <seconds> 整个交互完成的超时时间场景: 通过设置-m参数,可以避免请求时间过长而导致的超时错误…...
K8S知识点(十)
(1)Pod详解-启动命令 创建Pod,里面的两个容器都正常运行 (2)Pod详解-环境变量 (3)Pod详解-端口设置 (4)Pod详解-资源配额 修改:memory 不满足条件是不能正常…...
Netty实现通信框架
一、LengthFieldBasedFrameDecoder的参数解释 1、LengthFieldBasedFrameDecoder的构造方法参数 看下最多参数的构造方法 /*** Creates a new instance.** param byteOrder* the {link ByteOrder} of the length field* param maxFrameLength* the maximum len…...
【OpenCV实现图像:用OpenCV图像处理技巧之白平衡算法】
文章目录 概要加载样例图像统计数据分析White Patch Algorithm小结 概要 白平衡技术在摄影和图像处理中扮演着至关重要的角色。在不同的光照条件下,相机可能无法准确地捕捉到物体的真实颜色,导致图像呈现出暗淡、色调不自然或者褪色的效果。为了解决这个…...
文件包含 [ZJCTF 2019]NiZhuanSiWei1
打开题目 代码审计 if(isset($text)&&(file_get_contents($text,r)"welcome to the zjctf")){ 首先isset函数检查text参数是否存在且不为空 用file_get_contents函数读取text制定的文件内容并与welcome to the zjctf进行强比较 echo "<br><h…...
Java网络编程基础内容
IP地址 域名解析: 本机访问域名时,会从本地的DNS上解析数据(每个电脑都有),如果有,获取其对应的IP,通过IP访问服务器。如果本地没有,会去网络提供商的DNS找域名对应的IP࿰…...
DevChat:开发者专属的基于IDE插件化编程协助工具
DevChat:开发者专属的基于IDE插件化编程协助工具 一、DevChat 的介绍1.1 DevChat 简介1.2 DevChat 优势 二、DevChat 在 VSCode 上的使用2.1 安装 DevChat2.2 注册 DevChat2.3 使用 DevChat 三、DevChat 的实战四、总结 一、DevChat 的介绍 在AI浪潮的席卷下&#x…...
Python数据容器之[列表]
Python数据容器 Python中的数据容器: 一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素 每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。 数据容器根据特点的不同,如: 是否支…...
大咖直播间”系列直播课第一期——如何抓住HarmonyOS带来的机遇?
想了解#HarmonyOS#背后隐藏着怎样的商业机遇? 想成功搭上万物互联快车,与HarmonyOS一起发展壮大? 想知道开发者应该怎样把握时代机遇,实现高质高效就业? 答案尽在#华为开发者学堂#《大咖直播间》第一期课程,…...
跨域:利用JSONP、WebSocket实现跨域访问
跨域基础知识点:跨域知识点 iframe实现跨域的四种方式:iframe实现跨域的四种方式 注:本篇中使用到的虚拟主机也是上面iframe中配置的 目录 JSONP跨域 JSONP介绍 跨域实验: WebSocket跨域 websocket介绍 跨域实验 JSONP跨域 …...
java项目之戒烟网站(ssm+vue)
项目简介 戒烟网站实现了以下功能: 用户可以对首页,用户分享,论坛交流,公告文章,个人中心,后台管理等功能进行操作。 管理员可以对网站所有功能进行管理,包括管理用户的基本信息。 Ǵ…...
Redis集群,你真的学会了吗?
目录 1、为什么引入集群 1.1、先来了解集群是什么 1.2、哨兵模式的缺陷 引入集群解决了什么问题 1.3、使用集群,如何存储数据 2、三种主流的分片方式【经典面试题】 2.1、哈希求余算法 2.1.1、哈希求余算法的介绍 2.1.2、哈希求余算法如何扩容 2.2、一致性…...
手机地磁传感器与常见问题
在手机中,存在不少传感器,例如光距感,陀螺仪,重力加速度,地磁等。关于各传感器,虽功能作用大家都有所了解,但是在研发设计debug过程中,却总是会遇到很多头疼的问题。关于传感器&…...
EF Core 数据库映射成实体类
首先在 NuGet 包管理器中安装三个包 Microsoft.EntityFrameworkCore.SqlServer 是一个用于与 SQL Server 数据库进行交互的实体框架核心包。这个包提供了方便的方法和工具,用于在 .NET Core 应用程序中操作 SQL Server 数据库。 Microsoft.EntityFrameworkCore.Too…...
【算法优选】 动态规划之斐波那契数列模型
文章目录 🎋前言🍀[第 N 个泰波那契数](https://leetcode.cn/problems/n-th-tribonacci-number/)🚩题目描述🚩算法流程🚩代码实现 🎄[使用最小花费爬楼梯](https://leetcode.cn/problems/min-cost-climbing…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...
