婚纱摄影管理系统(发送邮箱、腾讯地图API、物流API、webSocket实时聊天、协同过滤算法、Echarts图形化分析)

🎈系统亮点:发送邮箱、腾讯地图API、物流API、webSocket实时聊天、协同过滤算法、Echarts图形化分析;

一.系统开发工具与环境搭建

1.系统设计开发工具

后端使用Java编程语言的Spring boot框架

项目架构:B/S架构

运行环境:win10/win11、jdk17

前端:

技术:框架Vue.js;UI库:ElementUI;

开发工具:Visual Studio Code;


后端:

技术:Java语言、mybatis plus、Spring boot框架;

开发工具:IDEA 2023.3.3版本;


数据库:

数据库:mysql5.7/8.0

数据库工具:Navicat12版本;


二.系统实现(部分截图)

2.1 店铺模块的设计与实现

2.1.1 店铺展示功能的实现

(1)功能设计思路

在首页的主体部分,采用轮播图展示精选摄影作品。轮播图可以自动切换,同时支持用户通过左右箭头手动切换。在轮播图下方,列出婚纱摄影店铺的卡片式布局,每个卡片显示店铺名称、地址、好评率、成交订单数、关注人数。用户点击店铺,前端会调用ToShop的异步函数,传递一个参数店铺Id。使用Vue.js框架中的路由功能将用户导航到一个新的URL路径,即/Front/ShopGood,即可进入该店铺的专属页面。

(2)实现代码

复制代码
async ToShop(Id) {
    this.$router.push({
        path: "/Front/ShopGood",
        query: {
            ShopId: Id } }); }
//得到店铺信息
async GetShopApi() {
    let { Data } = await this.$Post("/Shop/Get", { Id: this.$route.query.ShopId })
    this.Shop = Data; },
//得到商品分类
async GetGoodTypeApi() {
    let { Data: { Items } } = await this.$Post("/GoodType/List", { ShopId: this.$route.query.ShopId })
    this.GoodTypeList = Items; },
//分类选择
async handleClick(e) {
    this.$refs.Pagination.Reload({ ShopGoodTypeId: e.name }); },

(3)店铺展示界面

当用户进入首页时,首先映入眼帘的是一系列的摄影店铺。在浏览过程中,用户可以根据自己的需求和喜好,参考摄影店铺提供的信息进行筛选。一旦用户对某个店铺产生兴趣,只需轻轻点击,即可进入该店铺的专属页面,查看每个店铺的作品和商品信息。店铺展示界面如图4-1所示。

4 -1 店铺界面展示

4.1.2 店铺管理功能的实现

(1)功能设计思路

店铺管理属于摄影师角色的权限,当摄影师对店铺信息进行修改时,前端会将输入的文本传递给后面接口/Shop/CreateOrEdit,首先,检查当前用户的角色类型是否为摄影师。如果是摄影师并且审核状态为审核失败,那么将审核状态设置为待审核,同时清除审核用户ID和审核原因。随后,将输入的店铺数据传输对象映射为店铺实体对象。调用saveOrUpdate方法,将店铺实体对象保存到数据库中。最后,将更新后的店铺实体对象映射回店铺数据传输对象,并返回给前端。

(2) 功能实现代码

复制代码
public ShopDto CreateOrEdit(ShopDto input) {
//如果等于摄影商家并且之前审核失败了,那么就把审核信息都清除等待再次审核
if (BaseContext.getCurrentUserDto().getRoleType() == RoleTypeEnum.摄影师) {
    if (input.getAuditStatus() == AuditStatus.审核失败.index()) {
        input.setAuditStatus(AuditStatus.待审核.index());
        input.setAuditUserId(null);
        input.setAuditReason(null);
    }
}
//声明一个店铺实体
Shop Shop = input.MapToEntity();
//调用数据库的增加或者修改方法
saveOrUpdate(Shop);
//把传输模型返回给前端
return Shop.MapToDto();
}

(3) 店铺管理界面

摄影师进入店铺管理界面,店铺的名称、logo、店铺地址、店铺保障和详情信息。这些店铺的信息可以帮助顾客更全面地了解店铺,向顾客保证他们的权益,让他们更加放心地购买商品。店铺管理界面如图4-2所示。

4 - 2 店铺管理界面展示

2.2 摄影作品模块的设计与实现

2.2.1 摄影作品展示功能的实现

(1)功能设计思路

