基于Uni-app的体育场馆预约系统的设计与实现

文章目录

    • 基于Uni-app的体育场馆预约系统的设计与实现
        • 1、前言介绍
        • 2、开发技术简介
        • 3、系统功能图
        • 3、功能实现
        • 4、库表设计
        • 5、关键代码
        • 6、源码获取
        • 7、 🎉写在最后

基于Uni-app的体育场馆预约系统的设计与实现

1、前言介绍

伴随着信息技术与互联网技术的不断发展,校园也进到了一个新的信息化时代,传统管理技术性没法高效率、容易地管理体育场预约信息内容。为了实现时代的发展必须,提升体育场预约高效率,各种各样体育场预约体系应时而生,体育场预约管理系统的实现是信息内容时代浪潮时代的产物之一。一切系统都要遵循系统设计的基本流程。它还需要通过市场调查、需求分析报告、汇总设计、详尽设计以及测试,根据Node语言表达设计,完成体育场预约管理系统。该系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Node技术,前端采用uniapp微信小程序等技术实现,选用MySQL作为后台系统。
本体育场预约管理系统采用前后端分离的方式来实现,前端Vue、Element组件编写前端代码为主、其特点可以实时渲染加载数据,不用像以前传统的页面,写完要重新启动项目才能加载数据。系统还采用的File文件组件上传和预览图片等,以及前端利用了第三方富文本编辑器框架技术实现了医生详情介绍和系统公告等模块。这样比传统文本框只能填写文字又来更好更直观的页面呈现方式。不仅可以上传文字,还可以直接复制网页图片文字等。实现动态渲染页面样式和内容等。

2、开发技术简介

本节介绍场馆预约平台用到的一些技术和开发环境的简介,用到开发技术主要包括:
(1)前端用到Element UI组件库和Vue框架
(2)后端用到Node
(3)包管理器Npm
(4)中间件Express
(5)数据库MySQL
系统开发环境主要是:前端开发工具Vscode,Hbuilder、操作系统Win10、CPU i5-9300H、内存8G。

在这里插入图片描述

3、系统功能图

Uniapp场馆预约系统主要由客户端(微信小程序和安卓手机App)和Web管理端(基于Web服务器Apache Tomcat,MySQL数据库)这两个子系统组成。这两个子系统之间通过Htpp的request请求和response响应以json形式的数据交互,共同实现了场馆预约平台的功能。
客户服务端主要包括三大主要的功能模块:登录、预约和扫码签到模块。Web管理端主要包括三大主要的功能模块:用户、动态和预约模块。这六大模块还有相应的子模块,通过对子模块的实现来实现整个客户端的功能。如图4-3所示。

在这里插入图片描述

3、功能实现

系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。下图就是管理员登录页面。
在这里插入图片描述
项目管理页面提供的功能操作有:查看体育场馆,删除体育场馆操作,新增体育场馆操作,修改体育场馆操作。下图就是体育场馆管理页面。
在这里插入图片描述
公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。下图就是公告信息管理页面。

在这里插入图片描述
项目管理页面提供的功能操作有:查看体育场馆,删除体育场馆操作,新增体育场馆操作,修改体育场馆操作。下图就是体育场馆管理页面。
在这里插入图片描述
如下是小程序端
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4、库表设计

程序设计是离不开对应数据库的设计操作的,这样的做法就是减少数据对程序的依赖性,所以数据库的设计也是需要花费大量的日常时间来进行设计的,在设计中对程序开发需要存储的数据信息进行实体划分,先确认实体,然后设计实体的属性等操作,这种设计就是数据库设计里面不能少的必须有的E-R模型设计。为了降低程序设计的对应的数据库设计难度,开发人员也可以使用相应的工具来进行E-R模型设计,现在市面上设计E-R模型的工具有PowerDesigner建模工具,Navicat制作工具,还有微软的Visio绘图工具。为了简便起见,本程序在设计E-R模型的时候,就选用了微软的Visio这款功能强大,操作便利的绘图工具。

1.预约实体及其附属图
在这里插入图片描述
2.用户实体及其附属图
在这里插入图片描述
3.下图是公告实体和其具备的属性
在这里插入图片描述

