添加route.js、route文件夹和transport-fee文件夹(路线管理和运输金额管理)

This commit is contained in:
雨yuuula 2025-08-07 05:27:14 +08:00
parent e8543fd0bb
commit beb8fbec76
6 changed files with 795 additions and 0 deletions

82
src/api/route.js Normal file
View File

@ -0,0 +1,82 @@
import request from '@/utils/request'
// 分页查询路线(支持路线名模糊查询)
export function getRoutesByPage(params) {
return request({
url: 'cpRoute',
method: 'get',
params
})
}
// 添加路线
export function createRoute(data) {
return request({
url: 'cpRoute',
method: 'post',
data
})
}
// 修改路线
export function updateRoute(data) {
return request({
url: 'cpRoute',
method: 'put',
data
})
}
// 全部路线
export function getAllRoutes(params) {
return request({
url: 'cpRoute/all',
method: 'get',
params
})
}
// 根据景区获取景区下的所有路线
export function getRoutesByAreaId(params) {
return request({
url: 'cpRoute/getByAreaId',
method: 'get',
params
})
}
// 根据景区名称模糊查询路线
export function searchRoutesByName(params) {
return request({
url: 'cpRoute/searchRoutesByName',
method: 'get',
params
})
}
// 查询单个路线
export function getRouteDetail(id) {
return request({
url: `cpRoute/${id}`,
method: 'get'
})
}
// 删除路线
export function deleteRoute(id) {
return request({
url: `cpRoute/${id}`,
method: 'delete'
})
}
export default {
getRoutesByPage,
createRoute,
updateRoute,
getAllRoutes,
getRoutesByAreaId,
searchRoutesByName,
getRouteDetail,
deleteRoute
}

View File

