当前位置: 首页 > article >正文

基于SpringBoot vue3 的山西文旅网java网页设计与实现

博主介绍:专注于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-15token表

字段名称

类型

长度

字段说明

主键

默认值

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-select
								class="search_sel"
								clearable
								v-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-table
				v-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 = true
		let 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 = false
			list.value = res.data.data.list
			total.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 = size
		getList()
	}
	const currentChange = (page) => {
		listQuery.value.page = page
		getList()
	}
	const prevClick = () => {
		listQuery.value.page = listQuery.value.page - 1
		getList()
	}
	const nextClick = () => {
		listQuery.value.page = listQuery.value.page + 1
		getList()
	}
	//分页
	//权限验证
	const btnAuth = (e,a)=>{
		return context?.$toolUtil.isAuth(e,a)
	}
	//搜索
	const searchClick = () => {
		listQuery.value.page = 1
		getList()
	}
	//表单
	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 = objectUrl
			a.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酒店信息界面图


http://www.kler.cn/news/337170.html

相关文章:

  • 【机器学习】KNN算法及鸢尾花案例练习
  • VUE a-table 动态拖动修改列宽+固定列
  • 弹性分布式数据集RDD详细说明
  • “欢迎”相关英语表达柯桥成人商务英语口语学习到蓝天广场
  • mysql学习教程,从入门到精通,SQL 临时表(37)
  • 【DC00026】基于java swing+MySQL图书借阅管理系统
  • 基于SpringBoot+Uniapp的家庭记账本微信小程序系统设计与实现
  • 【Kubernetes】常见面试题汇总(五十四)
  • 前端的全栈混合之路Meteor篇(四):支持自定义对象序列化的EJSON介绍
  • JAVA开发系统环境搭建
  • 用Arduino单片机制作一个简单的音乐播放器
  • Ajax开发技术
  • 安卓真机调试“no target device found“以及“ INSTALL_FAILED_USER_RESTRICTED“两个问题的解决办法
  • 商云10如何开启积分付款功能
  • 人工智能与医疗健康的融合:未来的机遇与挑战
  • 《 防MAC 地址欺骗攻击》
  • Steam Deck掌机可装“黑苹果” 开发者成功安装macOS 15 Sequoia
  • 20款奔驰CLS300升级原厂抬头显示HUD 23P智能辅助驾驶 触摸屏人机交互系统
  • MFC工控项目实例二十三模拟量输入设置界面
  • 反射在Go语言中的具体应用场景