5、关键代码
<template>
  <div>
    <el-dialog title="添加新闻" :visible.sync="dialogVisible" width="40%">
      <!-- 上传组件 -->
      <el-form ref="form" :rules="rules" :model="form" label-width="80px">
        <el-form-item label="标题" prop="title">
          <el-input v-model="form.title"></el-input>
        </el-form-item>
        <el-form-item label="上传图片">
          <commonUpload></commonUpload>
        </el-form-item>
        <el-form-item label="预约须知" prop="desc">
          <quill-editor
            ref="myQuillEditor"
            v-model="form.desc"
            class="editor"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="margin-right: 25%">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addDymic">确 定</el-button>
      </span>
    </el-dialog>
    <div class="manage-hander">
      <!-- 添加按钮 -->
      <!-- <el-button type="primary" @click="handleAdd">+ 新增</el-button> -->
    </div>
    <!-- 表格 -->
    <el-table
      :data="tableData"
      style="width: 100%"
      stripe
      height="650px"
      v-loading="loading"
    >
      <el-table-column label="标题" prop="username"> </el-table-column>
      <el-table-column label="图片" prop="userImg">
        <template slot-scope="scope">
          <el-image
            style="width: 150px; height: 100px"
            :src="scope.row.imgUrls[0]"
            :preview-src-list="[scope.row.imgUrls[0]]"
          >
          </el-image>
        </template>
      </el-table-column>
      <el-table-column label="内容" prop="desc" width="500rpx">
        <template slot-scope="scope">
          <el-popover
            placement="top-start"
            title="全部内容"
            width="500"
            trigger="hover"
            :content="scope.row.desc"
          >
            <div slot="reference" class="text">{{ scope.row.desc }}</div>
          </el-popover>
        </template>
      </el-table-column>
      <el-table-column prop="allow" label="审核">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.allow"
            active-color="#13ce66"
            inactive-color="#ff4949"
            active-value="1"
            inactive-value="0"
            @click.native="handle(scope.row)"
          >
          </el-switch>
        </template>
      </el-table-column>
      <el-table-column label="上传时间" prop="uploadTime"> </el-table-column>
      <el-table-column align="right" label="操作">
        <template slot-scope="scope">
          <el-button size="mini" type="danger" @click="handleDelete(scope.row)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      class="page"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage"
      :page-sizes="pageSizes"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next"
      :total="totalCount"
    >
    </el-pagination>
  </div>
</template>

<script>
const moment = require("moment");
import {
  getDynamic,
  addDynamic,
  deleteDynamic,
  updataIdDynamic,
} from "../api/dynamic";
import commonUpload from "@/components/commonUpload.vue";
export default {
  data() {
    return {
      form: {
        username: "",
        userImg: "",
        desc: "",
        uploadTime: "",
        allow: "",
      },
      rules: {
        name: [{ required: true, message: "请输入标题", trigger: "blur" }],
        desc: [
          {
            required: true,
            message: "请输入内容",
            trigger: "blur",
          },
        ],
      },
      tableData: [],
      // 默认显示第几页
      currentPage: 1,
      // 总条数,根据接口获取数据长度(注意:这里不能为空)
      totalCount: "",
      // 个数选择器(可修改)
      pageSizes: [4, 6, 8],
      // 默认每页显示的条数(可修改)
      PageSize: 1,
      dialogVisible: false,
      loading: true,
    };
  },
  components: {
    commonUpload,
  },
  methods: {
    handleAdd() {
      this.dialogVisible = true;
    },
    addDymic() {
      this.form.imgUrl = this.$store.state.upload.imgUrl;
      this.form.createTime = moment().format("YYYY-MM-DD");
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.dialogVisible = false;
          addDynamic(this.form).then((res) => {
            console.log("333", res);
          });
          this.$message({
            type: "success",
            message: "添加成功",
          });
          this.getList();
        }
      });
    },
    handle(e) {
      console.log();
      // let id = res.id;
      this.$confirm("审核通过吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then((res) => {
        console.log("44");
        updataIdDynamic(e).then((res1) => {
          console.log(res1.data.data);
          this.$message.success(res1.data.data.msg);
        });
      });
    },
    //分页
    handleCurrentChange(val) {
      let currentPage = {
        currentPage: val,
      };
      getDynamic(currentPage).then((res) => {
        setTimeout(() => {
          this.loading = false;
          this.tableData = res.data.results;
        }, 200);
      });
    },
    //分页每页显示多少
    handleSizeChange(val) {
      let pageSize = {
        pageSize: val,
      };
      getDynamic(pageSize).then((res) => {
        setTimeout(() => {
          this.loading = false;
          this.tableData = res.data.results;
        }, 200);
      });
    },
    // 获取数据
    getList() {
      getDynamic().then((res) => {
        let a = res.data.results;
        a.forEach((obj) => {
          const imgString = obj.imgUrl;
          const trimmedString = imgString.replace('["', "").replace('"]', "");
          const imgArray = trimmedString.split('"\,"');
          obj.imgUrls = imgArray;
        });
        console.log(a);
        this.tableData = a;

        this.totalCount = res.data.total;
        setTimeout(() => {
          this.loading = false;
        }, 500);
      });
    },
    // 删除数据
    handleDelete(res) {
      let id = {
        id: res.id,
      };
      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 调用删除接
          deleteDynamic(id).then(() => {
            this.$message({
              type: "success",
              message: "删除成功!",
            });
          });
          this.getList();
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
  },
  mounted() {
    this.getList();
  },
};
</script>