@ -0,0 +1,143 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span style="color: #027db4;">新增路线</span>
</div>
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px" class="detail-form">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="路线名称" prop="routeName">
<el-input v-model="form.routeName" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="景区名称" prop="scenicArea">
<el-select v-model="form.scenicArea" placeholder="请选择景区">
<el-option label="白云山" value="白云山" />
<el-option label="丹霞山" value="丹霞山" />
<el-option label="西樵山" value="西樵山" />
<el-option label="罗浮山" value="罗浮山" />
<el-option label="鼎湖山" value="鼎湖山" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="起飞点" prop="takeoffPoint">
<el-input v-model="form.takeoffPoint" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="降落点" prop="landingPoint">
<el-input v-model="form.landingPoint" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="16">
<el-form-item label="路线描述" prop="routeDesc">
<el-input type="textarea" v-model="form.routeDesc" :rows="4" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<div class="btn-container">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit">保存</el-button>
</div>
</div>
</template>
<script>
import { ElMessage } from 'element-ui'
import routeApi from '@/api/system/route'
export default {
name: 'AddRoute',
data() {
return {
form: {
routeName: '',
scenicArea: '',
takeoffPoint: '',
landingPoint: '',
routeDesc: '',
routeType: 'normal'
},
rules: {
routeName: [
{ required: true, message: '请输入路线名称', trigger: 'blur' }
],
scenicArea: [
{ required: true, message: '请选择景区', trigger: 'change' }
],
takeoffPoint: [
{ required: true, message: '请输入起飞点', trigger: 'blur' }
],
landingPoint: [
{ required: true, message: '请输入降落点', trigger: 'blur' }
]
}
}
},
methods: {
handleCancel() {
this.$router.go(-1)
},
handleSubmit() {
this.$refs.formRef.validate(valid => {
if (valid) {
this.submitForm()
} else {
return false
}
})
},
async submitForm() {
try {
await routeApi.createRoute(this.form)
ElMessage.success('新增成功')
this.$router.push({ path: '/route/manageroute' })
} catch (error) {
ElMessage.error('新增失败')
}
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
}
.detail-form {
.el-form-item {
margin-bottom: 20px;
}
::v-deep .el-input {
width: 240px;
}
::v-deep .el-select {
width: 240px;
}
::v-deep .el-input.is-disabled .el-input__inner {
background-color: white;
color: #686868;
}
::v-deep .el-textarea.is-disabled .el-textarea__inner {
background-color: white;
color: #686868;
}
}
.btn-container {
margin-top: 20px;
text-align: right;
padding-right: 40px;
}
</style>

View File

@ -0,0 +1,159 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span style="color: #027db4;">修改路线</span>
</div>
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px" class="detail-form">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="路线名称" prop="name">
<el-input v-model="form.name" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="景区ID" prop="scenicId">
<el-input v-model="form.scenicId" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="起点" prop="startPoint">
<el-input v-model="form.startPoint" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="终点" prop="endPoint">
<el-input v-model="form.endPoint" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="16">
<el-form-item label="路线描述" prop="link">
<el-input type="textarea" v-model="form.link" :rows="4" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<div class="btn-container">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit">修改</el-button>
</div>
</div>
</template>
<script>
import { ElMessage } from 'element-ui'
import routeApi from '@/api/system/route'
export default {
name: 'EditRoute',
data() {
return {
form: {
id: null,
name: '',
scenicId: null,
startPoint: '',
endPoint: '',
link: ''
},
rules: {
name: [
{ required: true, message: '请输入路线名称', trigger: 'blur' }
],
scenicId: [
{ required: true, message: '请输入景区ID', trigger: 'blur' }
],
startPoint: [
{ required: true, message: '请输入起点', trigger: 'blur' }
],
endPoint: [
{ required: true, message: '请输入终点', trigger: 'blur' }
]
}
}
},
created() {
this.getRouteDetail()
},
methods: {
async getRouteDetail() {
const id = this.$route.query.id
if (!id) {
ElMessage.error('缺少路线ID请从列表页进入修改')
this.$router.go(-1)
return
}
try {
const res = await routeApi.getRouteDetail(id)
this.form = {
...this.form,
...res.data
}
} catch (error) {
ElMessage.error('获取路线详情失败,请重试')
this.$router.go(-1)
}
},
handleCancel() {
this.$router.go(-1)
},
handleSubmit() {
this.$refs.formRef.validate(valid => {
if (valid) {
this.submitForm()
} else {
return false
}
})
},
async submitForm() {
try {
await routeApi.updateRoute(this.form)
ElMessage.success('修改成功')
this.$router.push({ path: '/route/manageroute' })
} catch (error) {
ElMessage.error('修改失败,请重试')
}
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
}
.detail-form {
.el-form-item {
margin-bottom: 20px;
}
::v-deep .el-input {
width: 240px;
}
::v-deep .el-select {
width: 240px;
}
::v-deep .el-input.is-disabled .el-input__inner {
background-color: white;
color: #686868;
}
::v-deep .el-textarea.is-disabled .el-textarea__inner {
background-color: white;
color: #686868;
}
}
.btn-container {
margin-top: 20px;
text-align: right;
padding-right: 40px;
}
</style>

View File

@ -0,0 +1,161 @@
<template>
<div class="app-container">
<!-- 搜索栏 -->
<el-card class="box-card">
<div class="filter-container">
<el-input
v-model="query.name"
placeholder="请输入路线名称"
class="filter-item"
style="width: 200px;"
clearable
/>
<el-button type="primary" class="filter-item" @click="handleSearch">
<i class="fa fa-search mr-1"></i>查询
</el-button>
<el-button type="success" class="filter-item" @click="handleAdd">
<i class="fa fa-plus mr-1"></i>新增路线
</el-button>
</div>
</el-card>
<!-- 表格 -->
<el-table
ref="table"
:data="tableData"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column prop="scenicId" label="景区ID" align="left" />
<el-table-column prop="name" label="路线名称" align="left" />
<el-table-column prop="createTime" label="创建时间" align="left" />
<el-table-column label="操作" width="120" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleEdit(scope.row)">修改</el-button>
<el-button type="text" size="small" class="text-danger" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
:current-page.sync="page.current"
:page-sizes="[10, 20, 50, 100]"
:page-size="page.size"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script>
import { ElMessage, ElMessageBox } from 'element-ui'
import routeApi from '@/api/system/route'
export default {
name: 'RouteManager',
data() {
return {
tableData: [],
selection: [],
query: {
name: ''
},
page: {
current: 1,
size: 10,
total: 0
}
}
},
mounted() {
this.fetchData()
},
methods: {
async fetchData() {
try {
const params = {
...this.query,
pageNum: this.page.current,
pageSize: this.page.size
}
const res = await routeApi.getAllRoutes(params)
this.tableData = res.data
this.page.total = res.totalElements
} catch (error) {
ElMessage.error('获取路线列表失败,请重试')
}
},
handleSearch() {
this.page.current = 1
this.fetchData()
},
handleAdd() {
this.$router.push({ path: '/route/manageroute/add-route' })
},
handleEdit(row) {
this.$router.push({
path: '/route/manageroute/edit-route',
query: { id: row.id }
})
},
async handleDelete(row) {
this.$confirm(
`确定要删除路线 "${row.name}" 吗?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(async () => {
try {
await routeApi.deleteRoute(row.id)
ElMessage.success('删除成功')
this.fetchData()
} catch (error) {
ElMessage.error('删除失败,请重试')
}
}).catch(() => {})
},
handleSelectionChange(val) {
this.selection = val
},
handleSizeChange(val) {
this.page.size = val
this.fetchData()
},
handleCurrentChange(val) {
this.page.current = val
this.fetchData()
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
}
.filter-container {
display: flex;
align-items: center;
margin-bottom: 20px;
gap: 10px;
.filter-item {
margin-right: 10px;
}
}
.el-table {
margin-top: 20px;
::v-deep .el-table__body-wrapper {
overflow-x: auto;
}
}
</style>

View File

@ -0,0 +1,98 @@
<template>
<el-dialog
title="设置运输金额"
:visible.sync="visible"
:close-on-click-modal="false"
width="400px"
>
<!-- 表单区域 -->
<el-form ref="feeForm" :model="form" :rules="rules" label-width="100px">
<!-- 景区名称只读 -->
<el-form-item label="景区名称" prop="scenicName">
<el-input v-model="form.scenicName" disabled></el-input>
</el-form-item>
<!-- 金额输入带校验 -->
<el-form-item label="金额 (KG)" prop="feePerKg">
<el-input-number
v-model="form.feePerKg"
:min="0.01"
:step="0.01"
:precision="2"
placeholder="请输入金额"
style="width: 100%"
></el-input-number>
</el-form-item>
</el-form>
<!-- 底部按钮区域 -->
<div slot="footer" class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'SetFeeModal',
props: {
visible: {
type: Boolean,
required: true
},
scenicInfo: {
type: Object,
default: () => null
}
},
data() {
return {
form: {
scenicName: '',
feePerKg: null,
id: null
},
rules: {
feePerKg: [
{ required: true, message: '请输入金额', trigger: 'blur' },
{ type: 'number', min: 0.01, message: '金额必须大于 0', trigger: 'blur' }
]
}
}
},
watch: {
scenicInfo(newVal) {
if (newVal) {
this.form = {
scenicName: newVal.scenicName || '',
feePerKg: newVal.feePerKg || null,
id: newVal.id || null
}
}
}
},
methods: {
async handleSubmit() {
try {
const valid = await this.$refs.feeForm.validate()
if (valid) {
// API
console.log('提交的数据:', {
id: this.form.id,
feePerKg: this.form.feePerKg
})
this.$message.success('设置成功')
this.$emit('success')
this.handleCancel()
}
} catch (error) {
console.error('表单验证失败', error)
this.$message.error('请输入正确的金额')
}
}
}
}
</script>

View File

@ -0,0 +1,152 @@
<template>
<div class="app-container">
<!-- 搜索栏 -->
<el-card class="box-card">
<div class="filter-container">
<el-input
v-model="query.scenicName"
placeholder="请输入景区名称或区域名称"
style="width: 200px"
clearable
/>
<el-button type="primary" @click="handleSearch">查询</el-button>
<el-button @click="handleReset">重置</el-button>
</div>
</el-card>
<!-- 表格 -->
<el-table :data="tableData" stripe style="width: 100%">
<el-table-column prop="areaName" label="区域名称" align="left" />
<el-table-column prop="scenicName" label="景区名称" align="left" />
<el-table-column prop="feePerKg" label="金额 / KG" align="left" />
<el-table-column label="操作" width="120" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleSetFee(scope.row)">设置金额</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
:current-page.sync="page.current"
:page-sizes="[10, 20, 30, 40]"
:page-size="page.size"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
<!-- 弹窗组件 -->
<SetFeeModal
:visible.sync="setFeeVisible"
:scenic-info="currentScenicInfo"
@success="handleSetFeeSuccess"
/>
</div>
</template>
<script>
export default {
name: 'TransportFee',
components: {
SetFeeModal
},
data() {
return {
//
query: {
scenicName: ''
},
//
tableData: [],
//
page: {
current: 1,
size: 10,
total: 0
},
//
setFeeVisible: false,
currentScenicInfo: null
}
},
mounted() {
this.fetchData()
},
methods: {
async fetchData() {
//
this.tableData = [
{ areaName: '华南区', scenicName: '白云山', feePerKg: 5.5 },
{ areaName: '华东区', scenicName: '西湖', feePerKg: 4.8 }
]
this.page.total = 2
}
},
//
handleSearch() {
this.page.current = 1
this.fetchData()
},
//
handleReset() {
this.query = {
scenicName: ''
}
this.page.current = 1
this.fetchData()
},
//
handleSizeChange(size) {
this.page.size = size
this.fetchData()
},
//
handleCurrentChange(current) {
this.page.current = current
this.fetchData()
},
//
handleSetFee(row) {
this.currentScenicInfo = row
this.setFeeVisible = true
},
//
handleSetFeeSuccess() {
this.setFeeVisible = false
this.fetchData()
}
}
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
}
.filter-container {
display: flex;
align-items: center;
margin-bottom: 20px;
gap: 10px;
.filter-item {
margin-right: 10px;
}
}
.pagination-container {
margin-top: 20px;
}
</style>