试一下
This commit is contained in:
parent
6e02d90999
commit
b936c8e0ca
|
|
@ -0,0 +1,27 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/icon.png">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>邺城博物馆管理系统</title>
|
||||||
|
<style>
|
||||||
|
*{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#app {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
|
|
@ -0,0 +1,41 @@
|
||||||
|
import axios from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询藏品分类列表
|
||||||
|
export function listItemCategory(query) {
|
||||||
|
return axios.get('/itemCategory/list',{
|
||||||
|
params: {
|
||||||
|
...query
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询全部藏品分类列表
|
||||||
|
export function listAllItemCategory(query) {
|
||||||
|
return axios.get('/itemCategory/listAll', {
|
||||||
|
params: {
|
||||||
|
...query
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询藏品分类详细
|
||||||
|
export function getItemCategory(id) {
|
||||||
|
return axios.get('/itemCategory/info/' + id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增藏品分类
|
||||||
|
export function addItemCategory(data) {
|
||||||
|
return axios.post('/itemCategory/add', {
|
||||||
|
...data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改藏品分类
|
||||||
|
export function updateItemCategory(data) {
|
||||||
|
return axios.put('/itemCategory', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除藏品分类
|
||||||
|
export function delItemCategory(id) {
|
||||||
|
return axios.delete('/itemCategory/' + id)
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
|
|
@ -0,0 +1,174 @@
|
||||||
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
import Layout from '@/components/Layout.vue'
|
||||||
|
import HLayout from '@/components/HLayout.vue'
|
||||||
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
redirect: '/tourist/home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
name: 'login',
|
||||||
|
component: () => import('@/views/login.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/register',
|
||||||
|
name: 'register',
|
||||||
|
component: () => import('@/views/register.vue')
|
||||||
|
},
|
||||||
|
// 管理端路径配置
|
||||||
|
{
|
||||||
|
path: '/admin',
|
||||||
|
name: 'admin',
|
||||||
|
component: Layout,
|
||||||
|
redirect: '/admin/statisticalAnalysis',
|
||||||
|
children: [
|
||||||
|
// 数据统计
|
||||||
|
{
|
||||||
|
path: 'statisticalAnalysis',
|
||||||
|
name: 'statisticalAnalysis',
|
||||||
|
component: () => import('@/views/admin/statisticalAnalysis/index.vue')
|
||||||
|
},
|
||||||
|
// 藏品管理
|
||||||
|
{
|
||||||
|
path: 'relic',
|
||||||
|
name: 'relic',
|
||||||
|
component: () => import('@/views/admin/relic/index.vue')
|
||||||
|
},
|
||||||
|
// 藏品分类管理
|
||||||
|
{
|
||||||
|
path: 'itemCategory',
|
||||||
|
name: 'itemCategory',
|
||||||
|
component: () => import('@/views/admin/itemCategory/index.vue')
|
||||||
|
},
|
||||||
|
// 预约时段管理
|
||||||
|
{
|
||||||
|
path: 'reservationTimeSlot',
|
||||||
|
name: 'reservationTimeSlot',
|
||||||
|
component: () => import('@/views/admin/reservationTimeSlot/index.vue')
|
||||||
|
},
|
||||||
|
// 预约明细管理
|
||||||
|
{
|
||||||
|
path: 'reservation',
|
||||||
|
name: 'reservation',
|
||||||
|
component: () => import('@/views/admin/reservation/index.vue')
|
||||||
|
},
|
||||||
|
// 公告管理
|
||||||
|
{
|
||||||
|
path: 'announcement',
|
||||||
|
name: 'announcement',
|
||||||
|
component: () => import('@/views/admin/announcement/index.vue')
|
||||||
|
},
|
||||||
|
// 轮播图管理
|
||||||
|
{
|
||||||
|
path: 'carousel',
|
||||||
|
name: 'carousel',
|
||||||
|
component: () => import('@/views/admin/carousel/index.vue')
|
||||||
|
},
|
||||||
|
// 用户管理
|
||||||
|
{
|
||||||
|
path: 'user',
|
||||||
|
name: 'user',
|
||||||
|
component: () => import('@/views/admin/user/user.vue')
|
||||||
|
},
|
||||||
|
// 博物馆信息管理
|
||||||
|
{
|
||||||
|
path: 'museumIntro',
|
||||||
|
name: 'museumIntro',
|
||||||
|
component: () => import('@/views/admin/museumIntro/index.vue')
|
||||||
|
},
|
||||||
|
// 用户详情
|
||||||
|
{
|
||||||
|
path: 'userInfo',
|
||||||
|
name: 'userInfo',
|
||||||
|
component: () => import('@/views/admin/user/userInfo.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 游客端路径配置
|
||||||
|
{
|
||||||
|
path: '/tourist',
|
||||||
|
name: 'tourist',
|
||||||
|
component: HLayout,
|
||||||
|
redirect: '/tourist/home',
|
||||||
|
children: [
|
||||||
|
// 首页
|
||||||
|
{
|
||||||
|
path: 'home',
|
||||||
|
name: 'tHome',
|
||||||
|
component: () => import('@/views/tourist/home/index.vue')
|
||||||
|
},
|
||||||
|
// 藏品
|
||||||
|
{
|
||||||
|
path: 'relic',
|
||||||
|
name: 'tRelic',
|
||||||
|
component: () => import('@/views/tourist/relic/index.vue')
|
||||||
|
},
|
||||||
|
// 藏品详情
|
||||||
|
{
|
||||||
|
path: 'relic/detail/:relicId',
|
||||||
|
name: 'tRelicDetail',
|
||||||
|
component: () => import('@/views/tourist/relic/detail.vue')
|
||||||
|
},
|
||||||
|
// 预约
|
||||||
|
{
|
||||||
|
path: 'reservation',
|
||||||
|
name: 'tReservation',
|
||||||
|
component: () => import('@/views/tourist/reservation/reserve.vue')
|
||||||
|
},
|
||||||
|
// 我的预约
|
||||||
|
{
|
||||||
|
path: 'myReservation',
|
||||||
|
name: 'myReservation',
|
||||||
|
component: () => import('@/views/tourist/reservation/index.vue')
|
||||||
|
},
|
||||||
|
// 公告
|
||||||
|
{
|
||||||
|
path: 'announcement',
|
||||||
|
name: 'tAnnouncement',
|
||||||
|
component: () => import('@/views/tourist/announcement/index.vue')
|
||||||
|
},
|
||||||
|
// 我的收藏
|
||||||
|
{
|
||||||
|
path: 'myRelicCollection',
|
||||||
|
name: 'tRelicCollection',
|
||||||
|
component: () => import('@/views/tourist/itemCollection/index.vue')
|
||||||
|
},
|
||||||
|
// 用户详情
|
||||||
|
{
|
||||||
|
path: 'userInfo',
|
||||||
|
name: 'tUserInfo',
|
||||||
|
component: () => import('@/views/tourist/user/userInfo.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
const type = Cookies.get('role')
|
||||||
|
const publicPaths = ['/login', '/register', '/tourist/home', '/tourist/relic', '/tourist/announcement']
|
||||||
|
if (publicPaths.includes(to.path) || to.path.startsWith('/tourist/relic/detail')) {
|
||||||
|
next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!type && to.path === '/tourist/reservation') {
|
||||||
|
ElMessage && ElMessage.warning('请先登录')
|
||||||
|
next(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!type) {
|
||||||
|
next('/login')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router
|
||||||
|
|
@ -0,0 +1,332 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.title"
|
||||||
|
placeholder="请输入标题"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="announcementList">
|
||||||
|
<el-table-column label="标题" align="center" prop="title" />
|
||||||
|
<el-table-column label="置顶标识" align="center" prop="isTop">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.isTop === 1" type="danger">置顶</el-tag>
|
||||||
|
<el-tag v-else type="info">普通</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.status === 1" type="success">显示</el-tag>
|
||||||
|
<el-tag v-else type="warning">隐藏</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.isTop === 0"
|
||||||
|
@click="toggleTop(scope.row, 1)"
|
||||||
|
icon="Top"
|
||||||
|
>设为置顶</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.isTop === 1"
|
||||||
|
@click="toggleTop(scope.row, 0)"
|
||||||
|
icon="Bottom"
|
||||||
|
>取消置顶</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.status === 1"
|
||||||
|
@click="toggleStatus(scope.row, 0)"
|
||||||
|
icon="Hide"
|
||||||
|
>隐藏</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.status === 0"
|
||||||
|
@click="toggleStatus(scope.row, 1)"
|
||||||
|
icon="View"
|
||||||
|
>显示</el-button>
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改公告对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="650px" append-to-body :close-on-click-modal="false">
|
||||||
|
<el-form ref="announcementRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input v-model="form.title" placeholder="请输入标题" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="内容" prop="content">
|
||||||
|
<Editor
|
||||||
|
:value="form.content || ''"
|
||||||
|
@updateValue="updateContent"
|
||||||
|
filePath="announcementContentImg" />
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="置顶标识" prop="isTop">
|
||||||
|
<el-input v-model="form.isTop" placeholder="请输入置顶标识" />
|
||||||
|
</el-form-item> -->
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Announcement">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listAnnouncement, getAnnouncement, delAnnouncement, addAnnouncement, updateAnnouncement, setTopAnnouncement } from "@/api/announcement";
|
||||||
|
import Editor from "@/components/Editor.vue";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const announcementList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
title: null,
|
||||||
|
content: null,
|
||||||
|
isTop: null,
|
||||||
|
status: null,
|
||||||
|
creator: null,
|
||||||
|
updater: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
title: [
|
||||||
|
{ required: true, message: "标题不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
content: [
|
||||||
|
{ required: true, message: "内容不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询公告列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listAnnouncement(queryParams.value).then(response => {
|
||||||
|
announcementList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
title: null,
|
||||||
|
content: null,
|
||||||
|
isTop: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
creator: null,
|
||||||
|
updateTime: null,
|
||||||
|
updater: null
|
||||||
|
};
|
||||||
|
const announcementRef = proxy.$refs["announcementRef"]
|
||||||
|
if (announcementRef) {
|
||||||
|
announcementRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加公告";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getAnnouncement(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改公告";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["announcementRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addAnnouncement(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateAnnouncement(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除公告编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delAnnouncement(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTop(row, nextVal) {
|
||||||
|
const text = nextVal === 1 ? '是否要将该公告置顶?' : '是否要取消该公告的置顶?';
|
||||||
|
proxy.$confirm(text).then(function() {
|
||||||
|
if (nextVal === 1) {
|
||||||
|
return setTopAnnouncement(row.id)
|
||||||
|
} else {
|
||||||
|
return updateAnnouncement({ id: row.id, isTop: nextVal })
|
||||||
|
}
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleStatus(row, nextVal) {
|
||||||
|
const text = nextVal === 1 ? '是否要显示该公告?' : '是否要隐藏该公告?';
|
||||||
|
proxy.$confirm(text).then(function() {
|
||||||
|
return updateAnnouncement({ id: row.id, status: nextVal });
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/announcement/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `announcement_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
function updateContent(value) {
|
||||||
|
form.value.content = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,351 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="carouselList">
|
||||||
|
<el-table-column label="标题" align="center" prop="title" />
|
||||||
|
<el-table-column label="图片" align="center" prop="imageUrl">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-image
|
||||||
|
v-if="scope.row.imageUrl"
|
||||||
|
:src="proxy.getFilePrefix + scope.row.imageUrl"
|
||||||
|
:preview-src-list="[proxy.getFilePrefix + scope.row.imageUrl]"
|
||||||
|
preview-teleported
|
||||||
|
fit="cover"
|
||||||
|
style="width: 80px; height: 80px; cursor: zoom-in"
|
||||||
|
/>
|
||||||
|
<span v-else>—</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="跳转链接" align="center" prop="link" />
|
||||||
|
<el-table-column label="排序序号" align="center" prop="sort" />
|
||||||
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.status === 1" type="success">显示</el-tag>
|
||||||
|
<el-tag v-else type="warning">隐藏</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.status === 1"
|
||||||
|
@click="toggleStatus(scope.row, 0)"
|
||||||
|
icon="Hide"
|
||||||
|
>隐藏</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.status === 0"
|
||||||
|
@click="toggleStatus(scope.row, 1)"
|
||||||
|
icon="View"
|
||||||
|
>显示</el-button>
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改轮播图对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="650px" append-to-body :close-on-click-modal="false">
|
||||||
|
<el-form ref="carouselRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input v-model="form.title" placeholder="请输入标题" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="图片" prop="imageUrl">
|
||||||
|
<el-upload
|
||||||
|
action="/api/files/upload"
|
||||||
|
:headers="headers"
|
||||||
|
name="file"
|
||||||
|
:data="{filePath: 'carousel'}"
|
||||||
|
list-type="picture-card"
|
||||||
|
:file-list="imageFileList"
|
||||||
|
:limit="1"
|
||||||
|
:on-success="handleImageSuccess"
|
||||||
|
:on-remove="handleImageRemove"
|
||||||
|
:on-exceed="handleImageExceed"
|
||||||
|
:before-upload="beforeImageUpload"
|
||||||
|
accept="image/*"
|
||||||
|
>
|
||||||
|
<el-icon><Plus /></el-icon>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="跳转链接" prop="link">
|
||||||
|
<el-input v-model="form.link" placeholder="请输入跳转链接" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序序号" prop="sort">
|
||||||
|
<el-input v-model="form.sort" placeholder="请输入排序序号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Carousel">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listCarousel, getCarousel, delCarousel, addCarousel, updateCarousel } from "@/api/carousel";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const carouselList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
title: null,
|
||||||
|
imageUrl: null,
|
||||||
|
link: null,
|
||||||
|
sort: null,
|
||||||
|
status: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
title: [
|
||||||
|
{ required: true, message: "标题不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
imageUrl: [
|
||||||
|
{ required: true, message: "图片地址不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
const imageFileList = ref([]);
|
||||||
|
const headers = {};
|
||||||
|
|
||||||
|
/** 查询轮播图列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listCarousel(queryParams.value).then(response => {
|
||||||
|
carouselList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
title: null,
|
||||||
|
imageUrl: null,
|
||||||
|
link: null,
|
||||||
|
sort: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
updateTime: null
|
||||||
|
};
|
||||||
|
const carouselRef = proxy.$refs["carouselRef"]
|
||||||
|
if (carouselRef) {
|
||||||
|
carouselRef.resetFields();
|
||||||
|
}
|
||||||
|
imageFileList.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加轮播图";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getCarousel(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改轮播图";
|
||||||
|
isAdd.value = false;
|
||||||
|
imageFileList.value = form.value.imageUrl ? [{ name: '图片', url: proxy.getFilePrefix + form.value.imageUrl }] : [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["carouselRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addCarousel(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateCarousel(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleImageSuccess(res, file, fileList) {
|
||||||
|
form.value.imageUrl = res;
|
||||||
|
imageFileList.value = [{ name: file.name, url: proxy.getFilePrefix + form.value.imageUrl }];
|
||||||
|
const carouselRef = proxy.$refs["carouselRef"];
|
||||||
|
if (carouselRef) {
|
||||||
|
carouselRef.validateField('imageUrl');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleImageRemove() {
|
||||||
|
form.value.imageUrl = null;
|
||||||
|
imageFileList.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleImageExceed(files, fileList) {
|
||||||
|
proxy.$message({
|
||||||
|
message: '只允许上传一张图片',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function beforeImageUpload(file) {
|
||||||
|
const ok = file.size / 1024 / 1024 <= 10;
|
||||||
|
if (!ok) {
|
||||||
|
proxy.$message({
|
||||||
|
message: '图片大小不能超过10MB',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleStatus(row, nextVal) {
|
||||||
|
const text = nextVal === 1 ? '是否要显示该轮播图?' : '是否要隐藏该轮播图?';
|
||||||
|
proxy.$confirm(text).then(function() {
|
||||||
|
return updateCarousel({ id: row.id, status: nextVal });
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除轮播图编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delCarousel(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/carousel/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `carousel_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.el-upload--picture-card {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
.el-upload-list__item {
|
||||||
|
width: 120px !important;
|
||||||
|
height: 120px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,246 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="分类名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.name"
|
||||||
|
placeholder="请输入分类名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="itemCategoryList">
|
||||||
|
<!-- <el-table-column label="分类ID" align="center" prop="id" /> -->
|
||||||
|
<el-table-column label="分类名称" align="center" prop="name" />
|
||||||
|
<!-- <el-table-column label="创建者" align="center" prop="creator" />
|
||||||
|
<el-table-column label="更新者" align="center" prop="updater" /> -->
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改藏品分类对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="itemCategoryRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="分类名称" prop="name">
|
||||||
|
<el-input v-model="form.name" placeholder="请输入分类名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ItemCategory">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listItemCategory, getItemCategory, delItemCategory, addItemCategory, updateItemCategory } from "@/api/itemCategory";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const itemCategoryList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
name: null,
|
||||||
|
creator: null,
|
||||||
|
updater: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: "分类名称不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询藏品分类列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listItemCategory(queryParams.value).then(response => {
|
||||||
|
itemCategoryList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
name: null,
|
||||||
|
creator: null,
|
||||||
|
createTime: null,
|
||||||
|
updater: null,
|
||||||
|
updateTime: null,
|
||||||
|
remark: null
|
||||||
|
};
|
||||||
|
const itemCategoryRef = proxy.$refs["itemCategoryRef"]
|
||||||
|
if (itemCategoryRef) {
|
||||||
|
itemCategoryRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加藏品分类";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getItemCategory(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改藏品分类";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["itemCategoryRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addItemCategory(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateItemCategory(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除藏品分类编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delItemCategory(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/itemCategory/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `itemCategory_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,251 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="用户id" prop="userId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.userId"
|
||||||
|
placeholder="请输入用户id"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="藏品id" prop="itemId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.itemId"
|
||||||
|
placeholder="请输入藏品id"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="itemCollectionList">
|
||||||
|
<el-table-column label="收藏id" align="center" prop="id" />
|
||||||
|
<el-table-column label="用户id" align="center" prop="userId" />
|
||||||
|
<el-table-column label="藏品id" align="center" prop="itemId" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改收藏对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="itemCollectionRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="用户id" prop="userId">
|
||||||
|
<el-input v-model="form.userId" placeholder="请输入用户id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="藏品id" prop="itemId">
|
||||||
|
<el-input v-model="form.itemId" placeholder="请输入藏品id" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ItemCollection">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listItemCollection, getItemCollection, delItemCollection, addItemCollection, updateItemCollection } from "@/api/itemCollection";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const itemCollectionList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
userId: null,
|
||||||
|
itemId: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
userId: [
|
||||||
|
{ required: true, message: "用户id不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
itemId: [
|
||||||
|
{ required: true, message: "藏品id不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询收藏列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listItemCollection(queryParams.value).then(response => {
|
||||||
|
itemCollectionList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
userId: null,
|
||||||
|
itemId: null,
|
||||||
|
createTime: null
|
||||||
|
};
|
||||||
|
const itemCollectionRef = proxy.$refs["itemCollectionRef"]
|
||||||
|
if (itemCollectionRef) {
|
||||||
|
itemCollectionRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加收藏";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getItemCollection(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改收藏";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["itemCollectionRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addItemCollection(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateItemCollection(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除收藏编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delItemCollection(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/itemCollection/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `itemCollection_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,253 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-table v-loading="loading" :data="museumIntroList">
|
||||||
|
<el-table-column label="博物馆名称" align="center" prop="museumName" />
|
||||||
|
<el-table-column label="内容" align="center" prop="content" :show-overflow-tooltip="true" />
|
||||||
|
<!-- <el-table-column label="Logo地址" align="center" prop="logoUrl" /> -->
|
||||||
|
<el-table-column label="地址" align="center" prop="address" />
|
||||||
|
<el-table-column label="联系电话" align="center" prop="phone" />
|
||||||
|
<el-table-column label="营业开始时间" align="center" prop="openTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.openTime }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="营业结束时间" align="center" prop="closeTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.closeTime}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- <el-table-column label="更新者id" align="center" prop="updater" /> -->
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button> -->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改博物馆简介对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="museumIntroRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="内容">
|
||||||
|
<editor v-model="form.content" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Logo地址" prop="logoUrl">
|
||||||
|
<el-input v-model="form.logoUrl" placeholder="请输入Logo地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="地址" prop="address">
|
||||||
|
<el-input v-model="form.address" placeholder="请输入地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="联系电话" prop="phone">
|
||||||
|
<el-input v-model="form.phone" placeholder="请输入联系电话" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="营业开始时间" prop="openTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.openTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择营业开始时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="营业结束时间" prop="closeTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.closeTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择营业结束时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="更新者id" prop="updater">
|
||||||
|
<el-input v-model="form.updater" placeholder="请输入更新者id" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="MuseumIntro">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listMuseumIntro, getMuseumIntro, delMuseumIntro, addMuseumIntro, updateMuseumIntro } from "@/api/museumIntro";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const museumIntroList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
content: null,
|
||||||
|
logoUrl: null,
|
||||||
|
address: null,
|
||||||
|
phone: null,
|
||||||
|
openTime: null,
|
||||||
|
closeTime: null,
|
||||||
|
updater: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
content: [
|
||||||
|
{ required: true, message: "内容不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询博物馆简介列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listMuseumIntro(queryParams.value).then(response => {
|
||||||
|
museumIntroList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
museumName: null,
|
||||||
|
content: null,
|
||||||
|
logoUrl: null,
|
||||||
|
address: null,
|
||||||
|
phone: null,
|
||||||
|
openTime: null,
|
||||||
|
closeTime: null,
|
||||||
|
updateTime: null,
|
||||||
|
updater: null
|
||||||
|
};
|
||||||
|
const museumIntroRef = proxy.$refs["museumIntroRef"]
|
||||||
|
if (museumIntroRef) {
|
||||||
|
museumIntroRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加博物馆简介";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _museumName = row.museumName || ids.value
|
||||||
|
getMuseumIntro(_museumName).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改博物馆简介";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["museumIntroRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addMuseumIntro(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateMuseumIntro(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除博物馆简介编号为"' + row.museumName + '"的数据项?').then(function() {
|
||||||
|
return delMuseumIntro(row.museumName);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/museumIntro/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `museumIntro_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,524 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.name"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类" prop="categoryId">
|
||||||
|
<el-select v-model="queryParams.categoryId" placeholder="请选择分类" clearable style="width: 170px">
|
||||||
|
<el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="年代" prop="age">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.age"
|
||||||
|
placeholder="请输入年代"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="热门标识" prop="isHot">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.isHot"
|
||||||
|
placeholder="请输入热门标识"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="relicList">
|
||||||
|
<!-- <el-table-column label="藏品id" align="center" prop="id" /> -->
|
||||||
|
<el-table-column label="名称" align="center" prop="name" />
|
||||||
|
<el-table-column label="分类" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.categoryInfo && scope.row.categoryInfo.name ? scope.row.categoryInfo.name : '—' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="封面" align="center" prop="coverImageUrl">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-image
|
||||||
|
v-if="scope.row.coverImageUrl"
|
||||||
|
:src="getFilePrefix + scope.row.coverImageUrl"
|
||||||
|
:preview-src-list="[getFilePrefix + scope.row.coverImageUrl]"
|
||||||
|
preview-teleported
|
||||||
|
fit="cover"
|
||||||
|
style="width: 80px; height: 80px; cursor: zoom-in"
|
||||||
|
/>
|
||||||
|
<span v-else>—</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="年代" align="center" prop="age" />
|
||||||
|
<el-table-column label="材质" align="center" prop="material" />
|
||||||
|
<!-- <el-table-column label="出土信息" align="center" prop="excavationInfo" /> -->
|
||||||
|
<!-- <el-table-column label="文物故事" align="center" prop="story" /> -->
|
||||||
|
<!-- <el-table-column label="3D/360°图地址" align="center" prop="modelUrl" /> -->
|
||||||
|
<el-table-column label="热门标识" align="center" prop="isHot">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.isHot === 1" type="danger">热门</el-tag>
|
||||||
|
<el-tag v-else type="info">普通</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.status === 1" type="success">显示</el-tag>
|
||||||
|
<el-tag v-else type="warning">隐藏</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- <el-table-column label="创建者id" align="center" prop="creator" />
|
||||||
|
<el-table-column label="更新者id" align="center" prop="updater" /> -->
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="350">
|
||||||
|
<template #default="scope">
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.isHot === 0"
|
||||||
|
@click="toggleHot(scope.row, 1)"
|
||||||
|
icon="Sunny"
|
||||||
|
>设为热门</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.isHot === 1"
|
||||||
|
@click="toggleHot(scope.row, 0)"
|
||||||
|
icon="CloseBold"
|
||||||
|
>取消热门</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.status === 1"
|
||||||
|
@click="toggleStatus(scope.row, 0)"
|
||||||
|
icon="Hide"
|
||||||
|
>隐藏</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
v-if="scope.row.status === 0"
|
||||||
|
@click="toggleStatus(scope.row, 1)"
|
||||||
|
icon="View"
|
||||||
|
>显示</el-button>
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改藏品对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="800px" append-to-body :close-on-click-modal="false">
|
||||||
|
<el-form ref="relicRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="名称" prop="name">
|
||||||
|
<el-input v-model="form.name" placeholder="请输入名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="分类" prop="categoryId">
|
||||||
|
<el-select v-model="form.categoryId" placeholder="请选择分类" style="width: 100%">
|
||||||
|
<el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="封面" prop="coverImageUrl">
|
||||||
|
<el-upload
|
||||||
|
action="/api/files/upload"
|
||||||
|
:headers="headers"
|
||||||
|
name="file"
|
||||||
|
:data="{filePath: 'relicCover'}"
|
||||||
|
list-type="picture-card"
|
||||||
|
:file-list="coverFileList"
|
||||||
|
:limit="1"
|
||||||
|
:on-success="handleCoverSuccess"
|
||||||
|
:on-remove="handleCoverRemove"
|
||||||
|
:on-exceed="handleCoverExceed"
|
||||||
|
:before-upload="beforeCoverUpload"
|
||||||
|
accept="image/*"
|
||||||
|
>
|
||||||
|
<el-icon><Plus /></el-icon>
|
||||||
|
</el-upload>
|
||||||
|
<div class="upload-tips">仅支持一张图片,大小≤10MB</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="年代" prop="age">
|
||||||
|
<el-input v-model="form.age" placeholder="请输入年代" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="材质" prop="material">
|
||||||
|
<el-input v-model="form.material" placeholder="请输入材质" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="出土信息" prop="excavationInfo">
|
||||||
|
<el-input v-model="form.excavationInfo" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="3D/360°图地址" prop="modelUrl">
|
||||||
|
<el-input v-model="form.modelUrl" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="文物故事" prop="story">
|
||||||
|
<Editor
|
||||||
|
:value="form.story || ''"
|
||||||
|
@updateValue="updateStory"
|
||||||
|
filePath="relicStoryImg"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Relic">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listRelic, getRelic, delRelic, addRelic, updateRelic } from "@/api/relic";
|
||||||
|
import { listAllItemCategory } from "@/api/itemCategory";
|
||||||
|
import Editor from "@/components/Editor.vue";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const relicList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
name: null,
|
||||||
|
categoryId: null,
|
||||||
|
coverImageUrl: null,
|
||||||
|
age: null,
|
||||||
|
material: null,
|
||||||
|
excavationInfo: null,
|
||||||
|
story: null,
|
||||||
|
modelUrl: null,
|
||||||
|
isHot: null,
|
||||||
|
status: null,
|
||||||
|
creator: null,
|
||||||
|
updater: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: "名称不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
categoryId: [
|
||||||
|
{ required: true, message: "分类ID不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
coverImageUrl: [
|
||||||
|
{ required: true, message: "封面不能为空", trigger: "change" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
const coverFileList = ref([]);
|
||||||
|
const categoryOptions = ref([]);
|
||||||
|
const headers = {};
|
||||||
|
|
||||||
|
// 上传成功后
|
||||||
|
function handleUploadSuccess(response, uploadFile, uploadFiles) {
|
||||||
|
form.value.coverImageUrl = response
|
||||||
|
proxy.$message.success('上传成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** 富文本回调 */
|
||||||
|
function updateStory(value) {
|
||||||
|
form.value.story = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询藏品列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listRelic(queryParams.value).then(response => {
|
||||||
|
relicList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCategories() {
|
||||||
|
listAllItemCategory({}).then(res => {
|
||||||
|
const arr = res || [];
|
||||||
|
categoryOptions.value = Array.isArray(arr) ? arr : [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
name: null,
|
||||||
|
categoryId: null,
|
||||||
|
coverImageUrl: null,
|
||||||
|
age: null,
|
||||||
|
material: null,
|
||||||
|
excavationInfo: null,
|
||||||
|
story: null,
|
||||||
|
modelUrl: null,
|
||||||
|
isHot: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
creator: null,
|
||||||
|
updateTime: null,
|
||||||
|
updater: null
|
||||||
|
};
|
||||||
|
const relicRef = proxy.$refs["relicRef"]
|
||||||
|
if (relicRef) {
|
||||||
|
relicRef.resetFields();
|
||||||
|
}
|
||||||
|
coverFileList.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加藏品";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getRelic(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改藏品";
|
||||||
|
isAdd.value = false;
|
||||||
|
coverFileList.value = form.value.coverImageUrl ? [{ name: '封面', url: proxy.getFilePrefix + form.value.coverImageUrl }] : [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["relicRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addRelic(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateRelic(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除藏品编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delRelic(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/relic/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `relic_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
function handleCoverSuccess(res, file, fileList) {
|
||||||
|
form.value.coverImageUrl = res;
|
||||||
|
coverFileList.value = [{ name: file.name, url: proxy.getFilePrefix + form.value.coverImageUrl }];
|
||||||
|
const relicRef = proxy.$refs["relicRef"];
|
||||||
|
if (relicRef) {
|
||||||
|
relicRef.validateField('coverImageUrl');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCoverRemove() {
|
||||||
|
form.value.coverImageUrl = null;
|
||||||
|
coverFileList.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCoverExceed(files, fileList) {
|
||||||
|
proxy.$message({
|
||||||
|
message: '只允许上传一张图片',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function beforeCoverUpload(file) {
|
||||||
|
const ok = file.size / 1024 / 1024 <= 10;
|
||||||
|
if (!ok) {
|
||||||
|
proxy.$message({
|
||||||
|
message: '图片大小不能超过10MB',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleHot(row, nextVal) {
|
||||||
|
const text = nextVal === 1 ? '是否要把该藏品设置为热门?' : '是否要取消该藏品的热门?';
|
||||||
|
proxy.$confirm(text).then(function() {
|
||||||
|
return updateRelic({ id: row.id, isHot: nextVal });
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleStatus(row, nextVal) {
|
||||||
|
const text = nextVal === 1 ? '是否要显示该藏品?' : '是否要隐藏该藏品?';
|
||||||
|
proxy.$confirm(text).then(function() {
|
||||||
|
return updateRelic({ id: row.id, status: nextVal });
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getList();
|
||||||
|
loadCategories();
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.upload-tips {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.el-upload--picture-card {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
.el-upload-list__item {
|
||||||
|
width: 120px !important;
|
||||||
|
height: 120px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,474 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="用户名" prop="username">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.username"
|
||||||
|
placeholder="请输入预约者用户名"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="昵称" prop="nickname">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.nickname"
|
||||||
|
placeholder="请输入预约者昵称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="预约日期" prop="dateRange">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
unlink-panels
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="reservationList">
|
||||||
|
<!-- <el-table-column label="预约id" align="center" prop="id" /> -->
|
||||||
|
<el-table-column label="用户名" align="center" prop="username" />
|
||||||
|
<el-table-column label="昵称" align="center" prop="nickname" />
|
||||||
|
<!-- <el-table-column label="预约发起者id" align="center" prop="userId" /> -->
|
||||||
|
<!-- <el-table-column label="预约时段id" align="center" prop="timeSlotId" /> -->
|
||||||
|
<el-table-column label="预约总人数" align="center" prop="totalVisitors" />
|
||||||
|
<el-table-column label="预约日期" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ formatDateYMD(scope.row.reservationTimeSlot && scope.row.reservationTimeSlot.date) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="预约时间" align="center" prop="reserveTime" />
|
||||||
|
|
||||||
|
<!-- <el-table-column label="预约凭证二维码" align="center" prop="qrCode" /> -->
|
||||||
|
|
||||||
|
<el-table-column label="整单状态" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tooltip v-if="Number(scope.row.status) === 3 && scope.row.remark" :content="`拒绝原因:${scope.row.remark}`" placement="top" effect="dark">
|
||||||
|
<el-tag :type="statusType(scope.row.status)" style="cursor: help;">{{ statusText(scope.row.status) }}</el-tag>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tag v-else :type="statusType(scope.row.status)">{{ statusText(scope.row.status) }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- <el-table-column label="审核者id" align="center" prop="updater" />
|
||||||
|
<el-table-column label="审核备注" align="center" prop="remark" /> -->
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button v-if="Number(scope.row.status) === 0" link type="success" icon="Check" @click="openAudit(scope.row)">审核</el-button>
|
||||||
|
<el-button v-else link type="primary" icon="View" @click="openDetail(scope.row)">详情</el-button>
|
||||||
|
<!-- <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button> -->
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改预约对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="reservationRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="预约发起者id" prop="userId">
|
||||||
|
<el-input v-model="form.userId" placeholder="请输入预约发起者id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="预约时段id" prop="timeSlotId">
|
||||||
|
<el-input v-model="form.timeSlotId" placeholder="请输入预约时段id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="预约总人数" prop="totalVisitors">
|
||||||
|
<el-input v-model="form.totalVisitors" placeholder="请输入预约总人数" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="预约时间" prop="reserveTime">
|
||||||
|
<el-input v-model="form.reserveTime" placeholder="请输入预约时间(HH:mm:ss)" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="预约凭证二维码" prop="qrCode">
|
||||||
|
<el-input v-model="form.qrCode" placeholder="请输入预约凭证二维码" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="审核者id" prop="updater">
|
||||||
|
<el-input v-model="form.updater" placeholder="请输入审核者id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="审核备注" prop="remark">
|
||||||
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="审核预约" v-model="auditOpen" width="700px" append-to-body>
|
||||||
|
<div class="audit-info">
|
||||||
|
<div class="audit-section-title">预约信息</div>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="用户名">{{ auditData.username }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="昵称">{{ auditData.nickname }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预约日期">{{ formatDateYMD(auditData.reservationTimeSlot && auditData.reservationTimeSlot.date) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预约时间">{{ auditData.reserveTime }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预约总人数">{{ auditData.totalVisitors }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<el-divider content-position="left"><span class="audit-section-title">游客信息</span></el-divider>
|
||||||
|
<div class="audit-visitors" v-if="auditData.reservationVisitors && auditData.reservationVisitors.length">
|
||||||
|
<el-table :data="auditData.reservationVisitors" size="small" style="margin-top: 12px;">
|
||||||
|
<el-table-column label="姓名" prop="realName" align="center" />
|
||||||
|
<el-table-column label="身份证号" prop="idCard" align="center" />
|
||||||
|
<el-table-column label="手机号" prop="phone" align="center" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="audit-visitors-empty" v-else>
|
||||||
|
<el-empty description="暂无游客信息" image-size="80" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-form :model="auditForm" :rules="auditRules" ref="auditRef" label-width="90px" style="margin-top: 12px;">
|
||||||
|
<el-form-item label="审核结果" prop="status">
|
||||||
|
<el-select v-model="auditForm.status" placeholder="请选择">
|
||||||
|
<el-option label="通过" :value="1" />
|
||||||
|
<el-option label="拒绝" :value="3" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="Number(auditForm.status) === 3" label="拒绝原因" prop="remark">
|
||||||
|
<el-input v-model="auditForm.remark" type="textarea" placeholder="请输入拒绝原因" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitAudit">提 交</el-button>
|
||||||
|
<el-button @click="auditOpen=false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="预约详情" v-model="detailOpen" width="700px" append-to-body>
|
||||||
|
<div class="audit-info">
|
||||||
|
<div class="audit-section-title">预约信息</div>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="用户名">{{ detailData.username }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="昵称">{{ detailData.nickname }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预约日期">{{ formatDateYMD(detailData.reservationTimeSlot && detailData.reservationTimeSlot.date) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预约时间">{{ detailData.reserveTime }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预约总人数">{{ detailData.totalVisitors }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="Number(detailData.status) === 1" label="整单核验二维码">
|
||||||
|
<el-image v-if="detailData.qrCode" :src="qrImg('/api' + detailData.qrCode)" :preview-src-list="[qrImg('/api' + detailData.qrCode)]" style="width: 160px; height: 160px;" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<el-divider content-position="left"><span class="audit-section-title">游客信息</span></el-divider>
|
||||||
|
<div class="audit-visitors" v-if="detailData.reservationVisitors && detailData.reservationVisitors.length">
|
||||||
|
<el-table :data="detailData.reservationVisitors" size="small" style="margin-top: 12px;">
|
||||||
|
<el-table-column label="姓名" prop="realName" align="center" />
|
||||||
|
<el-table-column label="身份证号" prop="idCard" align="center" />
|
||||||
|
<el-table-column label="手机号" prop="phone" align="center" />
|
||||||
|
<el-table-column label="核验二维码" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-image v-if="scope.row.visitorQrCode" :src="qrImg('/api' + scope.row.visitorQrCode)" :preview-src-list="[qrImg('/api' + scope.row.visitorQrCode)]" style="width: 120px; height: 120px;" />
|
||||||
|
<span v-else>—</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="audit-visitors-empty" v-else>
|
||||||
|
<el-empty description="暂无游客信息" image-size="80" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="detailOpen=false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Reservation">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listReservation, getReservation, delReservation, addReservation, updateReservation, auditReservation } from "@/api/reservation";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const reservationList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const auditOpen = ref(false)
|
||||||
|
const auditData = ref({})
|
||||||
|
const auditForm = ref({ id: null, status: null, remark: '' })
|
||||||
|
const auditRules = {
|
||||||
|
status: [{ required: true, message: '请选择审核结果', trigger: 'change' }],
|
||||||
|
remark: [{ validator: (rule, value, callback) => {
|
||||||
|
const s = auditForm.value.status
|
||||||
|
if (Number(s) === 3 && (!value || !value.trim())) callback(new Error('拒绝原因不能为空'))
|
||||||
|
else callback()
|
||||||
|
}, trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
username: null,
|
||||||
|
nickname: null,
|
||||||
|
dateRange: null,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
userId: null,
|
||||||
|
timeSlotId: null,
|
||||||
|
totalVisitors: null,
|
||||||
|
reserveTime: null,
|
||||||
|
qrCode: null,
|
||||||
|
status: null,
|
||||||
|
updater: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
userId: [
|
||||||
|
{ required: true, message: "预约发起者id不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
timeSlotId: [
|
||||||
|
{ required: true, message: "预约时段id不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
totalVisitors: [
|
||||||
|
{ required: true, message: "预约总人数不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
reserveTime: [
|
||||||
|
{ required: true, message: "预约时间不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询预约列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
const qp = {
|
||||||
|
...queryParams.value,
|
||||||
|
startDate: queryParams.value.dateRange && queryParams.value.dateRange[0],
|
||||||
|
endDate: queryParams.value.dateRange && queryParams.value.dateRange[1]
|
||||||
|
}
|
||||||
|
listReservation(qp).then(response => {
|
||||||
|
reservationList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
userId: null,
|
||||||
|
timeSlotId: null,
|
||||||
|
totalVisitors: null,
|
||||||
|
reserveTime: null,
|
||||||
|
qrCode: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
updateTime: null,
|
||||||
|
updater: null,
|
||||||
|
remark: null
|
||||||
|
};
|
||||||
|
const reservationRef = proxy.$refs["reservationRef"]
|
||||||
|
if (reservationRef) {
|
||||||
|
reservationRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加预约";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getReservation(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改预约";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openAudit(row) {
|
||||||
|
getReservation(row.id).then(response => {
|
||||||
|
auditData.value = response.data
|
||||||
|
auditForm.value = { id: row.id, status: 1, remark: '' }
|
||||||
|
auditOpen.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const detailOpen = ref(false)
|
||||||
|
const detailData = ref({})
|
||||||
|
|
||||||
|
function qrImg(url) {
|
||||||
|
if (!url) return ''
|
||||||
|
const u = encodeURIComponent(url)
|
||||||
|
return `https://api.qrserver.com/v1/create-qr-code/?size=160x160&data=${u}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDetail(row) {
|
||||||
|
getReservation(row.id).then(response => {
|
||||||
|
detailData.value = response.data
|
||||||
|
detailOpen.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitAudit() {
|
||||||
|
const auditRef = proxy.$refs["auditRef"]
|
||||||
|
if (auditRef) {
|
||||||
|
auditRef.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
const payload = { id: auditForm.value.id, status: auditForm.value.status, remark: auditForm.value.remark }
|
||||||
|
auditReservation(payload).then(resp => {
|
||||||
|
proxy.$message({ message: resp.msg, type: 'success' })
|
||||||
|
auditOpen.value = false
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["reservationRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addReservation(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateReservation(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除预约编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delReservation(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/reservation/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `reservation_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
formatDateYMD(val) {
|
||||||
|
if (!val) return ''
|
||||||
|
if (typeof val === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(val)) return val
|
||||||
|
const d = new Date(val)
|
||||||
|
if (isNaN(d.getTime())) return ''
|
||||||
|
const y = d.getFullYear()
|
||||||
|
const M = String(d.getMonth() + 1).padStart(2, '0')
|
||||||
|
const D = String(d.getDate()).padStart(2, '0')
|
||||||
|
return `${y}-${M}-${D}`
|
||||||
|
},
|
||||||
|
statusText(s) {
|
||||||
|
const n = Number(s)
|
||||||
|
if (n === 1) return '已通过'
|
||||||
|
if (n === 2) return '已取消'
|
||||||
|
if (n === 3) return '已驳回'
|
||||||
|
return '待审核'
|
||||||
|
},
|
||||||
|
statusType(s) {
|
||||||
|
const n = Number(s)
|
||||||
|
if (n === 1) return 'success'
|
||||||
|
if (n === 2) return 'info'
|
||||||
|
if (n === 3) return 'danger'
|
||||||
|
return 'warning'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,733 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增时段</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="info"
|
||||||
|
plain
|
||||||
|
icon="List"
|
||||||
|
@click="toggleView"
|
||||||
|
>{{ viewMode === 'calendar' ? '列表视图' : '日历视图' }}</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<!-- 日历视图 -->
|
||||||
|
<div v-if="viewMode === 'calendar'" class="calendar-container">
|
||||||
|
<el-calendar v-model="calendarDate">
|
||||||
|
<template #date-cell="{ data }">
|
||||||
|
<div class="calendar-day">
|
||||||
|
<div class="day-number" :class="{ 'is-today': isToday(data.day) }">
|
||||||
|
{{ data.day.split('-').slice(-1)[0] }}
|
||||||
|
</div>
|
||||||
|
<div v-if="isDayBlocked(data.day)" class="blocked-day" @click="openEditForDay(data.day)">
|
||||||
|
<span class="blocked-tag">不可预约</span>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="getTimeSlotsForDate(data.day).length > 0" class="time-slots">
|
||||||
|
<div
|
||||||
|
v-for="slot in getTimeSlotsForDate(data.day)"
|
||||||
|
:key="slot.id"
|
||||||
|
class="time-slot-card"
|
||||||
|
:class="getSlotStatusClass(slot)"
|
||||||
|
>
|
||||||
|
<div class="slot-time">
|
||||||
|
<el-icon><Clock /></el-icon>
|
||||||
|
{{ formatTime(slot.startTime) }}-{{ formatTime(slot.endTime) }}
|
||||||
|
</div>
|
||||||
|
<div class="slot-info">
|
||||||
|
<el-icon><User /></el-icon>
|
||||||
|
<span>{{ slot.currentPeople }}/{{ slot.maxPeople }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="slot-actions">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
icon="Edit"
|
||||||
|
@click.stop="handleUpdate(slot)"
|
||||||
|
></el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
size="small"
|
||||||
|
icon="Delete"
|
||||||
|
@click.stop="handleDelete(slot)"
|
||||||
|
></el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="no-slots">
|
||||||
|
<span class="no-slots-text">暂无时段</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-calendar>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 列表视图 -->
|
||||||
|
<div v-else>
|
||||||
|
<el-table v-loading="loading" :data="reservationTimeSlotList">
|
||||||
|
<el-table-column label="日期" align="center" prop="date" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.date, 'yyyy-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="开始时间" align="center" prop="startTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ formatTime(scope.row.startTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="结束时间" align="center" prop="endTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ formatTime(scope.row.endTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="最大人数" align="center" prop="maxPeople" />
|
||||||
|
<el-table-column label="已预约人数" align="center" prop="currentPeople" />
|
||||||
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="statusMap[scope.row.status] ? (statusMap[scope.row.status] === '可预约' ? 'success' : 'danger') : 'info'">
|
||||||
|
{{ statusMap[scope.row.status] || '未设置' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog v-if="isAdd" :title="title" v-model="open" width="600px" append-to-body>
|
||||||
|
<el-form ref="reservationTimeSlotRef" :model="form" :rules="rules" label-width="100px">
|
||||||
|
<el-form-item label="日期范围" prop="dateRange">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
unlink-panels
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开始时间" prop="startTime">
|
||||||
|
<el-time-picker
|
||||||
|
v-model="form.startTime"
|
||||||
|
placeholder="请选择开始时间"
|
||||||
|
format="HH:mm:ss"
|
||||||
|
value-format="HH:mm:ss"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束时间" prop="endTime">
|
||||||
|
<el-time-picker
|
||||||
|
v-model="form.endTime"
|
||||||
|
placeholder="请选择结束时间"
|
||||||
|
format="HH:mm:ss"
|
||||||
|
value-format="HH:mm:ss"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="最大人数" prop="maxPeople">
|
||||||
|
<el-input v-model="form.maxPeople" placeholder="请输入最大人数" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog v-else title="修改预约时段信息" v-model="open" width="600px" append-to-body>
|
||||||
|
<el-form ref="reservationTimeSlotRef" :model="form" :rules="rules" label-width="100px">
|
||||||
|
<el-form-item label="预约日期" prop="date">
|
||||||
|
<el-input :model-value="parseTime(form.date, 'yyyy-MM-DD')" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开始时间" prop="startTime">
|
||||||
|
<el-time-picker
|
||||||
|
v-model="form.startTime"
|
||||||
|
placeholder="请选择开始时间"
|
||||||
|
format="HH:mm:ss"
|
||||||
|
value-format="HH:mm:ss"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束时间" prop="endTime">
|
||||||
|
<el-time-picker
|
||||||
|
v-model="form.endTime"
|
||||||
|
placeholder="请选择结束时间"
|
||||||
|
format="HH:mm:ss"
|
||||||
|
value-format="HH:mm:ss"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="最大人数" prop="maxPeople">
|
||||||
|
<el-input v-model="form.maxPeople" placeholder="请输入最大人数" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-select v-model="form.status" placeholder="请选择状态" style="width: 100%">
|
||||||
|
<el-option label="不可约" :value="0" />
|
||||||
|
<el-option label="可约" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">提 交</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ReservationTimeSlot">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listReservationTimeSlot, getReservationTimeSlot, delReservationTimeSlot, addReservationTimeSlot, updateReservationTimeSlot, batchAddReservationTimeSlot } from "@/api/reservationTimeSlot";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const reservationTimeSlotList = ref([]);
|
||||||
|
const allTimeSlots = ref([]); // 存储所有时段数据用于日历显示
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
const viewMode = ref('calendar'); // 'calendar' 或 'list'
|
||||||
|
const calendarDate = ref(new Date());
|
||||||
|
|
||||||
|
const statusMap = { 1: '可预约', 0: '不可约' };
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
maxPeople: null,
|
||||||
|
currentPeople: null,
|
||||||
|
status: null,
|
||||||
|
creator: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
dateRange: [
|
||||||
|
{ required: true, message: "预约日期范围不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
startTime: [
|
||||||
|
{ required: true, message: "开始时间不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
endTime: [
|
||||||
|
{ required: true, message: "结束时间不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
maxPeople: [
|
||||||
|
{ required: true, message: "最大人数不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询预约时段列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listReservationTimeSlot(queryParams.value).then(response => {
|
||||||
|
reservationTimeSlotList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取所有时段数据(用于日历视图) */
|
||||||
|
function getAllTimeSlots() {
|
||||||
|
loading.value = true;
|
||||||
|
const params = {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 1000 // 获取足够多的数据用于日历显示
|
||||||
|
};
|
||||||
|
listReservationTimeSlot(params).then(response => {
|
||||||
|
allTimeSlots.value = response.list;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 切换视图模式 */
|
||||||
|
function toggleView() {
|
||||||
|
viewMode.value = viewMode.value === 'calendar' ? 'list' : 'calendar';
|
||||||
|
if (viewMode.value === 'calendar') {
|
||||||
|
getAllTimeSlots();
|
||||||
|
} else {
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据日期获取时段 */
|
||||||
|
function getTimeSlotsForDate(date) {
|
||||||
|
return allTimeSlots.value.filter(slot => {
|
||||||
|
const slotDate = parseTime(slot.date, 'yyyy-MM-DD');
|
||||||
|
return slotDate === date;
|
||||||
|
}).sort((a, b) => {
|
||||||
|
return formatTime(a.startTime).localeCompare(formatTime(b.startTime));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDayBlocked(date) {
|
||||||
|
const slots = allTimeSlots.value.filter(slot => {
|
||||||
|
const slotDate = parseTime(slot.date, 'yyyy-MM-DD');
|
||||||
|
return slotDate === date;
|
||||||
|
});
|
||||||
|
return slots.length > 0 && slots.every(s => Number(s.status) === 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openEditForDay(date) {
|
||||||
|
const slots = getTimeSlotsForDate(date);
|
||||||
|
if (slots.length > 0) {
|
||||||
|
handleUpdate(slots[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 格式化时间 */
|
||||||
|
function formatTime(time) {
|
||||||
|
if (!time) return '';
|
||||||
|
if (typeof time === 'string' && time.includes(' ')) {
|
||||||
|
return time.split(' ')[1].substring(0, 5);
|
||||||
|
}
|
||||||
|
if (typeof time === 'string' && time.includes(':')) {
|
||||||
|
return time.substring(0, 5);
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 判断是否是今天 */
|
||||||
|
function isToday(date) {
|
||||||
|
const today = new Date();
|
||||||
|
const targetDate = new Date(date);
|
||||||
|
return today.getFullYear() === targetDate.getFullYear() &&
|
||||||
|
today.getMonth() === targetDate.getMonth() &&
|
||||||
|
today.getDate() === targetDate.getDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** 获取时段状态样式 */
|
||||||
|
function getSlotStatusClass(slot) {
|
||||||
|
const ratio = slot.currentPeople / slot.maxPeople;
|
||||||
|
if (ratio >= 1) return 'slot-full';
|
||||||
|
if (ratio >= 0.8) return 'slot-almost-full';
|
||||||
|
return 'slot-available';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 时间格式化工具函数 */
|
||||||
|
function parseTime(time, format = 'yyyy-MM-DD HH:mm:ss') {
|
||||||
|
if (!time) return '';
|
||||||
|
const date = new Date(time);
|
||||||
|
const formatObj = {
|
||||||
|
yyyy: date.getFullYear(),
|
||||||
|
MM: String(date.getMonth() + 1).padStart(2, '0'),
|
||||||
|
DD: String(date.getDate()).padStart(2, '0'),
|
||||||
|
HH: String(date.getHours()).padStart(2, '0'),
|
||||||
|
mm: String(date.getMinutes()).padStart(2, '0'),
|
||||||
|
ss: String(date.getSeconds()).padStart(2, '0')
|
||||||
|
};
|
||||||
|
return format.replace(/(yyyy|MM|DD|HH|mm|ss)/g, (match) => formatObj[match]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
dateRange: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
maxPeople: null,
|
||||||
|
currentPeople: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
creator: null
|
||||||
|
};
|
||||||
|
const reservationTimeSlotRef = proxy.$refs["reservationTimeSlotRef"]
|
||||||
|
if (reservationTimeSlotRef) {
|
||||||
|
reservationTimeSlotRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加预约时段";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getReservationTimeSlot(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改预约时段信息";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["reservationTimeSlotRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
batchAddReservationTimeSlot({
|
||||||
|
startDate: form.value.dateRange && form.value.dateRange[0],
|
||||||
|
endDate: form.value.dateRange && form.value.dateRange[1],
|
||||||
|
startTime: form.value.startTime,
|
||||||
|
endTime: form.value.endTime,
|
||||||
|
maxPeople: form.value.maxPeople,
|
||||||
|
status: 1
|
||||||
|
}).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
refreshData();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
const payload = { ...form.value };
|
||||||
|
if (typeof payload.startTime === 'string') {
|
||||||
|
payload.startTime = payload.startTime.length > 8 ? payload.startTime.slice(-8) : payload.startTime;
|
||||||
|
}
|
||||||
|
if (typeof payload.endTime === 'string') {
|
||||||
|
payload.endTime = payload.endTime.length > 8 ? payload.endTime.slice(-8) : payload.endTime;
|
||||||
|
}
|
||||||
|
updateReservationTimeSlot(payload).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
refreshData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除预约时段编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delReservationTimeSlot(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
refreshData();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/reservationTimeSlot/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `reservationTimeSlot_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 初始化时根据视图模式加载数据
|
||||||
|
if (viewMode.value === 'calendar') {
|
||||||
|
getAllTimeSlots();
|
||||||
|
} else {
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshData() {
|
||||||
|
if (viewMode.value === 'calendar') {
|
||||||
|
getAllTimeSlots();
|
||||||
|
} else {
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.calendar-container {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-day {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 110px;
|
||||||
|
padding: 4px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day-number {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day-number.is-today {
|
||||||
|
background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slots {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slot-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||||
|
border-left: 2px solid transparent;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slot-card:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-available {
|
||||||
|
border-left-color: #67c23a;
|
||||||
|
background: linear-gradient(to right, #f0f9ff 0%, #fff 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-available:hover {
|
||||||
|
background: linear-gradient(to right, #e1f3ff 0%, #fff 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-almost-full {
|
||||||
|
border-left-color: #e6a23c;
|
||||||
|
background: linear-gradient(to right, #fef9f0 0%, #fff 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-almost-full:hover {
|
||||||
|
background: linear-gradient(to right, #fdf3e1 0%, #fff 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-full {
|
||||||
|
border-left-color: #f56c6c;
|
||||||
|
background: linear-gradient(to right, #fef0f0 0%, #fff 100%);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-full:hover {
|
||||||
|
background: linear-gradient(to right, #fee5e5 0%, #fff 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-time .el-icon {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
color: #606266;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-info .el-icon {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 2px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slot-card:hover .slot-actions {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-actions .el-button {
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-slots {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-slots-text {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #c0c4cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blocked-day {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16px 0;
|
||||||
|
flex: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blocked-tag {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
background: #f56c6c;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 4px 12px rgba(245, 108, 108, 0.35);
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-calendar-table .el-calendar-day) {
|
||||||
|
padding: 2px;
|
||||||
|
height: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-calendar-table td) {
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-calendar-table td.is-selected) {
|
||||||
|
background-color: #f0f9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-calendar__header) {
|
||||||
|
padding: 12px 20px;
|
||||||
|
border-bottom: 2px solid #e4e7ed;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-calendar__body) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-calendar-table thead th) {
|
||||||
|
padding: 8px 0;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb8 {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滚动条样式 */
|
||||||
|
.time-slots::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slots::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #dcdfe6;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slots::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color: #c0c4cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slots::-webkit-scrollbar-track {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="预约id" prop="reservationId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.reservationId"
|
||||||
|
placeholder="请输入预约id"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客真实姓名" prop="realName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.realName"
|
||||||
|
placeholder="请输入游客真实姓名"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客身份证号" prop="idCard">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.idCard"
|
||||||
|
placeholder="请输入游客身份证号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客手机号" prop="phone">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.phone"
|
||||||
|
placeholder="请输入游客手机号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="入场验证时间" prop="verifyTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="queryParams.verifyTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择入场验证时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="reservationVisitorList">
|
||||||
|
<el-table-column label="明细ID" align="center" prop="id" />
|
||||||
|
<el-table-column label="预约id" align="center" prop="reservationId" />
|
||||||
|
<el-table-column label="游客真实姓名" align="center" prop="realName" />
|
||||||
|
<el-table-column label="游客身份证号" align="center" prop="idCard" />
|
||||||
|
<el-table-column label="游客手机号" align="center" prop="phone" />
|
||||||
|
<el-table-column label="游客个人入场二维码" align="center" prop="visitorQrCode" />
|
||||||
|
<el-table-column label="游客入场验证状态" align="center" prop="verifyStatus" />
|
||||||
|
<el-table-column label="入场验证时间" align="center" prop="verifyTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.verifyTime, 'yyyy-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改游客预约明细对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="reservationVisitorRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="预约id" prop="reservationId">
|
||||||
|
<el-input v-model="form.reservationId" placeholder="请输入预约id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客真实姓名" prop="realName">
|
||||||
|
<el-input v-model="form.realName" placeholder="请输入游客真实姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客身份证号" prop="idCard">
|
||||||
|
<el-input v-model="form.idCard" placeholder="请输入游客身份证号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客手机号" prop="phone">
|
||||||
|
<el-input v-model="form.phone" placeholder="请输入游客手机号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客个人入场二维码" prop="visitorQrCode">
|
||||||
|
<el-input v-model="form.visitorQrCode" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="入场验证时间" prop="verifyTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.verifyTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择入场验证时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ReservationVisitor">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listReservationVisitor, getReservationVisitor, delReservationVisitor, addReservationVisitor, updateReservationVisitor } from "@/api/reservationVisitor";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const reservationVisitorList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
reservationId: null,
|
||||||
|
realName: null,
|
||||||
|
idCard: null,
|
||||||
|
phone: null,
|
||||||
|
visitorQrCode: null,
|
||||||
|
verifyStatus: null,
|
||||||
|
verifyTime: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
reservationId: [
|
||||||
|
{ required: true, message: "预约id不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
realName: [
|
||||||
|
{ required: true, message: "游客真实姓名不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
idCard: [
|
||||||
|
{ required: true, message: "游客身份证号不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: "游客手机号不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询游客预约明细列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listReservationVisitor(queryParams.value).then(response => {
|
||||||
|
reservationVisitorList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
reservationId: null,
|
||||||
|
realName: null,
|
||||||
|
idCard: null,
|
||||||
|
phone: null,
|
||||||
|
visitorQrCode: null,
|
||||||
|
verifyStatus: null,
|
||||||
|
verifyTime: null
|
||||||
|
};
|
||||||
|
const reservationVisitorRef = proxy.$refs["reservationVisitorRef"]
|
||||||
|
if (reservationVisitorRef) {
|
||||||
|
reservationVisitorRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加游客预约明细";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getReservationVisitor(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改游客预约明细";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["reservationVisitorRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addReservationVisitor(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateReservationVisitor(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除游客预约明细编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delReservationVisitor(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/reservationVisitor/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `reservationVisitor_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,241 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-card class="kpi-card"><div class="kpi-title">用户数</div><div class="kpi-value">{{ kpi.users }}</div></el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-card class="kpi-card"><div class="kpi-title">藏品数</div><div class="kpi-value">{{ kpi.relics }}</div></el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-card class="kpi-card"><div class="kpi-title">公告数</div><div class="kpi-value">{{ kpi.announcements }}</div></el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-card class="kpi-card"><div class="kpi-title">预约数</div><div class="kpi-value">{{ kpi.reservations }}</div></el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-card class="kpi-card"><div class="kpi-title">游客数</div><div class="kpi-value">{{ kpi.visitors }}</div></el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-card class="kpi-card"><div class="kpi-title">时段数</div><div class="kpi-value">{{ kpi.timeSlots }}</div></el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12"><el-card><div ref="userRoleChart" class="chart"></div></el-card></el-col>
|
||||||
|
<el-col :span="12"><el-card><div ref="reservationStatusChart" class="chart"></div></el-card></el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12"><el-card><div ref="relicHotStatusChart" class="chart"></div></el-card></el-col>
|
||||||
|
<el-col :span="12"><el-card><div ref="visitorVerifyChart" class="chart"></div></el-card></el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12"><el-card><div ref="timeSlotDayChart" class="chart"></div></el-card></el-col>
|
||||||
|
<el-col :span="12"><el-card><div ref="reservationDailyChart" class="chart"></div></el-card></el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
import { listAllSysUser } from '@/api/sysUser'
|
||||||
|
import { listAllRelic } from '@/api/relic'
|
||||||
|
import { listAllAnnouncement } from '@/api/announcement'
|
||||||
|
import { listAllReservation } from '@/api/reservation'
|
||||||
|
import { listAllReservationVisitor } from '@/api/reservationVisitor'
|
||||||
|
import { listAllReservationTimeSlot } from '@/api/reservationTimeSlot'
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
|
const kpi = reactive({ users: 0, relics: 0, announcements: 0, reservations: 0, visitors: 0, timeSlots: 0 })
|
||||||
|
|
||||||
|
const userRoleChart = ref(null)
|
||||||
|
const reservationStatusChart = ref(null)
|
||||||
|
const relicHotStatusChart = ref(null)
|
||||||
|
const visitorVerifyChart = ref(null)
|
||||||
|
const timeSlotDayChart = ref(null)
|
||||||
|
const reservationDailyChart = ref(null)
|
||||||
|
|
||||||
|
let charts = []
|
||||||
|
|
||||||
|
function toArray(res) {
|
||||||
|
return Array.isArray(res) ? res : (res.list || res.data || [])
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDate(val) {
|
||||||
|
if (!val) return ''
|
||||||
|
const d = new Date(val)
|
||||||
|
const yyyy = d.getFullYear()
|
||||||
|
const MM = String(d.getMonth() + 1).padStart(2, '0')
|
||||||
|
const DD = String(d.getDate()).padStart(2, '0')
|
||||||
|
return `${yyyy}-${MM}-${DD}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastNDates(n) {
|
||||||
|
const arr = []
|
||||||
|
const d = new Date()
|
||||||
|
for (let i = n - 1; i >= 0; i--) {
|
||||||
|
const t = new Date(d)
|
||||||
|
t.setDate(d.getDate() - i)
|
||||||
|
arr.push(formatDate(t))
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderUserRoleChart(users) {
|
||||||
|
const roleCount = { '1': 0, '2': 0 }
|
||||||
|
users.forEach(u => { if (u && u.role) roleCount[u.role] = (roleCount[u.role] || 0) + 1 })
|
||||||
|
const chart = echarts.init(userRoleChart.value)
|
||||||
|
charts.push(chart)
|
||||||
|
chart.setOption({
|
||||||
|
title: { text: '用户角色分布', left: 'center' },
|
||||||
|
tooltip: { trigger: 'item' },
|
||||||
|
legend: { bottom: 0 },
|
||||||
|
series: [{ type: 'pie', radius: '60%', data: [
|
||||||
|
{ name: '超级管理员', value: roleCount['1'] || 0 },
|
||||||
|
{ name: '普通用户', value: roleCount['2'] || 0 }
|
||||||
|
] }]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderReservationStatusChart(reservations) {
|
||||||
|
const map = { 0: '待审核', 1: '已通过', 2: '已取消', 3: '已驳回' }
|
||||||
|
const cnt = { 0: 0, 1: 0, 2: 0, 3: 0 }
|
||||||
|
reservations.forEach(r => { const s = Number(r.status); if (s in cnt) cnt[s]++ })
|
||||||
|
const chart = echarts.init(reservationStatusChart.value)
|
||||||
|
charts.push(chart)
|
||||||
|
chart.setOption({
|
||||||
|
title: { text: '预约状态分布', left: 'center' },
|
||||||
|
tooltip: { trigger: 'item' },
|
||||||
|
legend: { bottom: 0 },
|
||||||
|
series: [{ type: 'pie', radius: '60%', data: Object.keys(cnt).map(k => ({ name: map[k], value: cnt[k] })) }]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderRelicHotStatusChart(relics) {
|
||||||
|
let hot = 0, normal = 0, show = 0, hide = 0
|
||||||
|
relics.forEach(r => {
|
||||||
|
if (Number(r.isHot) === 1) hot++; else normal++
|
||||||
|
if (Number(r.status) === 1) show++; else hide++
|
||||||
|
})
|
||||||
|
const chart = echarts.init(relicHotStatusChart.value)
|
||||||
|
charts.push(chart)
|
||||||
|
chart.setOption({
|
||||||
|
title: { text: '藏品热门与状态', left: 'center' },
|
||||||
|
tooltip: { trigger: 'axis' },
|
||||||
|
legend: { bottom: 0 },
|
||||||
|
xAxis: { type: 'category', data: ['热门', '普通', '显示', '隐藏'] },
|
||||||
|
yAxis: { type: 'value' },
|
||||||
|
series: [{ name: '数量', type: 'bar', data: [hot, normal, show, hide] }]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderVisitorVerifyChart(visitors) {
|
||||||
|
let verified = 0, unverified = 0
|
||||||
|
visitors.forEach(v => { Number(v.verifyStatus) === 1 ? verified++ : unverified++ })
|
||||||
|
const chart = echarts.init(visitorVerifyChart.value)
|
||||||
|
charts.push(chart)
|
||||||
|
chart.setOption({
|
||||||
|
title: { text: '游客验证状态', left: 'center' },
|
||||||
|
tooltip: { trigger: 'item' },
|
||||||
|
legend: { bottom: 0 },
|
||||||
|
series: [{ type: 'pie', radius: '60%', data: [
|
||||||
|
{ name: '已验证', value: verified },
|
||||||
|
{ name: '未验证', value: unverified }
|
||||||
|
] }]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTimeSlotDayChart(slots) {
|
||||||
|
const byDay = {}
|
||||||
|
slots.forEach(s => {
|
||||||
|
const d = formatDate(s.date)
|
||||||
|
const key = d
|
||||||
|
if (!byDay[key]) byDay[key] = { bookable: 0, blocked: 0 }
|
||||||
|
Number(s.status) === 1 ? byDay[key].bookable++ : byDay[key].blocked++
|
||||||
|
})
|
||||||
|
const days = getLastNDates(7)
|
||||||
|
const bookable = days.map(d => (byDay[d]?.bookable || 0))
|
||||||
|
const blocked = days.map(d => (byDay[d]?.blocked || 0))
|
||||||
|
const chart = echarts.init(timeSlotDayChart.value)
|
||||||
|
charts.push(chart)
|
||||||
|
chart.setOption({
|
||||||
|
title: { text: '近7天时段可约/不可约', left: 'center' },
|
||||||
|
tooltip: { trigger: 'axis' },
|
||||||
|
legend: { bottom: 0 },
|
||||||
|
xAxis: { type: 'category', data: days },
|
||||||
|
yAxis: { type: 'value' },
|
||||||
|
series: [
|
||||||
|
{ name: '可约', type: 'bar', stack: 'total', data: bookable },
|
||||||
|
{ name: '不可约', type: 'bar', stack: 'total', data: blocked }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderReservationDailyChart(reservations) {
|
||||||
|
const days = getLastNDates(14)
|
||||||
|
const cnt = days.reduce((acc, d) => (acc[d] = 0, acc), {})
|
||||||
|
reservations.forEach(r => { const d = formatDate(r.createTime || r.create_time); if (d in cnt) cnt[d]++ })
|
||||||
|
const chart = echarts.init(reservationDailyChart.value)
|
||||||
|
charts.push(chart)
|
||||||
|
chart.setOption({
|
||||||
|
title: { text: '近14天预约趋势', left: 'center' },
|
||||||
|
tooltip: { trigger: 'axis' },
|
||||||
|
xAxis: { type: 'category', data: days },
|
||||||
|
yAxis: { type: 'value' },
|
||||||
|
series: [{ name: '预约数', type: 'line', smooth: true, data: days.map(d => cnt[d]) }]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
Promise.all([
|
||||||
|
listAllSysUser({}),
|
||||||
|
listAllRelic({}),
|
||||||
|
listAllAnnouncement({}),
|
||||||
|
listAllReservation({}),
|
||||||
|
listAllReservationVisitor({}),
|
||||||
|
listAllReservationTimeSlot({})
|
||||||
|
]).then(([u, r, a, rs, rv, ts]) => {
|
||||||
|
const users = toArray(u)
|
||||||
|
const relics = toArray(r)
|
||||||
|
const announcements = toArray(a)
|
||||||
|
const reservations = toArray(rs)
|
||||||
|
const visitors = toArray(rv)
|
||||||
|
const timeSlots = toArray(ts)
|
||||||
|
|
||||||
|
kpi.users = users.length
|
||||||
|
kpi.relics = relics.length
|
||||||
|
kpi.announcements = announcements.length
|
||||||
|
kpi.reservations = reservations.length
|
||||||
|
kpi.visitors = visitors.length
|
||||||
|
kpi.timeSlots = timeSlots.length
|
||||||
|
|
||||||
|
renderUserRoleChart(users)
|
||||||
|
renderReservationStatusChart(reservations)
|
||||||
|
renderRelicHotStatusChart(relics)
|
||||||
|
renderVisitorVerifyChart(visitors)
|
||||||
|
renderTimeSlotDayChart(timeSlots)
|
||||||
|
renderReservationDailyChart(reservations)
|
||||||
|
|
||||||
|
window.addEventListener('resize', () => { charts.forEach(c => c.resize()) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => { init() })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.kpi-card { text-align: center; }
|
||||||
|
.kpi-title { font-size: 14px; color: #606266; }
|
||||||
|
.kpi-value { font-size: 24px; font-weight: 700; color: #303133; }
|
||||||
|
.chart { width: 100%; height: 360px; }
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,273 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="真实姓名" prop="realName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.realName"
|
||||||
|
placeholder="请输入真实姓名"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身份证号" prop="idCard">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.idCard"
|
||||||
|
placeholder="请输入身份证号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号" prop="phone">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.phone"
|
||||||
|
placeholder="请输入手机号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.email"
|
||||||
|
placeholder="请输入邮箱"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="touristList">
|
||||||
|
<el-table-column label="用户id" align="center" prop="id" />
|
||||||
|
<el-table-column label="真实姓名" align="center" prop="realName" />
|
||||||
|
<el-table-column label="身份证号" align="center" prop="idCard" />
|
||||||
|
<el-table-column label="手机号" align="center" prop="phone" />
|
||||||
|
<el-table-column label="邮箱" align="center" prop="email" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改普通用户子对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="touristRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="真实姓名" prop="realName">
|
||||||
|
<el-input v-model="form.realName" placeholder="请输入真实姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身份证号" prop="idCard">
|
||||||
|
<el-input v-model="form.idCard" placeholder="请输入身份证号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号" prop="phone">
|
||||||
|
<el-input v-model="form.phone" placeholder="请输入手机号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input v-model="form.email" placeholder="请输入邮箱" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Tourist">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listTourist, getTourist, delTourist, addTourist, updateTourist } from "@/api/tourist";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const touristList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
realName: null,
|
||||||
|
idCard: null,
|
||||||
|
phone: null,
|
||||||
|
email: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询普通用户子列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listTourist(queryParams.value).then(response => {
|
||||||
|
touristList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
realName: null,
|
||||||
|
idCard: null,
|
||||||
|
phone: null,
|
||||||
|
email: null,
|
||||||
|
updateTime: null
|
||||||
|
};
|
||||||
|
const touristRef = proxy.$refs["touristRef"]
|
||||||
|
if (touristRef) {
|
||||||
|
touristRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加普通用户子";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getTourist(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改普通用户子";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["touristRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addTourist(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateTourist(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除普通用户子编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delTourist(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/tourist/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `tourist_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,308 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.title"
|
||||||
|
placeholder="请输入标题"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div v-loading="loading">
|
||||||
|
<div v-if="topList && topList.length" class="ann-list">
|
||||||
|
<div class="ann-list-title">置顶公告</div>
|
||||||
|
<div class="ann-item" v-for="a in topList" :key="'top-'+a.id">
|
||||||
|
<div class="ann-left">
|
||||||
|
<span class="ann-icon"></span>
|
||||||
|
<span class="ann-title" @click="openDetail(a)">{{ a.title }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="ann-date">{{ formatDate(a.createTime) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="announcementList && announcementList.length" class="ann-list" style="margin-top: 12px;">
|
||||||
|
<div class="ann-list-title">公告列表</div>
|
||||||
|
<div class="ann-item" v-for="a in announcementList" :key="a.id">
|
||||||
|
<div class="ann-left">
|
||||||
|
<span class="ann-icon"></span>
|
||||||
|
<span class="ann-title" @click="openDetail(a)">{{ a.title }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="ann-date">{{ formatDate( a.createTime) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-empty v-else description="暂无公告" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog v-model="detailOpen" title="公告详情" width="700px" append-to-body>
|
||||||
|
<div class="ann-detail">
|
||||||
|
<div class="ann-detail-title">{{ detailData.title }}</div>
|
||||||
|
<div class="ann-detail-meta">发布时间:{{ formatDate(detailData.updateTime || detailData.createTime) }}</div>
|
||||||
|
<div class="ann-detail-content" v-html="detailData.content"></div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="detailOpen=false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout=", prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Announcement">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listTouristAnnouncements, getAnnouncement, delAnnouncement, addAnnouncement, updateAnnouncement } from "@/api/announcement";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const announcementList = ref([]);
|
||||||
|
const topList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
title: null,
|
||||||
|
content: null,
|
||||||
|
isTop: null,
|
||||||
|
status: null,
|
||||||
|
creator: null,
|
||||||
|
updater: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
title: [
|
||||||
|
{ required: true, message: "标题不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
content: [
|
||||||
|
{ required: true, message: "内容不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询公告列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
const { pageNum, pageSize, title } = queryParams.value
|
||||||
|
listTouristAnnouncements({ pageNum, pageSize, title }).then(response => {
|
||||||
|
const data = response.data || response
|
||||||
|
topList.value = data.topList || []
|
||||||
|
announcementList.value = data.list || []
|
||||||
|
total.value = Number(data.total || 0)
|
||||||
|
}).finally(() => { loading.value = false })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
title: null,
|
||||||
|
content: null,
|
||||||
|
isTop: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
creator: null,
|
||||||
|
updateTime: null,
|
||||||
|
updater: null
|
||||||
|
};
|
||||||
|
const announcementRef = proxy.$refs["announcementRef"]
|
||||||
|
if (announcementRef) {
|
||||||
|
announcementRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加公告";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getAnnouncement(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改公告";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDate(val) {
|
||||||
|
if (!val) return ''
|
||||||
|
const d = new Date(val)
|
||||||
|
if (isNaN(d.getTime())) return ''
|
||||||
|
const y = d.getFullYear()
|
||||||
|
const M = String(d.getMonth() + 1).padStart(2, '0')
|
||||||
|
const D = String(d.getDate()).padStart(2, '0')
|
||||||
|
return `${y}.${M}.${D}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const detailOpen = ref(false)
|
||||||
|
const detailData = ref({})
|
||||||
|
|
||||||
|
function openDetail(a) {
|
||||||
|
const id = a && a.id
|
||||||
|
if (!id) return
|
||||||
|
getAnnouncement(id).then(response => {
|
||||||
|
detailData.value = response.data || {}
|
||||||
|
detailOpen.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["announcementRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addAnnouncement(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateAnnouncement(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除公告编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delAnnouncement(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/announcement/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `announcement_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.app-container {
|
||||||
|
width: 80%;
|
||||||
|
margin: 24px auto 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb8 { margin-bottom: 8px; }
|
||||||
|
|
||||||
|
:deep(.el-form) {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-wrapper { display: flex; justify-content: center; }
|
||||||
|
|
||||||
|
:deep(.el-row.mb8) { justify-content: center; }
|
||||||
|
|
||||||
|
.ann-list { background: #fff; border: 1px solid #e7dfcf; border-radius: 12px; padding: 8px 16px; }
|
||||||
|
.ann-list-title { font-weight: 700; color: #2c1f1f; margin: 8px 0; }
|
||||||
|
.ann-item { display: flex; align-items: center; justify-content: space-between; padding: 12px 6px; border-bottom: 1px dashed #e7dfcf; }
|
||||||
|
.ann-item:last-child { border-bottom: none; }
|
||||||
|
.ann-left { display: flex; align-items: center; gap: 8px; }
|
||||||
|
.ann-icon { width: 10px; height: 10px; border: 1px solid #c9a36a; border-radius: 2px; background: #f9f6f1; display: inline-block; }
|
||||||
|
.ann-title { color: #2c1f1f; }
|
||||||
|
.ann-title:hover { color: #8a2b2b; }
|
||||||
|
.ann-title { cursor: pointer; }
|
||||||
|
.ann-date { color: #8a2b2b; font-size: 12px; }
|
||||||
|
|
||||||
|
.ann-detail-title { font-size: 20px; font-weight: 700; color: #2c1f1f; }
|
||||||
|
.ann-detail-meta { color: #909399; font-size: 12px; margin: 6px 0 12px; }
|
||||||
|
.ann-detail-content :deep(p) { margin: 8px 0; line-height: 1.8; }
|
||||||
|
.ann-detail-content { color: #606266; }
|
||||||
|
.ann-detail-content>>>img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,283 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.title"
|
||||||
|
placeholder="请输入标题"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="图片地址" prop="imageUrl">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.imageUrl"
|
||||||
|
placeholder="请输入图片地址"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="跳转链接" prop="link">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.link"
|
||||||
|
placeholder="请输入跳转链接"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序序号" prop="sort">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.sort"
|
||||||
|
placeholder="请输入排序序号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="carouselList">
|
||||||
|
<el-table-column label="轮播图id" align="center" prop="id" />
|
||||||
|
<el-table-column label="标题" align="center" prop="title" />
|
||||||
|
<el-table-column label="图片地址" align="center" prop="imageUrl" />
|
||||||
|
<el-table-column label="跳转链接" align="center" prop="link" />
|
||||||
|
<el-table-column label="排序序号" align="center" prop="sort" />
|
||||||
|
<el-table-column label="状态" align="center" prop="status" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改轮播图对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="carouselRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input v-model="form.title" placeholder="请输入标题" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="图片地址" prop="imageUrl">
|
||||||
|
<el-input v-model="form.imageUrl" placeholder="请输入图片地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="跳转链接" prop="link">
|
||||||
|
<el-input v-model="form.link" placeholder="请输入跳转链接" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序序号" prop="sort">
|
||||||
|
<el-input v-model="form.sort" placeholder="请输入排序序号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Carousel">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listCarousel, getCarousel, delCarousel, addCarousel, updateCarousel } from "@/api/carousel";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const carouselList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
title: null,
|
||||||
|
imageUrl: null,
|
||||||
|
link: null,
|
||||||
|
sort: null,
|
||||||
|
status: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
title: [
|
||||||
|
{ required: true, message: "标题不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
imageUrl: [
|
||||||
|
{ required: true, message: "图片地址不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询轮播图列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listCarousel(queryParams.value).then(response => {
|
||||||
|
carouselList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
title: null,
|
||||||
|
imageUrl: null,
|
||||||
|
link: null,
|
||||||
|
sort: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
updateTime: null
|
||||||
|
};
|
||||||
|
const carouselRef = proxy.$refs["carouselRef"]
|
||||||
|
if (carouselRef) {
|
||||||
|
carouselRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加轮播图";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getCarousel(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改轮播图";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["carouselRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addCarousel(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateCarousel(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除轮播图编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delCarousel(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/carousel/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `carousel_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,512 @@
|
||||||
|
<template>
|
||||||
|
<div class="home-container">
|
||||||
|
<el-carousel height="520px" indicator-position="outside" arrow="hover" :autoplay="true">
|
||||||
|
<el-carousel-item v-for="item in carouselList" :key="item.id">
|
||||||
|
<div class="hero" :style="{ backgroundImage: 'url(' + (getFilePrefix + item.imageUrl) + ')' }">
|
||||||
|
<div class="hero-overlay">
|
||||||
|
<div class="hero-title">{{ item.title }}</div>
|
||||||
|
<div class="hero-actions">
|
||||||
|
<el-button v-if="item.link" type="warning" size="large" @click="openLink(item.link)">查看详情</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-carousel-item>
|
||||||
|
</el-carousel>
|
||||||
|
|
||||||
|
<div class="info-bar combined">
|
||||||
|
<div class="time-row">
|
||||||
|
<div class="time-group">
|
||||||
|
<div class="time-label">开馆时间</div>
|
||||||
|
<div class="time-big">{{ formatTime(museumIntro?.openTime) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="time-dash">—</div>
|
||||||
|
<div class="time-group">
|
||||||
|
<div class="time-label">闭馆时间</div>
|
||||||
|
<div class="time-big">{{ formatTime(museumIntro?.closeTime) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-area">
|
||||||
|
<div class="circle-btn" @click="goReserve">参观预约</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hot-section">
|
||||||
|
<div class="hot-title">热门藏品</div>
|
||||||
|
<div class="hot-grid">
|
||||||
|
<div class="hot-card" v-for="item in hotRelics" :key="item.id">
|
||||||
|
<div class="hot-cover">
|
||||||
|
<el-image
|
||||||
|
v-if="item.coverImageUrl"
|
||||||
|
:src="getFilePrefix + item.coverImageUrl"
|
||||||
|
:preview-src-list="[getFilePrefix + item.coverImageUrl]"
|
||||||
|
preview-teleported
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
<div v-else class="hot-cover-empty">—</div>
|
||||||
|
</div>
|
||||||
|
<div class="hot-info">
|
||||||
|
<div class="hot-name">{{ item.name }}</div>
|
||||||
|
<div class="hot-cat">{{ item.categoryInfo && item.categoryInfo.name ? item.categoryInfo.name : '—' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hot-more">
|
||||||
|
<div class="hot-more-btn" @click="goMoreHot">查看更多藏品</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="announce-section">
|
||||||
|
<div class="announce-title">公告</div>
|
||||||
|
<div class="announce-list">
|
||||||
|
<div class="announce-item" v-for="a in announcements" :key="a.id">
|
||||||
|
<div class="title"><span v-if="Number(a.isTop) === 1" class="top-badge">置顶</span><span class="ann-link" @click="openAnnDetail(a)">{{ a.title }}</span></div>
|
||||||
|
<div class="date">{{ formatDateYMD(a.updateTime || a.createTime) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="announce-more">
|
||||||
|
<div class="announce-more-btn" @click="goMoreAnnouncement">查看更多公告</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 公告详情弹出框 -->
|
||||||
|
<el-dialog v-model="annDetailOpen" title="公告详情" width="700px" append-to-body>
|
||||||
|
<div class="ann-detail">
|
||||||
|
<div class="ann-detail-title">{{ annDetailData.title }}</div>
|
||||||
|
<div class="ann-detail-meta">发布时间:{{ formatDateYMD(annDetailData.updateTime || annDetailData.createTime) }}</div>
|
||||||
|
<div class="ann-detail-content" v-html="annDetailData.content"></div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="annDetailOpen=false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, getCurrentInstance } from 'vue'
|
||||||
|
import { listAllCarousel } from '@/api/carousel'
|
||||||
|
import { listAllMuseumIntro } from '@/api/museumIntro'
|
||||||
|
import { listAllRelic } from '@/api/relic'
|
||||||
|
import { listAllAnnouncement, getAnnouncement } from '@/api/announcement'
|
||||||
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
const getFilePrefix = proxy.getFilePrefix
|
||||||
|
const carouselList = ref([])
|
||||||
|
const museumIntro = ref(null)
|
||||||
|
const hotRelics = ref([])
|
||||||
|
const announcements = ref([])
|
||||||
|
const annDetailOpen = ref(false)
|
||||||
|
const annDetailData = ref({})
|
||||||
|
const home1 = new URL('@/assets/home1.png', import.meta.url).href
|
||||||
|
const home2 = new URL('@/assets/home2.png', import.meta.url).href
|
||||||
|
|
||||||
|
function openLink(link) {
|
||||||
|
window.open(link, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
function goReserve() {
|
||||||
|
const role = Cookies.get('role')
|
||||||
|
if (!role) {
|
||||||
|
proxy.$message.warning('请先登录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
proxy.$router.push('/tourist/reservation')
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTime(val) {
|
||||||
|
if (!val) return '—'
|
||||||
|
if (typeof val === 'string' && val.includes(':')) {
|
||||||
|
return val.slice(0, 5)
|
||||||
|
}
|
||||||
|
const d = new Date(val)
|
||||||
|
if (isNaN(d.getTime())) return '—'
|
||||||
|
const HH = String(d.getHours()).padStart(2, '0')
|
||||||
|
const mm = String(d.getMinutes()).padStart(2, '0')
|
||||||
|
return `${HH}:${mm}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDateYMD(val) {
|
||||||
|
if (!val) return ''
|
||||||
|
const d = new Date(val)
|
||||||
|
if (isNaN(d.getTime())) return ''
|
||||||
|
const yyyy = d.getFullYear()
|
||||||
|
const MM = String(d.getMonth() + 1).padStart(2, '0')
|
||||||
|
const DD = String(d.getDate()).padStart(2, '0')
|
||||||
|
return `${yyyy}-${MM}-${DD}`
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
Promise.all([
|
||||||
|
listAllCarousel({}),
|
||||||
|
listAllMuseumIntro({}),
|
||||||
|
listAllRelic({}),
|
||||||
|
listAllAnnouncement({})
|
||||||
|
]).then(([resC, resM, resR, resA]) => {
|
||||||
|
const arrC = Array.isArray(resC) ? resC : (resC.list || resC.data || [])
|
||||||
|
const listC = Array.isArray(arrC) ? arrC : []
|
||||||
|
carouselList.value = listC.filter(i => Number(i.status) === 1).sort((a, b) => (Number(a.sort || 0) - Number(b.sort || 0)))
|
||||||
|
|
||||||
|
const arrM = Array.isArray(resM) ? resM : (resM.list || resM.data || [])
|
||||||
|
const listM = Array.isArray(arrM) ? arrM : []
|
||||||
|
museumIntro.value = listM.length > 0 ? listM[0] : null
|
||||||
|
|
||||||
|
const arrR = Array.isArray(resR) ? resR : (resR.list || resR.data || [])
|
||||||
|
const listR = Array.isArray(arrR) ? arrR : []
|
||||||
|
const filteredHot = listR.filter(r => Number(r.isHot) === 1 && Number(r.status) === 1)
|
||||||
|
hotRelics.value = filteredHot.slice(0, 8)
|
||||||
|
const arrA = Array.isArray(resA) ? resA : (resA.list || resA.data || [])
|
||||||
|
const listA = Array.isArray(arrA) ? arrA : []
|
||||||
|
const active = listA.filter(a => Number(a.status) === 1)
|
||||||
|
const sortByTimeDesc = (x, y) => {
|
||||||
|
const tx = new Date(x.updateTime || x.createTime).getTime() || 0
|
||||||
|
const ty = new Date(y.updateTime || y.createTime).getTime() || 0
|
||||||
|
return ty - tx
|
||||||
|
}
|
||||||
|
const topList = active.filter(a => Number(a.isTop) === 1).sort(sortByTimeDesc)
|
||||||
|
const top = topList.length ? topList[0] : null
|
||||||
|
const nonTop = active.filter(a => Number(a.isTop) !== 1).sort(sortByTimeDesc)
|
||||||
|
const result = []
|
||||||
|
if (top) result.push(top)
|
||||||
|
result.push(...nonTop.slice(0, top ? 4 : 5))
|
||||||
|
announcements.value = result
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function goMoreHot() {
|
||||||
|
proxy.$router.push('/tourist/relic')
|
||||||
|
}
|
||||||
|
|
||||||
|
function goMoreAnnouncement() {
|
||||||
|
proxy.$router.push('/tourist/announcement')
|
||||||
|
}
|
||||||
|
|
||||||
|
function openAnnDetail(a) {
|
||||||
|
const id = a && a.id
|
||||||
|
if (!id) return
|
||||||
|
getAnnouncement(id).then(res => {
|
||||||
|
annDetailData.value = res.data || {}
|
||||||
|
annDetailOpen.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.home-container {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.hero {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.hero-overlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(0deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.15) 50%, rgba(0,0,0,0.3) 100%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.hero-title {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 4px;
|
||||||
|
text-shadow: 0 2px 12px rgba(0,0,0,0.4);
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.hero-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.content-card .el-card__body) {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-carousel) {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-carousel__container) {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-bar {
|
||||||
|
width: 55%;
|
||||||
|
margin: 16px auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 50px;
|
||||||
|
}
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
.info-icon img {
|
||||||
|
width: 110px;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
filter: hue-rotate(190deg) saturate(120%);
|
||||||
|
}
|
||||||
|
.info-content { flex: 1; width: 100%; }
|
||||||
|
.info-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1f1f1f;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.info-line { display: flex; align-items: center; justify-content: flex-start; gap: 8px; color: #606266; padding: 2px 0; }
|
||||||
|
.info-line .label { color: #909399; }
|
||||||
|
.info-line .val {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
.info-line .gap { margin: 0 6px; color: #c0c4cc; }
|
||||||
|
.info-text { color: #606266; line-height: 1.6; margin-bottom: 8px; }
|
||||||
|
.time-val { font-weight: 700; }
|
||||||
|
.reserve-block { display: flex; align-items: center; justify-content: center; gap: 16px; padding-top: 6px; }
|
||||||
|
.reserve-btn {
|
||||||
|
background: #1f4fff;
|
||||||
|
border-color: #1f4fff;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 11px 22px;
|
||||||
|
font-size: 13px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 6px 16px rgba(31,79,255,0.22);
|
||||||
|
}
|
||||||
|
.reserve-btn:hover { filter: brightness(1.05); }
|
||||||
|
|
||||||
|
/* 开放时间与预约样式仿照参考图 */
|
||||||
|
.open-time .info-icon { display: none; }
|
||||||
|
.time-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.time-group { display: flex; flex-direction: column; align-items: flex-start; }
|
||||||
|
.time-label { font-size: 12px; color: #909399; }
|
||||||
|
.time-big { font-size: 22px; font-weight: 800; color: #333; letter-spacing: 2px; }
|
||||||
|
.time-dash { font-size: 22px; color: #999; padding: 0 2px; }
|
||||||
|
|
||||||
|
.reserve .info-icon { display: none; }
|
||||||
|
.circle-btn {
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2px solid #8a2b2b;
|
||||||
|
color: #8a2b2b;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 700;
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.circle-btn:hover { background: #fef4f4; }
|
||||||
|
.circle-area {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hot-section {
|
||||||
|
width: 80%;
|
||||||
|
margin: 24px auto 40px;
|
||||||
|
}
|
||||||
|
.hot-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #1f1f1f;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.hot-title::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 64px;
|
||||||
|
height: 0;
|
||||||
|
border-bottom: 2px solid #8a2b2b;
|
||||||
|
margin: 8px auto 0;
|
||||||
|
}
|
||||||
|
.hot-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
.hot-card {
|
||||||
|
background: #f9f6f1;
|
||||||
|
border: 1px solid #e7dfcf;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 6px 14px rgba(138, 43, 43, 0.08);
|
||||||
|
overflow: hidden;
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
}
|
||||||
|
.hot-cover {
|
||||||
|
width: 100%;
|
||||||
|
height: 160px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.hot-cover :deep(.el-image) {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transition: transform 0.25s ease;
|
||||||
|
}
|
||||||
|
.hot-cover:hover :deep(.el-image) { transform: scale(1.03); }
|
||||||
|
.hot-cover::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(0deg, rgba(0,0,0,0.06) 0%, rgba(0,0,0,0.02) 60%, rgba(0,0,0,0.05) 100%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.hot-cover-empty {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
.hot-info {
|
||||||
|
padding: 14px;
|
||||||
|
background: linear-gradient(180deg, #faf7f2 0%, #f7f3ea 100%);
|
||||||
|
}
|
||||||
|
.hot-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #2c1f1f;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
.hot-name::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 36px;
|
||||||
|
border-bottom: 2px solid #8a2b2b;
|
||||||
|
margin: 6px 0 0;
|
||||||
|
}
|
||||||
|
.hot-cat {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #8a2b2b;
|
||||||
|
background: #f5e9e2;
|
||||||
|
border: 1px solid #e8d9cf;
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.hot-more {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.hot-more-btn {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border: 1px solid #8a2b2b;
|
||||||
|
color: #8a2b2b;
|
||||||
|
background: #f5e9e2;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.hot-more-btn:hover { background: #fef4f4; }
|
||||||
|
.hot-card:hover { transform: translateY(-2px); box-shadow: 0 10px 18px rgba(138, 43, 43, 0.12); }
|
||||||
|
|
||||||
|
.announce-section {
|
||||||
|
width: 80%;
|
||||||
|
margin: 0 auto 40px;
|
||||||
|
}
|
||||||
|
.announce-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #1f1f1f;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.announce-title::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 64px;
|
||||||
|
border-bottom: 2px solid #8a2b2b;
|
||||||
|
margin: 8px auto 0;
|
||||||
|
}
|
||||||
|
.announce-list {
|
||||||
|
background: #f9f6f1;
|
||||||
|
border: 1px solid #e7dfcf;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.announce-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-bottom: 1px solid #eadfce;
|
||||||
|
}
|
||||||
|
.announce-item:last-child { border-bottom: none; }
|
||||||
|
.announce-item .title {
|
||||||
|
color: #2c1f1f;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.top-badge {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
color: #fff;
|
||||||
|
background: #d93025;
|
||||||
|
box-shadow: 0 0 0 2px rgba(217,48,37,0.12) inset, 0 6px 12px rgba(217,48,37,0.18);
|
||||||
|
}
|
||||||
|
.announce-item .date {
|
||||||
|
color: #8a2b2b;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.announce-more {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.announce-more-btn {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border: 1px solid #8a2b2b;
|
||||||
|
color: #8a2b2b;
|
||||||
|
background: #f5e9e2;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.announce-more-btn:hover { background: #fef4f4; }
|
||||||
|
|
||||||
|
.ann-link { cursor: pointer; }
|
||||||
|
.ann-link:hover { color: #8a2b2b; }
|
||||||
|
|
||||||
|
:deep(.ann-detail-content img) { width: 100%; }
|
||||||
|
|
||||||
|
.ann-detail-title { font-size: 26px; font-weight: 800; color: #2c1f1f; letter-spacing: 1px; margin-bottom: 10px; }
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,268 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="分类名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.name"
|
||||||
|
placeholder="请输入分类名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建者" prop="creator">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.creator"
|
||||||
|
placeholder="请输入创建者"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="更新者" prop="updater">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.updater"
|
||||||
|
placeholder="请输入更新者"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="itemCategoryList">
|
||||||
|
<el-table-column label="分类ID" align="center" prop="id" />
|
||||||
|
<el-table-column label="分类名称" align="center" prop="name" />
|
||||||
|
<el-table-column label="创建者" align="center" prop="creator" />
|
||||||
|
<el-table-column label="更新者" align="center" prop="updater" />
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改藏品分类对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="itemCategoryRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="分类名称" prop="name">
|
||||||
|
<el-input v-model="form.name" placeholder="请输入分类名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建者" prop="creator">
|
||||||
|
<el-input v-model="form.creator" placeholder="请输入创建者" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="更新者" prop="updater">
|
||||||
|
<el-input v-model="form.updater" placeholder="请输入更新者" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ItemCategory">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listItemCategory, getItemCategory, delItemCategory, addItemCategory, updateItemCategory } from "@/api/itemCategory";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const itemCategoryList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
name: null,
|
||||||
|
creator: null,
|
||||||
|
updater: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: "分类名称不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询藏品分类列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listItemCategory(queryParams.value).then(response => {
|
||||||
|
itemCategoryList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
name: null,
|
||||||
|
creator: null,
|
||||||
|
createTime: null,
|
||||||
|
updater: null,
|
||||||
|
updateTime: null,
|
||||||
|
remark: null
|
||||||
|
};
|
||||||
|
const itemCategoryRef = proxy.$refs["itemCategoryRef"]
|
||||||
|
if (itemCategoryRef) {
|
||||||
|
itemCategoryRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加藏品分类";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getItemCategory(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改藏品分类";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["itemCategoryRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addItemCategory(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateItemCategory(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除藏品分类编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delItemCategory(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/itemCategory/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `itemCategory_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,291 @@
|
||||||
|
<template>
|
||||||
|
<div class="collection-container">
|
||||||
|
<el-form class="search-form" :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.name"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div v-loading="loading">
|
||||||
|
<div class="collection-grid" v-if="collectionList && collectionList.length">
|
||||||
|
<div class="collection-card" v-for="ic in collectionList" :key="ic.id" @click="goDetail(ic.relic)">
|
||||||
|
<div class="collection-cover">
|
||||||
|
<el-image
|
||||||
|
v-if="ic.relic && ic.relic.coverImageUrl"
|
||||||
|
:src="getFilePrefix + ic.relic.coverImageUrl"
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
<div v-else class="collection-cover-empty">—</div>
|
||||||
|
</div>
|
||||||
|
<div class="collection-info">
|
||||||
|
<div class="collection-info-top">
|
||||||
|
<div class="collection-name">{{ ic.relic && ic.relic.name ? ic.relic.name : ('#' + ic.itemId) }}</div>
|
||||||
|
<el-button class="collection-unfav" type="danger" size="small" plain @click.stop="handleDelete(ic)">取消收藏</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="collection-meta">
|
||||||
|
<span class="collection-cat">{{ ic.relic && ic.relic.categoryInfo && ic.relic.categoryInfo.name ? ic.relic.categoryInfo.name : '—' }}</span>
|
||||||
|
<span v-if="ic.relic && ic.relic.material" class="collection-tag">{{ ic.relic.material }}</span>
|
||||||
|
<span v-if="ic.relic && ic.relic.age" class="collection-tag">{{ ic.relic.age }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="empty" v-else>
|
||||||
|
<el-empty description="暂无收藏的藏品" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-pagination">
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ItemCollection">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listItemCollection, getItemCollection, delItemCollection, addItemCollection, updateItemCollection } from "@/api/itemCollection";
|
||||||
|
import { getRelic } from "@/api/relic";
|
||||||
|
import { getCurrentSysUser } from "@/api/sysUser";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const itemCollectionList = ref([]);
|
||||||
|
const collectionList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
const currentUserId = ref(null)
|
||||||
|
const getFilePrefix = proxy.getFilePrefix
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
userId: null,
|
||||||
|
name: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
userId: [
|
||||||
|
{ required: true, message: "用户id不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
itemId: [
|
||||||
|
{ required: true, message: "藏品id不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询收藏列表 */
|
||||||
|
async function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const response = await listItemCollection(queryParams.value)
|
||||||
|
const list = Array.isArray(response.list) ? response.list : (response.data && response.data.list) || []
|
||||||
|
const tot = response.total ?? (response.data && response.data.total) ?? 0
|
||||||
|
itemCollectionList.value = list
|
||||||
|
total.value = tot
|
||||||
|
const ids = list.map(it => it.itemId).filter(Boolean)
|
||||||
|
const uniqueIds = Array.from(new Set(ids))
|
||||||
|
const detailMap = {}
|
||||||
|
await Promise.all(uniqueIds.map(id => getRelic(id).then(r => {
|
||||||
|
const d = r?.data || r
|
||||||
|
detailMap[id] = d
|
||||||
|
}).catch(() => {})))
|
||||||
|
let result = list.map(ic => ({ ...ic, relic: detailMap[ic.itemId] || {} }))
|
||||||
|
const kw = (queryParams.value.name || '').trim().toLowerCase()
|
||||||
|
if (kw) {
|
||||||
|
result = result.filter(ic => {
|
||||||
|
const n = (ic.relic && ic.relic.name) ? String(ic.relic.name) : ''
|
||||||
|
return n.toLowerCase().includes(kw)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
collectionList.value = result
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
userId: null,
|
||||||
|
itemId: null,
|
||||||
|
createTime: null
|
||||||
|
};
|
||||||
|
const itemCollectionRef = proxy.$refs["itemCollectionRef"]
|
||||||
|
if (itemCollectionRef) {
|
||||||
|
itemCollectionRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
// 保持为当前用户
|
||||||
|
queryParams.value.userId = currentUserId.value
|
||||||
|
queryParams.value.name = null
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加收藏";
|
||||||
|
isAdd.value = true;
|
||||||
|
// 新增时绑定当前用户ID
|
||||||
|
form.value.userId = currentUserId.value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getItemCollection(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改收藏";
|
||||||
|
isAdd.value = false;
|
||||||
|
// 保护性覆盖为当前用户
|
||||||
|
form.value.userId = currentUserId.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["itemCollectionRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addItemCollection(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateItemCollection(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('确定要取消收藏该藏品吗?').then(function() {
|
||||||
|
return delItemCollection(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
// proxy.$message({
|
||||||
|
// message: response.msg,
|
||||||
|
// type: 'success'
|
||||||
|
// })
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/itemCollection/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `itemCollection_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 仅查询当前登录用户的收藏
|
||||||
|
getCurrentSysUser().then(res => {
|
||||||
|
const data = res?.data || {}
|
||||||
|
const uid = data.id || data.userId || null
|
||||||
|
currentUserId.value = uid
|
||||||
|
queryParams.value.userId = uid
|
||||||
|
getList();
|
||||||
|
}).catch(() => {
|
||||||
|
// 获取当前用户失败时,不进行查询
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
|
|
||||||
|
function goDetail(item) {
|
||||||
|
if (!item || !item.id) return
|
||||||
|
proxy.$router.push(`/tourist/relic/detail/${item.id}`)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.collection-container { width: 80%; margin: 24px auto 40px; padding-top: 16px; }
|
||||||
|
.search-form { display: flex; justify-content: center; align-items: center; gap: 12px; }
|
||||||
|
.collection-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
|
||||||
|
.collection-card { background: #f9f6f1; border: 1px solid #e7dfcf; border-radius: 12px; box-shadow: 0 6px 14px rgba(138,43,43,0.08); overflow: hidden; transition: transform 0.2s ease, box-shadow 0.2s ease; cursor: pointer; }
|
||||||
|
.collection-cover { width: 100%; height: 180px; position: relative; overflow: hidden; }
|
||||||
|
.collection-cover :deep(.el-image) { width: 100%; height: 100%; transition: transform 0.25s ease; }
|
||||||
|
.collection-cover:hover :deep(.el-image) { transform: scale(1.03); }
|
||||||
|
.collection-cover::after { content: ''; position: absolute; inset: 0; background: linear-gradient(0deg, rgba(0,0,0,0.06) 0%, rgba(0,0,0,0.02) 60%, rgba(0,0,0,0.05) 100%); pointer-events: none; }
|
||||||
|
.collection-cover-empty { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #909399; }
|
||||||
|
.collection-info { padding: 14px; background: linear-gradient(180deg, #faf7f2 0%, #f7f3ea 100%); }
|
||||||
|
.collection-info-top { display: flex; justify-content: space-between; align-items: center; }
|
||||||
|
.collection-name { font-size: 16px; font-weight: 800; color: #2c1f1f; letter-spacing: 1px; }
|
||||||
|
.collection-name::after { content: ''; display: block; width: 36px; border-bottom: 2px solid #8a2b2b; margin: 6px 0 0; }
|
||||||
|
.collection-meta { margin-top: 8px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
||||||
|
.collection-cat { font-size: 12px; color: #8a2b2b; background: #f5e9e2; border: 1px solid #e8d9cf; border-radius: 999px; padding: 2px 8px; }
|
||||||
|
.collection-tag { font-size: 12px; color: #2c1f1f; background: #efe9df; border: 1px solid #e0d6c7; border-radius: 999px; padding: 2px 8px; }
|
||||||
|
.grid-pagination { display: flex; justify-content: center; margin-top: 16px; }
|
||||||
|
.empty { display: flex; justify-content: center; padding: 32px 0; }
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,328 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="Logo地址" prop="logoUrl">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.logoUrl"
|
||||||
|
placeholder="请输入Logo地址"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="地址" prop="address">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.address"
|
||||||
|
placeholder="请输入地址"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="联系电话" prop="phone">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.phone"
|
||||||
|
placeholder="请输入联系电话"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="营业开始时间" prop="openTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="queryParams.openTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择营业开始时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="营业结束时间" prop="closeTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="queryParams.closeTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择营业结束时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="更新者id" prop="updater">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.updater"
|
||||||
|
placeholder="请输入更新者id"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="museumIntroList">
|
||||||
|
<el-table-column label="博物馆名称" align="center" prop="museumName" />
|
||||||
|
<el-table-column label="内容" align="center" prop="content" />
|
||||||
|
<el-table-column label="Logo地址" align="center" prop="logoUrl" />
|
||||||
|
<el-table-column label="地址" align="center" prop="address" />
|
||||||
|
<el-table-column label="联系电话" align="center" prop="phone" />
|
||||||
|
<el-table-column label="营业开始时间" align="center" prop="openTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.openTime, 'yyyy-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="营业结束时间" align="center" prop="closeTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.closeTime, 'yyyy-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="更新者id" align="center" prop="updater" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改博物馆简介对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="museumIntroRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="内容">
|
||||||
|
<editor v-model="form.content" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Logo地址" prop="logoUrl">
|
||||||
|
<el-input v-model="form.logoUrl" placeholder="请输入Logo地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="地址" prop="address">
|
||||||
|
<el-input v-model="form.address" placeholder="请输入地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="联系电话" prop="phone">
|
||||||
|
<el-input v-model="form.phone" placeholder="请输入联系电话" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="营业开始时间" prop="openTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.openTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择营业开始时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="营业结束时间" prop="closeTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.closeTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择营业结束时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="更新者id" prop="updater">
|
||||||
|
<el-input v-model="form.updater" placeholder="请输入更新者id" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="MuseumIntro">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listMuseumIntro, getMuseumIntro, delMuseumIntro, addMuseumIntro, updateMuseumIntro } from "@/api/museumIntro";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const museumIntroList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
content: null,
|
||||||
|
logoUrl: null,
|
||||||
|
address: null,
|
||||||
|
phone: null,
|
||||||
|
openTime: null,
|
||||||
|
closeTime: null,
|
||||||
|
updater: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
content: [
|
||||||
|
{ required: true, message: "内容不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询博物馆简介列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listMuseumIntro(queryParams.value).then(response => {
|
||||||
|
museumIntroList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
museumName: null,
|
||||||
|
content: null,
|
||||||
|
logoUrl: null,
|
||||||
|
address: null,
|
||||||
|
phone: null,
|
||||||
|
openTime: null,
|
||||||
|
closeTime: null,
|
||||||
|
updateTime: null,
|
||||||
|
updater: null
|
||||||
|
};
|
||||||
|
const museumIntroRef = proxy.$refs["museumIntroRef"]
|
||||||
|
if (museumIntroRef) {
|
||||||
|
museumIntroRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加博物馆简介";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _museumName = row.museumName || ids.value
|
||||||
|
getMuseumIntro(_museumName).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改博物馆简介";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["museumIntroRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addMuseumIntro(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateMuseumIntro(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除博物馆简介编号为"' + row.museumName + '"的数据项?').then(function() {
|
||||||
|
return delMuseumIntro(row.museumName);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/museumIntro/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `museumIntro_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,190 @@
|
||||||
|
<template>
|
||||||
|
<div class="relic-container">
|
||||||
|
<el-form class="search-form" :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.name"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类" prop="categoryId">
|
||||||
|
<el-select class="cat-select" v-model="queryParams.categoryId" placeholder="选择分类" clearable>
|
||||||
|
<el-option v-for="c in categoryOptions" :key="c.id" :label="c.name" :value="c.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="热门" prop="isHot">
|
||||||
|
<el-select class="hot-select" v-model="queryParams.isHot" placeholder="请选择" clearable>
|
||||||
|
<el-option label="热门" :value="1" />
|
||||||
|
<el-option label="非热门" :value="0" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="relic-grid" v-loading="loading">
|
||||||
|
<div class="relic-card" v-for="item in relicList" :key="item.id" @click="goDetail(item)">
|
||||||
|
<div class="relic-cover">
|
||||||
|
<el-image
|
||||||
|
v-if="item.coverImageUrl"
|
||||||
|
:src="getFilePrefix + item.coverImageUrl"
|
||||||
|
:preview-src-list="[getFilePrefix + item.coverImageUrl]"
|
||||||
|
preview-teleported
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
<div v-else class="relic-cover-empty">—</div>
|
||||||
|
</div>
|
||||||
|
<div class="relic-info">
|
||||||
|
<div class="relic-name">{{ item.name }}</div>
|
||||||
|
<div class="relic-meta">
|
||||||
|
<span class="relic-cat">{{ item.categoryInfo && item.categoryInfo.name ? item.categoryInfo.name : (item.categoryId || '—') }}</span>
|
||||||
|
<span v-if="item.material" class="relic-tag">{{ item.material }}</span>
|
||||||
|
<span v-if="item.age" class="relic-tag">{{ item.age }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-pagination">
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[12, 24, 36, 48]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Relic">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance, onMounted } from 'vue';
|
||||||
|
import { listRelic } from "@/api/relic";
|
||||||
|
import { listAllItemCategory } from "@/api/itemCategory";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const relicList = ref([]);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const total = ref(0);
|
||||||
|
|
||||||
|
const getFilePrefix = proxy.getFilePrefix
|
||||||
|
const categoryOptions = ref([])
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 12,
|
||||||
|
name: null,
|
||||||
|
categoryId: null,
|
||||||
|
isHot: null
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询藏品列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listRelic(queryParams.value).then(response => {
|
||||||
|
const list = Array.isArray(response.list) ? response.list : (response.data && response.data.list) || []
|
||||||
|
const tot = response.total ?? (response.data && response.data.total) ?? 0
|
||||||
|
relicList.value = list;
|
||||||
|
total.value = tot;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchCategoryOptions() {
|
||||||
|
listAllItemCategory({}).then(res => {
|
||||||
|
const arr = Array.isArray(res) ? res : (res.list || res.data || [])
|
||||||
|
categoryOptions.value = Array.isArray(arr) ? arr : []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
queryParams.value.name = null
|
||||||
|
queryParams.value.categoryId = null
|
||||||
|
queryParams.value.isHot = null
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/relic/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `relic_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fetchCategoryOptions()
|
||||||
|
})
|
||||||
|
|
||||||
|
function goDetail(item) {
|
||||||
|
if (!item || !item.id) return
|
||||||
|
proxy.$router.push(`/tourist/relic/detail/${item.id}`)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.relic-container { width: 80%; margin: 24px auto 40px; padding-top: 16px; }
|
||||||
|
.filter-bar { display: flex; gap: 12px; align-items: center; justify-content: center; margin-bottom: 18px; }
|
||||||
|
.relic-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
|
||||||
|
.relic-card { background: #f9f6f1; border: 1px solid #e7dfcf; border-radius: 12px; box-shadow: 0 6px 14px rgba(138,43,43,0.08); overflow: hidden; transition: transform 0.2s ease, box-shadow 0.2s ease; }
|
||||||
|
.relic-card { cursor: pointer; }
|
||||||
|
.relic-cover { width: 100%; height: 180px; position: relative; overflow: hidden; }
|
||||||
|
.relic-cover :deep(.el-image) { width: 100%; height: 100%; transition: transform 0.25s ease; }
|
||||||
|
.relic-cover:hover :deep(.el-image) { transform: scale(1.03); }
|
||||||
|
.relic-cover::after { content: ''; position: absolute; inset: 0; background: linear-gradient(0deg, rgba(0,0,0,0.06) 0%, rgba(0,0,0,0.02) 60%, rgba(0,0,0,0.05) 100%); pointer-events: none; }
|
||||||
|
.relic-cover-empty { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #909399; }
|
||||||
|
.relic-info { padding: 14px; background: linear-gradient(180deg, #faf7f2 0%, #f7f3ea 100%); }
|
||||||
|
.relic-name { font-size: 16px; font-weight: 800; color: #2c1f1f; letter-spacing: 1px; }
|
||||||
|
.relic-name::after { content: ''; display: block; width: 36px; border-bottom: 2px solid #8a2b2b; margin: 6px 0 0; }
|
||||||
|
.relic-meta { margin-top: 8px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
||||||
|
.relic-cat { font-size: 12px; color: #8a2b2b; background: #f5e9e2; border: 1px solid #e8d9cf; border-radius: 999px; padding: 2px 8px; }
|
||||||
|
.relic-tag { font-size: 12px; color: #2c1f1f; background: #efe9df; border: 1px solid #e0d6c7; border-radius: 999px; padding: 2px 8px; }
|
||||||
|
.search-form { display: flex; justify-content: center; align-items: center; gap: 12px; }
|
||||||
|
.hot-select { width: 120px; }
|
||||||
|
.cat-select { width: 180px; }
|
||||||
|
.grid-pagination { display: flex; justify-content: center; margin-top: 16px; }
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,416 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="预约日期" prop="dateRange">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
unlink-panels
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="reservationList">
|
||||||
|
<el-table-column label="预约日期" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ formatDateYMD(scope.row.reservationTimeSlot && scope.row.reservationTimeSlot.date) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="预约时间" align="center" prop="reserveTime" />
|
||||||
|
<el-table-column label="预约总人数" align="center" prop="totalVisitors" />
|
||||||
|
<el-table-column label="整单状态" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tooltip v-if="Number(scope.row.status) === 3 && scope.row.remark" :content="`拒绝原因:${scope.row.remark}`" placement="top" effect="dark">
|
||||||
|
<el-tag :type="statusType(scope.row.status)" style="cursor: help;">{{ statusText(scope.row.status) }}</el-tag>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tag v-else :type="statusType(scope.row.status)">{{ statusText(scope.row.status) }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="View" @click="openDetail(scope.row)">详情</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="Number(scope.row.status) === 0 || Number(scope.row.status) === 1"
|
||||||
|
link
|
||||||
|
type="warning"
|
||||||
|
icon="CloseBold"
|
||||||
|
@click="handleCancel(scope.row)"
|
||||||
|
>取消预约</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 预约详情对话框 -->
|
||||||
|
<el-dialog title="预约详情" v-model="detailOpen" width="700px" append-to-body>
|
||||||
|
<div class="audit-info">
|
||||||
|
<div class="audit-section-title">预约信息</div>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="预约日期">{{ formatDateYMD(detailData.reservationTimeSlot && detailData.reservationTimeSlot.date) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预约时间">{{ detailData.reserveTime }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预约总人数">{{ detailData.totalVisitors }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="Number(detailData.status) === 1" label="整单核验二维码">
|
||||||
|
<el-image v-if="detailData.qrCode" :src="qrImg('/api' + detailData.qrCode)" :preview-src-list="[qrImg('/api' + detailData.qrCode)]" style="width: 160px; height: 160px;" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<el-divider content-position="left"><span class="audit-section-title">游客信息</span></el-divider>
|
||||||
|
<div class="audit-visitors" v-if="detailData.reservationVisitors && detailData.reservationVisitors.length">
|
||||||
|
<el-table :data="detailData.reservationVisitors" size="small" style="margin-top: 12px;">
|
||||||
|
<el-table-column label="姓名" prop="realName" align="center" />
|
||||||
|
<el-table-column label="身份证号" prop="idCard" align="center" />
|
||||||
|
<el-table-column label="手机号" prop="phone" align="center" />
|
||||||
|
<el-table-column label="核验状态" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="Number(scope.row.verifyStatus) === 1 ? 'success' : 'warning'">
|
||||||
|
{{ Number(scope.row.verifyStatus) === 1 ? '已验证' : '未验证' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="核验二维码" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-image v-if="scope.row.visitorQrCode" :src="qrImg('/api' + scope.row.visitorQrCode)" :preview-src-list="[qrImg('/api' + scope.row.visitorQrCode)]" style="width: 120px; height: 120px;" />
|
||||||
|
<span v-else>—</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="audit-visitors-empty" v-else>
|
||||||
|
<el-empty description="暂无游客信息" image-size="80" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="detailOpen=false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Reservation">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance, onMounted } from 'vue';
|
||||||
|
import { listReservation, getReservation, delReservation, addReservation, updateReservation } from "@/api/reservation";
|
||||||
|
import { getCurrentSysUser } from "@/api/sysUser";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const reservationList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const detailOpen = ref(false)
|
||||||
|
const detailData = ref({})
|
||||||
|
|
||||||
|
function qrImg(url) {
|
||||||
|
if (!url) return ''
|
||||||
|
const u = encodeURIComponent(url)
|
||||||
|
return `https://api.qrserver.com/v1/create-qr-code/?size=160x160&data=${u}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
userId: null,
|
||||||
|
dateRange: null,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
status: null,
|
||||||
|
},
|
||||||
|
rules: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询预约列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
const qp = {
|
||||||
|
...queryParams.value,
|
||||||
|
startDate: queryParams.value.dateRange && queryParams.value.dateRange[0],
|
||||||
|
endDate: queryParams.value.dateRange && queryParams.value.dateRange[1]
|
||||||
|
}
|
||||||
|
listReservation(qp).then(response => {
|
||||||
|
reservationList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
userId: null,
|
||||||
|
timeSlotId: null,
|
||||||
|
totalVisitors: null,
|
||||||
|
qrCode: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
updateTime: null,
|
||||||
|
updater: null,
|
||||||
|
remark: null
|
||||||
|
};
|
||||||
|
const reservationRef = proxy.$refs["reservationRef"]
|
||||||
|
if (reservationRef) {
|
||||||
|
reservationRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加预约";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getReservation(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改预约";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDetail(row) {
|
||||||
|
getReservation(row.id).then(response => {
|
||||||
|
detailData.value = response.data
|
||||||
|
detailOpen.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDateCN = (val) => {
|
||||||
|
if (!val) return ''
|
||||||
|
let y, M, D
|
||||||
|
if (typeof val === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(val)) {
|
||||||
|
const parts = val.split('-')
|
||||||
|
y = Number(parts[0])
|
||||||
|
M = Number(parts[1])
|
||||||
|
D = Number(parts[2])
|
||||||
|
} else {
|
||||||
|
const d = new Date(val)
|
||||||
|
if (isNaN(d.getTime())) return ''
|
||||||
|
y = d.getFullYear()
|
||||||
|
M = d.getMonth() + 1
|
||||||
|
D = d.getDate()
|
||||||
|
}
|
||||||
|
return `${y}年${M}月${D}日`
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatTimeHMS = (v) => {
|
||||||
|
if (!v) return ''
|
||||||
|
if (typeof v === 'string') {
|
||||||
|
const m = v.match(/\d{2}:\d{2}:\d{2}/)
|
||||||
|
if (m) return m[0]
|
||||||
|
const m2 = v.match(/\d{2}:\d{2}/)
|
||||||
|
return m2 ? `${m2[0]}:00` : ''
|
||||||
|
}
|
||||||
|
const d = new Date(v)
|
||||||
|
if (isNaN(d.getTime())) return ''
|
||||||
|
const HH = String(d.getHours()).padStart(2, '0')
|
||||||
|
const mm = String(d.getMinutes()).padStart(2, '0')
|
||||||
|
const ss = String(d.getSeconds()).padStart(2, '0')
|
||||||
|
return `${HH}:${mm}:${ss}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCancel(row) {
|
||||||
|
const dateStr = formatDateCN(row.reservationTimeSlot && row.reservationTimeSlot.date)
|
||||||
|
const timeStr = formatTimeHMS(row.reserveTime)
|
||||||
|
const ppl = row.totalVisitors
|
||||||
|
const msg = `是否要取消${dateStr} ${timeStr} 预约人数为${ppl}人的预约?`
|
||||||
|
proxy.$confirm(msg).then(function() {
|
||||||
|
return updateReservation({ id: row.id, status: 2 })
|
||||||
|
}).then(resp => {
|
||||||
|
proxy.$message({ message: resp.msg || '取消成功', type: 'success' })
|
||||||
|
handleQuery()
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDateYMD = (val) => {
|
||||||
|
if (!val) return ''
|
||||||
|
if (typeof val === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(val)) return val
|
||||||
|
const d = new Date(val)
|
||||||
|
if (isNaN(d.getTime())) return ''
|
||||||
|
const y = d.getFullYear()
|
||||||
|
const M = String(d.getMonth() + 1).padStart(2, '0')
|
||||||
|
const D = String(d.getDate()).padStart(2, '0')
|
||||||
|
return `${y}-${M}-${D}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusText = (s) => {
|
||||||
|
const n = Number(s)
|
||||||
|
if (n === 1) return '已通过'
|
||||||
|
if (n === 2) return '已取消'
|
||||||
|
if (n === 3) return '已驳回'
|
||||||
|
return '待审核'
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusType = (s) => {
|
||||||
|
const n = Number(s)
|
||||||
|
if (n === 1) return 'success'
|
||||||
|
if (n === 2) return 'info'
|
||||||
|
if (n === 3) return 'danger'
|
||||||
|
return 'warning'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["reservationRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addReservation(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateReservation(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除预约编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delReservation(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/reservation/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `reservation_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getCurrentSysUser().then(u => {
|
||||||
|
const data = u && (u.data || u)
|
||||||
|
const uid = data && (data.id || data.userId)
|
||||||
|
queryParams.value.userId = uid || null
|
||||||
|
handleQuery()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.app-container {
|
||||||
|
width: 80%;
|
||||||
|
margin: 24px auto 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb8 {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-form) {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-pagination) {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-row.mb8) {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,343 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="预约日期" prop="date">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="queryParams.date"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择预约日期">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开始时间" prop="startTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="queryParams.startTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择开始时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束时间" prop="endTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="queryParams.endTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择结束时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="最大人数" prop="maxPeople">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.maxPeople"
|
||||||
|
placeholder="请输入最大人数"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="已预约人数" prop="currentPeople">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.currentPeople"
|
||||||
|
placeholder="请输入已预约人数"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建者id" prop="creator">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.creator"
|
||||||
|
placeholder="请输入创建者id"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="reservationTimeSlotList">
|
||||||
|
<el-table-column label="时段id" align="center" prop="id" />
|
||||||
|
<el-table-column label="预约日期" align="center" prop="date" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.date, 'yyyy-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="开始时间" align="center" prop="startTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.startTime, 'yyyy-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="结束时间" align="center" prop="endTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.endTime, 'yyyy-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="最大人数" align="center" prop="maxPeople" />
|
||||||
|
<el-table-column label="已预约人数" align="center" prop="currentPeople" />
|
||||||
|
<el-table-column label="状态" align="center" prop="status" />
|
||||||
|
<el-table-column label="创建者id" align="center" prop="creator" />
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改预约时段对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="reservationTimeSlotRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="预约日期" prop="date">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.date"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择预约日期">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开始时间" prop="startTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.startTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择开始时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束时间" prop="endTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.endTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择结束时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="最大人数" prop="maxPeople">
|
||||||
|
<el-input v-model="form.maxPeople" placeholder="请输入最大人数" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="已预约人数" prop="currentPeople">
|
||||||
|
<el-input v-model="form.currentPeople" placeholder="请输入已预约人数" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建者id" prop="creator">
|
||||||
|
<el-input v-model="form.creator" placeholder="请输入创建者id" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ReservationTimeSlot">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listReservationTimeSlot, getReservationTimeSlot, delReservationTimeSlot, addReservationTimeSlot, updateReservationTimeSlot } from "@/api/reservationTimeSlot";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const reservationTimeSlotList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
maxPeople: null,
|
||||||
|
currentPeople: null,
|
||||||
|
status: null,
|
||||||
|
creator: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
date: [
|
||||||
|
{ required: true, message: "预约日期不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
startTime: [
|
||||||
|
{ required: true, message: "开始时间不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
endTime: [
|
||||||
|
{ required: true, message: "结束时间不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
maxPeople: [
|
||||||
|
{ required: true, message: "最大人数不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询预约时段列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listReservationTimeSlot(queryParams.value).then(response => {
|
||||||
|
reservationTimeSlotList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
maxPeople: null,
|
||||||
|
currentPeople: null,
|
||||||
|
status: null,
|
||||||
|
createTime: null,
|
||||||
|
creator: null
|
||||||
|
};
|
||||||
|
const reservationTimeSlotRef = proxy.$refs["reservationTimeSlotRef"]
|
||||||
|
if (reservationTimeSlotRef) {
|
||||||
|
reservationTimeSlotRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加预约时段";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getReservationTimeSlot(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改预约时段";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["reservationTimeSlotRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addReservationTimeSlot(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateReservationTimeSlot(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除预约时段编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delReservationTimeSlot(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/reservationTimeSlot/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `reservationTimeSlot_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="预约id" prop="reservationId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.reservationId"
|
||||||
|
placeholder="请输入预约id"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客真实姓名" prop="realName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.realName"
|
||||||
|
placeholder="请输入游客真实姓名"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客身份证号" prop="idCard">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.idCard"
|
||||||
|
placeholder="请输入游客身份证号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客手机号" prop="phone">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.phone"
|
||||||
|
placeholder="请输入游客手机号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="入场验证时间" prop="verifyTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="queryParams.verifyTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择入场验证时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAdd"
|
||||||
|
>新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<!--<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
>导出</el-button>
|
||||||
|
</el-col>-->
|
||||||
|
</el-row>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="reservationVisitorList">
|
||||||
|
<el-table-column label="明细ID" align="center" prop="id" />
|
||||||
|
<el-table-column label="预约id" align="center" prop="reservationId" />
|
||||||
|
<el-table-column label="游客真实姓名" align="center" prop="realName" />
|
||||||
|
<el-table-column label="游客身份证号" align="center" prop="idCard" />
|
||||||
|
<el-table-column label="游客手机号" align="center" prop="phone" />
|
||||||
|
<el-table-column label="游客个人入场二维码" align="center" prop="visitorQrCode" />
|
||||||
|
<el-table-column label="游客入场验证状态" align="center" prop="verifyStatus" />
|
||||||
|
<el-table-column label="入场验证时间" align="center" prop="verifyTime" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.verifyTime, 'yyyy-MM-DD') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="queryParams.pageNum"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="queryParams.pageSize"
|
||||||
|
layout="->, total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
|
||||||
|
<!-- 添加或修改游客预约明细对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="reservationVisitorRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="预约id" prop="reservationId">
|
||||||
|
<el-input v-model="form.reservationId" placeholder="请输入预约id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客真实姓名" prop="realName">
|
||||||
|
<el-input v-model="form.realName" placeholder="请输入游客真实姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客身份证号" prop="idCard">
|
||||||
|
<el-input v-model="form.idCard" placeholder="请输入游客身份证号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客手机号" prop="phone">
|
||||||
|
<el-input v-model="form.phone" placeholder="请输入游客手机号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="游客个人入场二维码" prop="visitorQrCode">
|
||||||
|
<el-input v-model="form.visitorQrCode" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="入场验证时间" prop="verifyTime">
|
||||||
|
<el-date-picker clearable
|
||||||
|
v-model="form.verifyTime"
|
||||||
|
type="date"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择入场验证时间">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ReservationVisitor">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
|
import { listReservationVisitor, getReservationVisitor, delReservationVisitor, addReservationVisitor, updateReservationVisitor } from "@/api/reservationVisitor";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const reservationVisitorList = ref([]);
|
||||||
|
const open = ref(false);
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
const isAdd = ref(false)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
reservationId: null,
|
||||||
|
realName: null,
|
||||||
|
idCard: null,
|
||||||
|
phone: null,
|
||||||
|
visitorQrCode: null,
|
||||||
|
verifyStatus: null,
|
||||||
|
verifyTime: null
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
reservationId: [
|
||||||
|
{ required: true, message: "预约id不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
realName: [
|
||||||
|
{ required: true, message: "游客真实姓名不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
idCard: [
|
||||||
|
{ required: true, message: "游客身份证号不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: "游客手机号不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询游客预约明细列表 */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listReservationVisitor(queryParams.value).then(response => {
|
||||||
|
reservationVisitorList.value = response.list;
|
||||||
|
total.value = response.total;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改变每页条数大小
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
queryParams.value.pageSize = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换页
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
queryParams.value.pageNum = val;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
function cancel() {
|
||||||
|
open.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单重置
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
id: null,
|
||||||
|
reservationId: null,
|
||||||
|
realName: null,
|
||||||
|
idCard: null,
|
||||||
|
phone: null,
|
||||||
|
visitorQrCode: null,
|
||||||
|
verifyStatus: null,
|
||||||
|
verifyTime: null
|
||||||
|
};
|
||||||
|
const reservationVisitorRef = proxy.$refs["reservationVisitorRef"]
|
||||||
|
if (reservationVisitorRef) {
|
||||||
|
reservationVisitorRef.resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
const queryRef = proxy.$refs["queryRef"]
|
||||||
|
if (queryRef) {
|
||||||
|
queryRef.resetFields();
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
function handleAdd() {
|
||||||
|
reset();
|
||||||
|
open.value = true;
|
||||||
|
title.value = "添加游客预约明细";
|
||||||
|
isAdd.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset();
|
||||||
|
const _id = row.id || ids.value
|
||||||
|
getReservationVisitor(_id).then(response => {
|
||||||
|
form.value = response.data;
|
||||||
|
open.value = true;
|
||||||
|
title.value = "修改游客预约明细";
|
||||||
|
isAdd.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单提交按钮 */
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs["reservationVisitorRef"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (isAdd.value) { // 添加
|
||||||
|
addReservationVisitor(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
} else { // 更新
|
||||||
|
updateReservationVisitor(form.value).then(response => {
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
open.value = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
function handleDelete(row) {
|
||||||
|
proxy.$confirm('是否确认删除游客预约明细编号为"' + row.id + '"的数据项?').then(function() {
|
||||||
|
return delReservationVisitor(row.id);
|
||||||
|
}).then(response => {
|
||||||
|
getList();
|
||||||
|
proxy.$message({
|
||||||
|
message: response.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
// function handleExport() {
|
||||||
|
// proxy.download('system/reservationVisitor/export', {
|
||||||
|
// ...queryParams.value
|
||||||
|
// }, `reservationVisitor_${new Date().getTime()}.xlsx`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.amms.controller;
|
||||||
|
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import com.amms.domain.vo.Result;
|
||||||
|
import com.amms.domain.ItemCategory;
|
||||||
|
import com.amms.service.IItemCategoryService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 藏品分类Controller
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/itemCategory")
|
||||||
|
public class ItemCategoryController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IItemCategoryService itemCategoryService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询藏品分类列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/list")
|
||||||
|
public PageInfo list(ItemCategory itemCategory, @RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize) {
|
||||||
|
PageHelper.startPage(pageNum, pageSize);
|
||||||
|
List<ItemCategory> itemCategorys = itemCategoryService.selectItemCategoryList(itemCategory);
|
||||||
|
return new PageInfo(itemCategorys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询全部藏品分类列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/listAll")
|
||||||
|
public List<ItemCategory> listAll(ItemCategory itemCategory) {
|
||||||
|
return itemCategoryService.selectItemCategoryList(itemCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取藏品分类详细信息
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/info/{id}")
|
||||||
|
public Result getInfo(@PathVariable("id") Long id) {
|
||||||
|
return Result.success(itemCategoryService.selectItemCategoryById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增藏品分类
|
||||||
|
*/
|
||||||
|
@PostMapping("/add")
|
||||||
|
public Result add(@RequestBody ItemCategory itemCategory) {
|
||||||
|
return itemCategoryService.insertItemCategory(itemCategory) > 0 ? Result.success("新增成功") : Result.error("新增失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改藏品分类
|
||||||
|
*/
|
||||||
|
@PutMapping
|
||||||
|
public Result update(@RequestBody ItemCategory itemCategory) {
|
||||||
|
return itemCategoryService.updateItemCategory(itemCategory) > 0 ? Result.success("修改成功") : Result.error("修改失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除藏品分类
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public Result delete(@PathVariable Long id) {
|
||||||
|
return itemCategoryService.deleteItemCategoryById(id) > 0 ? Result.success("删除成功") : Result.error("删除失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
package com.amms.domain;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 藏品分类对象 item_category
|
||||||
|
*/
|
||||||
|
public class ItemCategory {
|
||||||
|
|
||||||
|
/** 分类ID */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 分类名称 */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 创建者 */
|
||||||
|
private Long creator;
|
||||||
|
|
||||||
|
/** 更新者 */
|
||||||
|
private Long updater;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/** 备注*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreator(Long creator) {
|
||||||
|
this.creator = creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCreator() {
|
||||||
|
return creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setUpdater(Long updater) {
|
||||||
|
this.updater = updater;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUpdater() {
|
||||||
|
return updater;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Date createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getUpdateTime() {
|
||||||
|
return updateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdateTime(Date updateTime) {
|
||||||
|
this.updateTime = updateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemark() {
|
||||||
|
return remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemark(String remark) {
|
||||||
|
this.remark = remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ItemCategory{" +
|
||||||
|
"id=" + id +
|
||||||
|
", name=" + name +
|
||||||
|
", creator=" + creator +
|
||||||
|
", createTime=" + createTime +
|
||||||
|
", updater=" + updater +
|
||||||
|
", updateTime=" + updateTime +
|
||||||
|
", remark=" + remark +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.amms.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import com.amms.domain.ItemCategory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 藏品分类Mapper接口
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ItemCategoryMapper {
|
||||||
|
/**
|
||||||
|
* 查询藏品分类
|
||||||
|
*
|
||||||
|
* @param id 藏品分类主键
|
||||||
|
* @return 藏品分类
|
||||||
|
*/
|
||||||
|
public ItemCategory selectItemCategoryById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询藏品分类列表
|
||||||
|
*
|
||||||
|
* @param itemCategory 藏品分类
|
||||||
|
* @return 藏品分类集合
|
||||||
|
*/
|
||||||
|
public List<ItemCategory> selectItemCategoryList(ItemCategory itemCategory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增藏品分类
|
||||||
|
*
|
||||||
|
* @param itemCategory 藏品分类
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertItemCategory(ItemCategory itemCategory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改藏品分类
|
||||||
|
*
|
||||||
|
* @param itemCategory 藏品分类
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateItemCategory(ItemCategory itemCategory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除藏品分类
|
||||||
|
*
|
||||||
|
* @param id 藏品分类主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteItemCategoryById(Long id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.amms.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.amms.domain.Announcement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公告Service接口
|
||||||
|
*/
|
||||||
|
public interface IAnnouncementService {
|
||||||
|
/**
|
||||||
|
* 查询公告列表
|
||||||
|
*
|
||||||
|
* @param announcement 公告
|
||||||
|
* @return 公告集合
|
||||||
|
*/
|
||||||
|
public List<Announcement> selectAnnouncementList(Announcement announcement);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询公告
|
||||||
|
*
|
||||||
|
* @param id 公告主键
|
||||||
|
* @return 公告
|
||||||
|
*/
|
||||||
|
public Announcement selectAnnouncementById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增公告
|
||||||
|
*
|
||||||
|
* @param announcement 公告
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertAnnouncement(Announcement announcement);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改公告
|
||||||
|
*
|
||||||
|
* @param announcement 公告
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateAnnouncement(Announcement announcement);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除公告信息
|
||||||
|
*
|
||||||
|
* @param id 公告主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteAnnouncementById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设为置顶(保证全局仅一个置顶)
|
||||||
|
* @param id 公告ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int setTop(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询置顶公告(显示状态)
|
||||||
|
* @return 置顶公告列表
|
||||||
|
*/
|
||||||
|
public List<Announcement> selectTopAnnouncements();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询普通公告(非置顶且显示,时间倒序)
|
||||||
|
* @return 普通公告列表
|
||||||
|
*/
|
||||||
|
public List<Announcement> selectNormalAnnouncements(Announcement filter);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.amms.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.amms.domain.Carousel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮播图Service接口
|
||||||
|
*/
|
||||||
|
public interface ICarouselService {
|
||||||
|
/**
|
||||||
|
* 查询轮播图列表
|
||||||
|
*
|
||||||
|
* @param carousel 轮播图
|
||||||
|
* @return 轮播图集合
|
||||||
|
*/
|
||||||
|
public List<Carousel> selectCarouselList(Carousel carousel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询轮播图
|
||||||
|
*
|
||||||
|
* @param id 轮播图主键
|
||||||
|
* @return 轮播图
|
||||||
|
*/
|
||||||
|
public Carousel selectCarouselById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增轮播图
|
||||||
|
*
|
||||||
|
* @param carousel 轮播图
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertCarousel(Carousel carousel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改轮播图
|
||||||
|
*
|
||||||
|
* @param carousel 轮播图
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateCarousel(Carousel carousel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除轮播图信息
|
||||||
|
*
|
||||||
|
* @param id 轮播图主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteCarouselById(Long id);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.amms.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.amms.domain.ItemCategory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 藏品分类Service接口
|
||||||
|
*/
|
||||||
|
public interface IItemCategoryService {
|
||||||
|
/**
|
||||||
|
* 查询藏品分类列表
|
||||||
|
*
|
||||||
|
* @param itemCategory 藏品分类
|
||||||
|
* @return 藏品分类集合
|
||||||
|
*/
|
||||||
|
public List<ItemCategory> selectItemCategoryList(ItemCategory itemCategory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询藏品分类
|
||||||
|
*
|
||||||
|
* @param id 藏品分类主键
|
||||||
|
* @return 藏品分类
|
||||||
|
*/
|
||||||
|
public ItemCategory selectItemCategoryById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增藏品分类
|
||||||
|
*
|
||||||
|
* @param itemCategory 藏品分类
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertItemCategory(ItemCategory itemCategory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改藏品分类
|
||||||
|
*
|
||||||
|
* @param itemCategory 藏品分类
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateItemCategory(ItemCategory itemCategory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除藏品分类信息
|
||||||
|
*
|
||||||
|
* @param id 藏品分类主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteItemCategoryById(Long id);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.amms.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.amms.domain.ItemCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏Service接口
|
||||||
|
*/
|
||||||
|
public interface IItemCollectionService {
|
||||||
|
/**
|
||||||
|
* 查询收藏列表
|
||||||
|
*
|
||||||
|
* @param itemCollection 收藏
|
||||||
|
* @return 收藏集合
|
||||||
|
*/
|
||||||
|
public List<ItemCollection> selectItemCollectionList(ItemCollection itemCollection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询收藏
|
||||||
|
*
|
||||||
|
* @param id 收藏主键
|
||||||
|
* @return 收藏
|
||||||
|
*/
|
||||||
|
public ItemCollection selectItemCollectionById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增收藏
|
||||||
|
*
|
||||||
|
* @param itemCollection 收藏
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertItemCollection(ItemCollection itemCollection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改收藏
|
||||||
|
*
|
||||||
|
* @param itemCollection 收藏
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateItemCollection(ItemCollection itemCollection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除收藏信息
|
||||||
|
*
|
||||||
|
* @param id 收藏主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteItemCollectionById(Long id);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.amms.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.amms.domain.MuseumIntro;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 博物馆简介Service接口
|
||||||
|
*/
|
||||||
|
public interface IMuseumIntroService {
|
||||||
|
/**
|
||||||
|
* 查询博物馆简介列表
|
||||||
|
*
|
||||||
|
* @param museumIntro 博物馆简介
|
||||||
|
* @return 博物馆简介集合
|
||||||
|
*/
|
||||||
|
public List<MuseumIntro> selectMuseumIntroList(MuseumIntro museumIntro);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询博物馆简介
|
||||||
|
*
|
||||||
|
* @param museumName 博物馆简介主键
|
||||||
|
* @return 博物馆简介
|
||||||
|
*/
|
||||||
|
public MuseumIntro selectMuseumIntroByMuseumName(String museumName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增博物馆简介
|
||||||
|
*
|
||||||
|
* @param museumIntro 博物馆简介
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertMuseumIntro(MuseumIntro museumIntro);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改博物馆简介
|
||||||
|
*
|
||||||
|
* @param museumIntro 博物馆简介
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateMuseumIntro(MuseumIntro museumIntro);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除博物馆简介信息
|
||||||
|
*
|
||||||
|
* @param museumName 博物馆简介主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteMuseumIntroByMuseumName(String museumName);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.amms.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.amms.domain.ReservationVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 游客预约明细Service接口
|
||||||
|
*/
|
||||||
|
public interface IReservationVisitorService {
|
||||||
|
/**
|
||||||
|
* 查询游客预约明细列表
|
||||||
|
*
|
||||||
|
* @param reservationVisitor 游客预约明细
|
||||||
|
* @return 游客预约明细集合
|
||||||
|
*/
|
||||||
|
public List<ReservationVisitor> selectReservationVisitorList(ReservationVisitor reservationVisitor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询游客预约明细
|
||||||
|
*
|
||||||
|
* @param id 游客预约明细主键
|
||||||
|
* @return 游客预约明细
|
||||||
|
*/
|
||||||
|
public ReservationVisitor selectReservationVisitorById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增游客预约明细
|
||||||
|
*
|
||||||
|
* @param reservationVisitor 游客预约明细
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertReservationVisitor(ReservationVisitor reservationVisitor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改游客预约明细
|
||||||
|
*
|
||||||
|
* @param reservationVisitor 游客预约明细
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateReservationVisitor(ReservationVisitor reservationVisitor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除游客预约明细信息
|
||||||
|
*
|
||||||
|
* @param id 游客预约明细主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteReservationVisitorById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据预约ID批量删除游客预约明细信息
|
||||||
|
*
|
||||||
|
* @param reservationId 预约主表ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteReservationVisitorsByReservationId(Long reservationId);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.amms.service;
|
||||||
|
|
||||||
|
import com.amms.domain.SysUser;
|
||||||
|
import com.amms.domain.dto.LoginParam;
|
||||||
|
import com.amms.domain.vo.Result;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ISysUserService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录方法
|
||||||
|
* @param loginParam 登录参数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Result login(LoginParam loginParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户列表
|
||||||
|
* @param sysUser 用户
|
||||||
|
* @return 用户
|
||||||
|
*/
|
||||||
|
List<SysUser> selectSysUserList(SysUser sysUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户
|
||||||
|
* @param username 用户
|
||||||
|
* @return 用户
|
||||||
|
*/
|
||||||
|
SysUser selectByUsername(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户详情
|
||||||
|
* @param id 用户
|
||||||
|
* @return 用户
|
||||||
|
*/
|
||||||
|
SysUser selectById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增用户
|
||||||
|
*
|
||||||
|
* @param sysUser 用户
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int insertSysUser(SysUser sysUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户
|
||||||
|
*
|
||||||
|
* @param sysUser 用户
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int updateSysUser(SysUser sysUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除用户
|
||||||
|
*
|
||||||
|
* @param id 用户主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int deleteSysUserById(Long id);
|
||||||
|
|
||||||
|
int registerTourist(SysUser sysUser);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?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.amms.mapper.ItemCategoryMapper">
|
||||||
|
|
||||||
|
<resultMap type="com.amms.domain.ItemCategory" id="ItemCategoryResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="name" column="name" />
|
||||||
|
<result property="creator" column="creator" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updater" column="updater" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
<result property="remark" column="remark" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectItemCategoryVo">
|
||||||
|
select id, name, creator, create_time, updater, update_time, remark from item_category
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectItemCategoryList" parameterType="com.amms.domain.ItemCategory" resultMap="ItemCategoryResult">
|
||||||
|
<include refid="selectItemCategoryVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
|
||||||
|
<if test="creator != null "> and creator = #{creator}</if>
|
||||||
|
<if test="updater != null "> and updater = #{updater}</if>
|
||||||
|
</where>
|
||||||
|
order by create_time desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectItemCategoryById" parameterType="Long" resultMap="ItemCategoryResult">
|
||||||
|
<include refid="selectItemCategoryVo"/>
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertItemCategory" parameterType="com.amms.domain.ItemCategory" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into item_category
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="name != null and name != ''">name,</if>
|
||||||
|
<if test="creator != null">creator,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updater != null">updater,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
|
<if test="remark != null">remark,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="name != null and name != ''">#{name},</if>
|
||||||
|
<if test="creator != null">#{creator},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updater != null">#{updater},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
|
<if test="remark != null">#{remark},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateItemCategory" parameterType="com.amms.domain.ItemCategory">
|
||||||
|
update item_category
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="name != null and name != ''">name = #{name},</if>
|
||||||
|
<if test="creator != null">creator = #{creator},</if>
|
||||||
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="updater != null">updater = #{updater},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
<if test="remark != null">remark = #{remark},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteItemCategoryById" parameterType="Long">
|
||||||
|
delete from item_category where id = #{id}
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
||||||
Loading…
Reference in New Issue