<style lang="less">
.manage-hander {
  margin-bottom: 10px;
}
.upload {
  margin-left: 15%;
}
.page {
  position: absolute;
  bottom: 50px;
  right: 20px;
}
.text {
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}
</style>

<template>
	<view class="content">
		<view v-for="item in newList" :key="item.id">
			<view class="title">{{ item.name }}</view>
			<view class="time">{{item.uploadTime}}</view>
			<rich-text :nodes="item.desc" class="text"></rich-text>
			<view class="img" @click="previewImg(item.imgUrl)"><img :src="item.imgUrl" alt="" /></view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			newList: [],
		};
	},
	onLoad(res) {
		uni.showLoading({
			title: '加载中',
			mask:true
		});
		uni.request({
			url: '/api/index/searchNews?id=' + res.id,
			method: 'POST',
			success: res => {
				console.log(res.data);
				this.newList = res.data;
				uni.setNavigationBarTitle({
					title:this.newList[0].name
				})
				setTimeout(function () {
					uni.hideLoading();
				}, 200);
			},
			fail: () => {},
			complete: () => {}
		});
	},
	methods: {
		previewImg(urlimg) {
			let _this = this;
			let imgsArray = [];
			imgsArray[0] = urlimg;
			uni.previewImage({
				current: 0,
				urls: imgsArray
			});
		},
	}
};
</script>

<style lang="less">
page {
	background-color: #efefef;
}
.content {
	margin-top: 20rpx;
	border-radius: 20rpx;
	margin-left: 2%;
	width: 90%;
	background-color: white;
	padding: 10rpx 20rpx;
	.title {
		padding: 10rpx 0;
		font-size: 35rpx;
		font-weight: 700;
	}
	.time {
		padding: 10rpx 0;
		font-size: 20rpx;
		color: gray;
	}
	.item {
		font-size: 30rpx;
		color: gray;
		text-indent: 2em;
		text-align: justify;
		line-height: 50rpx;
	}
	.img img {
		width: 100%;
		border-radius: 20rpx;
	}
	.text{
		text-indent: 2em;
		letter-spacing: 2rpx;
		line-height: 55rpx;
		color: #666;
	}
}
</style>

6、源码获取

大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻
** vx: code8896**

7、 🎉写在最后

🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star ✨支持一下哦!手动码字,如有错误,欢迎在评论区指正💬~

你的支持就是我更新的最大动力💪~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/506484.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

服务器固定IP(固定出口IP)去访问外部服务

背景 服务器上有多个IP&#xff0c;那么在服务器请求外部服务的时候&#xff0c;到底是使用哪个IP呢&#xff1f;如果要使用特定的IP去请求外部服务&#xff0c;该如何设置呢&#xff1f; 分析 遇到一个实际的场景&#xff1a; 我们产品和其他产品联调&#xff0c;我们的服务…

软考历史题目

2023.3 1. 磁盘索引块1KB,每个地址项4字节&#xff0c;每个磁盘索引块可以存放256个物理块地址 2.5个地址项为直接索引地址&#xff0c;所以0-5逻辑块是直接索引 3.一级间接地址索引&#xff0c;每个指向的物理块存255个地址 4.二级间接地址&#xff1a;256个间接索引表地址…

Php_Code_challenge16

题目&#xff1a; 答案&#xff1a; 解析&#xff1a; 所以科学计数法绕过即可。

蓝桥杯练习系统(算法训练)ALGO-963 转圈游戏

资源限制 内存限制&#xff1a;128.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 n个小伙伴&#xff08;编号从0到n-1&#xff09;围坐一圈玩游戏。按照顺时针方向给n个位置编号&#xff0c;从0到n-1。   …

Windows 电脑麦克风 自动启用/禁用 小玩具!

WinMicrophone Windows 系统的 麦克风设备&#xff08;启用/禁用&#xff09;切换驱动&#xff01;它是小巧且快速的&#xff0c;它能够自动的检测并切换麦克风的情况。 您可以在软件包仓库中找到发布版本的exe包&#xff0c;无需安装&#xff01;其能够大大增大您在Windows中…

家用储能配套用AKH-0.66 K-Φ16-HM 开口电流互感器-安科瑞 蒋静

1.产品特点 产品外形美观&#xff0c;安装、接线方便&#xff0c;专用于通讯机房 100A 及以下配电系统改造&#xff0c;可与 AMC16 多回路监控仪表配合使用。 2.型号说明 3.外形尺寸(公差&#xff1a;2mm) 注&#xff1a;引线长度为 2 米 2*26AWG 护套线&#xff0c;线头…

认识V模型、W模型、H模型

