uniapp+springboot实现简单失物招领

10 篇文章 0 订阅


前言

本文主要讲解如何实现失物招领在uniapp+springboot中的实现,其中前端包括v-model,uni-request的简单使用,后端包括增删改查+模糊查询等接口实现。
编译器:idea+Hbuilder
运行器:微信开发者工具


一、实现步骤

流程如下:构思=>制作数据表=>配置springboot基础设置+uniapp的css样式和template结构=>后端实体类、mapper接口、mapper.xml、service、serviceimpl实体类、Controller控制层=>postman测试接口是否好用=>前端利用uni.request调用接口=>测试。

二、实现

1.创建数据表

代码如下(示例):

-- 创建 stype 表
CREATE TABLE stype (
  sid INT PRIMARY KEY,     -- 物品类型ID
  sname VARCHAR(255)      -- 物品类型名称
);

-- 创建 lost 表
CREATE TABLE lost (
  id INT PRIMARY KEY,       -- 失物ID
  uid INT,                  -- 用户ID
  lostType INT,             -- 所属商品类型ID
  lostName VARCHAR(255),    -- 失物名称
  losttime DATETIME,        -- 失物时间
  lostphone VARCHAR(20),    -- 联系电话
  detail TEXT,              -- 失物详情
  FOREIGN KEY (lostType) REFERENCES stype(sid) -- 外键关联到 stype 表的 sid 字段
);

首先创建两个数据表,一个用于存储用户失物的具体数据,另一个用于装物品类型。

2.引入pom和配置maven

pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.shop</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project> <!--在build中配置resources,来防止我们资源导出失败的问题!-->
<build>
<resources>
    <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.properties</include>/
            <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
    </resource>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.properties</include>/
            <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
    </resource>
</resources>

</build>

注:springboot版本最好设置3.0以下版本,不然可能后续会有问题。
除了必需的springboot之外,还需要lombok,虽然它的安全性低,但是它会省去实体类中的get、set方法,可以用@Data代替,还需要引入mysql、mybatis等插件,这里就不细说了。

maven配置:

点击file=>setting=>搜索框搜索maven,把里面的Maven home directory、User settings file和Local repository配置成自己的,如果电脑没有maven也可以不配置用本地的,
Maven下载地址:https://maven.apache.org/download.cgi
在这里插入图片描述

3.uniapp的样式和结构

可以通过自己画图来做,也可以通过花瓣等UI库中找自己喜欢的样式来制作,在做样式的过程中可能会用到图标,这里推荐阿里巴巴图标库,免费还比较全面,下载即用。地址放下面了。
https://www.iconfont.cn/
下面放一下我做的两个样式图
在这里插入图片描述
在这里插入图片描述
因为只是想练习功能调用和实现,所以样式后续可以再调整。

4.后端实体类、mapper接口、mapper.xml、service、serviceimpl实体类、Controller控制层实现

实体层

package com.shop.demo.pojo;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigInteger;
import java.util.Date;

@Data
public class lost {
    private Integer id;
    private Integer uid;
    private Integer lostType;
    private String sname;
    private String lostName;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date losttime; // 使用java.util.Date类型
    private BigInteger lostphone;
    private String detail;
    private String lostlocation;
}

mapper接口

package com.shop.demo.mapper;

import com.shop.demo.pojo.lost;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface lostmapper {
//    全部查询
    public List<lost> lostquery();
//    增加失物
    public int lostadd(lost ll);
//    删除失物
    public int lostdel(int id);
//    根据名字查询
    public List<lost> lostqueryByName(String lostName);
//    修改自己发布的物品
    public int lostupdata(lost l);
//    根据id查询
    public List<lost> lostqueryById(int uid);
}

mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.shop.demo.mapper.lostmapper">
    <update id="lostupdata">
        update lost set id=#{id}, lostType=#{lostType},lostName=#{lostName},losttime=#{losttime},lostphone=#{lostphone},detail=#{detail},lostlocation=#{lostlocation} where id=#{id}
    </update>
    <delete id="lostdel" parameterType="int">
        delete from lost where id=#{id}
    </delete>
    <insert id="lostadd" parameterType="com.shop.demo.pojo.lost">
    INSERT INTO lost(id, uid, lostType, lostName, losttime, lostphone, detail,lostlocation)
    VALUES (#{id}, #{uid}, #{lostType}, #{lostName}, #{losttime}, #{lostphone}, #{detail},#{lostlocation})
</insert>

    <select id="lostquery" resultType="com.shop.demo.pojo.lost">
    SELECT lost.id, lost.uid, stype.sname, lost.lostName, lost.losttime, lost.lostphone, lost.detail,lost.lostlocation
    FROM lost JOIN stype ON lost.lostType = stype.sid
</select>

    <select id="lostqueryByName" resultType="com.shop.demo.pojo.lost">
            select * from lost where 1=1
            <if test="lostName!=null and lostName!=''">
                and lostName like concat('%',#{lostName},'%')     </if>
    </select>
    <select id="lostqueryById" resultType="com.shop.demo.pojo.lost">
    select lost.* from lost, user where lost.uid=user.id
</select>

</mapper>

service层

package com.shop.demo.service;

import com.shop.demo.pojo.lost;

import java.util.List;

public interface lostservice {
    List<lost> lostquery();
    int lostadd(lost ll);
    int lostdel(int id);
    List<lost> lostqueryByName(String lostName);
    int lostupdata(lost l);
    List<lost> lostqueryById(int uid);
}

service实体类

package com.shop.demo.service;

import com.shop.demo.mapper.lostmapper;
import com.shop.demo.pojo.lost;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
public class lostserviceimpl implements lostservice {
    @Autowired
    lostmapper l;

    @Override
    public List<lost> lostquery(){
        return l.lostquery();
    }

    @Override
    public int lostadd(lost ll){
        return l.lostadd(ll);
    }

    @Override
    public int lostdel(int id){return l.lostdel(id);}

    @Override
    public List<lost> lostqueryByName(String lostName)
    {
        return l.lostqueryByName(lostName);
    }

    @Override
    public int lostupdata(lost ll)
    {
        return l.lostupdata(ll);
    }

    @Override
    public List<lost> lostqueryById(int uid)
    {
        return l.lostqueryById(uid);
    }
}

controller控制层

package com.shop.demo.controller;


import com.shop.demo.pojo.lost;
import com.shop.demo.service.lostservice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@ResponseBody
public class lostController {
    @Autowired
    lostservice l;

    @RequestMapping("hello")
    public String hello()
    {
        return "数据库中没有该条件下的数据";
    }

    @RequestMapping("lostquery")
    public List<lost> lostquery()
    {
        return l.lostquery();
    }

    @RequestMapping("lostadd")
    public int lostadd(lost ll){
        return l.lostadd(ll);
    }

    @RequestMapping("lostdel")
    public int lostdel(int id) {return l.lostdel(id);}

    @RequestMapping("lostqueryByName")
    public List<lost> lostqueryByName(String lostName)
    {
        return l.lostqueryByName(lostName);
    }

    @RequestMapping("lostupdata")
    public int lostupdata(lost ll)
    {
        return l.lostupdata(ll);
    }

    @RequestMapping("lostqueryById")
    public List<lost> lostqueryById(int uid)
    {
        return l.lostqueryById(uid);
    }
}

5.Postman测试

这里就不赘述了,放下postman官网,如有需要可自行下载。
https://www.postman.com/

6.前后端数据交互

主要用到的是uni.request和v-model
uni.request语法格式

				uni.request({
					url: '接口地址',
					header: {
						'请求头': 'application/x-www-form-urlencoded'
					},
					method: '方法名',
					data: {
						调用接口数据名称: this.实际在页面中的数据名
					},
					成功的回调函数
					success: (res) => {
						console.log(res)
						
						uni.showToast({
							title: '删除成功',
							duration: 3000
						})
					}
				})

v-model主要应用于表单,可以实现双向绑定。
删改查、模糊查询前端代码:

<template>
	<view class="page">
		<!-- 搜索框 -->
		<view class="search-box">
			<input type="text" v-model="queryByName" placeholder="请输入关键字" />
			<image src="../../static/取消.png" @click="notlostquery" style="width:30px;height:30px;" class="quxiao">
			</image><button @click="lostqueryByName" class="button_">搜索</button>

		</view>

		<!-- 推荐失物 -->
		<h2 class="title_body">最近失物</h2>
		<view v-if="index<4" v-for="(item, index) in LostList" :key="item.id" class="body_type"
			@tap="body_detail(item)">
			<p style="font-size:17px;font-weight:bold;margin:10px;">物品名:{{ item.lostName }}</p>
			<p style="float:left;">时间:{{item.losttime}}</p>
			<p style="float:left;">丢失地点:{{item.lostlocation}}</p>
		</view>
		<!-- 我的失物 -->
		<view>
			<h2 class="title_body">我的发布</h2>
			<view class="body_type" v-for="(item, index) in mylostList" :key="index">
				<p style="font-size:17px;font-weight:bold;">{{ item.lostName }}</p>
				<p>{{ item.losttime }}</p>
				<text @click="lostdel(item.id)" style="font-weight:bold;">删除||</text>
				<text @click="lostupdata(item.id)" style="font-weight:bold;">更新</text>
			</view>
		</view>
		<view v-show="updataflag" class="updata" style="text-align: center;">
			<view style="font-size:30px;margin-bottom: 10px;;">失物更新</view>
			<view style="text-align: left;">
				<input type="text" v-model="lostName" placeholder="请输入物品名" />
				<input type="number" v-model="lostType" placeholder="请输入物品类型" />
				<input type="number" v-model="lostphone" placeholder="请输入联系方式" />
				<input type="text" v-model="losttime" placeholder="丢失时间:yyyy-mm-dd" />
				<input type="text" v-model="lostlocation" placeholder="请输入丢失地点" />
				<input type="text" v-model="detail" placeholder="备注" />
			</view>
			<button style="float: left;width:45%;margin-right:20px;" @tap="upquxiao">取消</button>
			<button style="float:left;width:45%;" @tap="upsub">提交</button>
		</view>
	</view>
</template>

<script>
	import {
		vShow
	} from "vue";
	export default {
		mounted() {
			this.lostquery()
			this.lostqueryById()
		},
		data() {
			return {
				queryByName: "",
				LostList: [],
				mylostList: [],
				lostDelId: null,
				id: null,
				updataflag: false,
				lostName: "",
				lostType: null,
				losttime: "",
				lostphone: null,
				lostlocation: "",
				detail: ""
			};
		},
		methods: {
			body_detail(item) {
				uni.showModal({
					title: "具体内容",
					content: "丢失物品:" + item.lostName + "丢失类型:" + item.sname + "\n" + "丢失时间:" + item.losttime +
						"\n联系方式:" + item
						.lostphone + "\n备注:" + item.detail,
					showCancel: false,
					confirmText: "已查阅"
				})

			},
			lostqueryById() {
				uni.request({
					url: 'http://localhost:8080/lostqueryById',
					data: {
						uid: 1
					},
					success: (res) => {
						console.log(res.data)
						this.mylostList = res.data
						for (let i = 0; i < this.mylostList.length; i++) {
							this.mylostList[i].losttime = this.mylostList[i].losttime.substring(0, 10)
							console.log(this.mylostList[i].losttime)
						}
					}
				})
			},
			lostqueryByName() {
				uni.request({
					url: 'http://localhost:8080/lostqueryByName',
					data: {
						lostName: this.queryByName
					},
					success: (res) => {
						console.log(res.data)
						this.LostList = res.data
						for (let i = 0; i < this.LostList.length; i++) {
							this.LostList[i].losttime = this.LostList[i].losttime.substring(0, 10)
							console.log(this.LostList[i].losttime)
						}
					}
				})
			},
			lostquery() {
				uni.request({
					url: 'http://localhost:8080/lostquery',
					header: {
						'content-type': 'application/x-www-form-urlencoded'
					},
					success: (res) => {
						console.log(res.data)
						this.LostList = res.data
						for (let i = 0; i < this.LostList.length; i++) {
							this.LostList[i].losttime = this.LostList[i].losttime.substring(0, 10)
							console.log(this.LostList[i].losttime)
						}
					}
				})
			},
			lostdel(id) {
				console.log(id)
				this.lostDelId = id
				uni.request({
					url: 'http://localhost:8080/lostdel',
					header: {
						'content-type': 'application/x-www-form-urlencoded'
					},
					method: 'PUT',
					data: {
						id: this.lostDelId
					},
					success: (res) => {
						console.log(res)
						uni.showToast({
							title: '删除成功',
							duration: 3000
						})
					}
				})
				this.lostquery()
			},
			lostupdata(id) {
				this.id = id
				this.updataflag = !this.updataflag
			},
			upquxiao() {
				this.updataflag = !this.updataflag
				this.id=null,
				this.lostName="",
				this.lostType=null,
				this.losttime="",
				this.phone=null,
				this.detail="",
				this.lostlocation=""
				this.lostquery()
			},
			upsub() {
				this.updataflag = !this.updataflag
				console.log(this.id)
				console.log(this.lostType)
				uni.request({
					url: 'http://localhost:8080/lostupdata',
					header: {
						'content-type': 'application/x-www-form-urlencoded'
					},
					method: 'POST',
					data: {
						id:this.id,
						lostType: this.lostType,
						lostName: this.lostName,
						losttime: this.losttime,
						lostphone: this.lostphone,
						detail: this.detail,
						lostlocation: this.lostlocation
					},
					success: (res) => {
						console.log(res)
						this.lostquery()
						this.lostName-"",
						this.id=null,
						this.lostType=null,
						this.losttime="",
						this.phone=null,
						this.detail="",
						this.lostlocation=""
					},

				})
			},
			notlostquery() {
				this.queryByName = ""
				this.lostqueryByName()
			}
		}
	};
</script>

<style>
	page {
		background: #e8e8e8;
	}

	.title_body {
		font-size: 25px;
		font-weight: bold;
	}

	.page {
		padding: 20px;
	}

	.body_type {
		background-color: white;
		text-align: center;
		height: auto;
		display: inline-block;
		width: 43.5%;
		padding: 5px;
		margin: 5px;
		border-radius: 10px;
	}

	input {
		margin-left: 30px;
		width: 200px;
		border: 1px solid gray;
		padding: 7px;
		display: inline-block;
		margin-right: 5px;
	}

	.quxiao {
		position: absolute;
		left: 15px;
		top: 25px;
	}

	.button_ {
		background: linear-gradient(to bottom, #4097e8, #48c3e8);
		color: white;
		border-radius: 10px;
		line-height: 40px;
		width: 80px;
		height: 40px;
		display: inline-block;
	}

	.updata {
		position: fixed;
		bottom: 0;
		background-color: white;
		margin-right: 20px;
	}

	uni-modal .uni-modal__bd {
		white-space: pre-wrap;
	}
</style>

增加前端代码:

<template>
	<form class="form">
		<view class="form-group">
			<label for="studentId">*学号</label>
			<input type="number" id="studentId" name="studentId" v-model="uid" placeholder="请输入您的学号" required>
		</view>
		<view class="form-group">
			<label for="name">*丢失物品名</label>
			<input type="text" id="name" name="name" v-model="lostName" placeholder="请输入丢失物品名" required>
		</view>
		<view class="form-group">
			<label>丢失物品类型</label>
			<view class="radio-group">
				<radio-group name="lostType">
					<label v-for="(item,index) in lostType" @tap="queryType(item.id)">
						<radio value="value" /><text>{{item.name}}</text>
					</label>
				</radio-group>
			</view>
		</view>
		<view class="form-group">
			<label for="name">丢失地点</label>
			<input type="text" id="location" name="location" v-model="lostlocation" placeholder="请输入丢失物品名" required>
		</view>
		<view class="form-group">
			<label for="date">丢失日期</label>
			<input type="text" id="datename" name="datename" v-model="losttime" placeholder="格式:yyyy-mm-dd" required>
		</view>
		<view class="form-group">
			<label for="phone">*联系方式</label>
			<input type="tel" id="phone" name="phone" v-model="lostphone" placeholder="请输入您的手机号码" pattern="[0-9]{11}" required>
		</view>
		<view class="form-group">
			<label for="remark">备注</label>
			<textarea id="remark" name="remark" v-model="detail"></textarea>
		</view>
		<button type="submit" class="btn-submit" @click="sub">提交</button>
	</form>
</template>
<script>
	export default {
		data() {
			return {
				lostType:[
					{id:"1",name:"生活用品"},
					{id:"2",name:"学习用品"},
					{id:"3",name:"电子产品"},
					{id:"4",name:"其他"},
				],
				querytype:null,
				uid:null,
				lostName:"",
				losttime:"",
				lostphone:null,
				detail:"",
				lostlocation:""
			}
		},
		methods: {
			queryType(id){
				this.querytype=id
				console.log(this.querytype)
			},
			sub(){
				if (this.querytype != "" && this.lostName != "" && this.losttime != "" && this.lostphone != null) {
				uni.request({
					url:'http://localhost:8080/lostadd',
					method:'POST',
					header: {
						'content-type': 'application/x-www-form-urlencoded'
					},
					data:{
						uid:this.uid,
						lostType:this.querytype,
						lostName:this.lostName,
						lostphone:this.lostphone,
						losttime:this.losttime,
						detail:this.detail,
						lostlocation:this.lostlocation
					},
					success: (res) => {
						console.log(res.data)
						uni.redirectTo({
							url:'/pages/life/life'
						})
					}
				})
				}
				else{
					uni.showModal({
						content:"带*数据为必填项",
						showCancel:false,
						confirmText:"确认"
					})
				}
				
			}
		}
	}
</script>

<style scoped>
	.form {
		max-width: 500px;
		margin: 0 auto;
		padding: 20px;
		border: 1px solid #ccc;
		border-radius: 5px;
	}

	.form-group {
		margin-bottom: 10px;
	}

	label {
		display: block;
		font-weight: bold;
		margin-bottom: 5px;
	}

	input[type="text"],
	input[type="number"],
	input[type="tel"],
	textarea {
		width: 90%;
		padding: 10px;
		border: 1px solid #ccc;
		border-radius: 3px;
	}

	.radio-group {
		display: flex;
		flex-wrap: wrap;
	}

	.radio-group label {
		display: inline-block;
		margin-right: 20px;
	}

	.datetime-picker {
		width: 100%;
		padding: 10px;
		border: 1px solid #ccc;
		border-radius: 3px;
		font-size: 16px;
	}

	.btn-submit {
		display: block;
		width: 100%;
		padding: 10px;
		background-color: #007aff;
		color: #fff;
		border: none;
		border-radius: 3px;
		cursor: pointer;
	}
</style>

完整的代码会放在我的资源里面,需要可自取。


总结

总共做了一周,零零散散的时间,因为在事先没有做详细的需求调研和需求分析,这对后续的制作造成一些困难,最终是想做一个校园微社区,而失物招领是它的一个功能,希望看到这篇文章的各位能获得一点帮助。

进窄门,行远路,见微光。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃巧克li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值