目录
前言
经过前段时间对于Ajax、springboot、vue3以及若依框架的学习,我们进行了一个小组项目,项目的内容是物业管理系统(物业管理系统主要是实现对小区内建筑物、公共设施、业主信息以及各项服务的高效、便捷管理),其中我们小组还添加了关于租房的功能业务。
下面是关于我们这次项目的内容介绍。
一、项目介绍
1、目的和背景
提升物业管理效率:
通过引入信息化管理系统,提高物业管理的效率和准确性,降低人力成本。
推动智慧型社区建设:
作为智慧型社区的重要组成部分,小区物业管理系统有助于实现社区智能化、便捷化和安全化。
加强业主满意度:
通过优化服务流程,提高服务质量,增强业主对物业管理的满意度。
2、项目主要内容
前台:
- 登录注册
- 显示租房信息
- 查看房源详情信息
- 查看个人中心
- 收藏感兴趣的房源
- 历史浏览记录
- 租房下单
- 缴费
后台:
- 登录
- 系统管理
- 租赁管理
- 房屋管理
- 服务请求管理
- 收费管理
- 缴费管理
3、技术介绍
前台内容主要是使用html和Ajax完成
后台内容主要是依靠若依框架使用vue3完成
- Ajax:AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,可以在不重新加载整个页面的情况下,实现网页的局部更新和快速响应。
- Spring Boot:SpringBoot是一个由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。
- Vue3:Vue3是一个轻量、高效、响应式的现代前端框架,用于构建用户界面。引入了许多新功能和性能改进。
- 若依框架:若依框架是基于JAVA语言的开源Web应用程序框架,采用了Spring Boot、SpringCloud等核心技术,同时也支持多种安全框架和持久层框架。
二、功能模块
1、重要文件结构
2、功能实现(部分个人负责模块功能)
2.1 展示房源信息页面
(1)关联表:
(2)主要sql语句
<resultMap id="houseResources" type="House">
<id column="id" property="id"></id>
<result column="lease_time" property="leaseTime"></result>
<result column="status" property="status"></result>
<result column="room_id" property="roomId"></result>
<result column="facilities" property="facilities"></result>
<result column="img" property="img"></result>
<result column="description" property="description"></result>
<result column="price" property="price"></result>
<result column="rental_methods" property="rentalMethods"></result>
<result column="room_num" property="roomNum"></result>
<result column="floor" property="floor"></result>
<result column="room_type" property="roomType"></result>
<result column="area" property="area"></result>
<result column="user_id" property="userId"></result>
<result column="unit_id" property="unitId"></result>
<result column="toward" property="toward"></result>
<result column="unit_name" property="unitName"></result>
<result column="type" property="type"></result>
<result column="name" property="name"></result>
<result column="completion_time" property="completionTime"></result>
<result column="mobile" property="mobile"></result>
<result column="nick_name" property="nickName"></result>
</resultMap>
<select id="queryByStatus" resultMap="houseResources">
SELECT h.*,
r.*,
hu.unit_name,
hb.*,
u.mobile,
u.nick_name
FROM house_resources h
JOIN room r ON h.room_id = r.id
JOIN house_unit hu ON r.unit_id = hu.id
JOIN house_building hb ON hu.build_id = hb.id
left JOIN `sys_user` u ON u.user_id = r.user_id
WHERE h.STATUS = "0"
</select>
<select id="queryByPage" parameterType="HouseConditionVO" resultMap="houseResources">
SELECT
h.*,
r.*,
hu.unit_name,
hb.*,
u.mobile,
u.nick_name
FROM
house_resources h
JOIN room r ON h.room_id = r.id
JOIN house_unit hu ON r.unit_id = hu.id
JOIN house_building hb ON hu.build_id = hb.id
left JOIN `sys_user` u ON u.user_id = r.user_id
<where>
h.STATUS = "0"
<if test="roomType != ''">
and room_type like '%${roomType}%'
</if>
</where>
limit ${(pageIndex - 1) * pageCount},#{pageCount}
</select>
(3)控制层 (查询与分页)
@GetMapping(value = {"/index","/8080/index"})
@ResponseBody
public Map show() throws Exception {
Map map = new HashMap<>();
List<House> house = houseService.queryByStatus();
map.put("code","200");
map.put("msg","查询成功");
map.put("data",house);
return map;
}
@GetMapping(value = {"/queryByPage","/8080/queryByPage"})
@ResponseBody
public PageBean queryByPage(HouseConditionVO houseConditionVO){
//调用分页条件查询,响应分页模型对象
PageBean<House> house = houseService.queryByPage(houseConditionVO);
return house;
}
(4)页面显示(Ajax代码)
包含点击图片时跳转到详情页面
<script type="text/javascript">
var tId;
$(function () {
loadbypage(pageindex);
$("#TypeSearch").click(function () {
loadbypage(1);
})
});
var pageindex = 1;
var pagecount = 6;
var totalpage = 0;
function loadbypage(index) {
pageindex = index;
$.ajax({
url: "/house/8080/queryByPage",
type: "get",
data: {
roomType: $("#roomType").val(),
pageIndex: pageindex,
pageCount: pagecount
},
dataType: "json",
success: function (result) {
//获取分页的属性值
pageindex = result.currentPage;
pagecount = result.rows;
totalpage = result.totalPage;
var jsons = result.list;
//清空表格主体内容
$("#pro").empty();
//循环json数组将值绑定到表格中
var str = "";
for (let i = 0; i < jsons.length; i++) {
//获取循环的某一个json对象 {}
var pro = jsons[i];
str = "<div id='room' class=\"list-item\" style='width: 100%;' >\n" +
"<a href='javascript:void(0)' onclick='detailsProduct(" + pro.id + ")'>\n" +
" <img class=\"item-image\" src='" + pro.img + "' alt=\"图片1\" display='inline-block' width='270px' />\n" +
" <div class=\"item-description\" style='display:inline-block;vertical-align: top' >\n" +
" <h3 class=\"item-title\">幸福里" + pro.name + pro.unitName + "</h3>\n" +
" <p class=\"item-text\">" + pro.roomType + " | " + pro.area + "平米</p>\n" +
" <div class=\"item-actions\">\n" +
" <button class=\"item-button\">" + pro.rentalMethods + "</button>\n" +
" <span class=\"item-span\">" + pro.price + "元/月</span>\n" +
" </div>\n" +
" </div>\n" +
" </div>";
//循环向指定标签对象中追加元素内容
$("#pro").append(str);
}
//绑定分页链接
var pageStr = '<span><b style="margin-left: 110px">总计:' + result.totalCount + '条</b></span>';
//当前页面不等于1时
if (pageindex != 1) {
pageStr += '<a href = "javascript:void(0)" style="color:#000000";style="margin-left: 186px;" onclick="loadbypage(pageindex - 1)"><button class="page-link">上一页</button></a>';
}
for (let i = 1; i <= totalpage; i++) {
if (i == pageindex) {
pageStr += '<span>[' + i + ']</span>';
} else {
pageStr += '<a href="javascript:void(0)" style="color:black";style="margin-left: 186px;" onclick="loadbypage(' + i + ')"><button class="page-link active">' + i + '</button></a>';
}
}
//当前页面不等于最后一页时
if (pageindex != totalpage) {
pageStr += '<a href = "javascript:void(0)" style="color:black";style="margin-left: 186px;" onclick="loadbypage(pageindex + 1)"><button class="page-link">下一页</button></a>';
}
$("#pageDiv").empty();
$("#pageDiv").append(pageStr);
}
});
}
//内容的跳转
function detailsProduct(id) {
tId = localStorage.getItem("tId"); // 获取租户的id
$.ajax({
url: "/history/8080/add",
type: "post",
//contentType: "application/json",
data: {
hrId: id,
tId: tId
},
dataType: "json",
success:function (){
localStorage.setItem("id", id);
location.href = "details.html";
}
});
}
</script>
2.2 房屋详情页面
(1)关联表(同房源信息展示)
(2)主要sql语句
<select id="queryAllById" parameterType="Long" resultMap="houseResources">
SELECT h.*,
r.*,
hu.unit_name,
hb.*,
u.mobile,
u.nick_name
FROM house_resources h
JOIN room r ON h.room_id = r.id
JOIN house_unit hu ON r.unit_id = hu.id
JOIN house_building hb ON hu.build_id = hb.id
left JOIN `sys_user` u ON u.user_id = r.user_id
WHERE h.STATUS = "0"
and h.id = #{id}
</select>
(3)控制层
@GetMapping(value = {"/{id}","/8080/{id}"})
@ResponseBody
public ResponseData<House> getById(@PathVariable Long id) throws Exception {
return ResponseDataUtil.buildOk(houseService.queryAllById(id));
}
(4)页面显示(主要Ajax代码)
$(function() {
//获取路径地址中的编号
id = localStorage.getItem("id");
});
function loadPage(id) {
$.get("/house/8080/"+id,{
id:id
},function (result) {
if (result.meta.status == 200) {
var pro = result.data;
$("#img").attr("src",pro.img);
$("#name").html("幸福里"+pro.name+pro.unitName);
$("#roomNum").html(pro.roomNum);
$("#roomType").html(pro.roomType);
$("#area").html(pro.area);
$("#price").html(pro.price+"/月");
$("#mobile").html(pro.mobile);
}
},"json");
}
2.3 房源信息管理
(1) 页面显示
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="租赁时间" prop="leaseTime">
<el-input
v-model="queryParams.leaseTime"
placeholder="请输入租赁时间"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="房间号" prop="roomNum">
<el-input
v-model="queryParams.roomNum"
placeholder="请输入房间号"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="卧室设施" prop="facilities">
<el-input
v-model="queryParams.facilities"
placeholder="请输入卧室设施"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input
v-model="queryParams.description"
placeholder="请输入描述"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="价格" prop="price">
<el-input
v-model="queryParams.price"
placeholder="请输入价格"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['system:resources:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:resources:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:resources:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['system:resources:export']"
>导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="resourcesList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="房源编号" align="center" prop="id" />
<el-table-column label="租赁时间" align="center" prop="leaseTime" />
<el-table-column label="是否出租" align="center" prop="status">
<template #default="scope">
<span>{{ getStatusText(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column label="房间号" align="center" prop="roomNum" />
<el-table-column label="楼栋" align="center" prop="name" />
<el-table-column label="单元" align="center" prop="unitName" />
<el-table-column label="卧室设施" align="center" prop="facilities" />
<el-table-column label="图片" align="center" prop="img" width="100">
<template #default="scope">
<image-preview :src="scope.row.img" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="描述" align="center" prop="description" />
<el-table-column label="价格" align="center" prop="price" />
<el-table-column label="租房方式" align="center" prop="rentalMethods" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:resources:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:resources:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改房源对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="resourcesRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="租赁时间" prop="leaseTime">
<el-input v-model="form.leaseTime" placeholder="请输入租赁时间" />
</el-form-item>
<el-form-item label="房间ID" prop="roomId">
<el-input v-model="form.roomId" placeholder="请输入房间ID" />
</el-form-item>
<el-form-item label="卧室设施" prop="facilities">
<el-input v-model="form.facilities" placeholder="请输入卧室设施" />
</el-form-item>
<el-form-item label="图片" prop="img">
<image-upload v-model="form.img"/>
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input v-model="form.description" placeholder="请输入描述" />
</el-form-item>
<el-form-item label="价格" prop="price">
<el-input v-model="form.price" placeholder="请输入价格" />
</el-form-item>
<el-form-item label="租房方式" prop="rentalMethods">
<el-input v-model="form.rentalMethods" placeholder="请输入租房方式" />
</el-form-item>
<el-form-item label="是否出租" prop="status">
<el-radio-group v-model="form.status">
<el-radio :label="1">已出租</el-radio>
<el-radio :label="0">未出租</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Resources">
import { listResources, getResources, delResources, addResources, updateResources } from "@/api/rent/resources";
const { proxy } = getCurrentInstance();
const resourcesList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
leaseTime: null,
status: null,
roomNum: null,
facilities: null,
img: null,
description: null,
price: null,
rentalMethods: null
},
rules: {
roomId: [
{ required: true, message: "外键列不能为空", trigger: "blur" }
],
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询房源列表 */
function getList() {
loading.value = true;
listResources(queryParams.value).then(response => {
resourcesList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
// 取消按钮
function cancel() {
open.value = false;
reset();
}
//0:未出租 1:已出租
function getStatusText(row) {
return row.status == 1 ? '已出租' : '未出租';
}
// 表单重置
function reset() {
form.value = {
id: null,
leaseTime: null,
status: null,
roomId: null,
facilities: null,
img: null,
description: null,
price: null,
rentalMethods: null
};
proxy.resetForm("resourcesRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加房源";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
const _id = row.id || ids.value
getResources(_id).then(response => {
form.value = response.data;
open.value = true;
title.value = "修改房源";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["resourcesRef"].validate(valid => {
if (valid) {
if (form.value.id != null) {
updateResources(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addResources(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _ids = row.id || ids.value;
proxy.$modal.confirm('是否确认删除房源编号为"' + _ids + '"的数据项?').then(function() {
return delResources(_ids);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
proxy.download('system/resources/export', {
...queryParams.value
}, `resources_${new Date().getTime()}.xlsx`)
}
getList();
</script>
(2)api方法
import request from '@/utils/request'
// 查询房源列表
export function listResources(query) {
return request({
url: 'house/list',
method: 'get',
params: query
})
}
// 查询房源详细
export function getResources(id) {
return request({
url: 'house/room/' + id,
method: 'get'
})
}
// 新增房源
export function addResources(data) {
return request({
url: 'house',
method: 'post',
data: data
})
}
// 修改房源
export function updateResources(data) {
return request({
url: 'house',
method: 'put',
data: data
})
}
// 删除房源
export function delResources(id) {
return request({
url: 'house/' + id,
method: 'delete'
})
}
(3)增加修改页面
三、功能模块页面
1、前台模块
(1)登录注册
(2)显示租房信息
(3)查看房源详情信息
(4)个人中心(用户登录后在个人中心可以显示个人信息)
(5)收藏感兴趣的房源
(6)历史浏览记录
(7)租房下单
(8)缴费
2、后台模块
(1)登录
(2)系统管理(包含用户管理、角色管理、菜单管理、字典管理)
如:用户管理
(3)租赁管理(包含租赁订单管理、房源信息管理)
如:房源信息管理
(4)房屋管理(包含楼栋管理、单元管理、房间管理)
如:房间管理
(5)服务请求管理(包含报修信息管理、投诉信息管理)
如:报修信息管理
(6)收费管理(包含水费余额、电费余额)
如:水费余额
(7)缴费管理(包含电费缴费记录、水费缴费记录)
如: 电费缴费记录
四、总结
- 深刻体会到了团队协作与项目管理的重要性,及时与团队成员的交流和讨论还是很重要的,只有这样问题才能快速解决项目中遇到的问题
- 经过这次的项目又重新的让我熟练使用Ajax技术
- 熟悉了若依框架,能够快速的写出若依框架的一些简单功能