软件测试与软件工程息息相关&#xff0c;软件测试是软件工程组成中不可或缺的一部分。 在软件工程、项目管理、质量管理得到规范化应用的企业&#xff0c;软件测试也会进行得比较顺利&#xff0c;软件测试发挥的价值也会更大。 要关注软件工程、质量管理以及配置管理与软件测试…

Stream流的详细说明

什么是stream流 Stream流是指一种数据处理的概念&#xff0c;它可以将数据以连续的方式传输&#xff0c;而不用等待整个数据集全部加载完成。在计算机编程中&#xff0c;Stream流通常用于处理大数据集或实时数据流。 Stream流可以分为输入流和输出流&#xff0c;输入流用于从数…

56 如何调试 npm run build 的代码/如何在测试环境,预发布环境进行调试

前言 测试环境/预发布环境 如何进行调试 这里主要是 提及一些一个 模拟的生产环境, 应该如何测试 比如 上线之前, 或者 线上出现问题, 需要 hotfix 的场景下 我们应该怎么 在一个 测试环境/预发布 的环境下面 进行一个模拟的调试呢? 对于 如果是没有网络请求的项目, 甚至…

【yy讲解PostCSS是如何安装和使用】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

STM32 uC/OS-III

What is uC/OS-III? C/OS-III 的发音为“Micro C O S Three”&#xff0c;这意味着 C/OS-III 是基于 C 语言编写的第三代 小型操作系统&#xff0c;当然这里所说的第三代是相对于 C/OS 的前两个版本 C/OS 和 C/OS-II 而言 的&#xff0c;后面也会介绍这三个版本的差别。C/OS/…

Vue前端项目打包

4.1编译打包 npm run build 4.2 前端项目 nginx的配置文件default.conf 和 dockerfile default.conf upstream wms-app { server 192.168.14.3:3666 ; server 192.168.14.3:3777 ; } server { listen 80; listen [::]:80; server_name localhost; access_log /var/log/nginx…

毛利率低从哪些维度分析?零售服装行业如何提升毛利率?

在零售服装行业中&#xff0c;毛利率是评估公司盈利能力的关键指标之一。然而&#xff0c;某服装公司在一段时间内销售总额达到5878.28万&#xff0c;但其总毛利额仅为591.26万&#xff0c;平均毛利率仅为10.06%。这一数字明显低于了服装行业通常的毛利率范围&#xff08;一般在…

语义分割——Dark Zurich数据集

一、重要性及意义 首先&#xff0c;Dark Zurich为语义分割提供了大量真实且多样化的图像数据。该数据集包含了在夜间、黄昏和白天拍摄的大量图像&#xff0c;涵盖了不同光照条件和场景下的图像变化。这些图像数据不仅丰富了语义分割任务的数据集&#xff0c;也为模型提供了更全…

政安晨:【Keras机器学习实践要点】(七)—— 使用TensorFlow自定义fit()

目录 前言 导入 来一个简单例子 下沉到更低的级别 支持样本权重和类别权重 提供您自己的评估步骤 总结&#xff1a;一个端到端的GAN示例 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的…

【Linux】TCP网络套接字编程+守护进程

文章目录 日志类&#xff08;完成TCP/UDP套接字常见连接过程中的日志打印&#xff09;单进程版本的服务器客户端通信多进程版本和多线程版本守护进程化的多线程服务器 日志类&#xff08;完成TCP/UDP套接字常见连接过程中的日志打印&#xff09; 为了让我们的代码更规范化&…

3万字80道Java基础经典面试题总结(2024修订版)

大家好&#xff0c;我是哪吒。 本系列是《10万字208道Java经典面试题总结(附答案)》的2024修订版。 目录 1、说说跨平台性2、Java是如何实现跨平台性的&#xff1f;3、JDK 和 JRE 有什么区别&#xff1f;4、为何要配置Java环境变量&#xff1f;5、Java都有哪些特性&#xff1f…

(八)Gateway服务网关

Gateway服务网关 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关&#xff0c;它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。…

Linux/Headless

Headless Enumeration nmap 用 nmap 扫描了常见的端口&#xff0c;发现对外开放了 22 和 5000&#xff0c;而且 nmap 显示 5000 端口的服务是 upnp&#xff1f; ┌──(kali㉿kali)-[~/vegetable/HTB/headless] └─$ nmap 10.10.11.8 Starting Nmap 7.93 ( https://nmap.or…

打造安全医疗网络:三网整体规划与云数据中心构建策略

医院网络安全问题涉及到医院日常管理多个方面&#xff0c;一旦医院信息管理系统在正常运行过程中受到外部恶意攻击&#xff0c;或者出现意外中断等情况&#xff0c;都会造成海量医疗数据信息的丢失。由于医院信息管理系统中存储了大量患者个人信息和治疗方案信息等&#xff0c;…