当用户通过店铺的链接进入到店铺的专属界面后,系统会以分页的形式展示该店铺的拍摄标题和作品。将使用Vue.js来创建一个网格布局,每行显示四个作品的缩略图。前端通过接口地址/Opus/List进行调用,获取到作品列表的数据。接下来,我们将这些数据传递给名为OpusListCard的组件进行渲染和显示。为了增加交互性,我们还需要为每个作品的缩略图添加点击事件监听器。当用户点击某个作品时,系统将打开一个新页面,并显示该作品的所有图片。

(2)功能实现代码

复制代码
public PagedResult<GoodDto> List(GoodPagedInput input) {
//构建where条件+排序
LambdaQueryWrapper<Good> queryWrapper = BuilderQuery(input);
List<Good> goods = _GoodMpper.selectList(queryWrapper);
//把Good实体转换成Good传输模型
List<GoodDto> items = Extension.copyBeanList(goods, GoodDto.class);
//计算表的数据
items = DispatchItem(items);
if (input.getIsHot() == Boolean.TRUE) {
//根据购买人次items.sort(Comparator.comparing(GoodDto::getBuyCount).reversed());
} else {
//根据创建时间从小到达排序
items.sort(Comparator.comparing(GoodDto::getCreationTime));
}
//返回一个分页结构给前端
return Extension.PagedResultBuild(items, input);
}

(3)摄影作品展示界面

用户通过店铺进入店铺的专属界面,会注意到店铺的拍摄标题和主图。如果用户对某个拍摄标题或主图感兴趣,可以点击进去查看这一组的所有图片,以便更全面地了解产品或服务的特点和细节。作品展示界面如图4-3所示。

4 - 3 摄影作品界面展示

2.2.2 摄影作品管理功能的实现

(1)功能设计思路

摄影师角色的功能,摄影作品管理。包括上传作品、浏览已有作品、搜索和筛选作品等功能。使用分页加载更多来处理大量数据。在作品列表中点击某一项,允许摄影师修改作品信息,如名称、封面等。提供"删除"按钮以便快速移除单个作品。实现多选框功能,支持摄影师一次性选择多个作品进行批量删除或修改状态。在作品详情页,所有可编辑字段通过表单呈现,提交后触发后端API更新数据库。提供搜索框和下拉菜单,允许摄影师按名称和拍摄景点快速找到目标作品。

(2)功能实现代码

复制代码
public PagedResult<OpusDto> List(OpusPagedInput input) {
//构建where条件+排序
LambdaQueryWrapper<Opus> queryWrapper = BuilderQuery(input);
//按创建时间从大到小排序 最新的显示在最前面
queryWrapper=queryWrapper.orderByDesc(Opus::getCreationTime);
//构建一个分页查询的model
Page<Opus> page = new Page<>(input.getPage(), input.getLimit());
//从数据库进行分页查询获取作品数据
IPage<Opus> pageRecords= _OpusMpper.selectPage(page, queryWrapper);
//获取所有满足条件的数据行数
Long totalCount= _OpusMpper.selectCount(queryWrapper);
//把Opus实体转换成Opus传输模型
List<OpusDto> items= Extension.copyBeanList(pageRecords.getRecords(),OpusDto.class);
//计算表的数据
items = DispatchItem(items);
//返回一个分页结构给前端
return PagedResult.GetInstance(items,totalCount);
}

(3)摄影作品管理展示界面

摄影师有权利管理摄影作品,摄影师可以将他们的摄影作品上传到系统中。摄影师可以通过内容浏览功能来查看和管理它们。他们可以浏览已上传的作品列表,并选择要进行修改、删除或批量删除的作品。这样,摄影师可以根据自己的需求对作品进行管理和调整。作品管理界面如图4-4所示。

4 - 4 摄影作品管理界面展示

2.3 摄影服务的设计与实现

2.3.1 摄影服务功能的实现

(1)功能设计思路

每个店铺都设有对应的摄影服务商品,可以通过点击店铺查看专属的商品。也可以在首页的热门推荐查找到推荐的商品。商品列表页面,每个商品以卡片形式展示,包括缩略图、名称、价格等基本信息。点击商品后进入详情页,左侧显示高清图片轮播图,右侧列出商品名称、详细参数、价格、用户评价等信息。提供"立即购买"和"加入购物车"按钮,以及"收藏"功能。下半部分展示商品的图文详情、参数信息以及用户评价。

(2) 功能实现代码

