博主介绍:专注于Java(springboot ssm springcloud等开发框架) vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作
☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟
我的博客空间发布了1000+毕设题目 方便大家学习使用
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人
更多项目地址 介绍 翰文编程-CSDN博客
系统实现预览
系统设计
4.1系统通用功能用例分析
系统的通用功能包括用户登录和密码修改,是三个角色共同需要使用的功能,用例分析如图4-1所示。
图4-1系统通用功能用例分析图
4.2 系统设计主要功能
本系统采用自上往下的方法开发与实现,本课题要求实现一套山西文旅网,系统主要包括管理员模块和运营商、用户模块的功能模块;
(1)运营商用例图如下所示:
图4-2运营商用例图
(2)用户用例图如下所示:
图4-3用户用例图
(2)管理员用例图如下所示:
图4-4管理员用例图
通过市场调研及咨询研究,可以按照用户的角色权限使不同用户角色看到不一样的信息界面。现根据需求阶段的分析,我们可以大致确定系统需要包含的功能如下图4-5所示:
图4-5山西文旅网结构功能图
4.3 数据库设计
4.3.1 数据库设计规范
数据可设计要遵循职责分离原则,即在设计时应该要考虑系统独立性,即每个系统之间互不干预不能混乱数据表和系统关系。
数据库命名也要遵循一定规范,否则容易混淆,数据库字段名要尽量做到与表名类似。
4.3.2 E-R图
用户信息E-R图,如图4-6所示:
图4-6用户信息E-R图
运营商E-R图,如图4-7所示:
图4-7运营商E-R图
景点信息E-R图如图4-8所示。
图4-8景点信息E-R图
酒店信息E-R图如图4-9所示。
图4-9酒店信息E-R图
山西文旅网总体E-R图如图4-10所示。
图4-10山西文旅网总体E-R图
4.3.3 数据表
本系统采用的是MySQL数据库存储数据,系统中使用到的主要数据表的具体展示部分如下所示。
表4-1:我的收藏
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
refid | bigint | refid | |||
tablename | varchar | 200 | 表名 | ||
name | varchar | 200 | 名称 | ||
picture | longtext | 4294967295 | 图片 | ||
type | varchar | 200 | 类型(1:收藏,21:赞,22:踩,31:竞拍参与,41:关注) | ||
inteltype | varchar | 200 | 推荐类型 | ||
remark | varchar | 200 | 备注 | ||
userid | bigint | 用户id |
表4-2:用户
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
yonghuzhanghao | varchar | 200 | 用户账号 | ||
yonghumima | varchar | 200 | 用户密码 | ||
yonghuxingming | varchar | 200 | 用户姓名 | ||
touxiang | longtext | 4294967295 | 头像 | ||
xingbie | varchar | 200 | 性别 | ||
shoujihaoma | varchar | 200 | 手机号码 |
表4-3:景点信息评论表
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
refid | bigint | 关联表id | |||
userid | bigint | 用户id | |||
avatarurl | longtext | 4294967295 | 头像 | ||
nickname | varchar | 200 | 用户名 | ||
content | longtext | 4294967295 | 评论内容 | ||
reply | longtext | 4294967295 | 回复内容 |
表4-4:菜单
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
menujson | longtext | 4294967295 | 菜单 |
表4-5:管理员
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
username | varchar | 200 | 用户名 | ||
password | varchar | 200 | 密码 | ||
role | varchar | 200 | 角色 |
表4-6:配置文件
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
name | varchar | 100 | 配置参数名称 | ||
value | varchar | 100 | 配置参数值 |
表4-7:门票购买
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
dingdanbianhao | varchar | 200 | 订单编号 | ||
jingdianmingcheng | varchar | 200 | 景点名称 | ||
menpiaojiage | double | 门票价格 | |||
shuliang | int | 数量 | |||
dingdanjine | double | 订单金额 | |||
goumaishijian | datetime | 购买时间 | |||
yonghuzhanghao | varchar | 200 | 用户账号 | ||
yonghuxingming | varchar | 200 | 用户姓名 | ||
shoujihaoma | varchar | 200 | 手机号码 | ||
ispay | varchar | 200 | 是否支付 | ||
yunyingshangzhanghao | varchar | 200 | 运营商账号 | ||
yunyingshangxingming | varchar | 200 | 运营商姓名 |
表4-8:旅游攻略
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
gonglvemingcheng | varchar | 200 | 攻略名称 | ||
gonglveleixing | varchar | 200 | 攻略类型 | ||
tupian | longtext | 4294967295 | 图片 | ||
qidian | varchar | 200 | 起点 | ||
tujingluduan | varchar | 200 | 途径路段 | ||
mudedi | varchar | 200 | 目的地 | ||
chuxingfangshi | varchar | 200 | 出行方式 | ||
meishituijian | longtext | 4294967295 | 美食推荐 | ||
jingdiantuijian | longtext | 4294967295 | 景点推荐 | ||
jiudiantuijian | longtext | 4294967295 | 酒店推荐 | ||
gonglvexiangqing | longtext | 4294967295 | 攻略详情 | ||
youwantianshu | varchar | 200 | 游玩天数 | ||
yujifeiyong | varchar | 200 | 预计费用 | ||
yonghuzhanghao | varchar | 200 | 用户账号 | ||
storeupnum | int | 收藏数量 | |||
sfsh | varchar | 200 | 是否审核 | ||
shhf | longtext | 4294967295 | 回复内容 |
表4-9:酒店预定
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
fangjianmingcheng | varchar | 200 | 房间名称 | ||
fangjianleixing | varchar | 200 | 房间类型 | ||
jiudianleixing | varchar | 200 | 酒店类型 | ||
fangjiandizhi | varchar | 200 | 房间地址 | ||
yiwanjiage | double | 一晚价格 | |||
yudingtianshu | int | 预定天数 | |||
zongjia | varchar | 200 | 总价 | ||
fuwudianhua | varchar | 200 | 服务电话 | ||
yudingshijian | datetime | 预定时间 | |||
yonghuzhanghao | varchar | 200 | 用户账号 | ||
yonghuxingming | varchar | 200 | 用户姓名 | ||
ispay | varchar | 200 | 是否支付 | ||
sfsh | varchar | 200 | 是否审核 | ||
shhf | longtext | 4294967295 | 回复内容 | ||
yunyingshangzhanghao | varchar | 200 | 运营商账号 | ||
yunyingshangxingming | varchar | 200 | 运营商姓名 |
表4-10:酒店信息
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
fangjianmingcheng | varchar | 200 | 房间名称 | ||
jiudianleixing | varchar | 200 | 酒店类型 | ||
fangjianleixing | varchar | 200 | 房间类型 | ||
fangjiantupian | longtext | 4294967295 | 房间图片 | ||
fangjiandizhi | varchar | 200 | 房间地址 | ||
yiwanjiage | int | 一晚价格 | |||
fuwudianhua | varchar | 200 | 服务电话 | ||
fangneisheshi | longtext | 4294967295 | 房内设施 | ||
storeupnum | int | 收藏数量 | |||
fangjianzhuangtai | varchar | 200 | 房间状态 | ||
yunyingshangzhanghao | varchar | 200 | 运营商账号 | ||
yunyingshangxingming | varchar | 200 | 运营商姓名 | ||
sfsh | varchar | 200 | 是否审核 | ||
shhf | longtext | 4294967295 | 回复内容 |
表4-11:酒店类型
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
jiudianleixing | varchar | 200 | 酒店类型 |
表4-12:景点信息
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
jingdianmingcheng | varchar | 200 | 景点名称 | ||
jingdiantupian | longtext | 4294967295 | 景点图片 | ||
menpiaojiage | double | 门票价格 | |||
shuliang | int | 数量 | |||
jingdianleixing | varchar | 200 | 景点类型 | ||
kaifangshijian | varchar | 200 | 开放时间 | ||
luxiantuijian | longtext | 4294967295 | 路线推荐 | ||
jingdianjieshao | longtext | 4294967295 | 景点介绍 | ||
jingdiandizhi | varchar | 200 | 景点地址 | ||
storeupnum | int | 收藏数量 | |||
clicktime | datetime | 最近点击时间 | |||
clicknum | int | 点击次数 | |||
yunyingshangzhanghao | varchar | 200 | 运营商账号 | ||
yunyingshangxingming | varchar | 200 | 运营商姓名 | ||
sfsh | varchar | 200 | 是否审核 | ||
shhf | longtext | 4294967295 | 回复内容 |
表4-13:景点类型
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
jingdianleixing | varchar | 200 | 景点类型 |
表4-14:攻略类型
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
gonglveleixing | varchar | 200 | 攻略类型 |
表4-15:token表
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
userid | bigint | 用户id | |||
username | varchar | 100 | 用户名 | ||
tablename | varchar | 100 | 表名 | ||
role | varchar | 100 | 角色 | ||
token | varchar | 200 | 密码 | ||
addtime | timestamp | 新增时间 | CURRENT_TIMESTAMP | ||
expiratedtime | timestamp | 过期时间 | CURRENT_TIMESTAMP |
表4-16:运营商
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
yunyingshangzhanghao | varchar | 200 | 运营商账号 | ||
mima | varchar | 200 | 密码 | ||
yunyingshangxingming | varchar | 200 | 运营商姓名 | ||
touxiang | longtext | 4294967295 | 头像 | ||
xingbie | varchar | 200 | 性别 | ||
shoujihaoma | varchar | 200 | 手机号码 | ||
sfsh | varchar | 200 | 是否审核 | ||
shhf | longtext | 4294967295 | 回复内容 |
表4-17:酒店信息评论表
字段名称 | 类型 | 长度 | 字段说明 | 主键 | 默认值 |
id | bigint | 主键 | 主键 | ||
addtime | timestamp | 创建时间 | CURRENT_TIMESTAMP | ||
refid | bigint | 关联表id | |||
userid | bigint | 用户id | |||
avatarurl | longtext | 4294967295 | 头像 | ||
nickname | varchar | 200 | 用户名 | ||
content | longtext | 4294967295 | 评论内容 | ||
reply | longtext | 4294967295 | 回复内容 |
5 系统实现
5.1前台用户功能模块
当游客打开系统的网址后,首先看到的就是首页界面。在这里,游客能够看到山西文旅网的导航条显示系统首页、旅游攻略、景点信息、酒店信息、个人中心等,如图5-1所示。
图5-1前台功能界面图
在注册流程中,用户在Vue前端填写必要信息(如用户名、密码等)并提交。前端将这些信息通过HTTP请求发送到Java后端。后端处理这些信息,检查用户名是否唯一,并将新用户数据存入MySQL数据库。完成后,后端向前端发送注册成功的确认,前端随后通知用户完成注册。这个过程实现了新用户的数据收集、验证和存储。如图5-2所示。
图5-2用户注册界面图
在登录流程中,用户首先在Vue前端界面输入用户名和密码。这些信息通过HTTP请求发送到Java后端。后端接收请求,通过与MySQL数据库交互验证用户凭证。如果认证成功,后端会返回给前端,允许用户访问系统。这个过程涵盖了从用户输入到系统验证和响应的全过程。如图5-3所示。
图5-3用户登录界面图
代码
<template><div><div class="app-contain"><div class="list_search_view"><el-form :model="searchQuery" class="search_form" ><div class="search_view"><div class="search_label">运营商账号:</div><div class="search_box"><el-input class="search_inp" v-model="searchQuery.yunyingshangzhanghao" placeholder="运营商账号"clearable></el-input></div></div><div class="search_view"><div class="search_label">审核状态:</div><div class="search_box"><el-selectclass="search_sel"clearablev-model="searchQuery.sfsh" placeholder="审核状态"><el-option v-for="item in approvalLists" :label="item" :value="item"></el-option></el-select></div></div><div class="search_btn_view"><el-button class="search_btn" type="primary" @click="searchClick()" size="small">搜索</el-button></div></el-form><br><div class="btn_view"><el-button type="success" @click="addClick" v-if="btnAuth('yunyingshang','新增')">新增</el-button><el-button v-if=" btnAuth('yunyingshang','查看')" type="info" :disabled="selRows.length==1?false:true" @click="infoClick(null)">详情</el-button><el-button type="primary" :disabled="selRows.length==1?false:true" @click="editClick" v-if=" btnAuth('yunyingshang','修改')">修改</el-button><el-button type="danger" :disabled="selRows.length?false:true" @click="delClick(null)" v-if="btnAuth('yunyingshang','删除')">删除</el-button></div></div><br><el-tablev-loading="listLoading"border :stripe='true'@selection-change="handleSelectionChange" ref="table"v-if="btnAuth('yunyingshang','查看')":data="list"@row-click="listChange"><el-table-column :resizable='true' align="left" header-align="left" type="selection" width="55" /><el-table-column label="序号" width="70" :resizable='true' :sortable='true' align="left" header-align="left"><template #default="scope">{{ scope.$index + 1}}</template></el-table-column><el-table-column:resizable='true' :sortable='true' align="left" header-align="left"label="运营商账号"><template #default="scope">{{scope.row.yunyingshangzhanghao}}</template></el-table-column><el-table-column:resizable='true' :sortable='true' align="left" header-align="left"label="运营商姓名"><template #default="scope">{{scope.row.yunyingshangxingming}}</template></el-table-column><el-table-column label="头像" width="120" :resizable='true' :sortable='true' align="left" header-align="left"><template #default="scope"><div v-if="scope.row.touxiang"><el-image v-if="scope.row.touxiang.substring(0,4)=='http'" preview-teleported:preview-src-list="[scope.row.touxiang.split(',')[0]]":src="scope.row.touxiang.split(',')[0]" style="width:100px;height:100px"></el-image><el-image v-else preview-teleported:preview-src-list="[$config.url+scope.row.touxiang.split(',')[0]]":src="$config.url+scope.row.touxiang.split(',')[0]" style="width:100px;height:100px"></el-image></div><div v-else>无图片</div></template></el-table-column><el-table-column:resizable='true' :sortable='true' align="left" header-align="left"label="性别"><template #default="scope">{{scope.row.xingbie}}</template></el-table-column><el-table-column:resizable='true' :sortable='true' align="left" header-align="left"label="手机号码"><template #default="scope">{{scope.row.shoujihaoma}}</template></el-table-column><el-table-column label="审核回复" :resizable='true' :sortable='true' align="left" header-align="left"><template #default="scope">{{scope.row.shhf}}</template></el-table-column><el-table-column label="审核状态" :resizable='true' :sortable='true' align="left" header-align="left"><template #default="scope"><el-tag type="success" v-if="scope.row.sfsh=='是'">通过</el-tag><el-tag type="danger" v-else-if="scope.row.sfsh=='否'">未通过</el-tag><el-tag type="warning" v-else>待审核</el-tag></template></el-table-column><el-table-column label="审核" v-if="btnAuth('yunyingshang','审核')" :resizable='true' :sortable='true' align="left" header-align="left"><template #default="scope"><el-button type="text" @click="approvalClick(scope.row)">审核</el-button></template></el-table-column><el-table-column label="操作" width="300" :resizable='true' :sortable='true' align="left" header-align="left"><template #default="scope"><el-button type="info" v-if=" btnAuth('yunyingshang','查看')" @click="infoClick(scope.row.id)">详情</el-button></template></el-table-column></el-table><el-pagination background:layout="layouts.join(',')":total="total" :page-size="listQuery.limit"prev-text="Prev"next-text="Next":hide-on-single-page="false":style='{"padding":"0","margin":"20px 0 0","whiteSpace":"nowrap","color":"#333","textAlign":"center","width":"100%","fontWeight":"500"}'@size-change="sizeChange"@current-change="currentChange" @prev-click="prevClick"@next-click="nextClick" /></div><formModel ref="formRef" @formModelChange="formModelChange"></formModel><Approval ref="approvalRef" :tableName="tableName" @shChange="searchClick()"></Approval></div>
</template>
<script setup>import axios from 'axios'import {reactive,ref,getCurrentInstance,nextTick,onMounted,watch,} from 'vue'import {useRoute,useRouter} from 'vue-router'import {ElMessageBox} from 'element-plus'const context = getCurrentInstance()?.appContext.config.globalProperties;import formModel from './formModel.vue'//基础信息const tableName = 'yunyingshang'const formName = '运营商'const route = useRoute()//基础信息onMounted(()=>{})//列表数据const list = ref(null)const table = ref(null)const listQuery = ref({page: 1,limit: 20,sort: 'id',order: 'desc'})const searchQuery = ref({})const selRows = ref([])const listLoading = ref(false)const listChange = (row) =>{nextTick(()=>{table.value.clearSelection()table.value.toggleRowSelection(row)})}//列表const getList = () => {listLoading.value = truelet params = JSON.parse(JSON.stringify(listQuery.value))params['sort'] = 'id'params['order'] = 'desc'if(searchQuery.value.yunyingshangzhanghao&&searchQuery.value.yunyingshangzhanghao!=''){params['yunyingshangzhanghao'] = '%' + searchQuery.value.yunyingshangzhanghao + '%'}if(searchQuery.value.sfsh && searchQuery.value.sfsh!=''){params['sfsh'] = searchQuery.value.sfsh}if(searchQuery.value.sfsh && searchQuery.value.sfsh!=''){params['sfsh'] = searchQuery.value.sfsh}if(searchQuery.value.sfsh && searchQuery.value.sfsh!=''){params['sfsh'] = searchQuery.value.sfsh}if(searchQuery.value.sfsh && searchQuery.value.sfsh!=''){params['sfsh'] = searchQuery.value.sfsh}if(searchQuery.value.sfsh && searchQuery.value.sfsh!=''){params['sfsh'] = searchQuery.value.sfsh}if(searchQuery.value.sfsh && searchQuery.value.sfsh!=''){params['sfsh'] = searchQuery.value.sfsh}if(searchQuery.value.sfsh && searchQuery.value.sfsh!=''){params['sfsh'] = searchQuery.value.sfsh}if(searchQuery.value.sfsh && searchQuery.value.sfsh!=''){params['sfsh'] = searchQuery.value.sfsh}context?.$http({url: `${tableName}/page`,method: 'get',params: params}).then(res => {listLoading.value = falselist.value = res.data.data.listtotal.value = Number(res.data.data.total)})}//删const delClick = (id) => {let ids = ref([])if (id) {ids.value = [id]} else {if (selRows.value.length) {for (let x in selRows.value) {ids.value.push(selRows.value[x].id)}} else {return false}}ElMessageBox.confirm(`是否删除选中${formName}`, '提示', {confirmButtonText: '是',cancelButtonText: '否',type: 'warning',}).then(() => {context?.$http({url: `${tableName}/delete`,method: 'post',data: ids.value}).then(res => {context?.$toolUtil.message('删除成功', 'success',()=>{getList()})})})}//多选const handleSelectionChange = (e) => {selRows.value = e}//列表数据//分页const total = ref(0)const layouts = ref(["prev","pager","next"])const sizeChange = (size) => {listQuery.value.limit = sizegetList()}const currentChange = (page) => {listQuery.value.page = pagegetList()}const prevClick = () => {listQuery.value.page = listQuery.value.page - 1getList()}const nextClick = () => {listQuery.value.page = listQuery.value.page + 1getList()}//分页//权限验证const btnAuth = (e,a)=>{return context?.$toolUtil.isAuth(e,a)}//搜索const searchClick = () => {listQuery.value.page = 1getList()}//表单const formRef = ref(null)const formModelChange=()=>{searchClick()}const addClick = ()=>{formRef.value.init()}const editClick = ()=>{if(selRows.value.length){formRef.value.init(selRows.value[0].id,'edit')}}const infoClick = (id=null)=>{if(id){formRef.value.init(id,'info')}else if(selRows.value.length){formRef.value.init(selRows.value[0].id,'info')}}// 表单// 预览文件const preClick = (file) =>{if(!file){context?.$toolUtil.message('文件不存在','error')}window.open(context?.$config.url + file)// const a = document.createElement('a');// a.style.display = 'none';// a.setAttribute('target', '_blank');// file && a.setAttribute('download', file);// a.href = context?.$config.url + file;// document.body.appendChild(a);// a.click();// document.body.removeChild(a);}// 下载文件const download = (file) => {if(!file){context?.$toolUtil.message('文件不存在','error')}let arr = file.replace(new RegExp('file/', "g"), "")axios.get((location.href.split(context?.$config.name).length>1 ? location.href.split(context?.$config.name)[0] :'') + context?.$config.name + '/file/download?fileName=' + arr, {headers: {token: context?.$toolUtil.storageGet('Token')},responseType: "blob"}).then(({data}) => {const binaryData = [];binaryData.push(data);const objectUrl = window.URL.createObjectURL(new Blob(binaryData, {type: 'application/pdf;chartset=UTF-8'}))const a = document.createElement('a')a.href = objectUrla.download = arr// a.click()// 下面这个写法兼容火狐a.dispatchEvent(new MouseEvent('click', {bubbles: true,cancelable: true,view: window}))window.URL.revokeObjectURL(data)})}//审核import Approval from '@/components/common/approval.vue'const approvalRef = ref(null)const approvalClick = (row) => {let params = {id:row.id,yunyingshangzhanghao: row.yunyingshangzhanghao,mima: row.mima,yunyingshangxingming: row.yunyingshangxingming,touxiang: row.touxiang,xingbie: row.xingbie,shoujihaoma: row.shoujihaoma,sfsh: row.sfsh,shhf: row.shhf,}nextTick(() => {approvalRef.value.approvalClick(params )})}//查询审核状态列表const approvalLists = ref([])//初始化const init = () => {approvalLists.value = "是,否,待审核".split(',');getList()}init()
</script>
<style lang="scss" scoped>// 操作盒子.list_search_view {margin: 0 0 20px;display: flex;justify-content: space-between;flex-wrap: wrap;// 搜索盒子.search_form {display: flex;align-items: center;order: 2;// 子盒子.search_view {margin: 0 10px 0 0;display: flex;align-items: center;// 搜索label.search_label {margin: 0 10px 0 0;color: #fff;background: none;font-weight: 500;display: inline-block;width: auto;font-size: 14px;line-height: 40px;text-align: right;min-width: 100px;height: 40px;}// 搜索item.search_box {display: inline-block;width: auto;// 输入框:deep(.search_inp) {border: 1px solid rgba(0, 0, 0, 0.1);border-radius: 4px;padding: 0 10px;color: #fff;background: rgba(0, 0, 0, 0.1);width: auto;line-height: 34px;box-sizing: border-box;//去掉默认样式.el-input__wrapper{border: none;box-shadow: none;background: none;border-radius: 0;height: 100%;padding: 0;}.is-focus {box-shadow: none !important;}}// 下拉框:deep(.search_sel) {border: 1px solid rgba(0, 0, 0, 0.1);border-radius: 4px;padding: 0 10px;color: #fff;background: rgba(0, 0, 0, 0.1);width: auto;line-height: 34px;box-sizing: border-box;//去掉默认样式.select-trigger{height: 100%;.el-input{height: 100%;.el-input__wrapper{border: none;box-shadow: none;background: none;border-radius: 0;height: 100%;padding: 0;}.is-focus {box-shadow: none !important;}}}}}}// 搜索按钮盒子.search_btn_view {width: 20%;display: flex;padding: 0 20px;// 搜索按钮.search_btn {border: 1px solid #357ebd;cursor: pointer;border-radius: 4px;padding: 0 24px;color: #fff;background: rgba(66, 139, 202, 0.45);width: auto;font-size: 14px;height: 36px;}// 搜索按钮-悬浮.search_btn:hover {border: 1px solid #357ebd;background: rgba(66, 139, 202, 0.45);}}}//头部按钮盒子.btn_view {margin: 0;display: flex;// 其他:deep(.el-button--default){border: 1px solid #ccc;cursor: pointer;border-radius: 3px;padding: 0 24px;margin: 0 10px 0 0;outline: none;color: #fff;background: rgba(222, 222, 222, 0.55);width: auto;font-size: 14px;height: 36px;}// 其他-悬浮:deep(.el-button--default:hover){background: rgba(222, 222, 222, 0.45);}// 新增:deep(.el-button--success){border: 1px solid #357ebd;cursor: pointer;border-radius: 3px;padding: 0 24px;margin: 0 10px 0 0;outline: none;color: #fff;background: rgba(66, 139, 202, 0.45);width: auto;font-size: 14px;height: 36px;}// 新增-悬浮:deep(.el-button--success:hover){background: rgba(66, 139, 202, 0.35);}// 修改:deep(.el-button--primary){border: 1px solid #4cae4c;cursor: pointer;border-radius: 3px;padding: 0 24px;margin: 0 10px 0 0;outline: none;color: #fff;background: rgba(92, 184, 92, 0.55);width: auto;font-size: 14px;height: 36px;}// 修改-悬浮:deep(.el-button--primary:hover){background: rgba(92, 184, 92, 0.45);}// 详情:deep(.el-button--info){border: 1px solid #46b8da;cursor: pointer;border-radius: 3px;padding: 0 24px;margin: 0 10px 0 0;outline: none;color: #fff;background: rgba(91, 192, 222, 0.45);width: auto;font-size: 14px;height: 36px;}// 详情-悬浮:deep(.el-button--info:hover){background: rgba(91, 192, 222, 0.35);}// 删除:deep(.el-button--danger){border: 1px solid #d43f3a;cursor: pointer;border-radius: 3px;padding: 0 24px;margin: 0 10px 0 0;outline: none;color: #fff;background: rgba(217, 83, 79, 0.55);width: auto;font-size: 14px;height: 36px;}// 删除-悬浮:deep(.el-button--danger:hover){background: rgba(217, 83, 79, 0.45);}// 统计:deep(.el-button--warning){border: 1px solid #eea236;cursor: pointer;border-radius: 3px;padding: 0 24px;margin: 0 10px 0 0;outline: none;color: #fff;background: rgba(240, 173, 78, 0.55);width: auto;font-size: 14px;height: 36px;}// 统计-悬浮:deep(.el-button--warning:hover){background: rgba(240, 173, 78, 0.45);}}}// 表格样式.el-table {border-radius: 0px;padding: 0;background: rgba(0, 0, 0, 0.25);width: 100%;border-color: rgba(254, 182, 203, 0.5);border-width: 1px 0 0 1px;border-style: solid;:deep(.el-table__header-wrapper) {thead {color: #fff;font-weight: 500;width: 100%;tr {background: rgba(0, 0, 0, 0.1);th {padding: 4px 0;background: none;border-color: rgba(254, 182, 203, 0.5);border-width: 0 0px 1px 0;border-style: solid;text-align: left;.cell {padding: 0 10px;word-wrap: normal;word-break: break-all;white-space: normal;font-weight: bold;display: inline-block;vertical-align: middle;width: 100%;line-height: 24px;position: relative;text-overflow: ellipsis;}}}}}:deep(.el-table__body-wrapper) {tbody {width: 100%;tr {background: none;td {padding: 6px 0;color: #eee;background: none;border-color: #d2d2d2;border-width: 0 0px 0px 0;border-style: solid;text-align: left;.cell {padding: 0 10px;overflow: hidden;word-break: break-all;white-space: normal;line-height: 24px;text-overflow: ellipsis;// 编辑.el-button--primary {border: 1px solid #d58512;cursor: pointer;border-radius: 4px;padding: 5px 10px;margin: 0 6px 6px 0;color: #fff;background: rgba(240, 173, 78, 0.45);width: auto;font-size: 12px;height: auto;}// 编辑-悬浮.el-button--primary:hover {}// 详情.el-button--info {border: 1px solid #357ebd;cursor: pointer;border-radius: 3px;padding: 5px 10px;margin: 0 6px 6px 0;color: #fff;background: rgba(66, 139, 202, 0.55);width: auto;font-size: 12px;height: auto;}// 详情-悬浮.el-button--info:hover {}// 删除.el-button--danger {border: 1px solid #ac2925;cursor: pointer;border-radius: 3px;padding: 5px 10px;margin: 0 6px 6px 0;color: #fff;background: rgba(217, 83, 79, 0.45);width: auto;font-size: 12px;height: auto;}// 删除-悬浮.el-button--danger:hover {}// 跨表.el-button--success {border: 1px solid #ccc;cursor: pointer;border-radius: 3px;padding: 5px 10px;margin: 0 6px 6px 0;color: #fff;background: rgba(222, 222, 222, 0.55);width: auto;font-size: 12px;height: 24px;}// 跨表-悬浮.el-button--success:hover {}// 操作.el-button--warning {border: 1px solid #4cae4c;cursor: pointer;border-radius: 3px;padding: 5px 10px;margin: 0 6px 6px 0;color: #fff;background: rgba(92, 184, 92, 0.55);width: auto;font-size: 12px;height: auto;}// 操作-悬浮.el-button--warning:hover {}}}}tr.el-table__row--striped {td {background: rgba(0, 0, 0, 0.10);}}tr:hover {td {padding: 6px 0;color: #fff;background: rgba(0, 0, 0, 0.10);border-color: #d2d2d2;border-width: 0 0px 0px 0;border-style: solid;text-align: left;}}}}}// 分页器.el-pagination {// 总页码:deep(.el-pagination__total) {margin: 0 10px 0 0;color: #666;font-weight: 400;display: inline-block;vertical-align: top;font-size: 13px;line-height: 28px;height: 28px;}// 上一页:deep(.btn-prev) {border: none;border-radius: 0px;padding: 0 5px;margin: 0 5px;color: #fff;background: none;display: inline-block;vertical-align: top;font-size: 13px;line-height: 26px;min-width: 35px;height: 26px;}// 下一页:deep(.btn-next) {border: none;border-radius: 0px;padding: 0 5px;margin: 0 5px;color: #fff;background: none;display: inline-block;vertical-align: top;font-size: 13px;line-height: 26px;min-width: 35px;height: 26px;}// 上一页禁用:deep(.btn-prev:disabled) {border: none;cursor: not-allowed;border-radius: 0px;padding: 0 5px;margin: 0 5px;color: #fff;background: none;display: inline-block;vertical-align: top;font-size: 13px;line-height: 26px;height: 26px;}// 下一页禁用:deep(.btn-next:disabled) {border: none;cursor: not-allowed;border-radius: 0px;padding: 0 5px;margin: 0 5px;color: #fff;background: none;display: inline-block;vertical-align: top;font-size: 13px;line-height: 26px;height: 26px;}// 页码:deep(.el-pager) {padding: 0;margin: 0;display: inline-block;vertical-align: top;// 数字.number {cursor: pointer;border: 1px solid rgba(255, 255, 255, 0.3);padding: 0 4px;margin: 0 5px;color: #fff;display: inline-block;vertical-align: top;font-size: 13px;line-height: 26px;border-radius: 0px;background: none;text-align: center;min-width: 30px;height: 26px;}// 数字悬浮.number:hover {cursor: pointer;border: 1px solid rgba(0, 0, 0, 0.05);padding: 0 4px;margin: 0 5px;color: #fff;display: inline-block;vertical-align: top;font-size: 13px;line-height: 26px;border-radius: 0px;background: rgba(0, 0, 0, 0.25);text-align: center;min-width: 30px;height: 26px;}// 选中.number.is-active {cursor: default;border: 1px solid rgba(0, 0, 0, 0.05);padding: 0 4px;margin: 0 5px;color: #fff;display: inline-block;vertical-align: top;font-size: 13px;line-height: 26px;border-radius: 0px;background: rgba(0, 0, 0, 0.25);text-align: center;min-width: 30px;height: 26px;}}// sizes:deep(.el-pagination__sizes) {display: inline-block;vertical-align: top;font-size: 13px;line-height: 28px;height: 28px;.el-select {border: 1px solid #DCDFE6;cursor: pointer;padding: 0;color: #606266;display: inline-block;font-size: 13px;line-height: 28px;border-radius: 3px;outline: 0;background: #FFF;width: 100%;text-align: center;height: 28px;}}// 跳页:deep(.el-pagination__jump) {margin: 0 0 0 24px;color: #606266;display: inline-block;vertical-align: top;font-size: 13px;line-height: 28px;height: 28px;// 输入框.el-input {border: 1px solid #DCDFE6;cursor: pointer;padding: 0 3px;color: #606266;display: inline-block;font-size: 14px;line-height: 28px;border-radius: 3px;outline: 0;background: #FFF;width: 100%;text-align: center;height: 28px;//去掉默认样式.el-input__wrapper{border: none;box-shadow: none;background: none;border-radius: 0;height: 100%;padding: 0;}.is-focus {box-shadow: none !important;}}}}
</style>
用户点击旅游攻略,在旅游攻略页面的搜索栏输入攻略名称、起点,进行搜索,然后可以查看目的地、出行方式、美食推荐、景点推荐、酒店推荐、游玩天数、预计费用、用户账号、收藏数量等信息,如有需要可以进行收藏等操作;如图5-4所示。
图5-4旅游攻略界面图
用户点击景点信息,在景点信息页面的搜索栏输入景点名称,进行搜索,然后可以查看景点图片、门票价格、数量、景点类型、开放时间、景点地址、运营商账号、运营商姓名等信息,如有需要可以点击购买、收藏等操作;如图5-5所示。
图5-5景点信息界面图
用户点击个人中心,在个人中心页面可以修改个人信息、密码修改进行详细操作,还可以对修改密码、酒店信息管理、旅游路线管理、我的收藏管理、景点信息管理进行详细操作;如图5-6所示。
图5-6个人中心界面图
5.2 后台管理员功能模块
管理员登录,通过登录页面输入用户名、密码、角色,进行登录操作,如图5-7所示。
图5-7管理员登录界面图
管理员登录进入山西文旅网可以查看首页、酒店信息管理、景点信息管理、旅游路线管理、管理员管理、运营商管理、用户管理等信息,进行相应操作,如图5-8所示。
图5-8管理员功能界面图
酒店信息功能在视图层(view层)进行交互,比如点击“新增”按钮或填写酒店信息表单。这些酒店信息动作被视图层捕获并作为请求发送给相应的控制器层(control1er层)。控制器接收到这些请求后,调用服务层(service层)以执行相关的业务逻辑,例如验证输入数据的有效性和与数据库的交互。服务层处理完这些逻辑后,进一步与数据访问对象层(DAO层)交互,后者负责具体的数据操作如搜索、新增、更新或删除酒店信息,并将操作结果返回给控制器。最终,控制器根据这些结果更新视图层,以便酒店信息功能可以看到最新的信息或相应的操作反馈。在酒店信息页面的输入栏中输入房间名称、房间类型、审核状态进行搜索,可以查看到酒店详细信息,并根据需要进行修改或者删除等操作;如图5-9所示。
图5-9酒店信息界面图