复制代码
async GetGoodApi() {
let { Data } = await this.$Post("/Good/Get", { Id: this.$route.query.GoodId })
let imgs = FullConvertUrlArray(Data.ImageUrls);
this.ActiveImgUrl = imgs[0].url;
this.ImageList = imgs;
this.Detail = Data; },
async GetGoodPropListApi() {
let { Data: { Items } } = await this.$Post("/GoodProp/List", { GoodId: this.$route.query.GoodId });
this.GoodPropList = Items;},
async ThumbnailMouseOver(url) {
this.ActiveImgUrl = url;
}

(3)摄影服务商品展示界面

用户浏览商品列表时,可以点击每个商品以查看其详细信息。在商品详情页面上,用户可以阅读商品的详细描述、规格、价格等信息。可以选择立即购买该商品、将其添加到购物车或将其收藏。摄影服务商品展示界面如图4-5所示。

4 - 5 摄影服务界面展示

4.3.2 摄影服务管理功能的实现

(1)功能设计思路

在商品列表页顶部添加一个搜索框,允许用户输入商品名称、单位或选择分类进行搜索。提供一个"导出"按钮,点击后将当前搜索结果以Excel格式下载到本地。使用ObjectMapper对象将JSON字符串query转换为GoodPagedInput类型的对象input。从input对象中获取商品列表items。创建一个Excel工作簿workbook。在工作簿中创建一个名为"商品表"的表格sheet。设置表格的列宽度为10个字节。遍历表头数据,为每个表头创建一个单元格,并将表头文本写入单元格,同时应用之前创建的样式。

(2)功能实现代码

复制代码
ObjectMapper mapper = new ObjectMapper();
GoodPagedInput input = mapper.readValue(query, GoodPagedInput.class);
List<GoodDto> items = List(input).getItems();
//声明一个工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
//生成一个表格,设置表格名称为"商品"
HSSFSheet sheet = workbook.createSheet("商品表");
//设置表格列宽度为10个字节
sheet.setDefaultColumnWidth(30);
//创建标题的显示样式
HSSFCellStyle headerStyle = workbook.createCellStyle();
headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
//创建第一行表头
HSSFRow headrow = sheet.createRow(0);
//表头数据
String[] header = {"名称", "封面", "主图", "价格", "库存", "详情内容", "店铺名称", "用户名称", "单位", "商品分类名称",};
//遍历添加表头(下面模拟遍历商品,也是同样的操作过程)
for (int i = 0; i < header.length; i++) {
}

(3)摄影服务管理界面

摄影师可以通过名称、单位和分类等条件搜索商品。可以通过导出功能,将搜索结果导出为Excel,方便给用户分享。允许对商品进行修改、删除和新增操作,查看商品属性(摄影包含的服务,比如:相框、相册等)。摄影服务管理界面如图4-6所示。

4 - 6 摄影服务管理界面展示

2.3.3 聊天会话功能的实现

(1)功能设计思路

实时通讯聊天使用了WebSocket技术,sendMessage方法用于向指定的用户发送消息。首先,通过userId从webSocketMap中获取对应的WebSocket对象。如果WebSocket对象存在,就尝试通过session的getBasicRemote()方法发送文本消息。如果发送成功,会打印一条日志信息,表示消息发送成功。如果发送失败,会捕获IOException异常并打印堆栈跟踪信息。如果WebSocket对象不存在,说明对方没有上线,会打印一条日志信息,表示消息发送失败。

(3) 功能实现代码

复制代码
public static void sendMessage(String message, String userId) {
WebSocket webSocket = webSocketMap.get(userId);
if (webSocket != null) {
try {
webSocket.session.getBasicRemote().sendText(message);
System.out.println("【websocket消息】发送消息成功,目标用户id=" + userId + ",消息内容:" + message);
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("【websocket消息】发送消息失败,用户id=" + userId + "对方没有上线");
}
}
//前端请求时一个websocket时
public void onOpen(Session session, @PathParam("userId") String userId) {
this.userId = userId;
this.session = session;
webSocketMap.put(userId, this);
System.out.println("【websocket消息】有新的连接,连接id=" + userId + ":" + this);
}

(2) 聊天会话展示界面

用户通过聊天界面发送消息时,商家会立刻接收到这些信息。用户询问关于某个产品的详细信息,他们只需要在对话框中输入自己的问题并发送。商家端在接收到这条消息后,会立即进行处理,并给予详尽的答复。聊天展示界面如图4-9所示。

图4-7 聊天会话界面展示图

2.4 旅拍景点模块的设计与实现

2.4.1 旅拍景点功能的实现

(1)功能设计思路

在"旅拍景点"菜单栏下展示全国各地的旅拍景点列表。当用户点击某个景点时,前端页面跳转到该景点的详情页面。在景点详情页面中展示该景点的拍摄作品和详细信息。添加一个"导航去这里"按钮,点击后触发线路规划功能。前端获取电脑的经纬度,它将创建一个地图实例,并将地图的中心设置为给定的经纬度坐标。然后,它检查是否有一个名为beginPosition的属性,如果有,它将使用该属性的经纬度作为路线规划的起点;否则,它将使用默认的经纬度坐标(39.984039, 116.307630307503)作为起点。最后,它将终点设置为与中心相同的经纬度坐标。随后,创建一个驾车路线规划类的实例,设置是否返回多方案以及规划策略。然后调用search方法,传入起点和终点坐标,获取路线规划结果。最后将结果中的路线信息赋值给this.routes,并绘制路径折线。

(2)功能实现代码

复制代码
let that = this;
if (this.Detail.Latitude && this.Detail.Longitude) {
var center = new TMap.LatLng(this.Detail.Latitude, this.Detail.Longitude) // 初始化地图
let map = new TMap.Map('containerMap', {
zoom: 6, // 设置地图缩放级别
center: center
});
this.map = map;
if (this.beginPosition) {
var startPosition = new TMap.LatLng(this.beginPosition.coords.latitude, this.beginPosition.coords.longitude); // 路线规划起点
}
else {
var startPosition = new TMap.LatLng(39.984039, 116.307630307503); // 路线规划起点
}
var endPosition = new TMap.LatLng(this.Detail.Latitude, this.Detail.Longitude); // 路线规划终点

(3)旅拍景点展示界面

用户点击"旅拍景点"菜单栏,可以看到全国各地的旅拍景点列表。选择想要的景点,前端跳转界面,进入景点详情。显示该景点拍摄的作品,以及景点的详细信息。可以点击"导航去这里",系统则会自动生成线路规划方案,仅供用户参考。旅拍景点展示界面如图4-8所示。

4 - 8 旅拍景点界面展示

2.4.2 旅拍景点管理功能的实现

(1)功能设计思路

管理员拥有添加、编辑和删除景点的权限。允许管理员输入景点名称、详细地址、介绍等信息并提交。提交后触发后端API将新景点插入数据库。每一列都提供一个"地址选址"按钮,前端会调用地图组件,允许管理员通过地图选择地点。一旦选择了地点,系统会自动获取该地点的经纬度。管理员确认无误后,系统会更新数据库中的经纬度字段。提供"删除"和"编辑"按钮以便快速修改或移除景点。

(2)功能实现代码

复制代码
Search.searchRectangle({  keyword: this.searchForm.address, bounds: map.getBounds() })  .then((result) => {
console.log("结果", result);
result.data.forEach((item, index) => {
var geometries = markers.getGeometries();
var infoWindow = new TMap.InfoWindow({
map: map,  position: item.location, content: `<h3>${item.title}</h3><p>地址:${item.address}</p><p>电话:${item.tel}</p>`,
offset: { x: 0, y: -50 }  }); 
infoWindow.close();
infoWindowList[index] = infoWindow;
geometries.push({
id: String(index), // 点标注数据数组
position: item.location   });
markers.updateGeometries(geometries); // 绘制地点标注
markers.on('click', (e) => {
infoWindowList[Number(e.geometry.id)].open();
});  });   });

(3)旅拍景点管理界面

管理员可以进行新增旅拍的景点,为景点设置"地点选址",获取经纬度。当设置了经纬度,用户在前台就可以通过地址进行导航并为用户规划路线。管理员可以进行删除、修改旅拍景点。旅拍景点管理界面如图4-9所示。

图4-9 旅拍景点管理展示图

2.5 订单模块的设计与实现

2.5.1 订单功能的实现

(1)功能设计思路

订单列表页面,每个订单以列表形式展示,包括订单编号、物流单号、商品概览、下单时间等基本信息,使用分页进行展示。在订单列表页提供一个搜索框,允许用户输入订单编号或物流单号进行搜索。根据输入的条件从数据库中筛选并返回匹配的订单。提供"退款售后"、"查看物流"、"确认收货"等操作按钮。点击后弹出确认对话框,用户确认后触发相应的后端API进行处理。

(2) 功能实现代码

复制代码
public PagedResult<OrderInfoDto> List(OrderInfoPagedInput input) {
LambdaQueryWrapper<OrderInfo> queryWrapper = BuilderQuery(input);
queryWrapper = queryWrapper.orderByDesc(OrderInfo::getCreationTime);
//构建一个分页查询的model
Page<OrderInfo> page = new Page<>(input.getPage(), input.getLimit());
IPage<OrderInfo> pageRecords = _OrderInfoMpper.selectPage(page, queryWrapper);
Long totalCount = _OrderInfoMpper.selectCount(queryWrapper);
List<OrderInfoDto> items = Extension.copyBeanList(pageRecords.getRecords(), OrderInfoDto.class);
items = DispatchItem(items);
return PagedResult.GetInstance(items, totalCount);
}

(3) 订单展示界面

用户可以在"个人中心"中,查看自己的所有订单。可以通过订单编号、物流单号等查看对应的订单信息。用户可以选择退款售后、查看物流、确认收货操作。订单展示界面如图4-10所示。

4 - 10 订单展示

2.5.2 订单分析功能的实现

(1)功能设计思路

在顶部展示了一个包含多个订单统计信息的列表。每个列表项都有一个标题和一个数量。数据通过后端接口获取的,然后通过JavaScript渲染到页面上。获取热门商品的数据并生成一个柱状图,获取最近30天收入的数据生成折线图。通过调用后端接口获取数据,然后对数据进行处理。接着,设置图表的配置项,包括标题、提示框、网格、x轴和y轴等。最后,使用 ECharts 库初始化图表并设置配置项,将图表渲染到页面上。同时,监听窗口大小变化事件,当窗口大小发生变化时,调整图表的大小以适应新的屏幕尺寸。

(2) 功能实现代码

复制代码
async GetGoodSalesApi() {
let { Data } = await this.$Post("/OrderInfo/GetGoodSales", { ShopId: this.ShopId })
Data = Data.slice(0, 10);
let option = { title: { text: '热门商品'  },
tooltip: {  trigger: 'axis',axisPointer: { type: 'shadow'  } },
grid: {   left: '3%',  right: '4%',  bottom: '3%',containLabel: true  },   xAxis: [{  type: 'category',
data: Data.map(x => x.Good.Name.substring(0, 10)),
axisTick: {
alignWithLabel: true }   } ],
yAxis: [  {   type: 'value' }    ],
series: [ {  name: '销量', type: 'bar', barWidth: '10%',  data: Data.map(x => x.Qty)  }    ]   };
let myChart = echarts.init(document.getElementById("GoodSalesEchart"));// 图标初始化
myChart.setOption(option);// 渲染页面
window.addEventListener("resize", () => {
myChart.resize();
});

(3) 订单分析界面

管理员登录后台管理系统,找到订单分析模块。在订单分析界面中,你可以看到各种状态的订单数量统计。对于"最近30天收入"、"热门商品"分别使用折现图、柱状图进行展示。订单分析界面图如图4-11所示。

图4-11 订单分析展示图

三.系统功能需求

1.用户

2.摄影师

3.管理员

四、系统代码结构截图

1.后端

2.前端

3.数据库

四、源码获取

1.系统非商用,非开源,非无偿。

2.由本人开发,如需源码,请联系以下方式,koimibuff。

3.项目有很多,并未全部上传,如果未找到想要的,可直接咨询。

相关推荐
倚栏听风雨4 分钟前
CompletableFuture 延时执行任务
后端
舒一笑16 分钟前
MySQL中模糊匹配like的一个坑
后端·mysql
BingoGo25 分钟前
PHP 集成 FFmpeg 处理音视频处理完整指南
后端·php
还听珊瑚海吗30 分钟前
基于WebSocket和SpringBoot聊天项目ChatterBox测试报告
spring boot·websocket·网络协议
我家大宝最可爱31 分钟前
动态规划:入门思考篇
算法·动态规划·代理模式
数字人直播33 分钟前
稳了!青否数字人分享3大精细化AI直播搭建方案!
前端·后端
听风的码38 分钟前
Vue2封装Axios
开发语言·前端·javascript·vue.js
肉夹馍不加青椒42 分钟前
第三十三天(信号量)
java·c语言·算法
掘金一周1 小时前
被老板逼出来的“表格生成器”:一个前端的自救之路| 掘金一周 8.21
前端·人工智能·后端
cc_z1 小时前
vue代码优化
前端·vue.js