试一下
This commit is contained in:
parent
6bc968ca6f
commit
6e02d90999
|
|
@ -0,0 +1,17 @@
|
|||
import js from '@eslint/js'
|
||||
import pluginVue from 'eslint-plugin-vue'
|
||||
|
||||
export default [
|
||||
{
|
||||
name: 'app/files-to-lint',
|
||||
files: ['**/*.{js,mjs,jsx,vue}'],
|
||||
},
|
||||
|
||||
{
|
||||
name: 'app/files-to-ignore',
|
||||
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
|
||||
},
|
||||
|
||||
js.configs.recommended,
|
||||
...pluginVue.configs['flat/essential'],
|
||||
]
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
|
|
@ -0,0 +1,41 @@
|
|||
import axios from '@/utils/request'
|
||||
|
||||
// 查询轮播图列表
|
||||
export function listCarousel(query) {
|
||||
return axios.get('/carousel/list',{
|
||||
params: {
|
||||
...query
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查询全部轮播图列表
|
||||
export function listAllCarousel(query) {
|
||||
return axios.get('/carousel/listAll', {
|
||||
params: {
|
||||
...query
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查询轮播图详细
|
||||
export function getCarousel(id) {
|
||||
return axios.get('/carousel/info/' + id)
|
||||
}
|
||||
|
||||
// 新增轮播图
|
||||
export function addCarousel(data) {
|
||||
return axios.post('/carousel/add', {
|
||||
...data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改轮播图
|
||||
export function updateCarousel(data) {
|
||||
return axios.put('/carousel', data)
|
||||
}
|
||||
|
||||
// 删除轮播图
|
||||
export function delCarousel(id) {
|
||||
return axios.delete('/carousel/' + id)
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<div>
|
||||
<QuillEditor ref="myQuillEditor"
|
||||
theme="snow"
|
||||
v-model:content="content"
|
||||
:options="data.editorOption"
|
||||
contentType="html"
|
||||
@update:content="setValue()"
|
||||
/>
|
||||
<!-- 使用自定义图片上传 -->
|
||||
<el-upload
|
||||
action="/api/files/upload"
|
||||
:data="{filePath: filePath}"
|
||||
:on-success="handleUploadSuccess"
|
||||
name="file"
|
||||
:show-file-list="false"
|
||||
style="display: none"
|
||||
ref="uploadRef"
|
||||
>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { QuillEditor } from '@vueup/vue-quill'
|
||||
import '@vueup/vue-quill/dist/vue-quill.snow.css'
|
||||
import { reactive, onMounted, ref, toRaw, getCurrentInstance, onUpdated, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const props = defineProps(['value', 'filePath'])
|
||||
const emit = defineEmits(['updateValue'])
|
||||
const content = ref('')
|
||||
const myQuillEditor = ref()
|
||||
const filePath = ref('')
|
||||
const data = reactive({
|
||||
content: '',
|
||||
editorOption: {
|
||||
modules: {
|
||||
toolbar: [
|
||||
['bold', 'italic', 'underline', 'strike'],
|
||||
[{ 'size': ['small', false, 'large', 'huge'] }],
|
||||
[{ 'font': [] }],
|
||||
[{ 'align': [] }],
|
||||
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
||||
[{ 'indent': '-1' }, { 'indent': '+1' }],
|
||||
[{ 'header': 1 }, { 'header': 2 }],
|
||||
['image'],
|
||||
[{ 'direction': 'rtl' }],
|
||||
[{ 'color': [] }, { 'background': [] }]
|
||||
]
|
||||
},
|
||||
placeholder: '请输入内容...'
|
||||
}
|
||||
})
|
||||
|
||||
const uploadRef = ref('')
|
||||
|
||||
const imgHandler = (state) => {
|
||||
if (state) {
|
||||
uploadRef.value.$el.querySelector('input').click();
|
||||
}
|
||||
}
|
||||
// 抛出更改内容,添加安全检查
|
||||
const setValue = () => {
|
||||
if (myQuillEditor.value) {
|
||||
try {
|
||||
const text = toRaw(myQuillEditor.value).getHTML();
|
||||
emit('updateValue', text);
|
||||
} catch (e) {
|
||||
console.warn('获取HTML内容时出错:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleUploadSuccess(res, file) {
|
||||
// 如果上传成功且编辑器实例存在
|
||||
if (res && myQuillEditor.value) {
|
||||
try {
|
||||
// 获取富文本组件实例
|
||||
const quill = toRaw(myQuillEditor.value).getQuill();
|
||||
// 获取当前选择
|
||||
const selection = quill.getSelection();
|
||||
// 安全地获取光标位置,默认为文档末尾
|
||||
const length = selection ? selection.index : quill.getLength();
|
||||
// 插入图片 res.url为服务器返回的图片地址
|
||||
quill.insertEmbed(length, "image", proxy.getFilePrefix + res);
|
||||
// 安全地调整光标位置
|
||||
try {
|
||||
quill.setSelection(Math.min(length + 1, quill.getLength()));
|
||||
} catch (e) {
|
||||
// 光标位置设置失败不影响功能
|
||||
console.warn('设置光标位置时出错:', e);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('插入图片时出错:', e);
|
||||
ElMessage.error("图片插入失败");
|
||||
}
|
||||
} else {
|
||||
ElMessage.error("图片插入失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onUpdated(() => {
|
||||
// 只有当编辑器实例存在且值确实发生变化时才更新内容
|
||||
if (myQuillEditor.value && props.value !== undefined) {
|
||||
const quill = toRaw(myQuillEditor.value).getQuill();
|
||||
const currentHtml = toRaw(myQuillEditor.value).getHTML();
|
||||
|
||||
// 避免不必要的更新
|
||||
if ((props.value === '' || props.value === null || props.value === '<p></p>') && currentHtml !== '<p><br></p>') {
|
||||
quill.setText('');
|
||||
} else if (props.value && props.value !== currentHtml && props.value !== '<p></p>') {
|
||||
try {
|
||||
toRaw(myQuillEditor.value).setHTML(props.value);
|
||||
} catch (e) {
|
||||
console.warn('设置HTML内容时出错:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 初始化编辑器
|
||||
onMounted(() => {
|
||||
if (myQuillEditor.value) {
|
||||
content.value = props.value || '';
|
||||
const quill = toRaw(myQuillEditor.value).getQuill();
|
||||
|
||||
// 添加图片处理程序
|
||||
try {
|
||||
quill.getModule('toolbar').addHandler('image', imgHandler);
|
||||
} catch (e) {
|
||||
console.warn('添加工具栏处理程序时出错:', e);
|
||||
}
|
||||
|
||||
// 初始设置内容
|
||||
if (props.value && props.value !== '<p></p>') {
|
||||
try {
|
||||
toRaw(myQuillEditor.value).setHTML(props.value);
|
||||
} catch (e) {
|
||||
console.warn('初始化HTML内容时出错:', e);
|
||||
}
|
||||
}
|
||||
|
||||
filePath.value = props.filePath;
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
<template>
|
||||
<el-container>
|
||||
<el-header class="top-header">
|
||||
<div class="header-left">
|
||||
<div class="logo">邺城博物馆</div>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<el-menu
|
||||
mode="horizontal"
|
||||
:default-active="$route.path"
|
||||
class="nav-menu"
|
||||
:router="true"
|
||||
background-color="#717171"
|
||||
>
|
||||
<template v-for="menu in touristMenuList" :key="menu.route">
|
||||
<el-menu-item :index="menu.route" :route="menu.route">{{ menu.label }}</el-menu-item>
|
||||
</template>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="user" v-if="isLogged">
|
||||
<div class="avator">
|
||||
<el-dropdown trigger="click">
|
||||
<div class="img">
|
||||
<img style="width: 100%; height: 100%;" :src="getFilePrefix + avatar" alt="" />
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="handleMyReverse">我的预约</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleMyCollection">我的收藏</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleUpdatePwd">修改密码</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleUserInfo">个人信息</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleLogout">
|
||||
<span style="color: brown;">退出登录</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login-btn" v-else>
|
||||
<el-button type="text" @click="goLogin">登录</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<RouterView />
|
||||
</el-main>
|
||||
<el-footer class="site-footer">
|
||||
<div class="footer-text">© {{ year }} 邺城博物馆 • 欢迎参观</div>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
<el-dialog title="修改密码" v-model="updatePwdOpen" width="400px" append-to-body>
|
||||
<el-form ref="updatePwdRef" :model="updatePwdForm" :rules="updatePwdRules" label-width="80px">
|
||||
<el-form-item label="旧密码" prop="oldPwd">
|
||||
<el-input type="password" v-model="updatePwdForm.oldPwd" placeholder="请输入旧密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPwd">
|
||||
<el-input type="password" v-model="updatePwdForm.newPwd" placeholder="请输入新密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPwd">
|
||||
<el-input type="password" v-model="updatePwdForm.confirmPwd" placeholder="请输入确认密码" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitUpdatePwd">确 定</el-button>
|
||||
<el-button @click="handleCancelUpdatePwd">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- </el-container> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, toRefs, getCurrentInstance, watch } from 'vue'
|
||||
import { RouterView } from 'vue-router'
|
||||
import { removeToken } from '@/utils/token'
|
||||
import { updatePwd } from '@/api/sysUser';
|
||||
import Cookies from 'js-cookie';
|
||||
import { House, Collection, Calendar, Message, Star, User } from '@element-plus/icons-vue'
|
||||
|
||||
const avatar = ref(Cookies.get('avatar'))
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const getFilePrefix = proxy.getFilePrefix
|
||||
const year = new Date().getFullYear()
|
||||
const isLogged = ref(!!Cookies.get('role'))
|
||||
|
||||
const touristMenuList = ref([
|
||||
{ label: '首页', route: '/tourist/home', icon: House },
|
||||
{ label: '藏品', route: '/tourist/relic', icon: Collection },
|
||||
{ label: '预约', route: '/tourist/reservation', icon: Calendar },
|
||||
{ label: '公告', route: '/tourist/announcement', icon: Message },
|
||||
// { label: '关于', route: '/tourist/userInfo', icon: User }
|
||||
])
|
||||
|
||||
// 自定义确认密码校验规则
|
||||
const confirmPwdRule = (rule, value, callback) => {
|
||||
if (!value) { // 如果确认密码为空
|
||||
callback(new Error('请输入确认密码'))
|
||||
} else if (updatePwdForm.value.newPwd !== value) { // 如果新密码与确认密码不一致
|
||||
callback(new Error('两次输入的密码不一致'))
|
||||
} else { // 校验通过
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const updatePwdOpen = ref(false)
|
||||
const data = reactive({
|
||||
updatePwdForm: {
|
||||
oldPwd: '',
|
||||
newPwd: '',
|
||||
confirmPwd: ''
|
||||
},
|
||||
updatePwdRules: {
|
||||
oldPwd: [
|
||||
{ required: true, message: '请输入旧密码', trigger: 'blur' }
|
||||
],
|
||||
newPwd: [
|
||||
{ required: true, message: '请输入新密码', trigger: 'blur' }
|
||||
],
|
||||
confirmPwd: [
|
||||
{ required: true, validator: confirmPwdRule, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const { updatePwdForm, updatePwdRules } = toRefs(data)
|
||||
|
||||
/** 我的预约操作 */
|
||||
function handleMyReverse() {
|
||||
proxy.$router.push('/tourist/myReservation')
|
||||
}
|
||||
|
||||
/** 我的收藏操作 */
|
||||
function handleMyCollection() {
|
||||
proxy.$router.push('/tourist/myRelicCollection')
|
||||
}
|
||||
|
||||
|
||||
/** 修改密码操作 */
|
||||
function handleUpdatePwd() {
|
||||
updatePwdOpen.value = true
|
||||
}
|
||||
|
||||
/** 提交修改密码 */
|
||||
function submitUpdatePwd() {
|
||||
proxy.$refs.updatePwdRef.validate((valid) => {
|
||||
if (valid) {
|
||||
updatePwd(updatePwdForm.value).then(res => {
|
||||
if (res.code == 200) {
|
||||
proxy.$message.success(res.msg)
|
||||
proxy.$refs.updatePwdRef.resetFields()
|
||||
updatePwdOpen.value = false
|
||||
} else {
|
||||
proxy.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 取消修改密码 */
|
||||
function handleCancelUpdatePwd() {
|
||||
proxy.$refs.updatePwdRef.resetFields()
|
||||
updatePwdOpen.value = false
|
||||
}
|
||||
|
||||
/** 个人信息操作 */
|
||||
function handleUserInfo() {
|
||||
proxy.$router.push('/tourist/userInfo')
|
||||
}
|
||||
|
||||
/** 退出登录操作 */
|
||||
function handleLogout() {
|
||||
console.log('退出登录')
|
||||
proxy.$confirm('确定要退出系统吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
console.log('确定退出')
|
||||
// 请求后端logout接口
|
||||
|
||||
// 清除本地token
|
||||
removeToken()
|
||||
Cookies.remove('role')
|
||||
Cookies.remove('avatar')
|
||||
Cookies.remove('username')
|
||||
Cookies.remove('nickname')
|
||||
isLogged.value = false
|
||||
avatar.value = ''
|
||||
// 跳转到登录页
|
||||
proxy.$router.push('/login')
|
||||
})
|
||||
.catch(() => {
|
||||
console.log('取消退出')
|
||||
})
|
||||
}
|
||||
|
||||
function goLogin() {
|
||||
proxy.$router.push('/login')
|
||||
}
|
||||
|
||||
watch(() => proxy.$route.fullPath, () => {
|
||||
isLogged.value = !!Cookies.get('role')
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.top-header {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
background: #1f1f1f;
|
||||
color: #fff;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
.header-left { flex: 0 0 120px; }
|
||||
.logo { font-size: 18px; font-weight: 700; letter-spacing: 2px; }
|
||||
.header-center { flex: 1 1 70%; display: flex; justify-content: center; }
|
||||
.header-right { flex: 0 0 80px; display: flex; align-items: center; justify-content: flex-end; }
|
||||
.nav-menu { background: transparent; border-bottom: none; }
|
||||
:deep(.nav-menu .el-menu-item) { color: #eaeaea; }
|
||||
:deep(.nav-menu .el-menu-item.is-active) { color: #ffd04b; }
|
||||
:deep(.nav-menu .el-menu-item:hover) { background: transparent; color: #ffffff; }
|
||||
|
||||
:deep(.nav-menu) { width: 100%; justify-content: center; }
|
||||
:deep(.nav-menu .el-menu-item) { padding: 0 14px; min-width: auto; }
|
||||
:deep(.nav-menu .el-menu-item:last-child) { display: inline-flex !important; }
|
||||
|
||||
:deep(.nav-menu .el-menu-item) { width: 150px; }
|
||||
|
||||
.top-header .user .img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-top: 10px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #b2b2b2;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.top-header .user .img:hover {
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 0px 20px #ffffff;
|
||||
}
|
||||
|
||||
.el-main {
|
||||
background: #f2f2f2;
|
||||
min-height: calc(100vh - 54px);
|
||||
padding: 0;
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
.site-footer {
|
||||
height: 54px;
|
||||
background: #1a1a1a;
|
||||
color: #cfcfcf;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-top: 1px solid #2a2a2a;
|
||||
}
|
||||
.footer-text { font-size: 13px; letter-spacing: 1px; }
|
||||
</style>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import moment from "moment";
|
||||
|
||||
/**
|
||||
* 参数处理
|
||||
* @param {*} params 参数
|
||||
*/
|
||||
export function tansParams(params) {
|
||||
let result = ''
|
||||
for (const propName of Object.keys(params)) {
|
||||
const value = params[propName];
|
||||
const part = encodeURIComponent(propName) + "=";
|
||||
if (value !== null && value !== "" && typeof (value) !== "undefined") {
|
||||
if (typeof value === 'object') {
|
||||
for (const key of Object.keys(value)) {
|
||||
if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
|
||||
const params = propName + '[' + key + ']';
|
||||
const subPart = encodeURIComponent(params) + "=";
|
||||
result += subPart + encodeURIComponent(value[key]) + "&";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result += part + encodeURIComponent(value) + "&";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 日期格式化
|
||||
export function parseTime(time, pattern) {
|
||||
return moment(time).format(pattern || 'YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
|
@ -0,0 +1,338 @@
|
|||
<template>
|
||||
<div class="detail-container">
|
||||
<div class="top-bar">
|
||||
<el-button link size="large" :icon="ArrowLeft" @click="goBack">返回</el-button>
|
||||
</div>
|
||||
<div class="detail-body" v-loading="loading">
|
||||
<div class="media">
|
||||
<div class="cover">
|
||||
<el-image v-if="detail?.coverImageUrl" :src="getFilePrefix + detail.coverImageUrl" :preview-src-list="[getFilePrefix + detail.coverImageUrl]" preview-teleported fit="cover" />
|
||||
<div v-else class="cover-empty">—</div>
|
||||
<div v-if="detail?.modelUrl" class="badge360" @click="openModel">360</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">{{ detail?.name || '—' }}</div>
|
||||
<!-- <div class="meta">
|
||||
<span class="cat">{{ detail?.categoryInfo?.name || detail?.categoryId || '—' }}</span>
|
||||
<span v-if="detail?.material" class="tag">{{ detail.material }}</span>
|
||||
<span v-if="detail?.age" class="tag">{{ detail.age }}</span>
|
||||
</div> -->
|
||||
<div class="chips">
|
||||
<span v-if="Number(detail?.isHot) === 1" class="chip hot">热门</span>
|
||||
<!-- <span class="chip status" :class="Number(detail?.status) === 1 ? 'on' : 'off'">{{ Number(detail?.status) === 1 ? '显示' : '隐藏' }}</span> -->
|
||||
</div>
|
||||
<div class="kv-list">
|
||||
<div class="kv-item">
|
||||
<div class="kv-label">分类名称</div>
|
||||
<div class="kv-val">{{ detail?.categoryInfo?.name || '—' }}</div>
|
||||
</div>
|
||||
<div class="kv-item">
|
||||
<div class="kv-label">材质</div>
|
||||
<div class="kv-val">{{ detail?.material || '—' }}</div>
|
||||
</div>
|
||||
<div class="kv-item">
|
||||
<div class="kv-label">年代</div>
|
||||
<div class="kv-val">{{ detail?.age || '—' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="desc">
|
||||
<div class="section">
|
||||
<div class="section-title">出土信息</div>
|
||||
<div class="section-text">{{ detail?.excavationInfo || '—' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collect-bar" v-if="isLogin">
|
||||
<el-button class="collect-btn" :type="isCollected ? 'danger' : 'warning'" size="large" @click="toggleCollect">
|
||||
{{ isCollected ? '取消收藏' : '收藏' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="story-panel">
|
||||
<div class="section">
|
||||
<div class="section-title">文物故事</div>
|
||||
<div class="section-text" v-html="detail?.story || '—'"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, getCurrentInstance, onMounted } from 'vue'
|
||||
import { getRelic } from '@/api/relic'
|
||||
import { addItemCollection, delItemCollection } from '@/api/itemCollection'
|
||||
// 不再在前端获取当前用户ID,改由后端基于登录态判断
|
||||
import { Back,ArrowLeft } from '@element-plus/icons-vue'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const getFilePrefix = proxy.getFilePrefix
|
||||
const loading = ref(true)
|
||||
const detail = ref(null)
|
||||
const isCollected = ref(false)
|
||||
const collectionId = ref(null)
|
||||
let relicIdCache = null
|
||||
const isLogin = ref(!!Cookies.get('role'))
|
||||
|
||||
function formatDate(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')
|
||||
const HH = String(d.getHours()).padStart(2, '0')
|
||||
const mm = String(d.getMinutes()).padStart(2, '0')
|
||||
return `${yyyy}-${MM}-${DD} ${HH}:${mm}`
|
||||
}
|
||||
|
||||
function openModel() {
|
||||
if (detail.value?.modelUrl) {
|
||||
window.open(getFilePrefix + detail.value.modelUrl, '_blank')
|
||||
}
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
proxy.$router.back()
|
||||
}
|
||||
|
||||
function refreshCollectStatus() {
|
||||
if (!isLogin.value) {
|
||||
isCollected.value = false
|
||||
collectionId.value = null
|
||||
return
|
||||
}
|
||||
const list = Array.isArray(detail.value?.itemCollections) ? detail.value.itemCollections : []
|
||||
const mine = list.length ? list[0] : null
|
||||
isCollected.value = !!mine
|
||||
collectionId.value = mine ? mine.id : null
|
||||
}
|
||||
|
||||
function fetchDetail() {
|
||||
if (!relicIdCache) { loading.value = false; return }
|
||||
getRelic(relicIdCache).then(res => {
|
||||
detail.value = res.data || res
|
||||
loading.value = false
|
||||
refreshCollectStatus()
|
||||
}).catch(() => { loading.value = false })
|
||||
}
|
||||
|
||||
function toggleCollect() {
|
||||
if (!relicIdCache) return
|
||||
if (!isLogin.value) return
|
||||
if (!isCollected.value) {
|
||||
addItemCollection({ itemId: relicIdCache }).then(r => {
|
||||
// proxy.$message.success((r && r.msg) || '已收藏')
|
||||
fetchDetail()
|
||||
})
|
||||
} else if (collectionId.value) {
|
||||
delItemCollection(collectionId.value).then(r => {
|
||||
// proxy.$message.success((r && r.msg) || '已取消收藏')
|
||||
fetchDetail()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const relicId = proxy.$route.params.relicId
|
||||
relicIdCache = relicId
|
||||
fetchDetail()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.detail-container {
|
||||
width: 80%;
|
||||
margin: 24px auto 40px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
.top-bar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.detail-body {
|
||||
display: grid;
|
||||
grid-template-columns: 1.3fr 1fr;
|
||||
gap: 28px;
|
||||
grid-auto-rows: min-content;
|
||||
}
|
||||
.media {
|
||||
display: flex;
|
||||
}
|
||||
.cover {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 520px;
|
||||
background: #f9f6f1;
|
||||
border: 1px solid #e7dfcf;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cover :deep(.el-image) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.cover-empty {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #909399;
|
||||
font-size: 18px;
|
||||
}
|
||||
.badge360 {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
background: #ffffff;
|
||||
color: #8a2b2b;
|
||||
border: 1px solid #e8d9cf;
|
||||
border-radius: 999px;
|
||||
padding: 8px 12px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
}
|
||||
.badge360:hover {
|
||||
background: #fef4f4;
|
||||
}
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: linear-gradient(180deg, #faf7f2 0%, #f7f3ea 100%);
|
||||
border: 1px solid #e7dfcf;
|
||||
border-radius: 16px;
|
||||
padding: 16px 18px;
|
||||
box-shadow: 0 6px 14px rgba(138,43,43,0.08);
|
||||
}
|
||||
.title {
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
color: #2c1f1f;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.meta {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.chips {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.chip {
|
||||
display: inline-block;
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid #e8d9cf;
|
||||
background: #f5e9e2;
|
||||
color: #8a2b2b;
|
||||
font-weight: 700;
|
||||
}
|
||||
.chip.hot {
|
||||
background: #ffefe6;
|
||||
border-color: #ffd5bf;
|
||||
color: #c64820;
|
||||
}
|
||||
.chip.status.on {
|
||||
background: #e8f5e9;
|
||||
border-color: #c8e6c9;
|
||||
color: #2e7d32;
|
||||
}
|
||||
.chip.status.off {
|
||||
background: #fdecea;
|
||||
border-color: #f5c6c6;
|
||||
color: #c62828;
|
||||
}
|
||||
.kv-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.kv-item {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: baseline;
|
||||
}
|
||||
.kv-label {
|
||||
width: 80px;
|
||||
color: #8a2b2b;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
}
|
||||
.kv-val {
|
||||
color: #2c1f1f;
|
||||
font-size: 14px;
|
||||
}
|
||||
.cat {
|
||||
font-size: 14px;
|
||||
color: #8a2b2b;
|
||||
background: #f5e9e2;
|
||||
border: 1px solid #e8d9cf;
|
||||
border-radius: 999px;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
.tag {
|
||||
font-size: 14px;
|
||||
color: #2c1f1f;
|
||||
background: #efe9df;
|
||||
border: 1px solid #e0d6c7;
|
||||
border-radius: 999px;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
.desc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
.section {
|
||||
background: #ffffff;
|
||||
border: 1px solid #eadfce;
|
||||
border-radius: 14px;
|
||||
padding: 16px;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
color: #2c1f1f;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.section-text {
|
||||
color: #606266;
|
||||
line-height: 1.9;
|
||||
font-size: 16px;
|
||||
}
|
||||
.story-panel {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.collect-bar {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.collect-btn {
|
||||
padding: 18px 44px;
|
||||
font-size: 18px;
|
||||
border-radius: 999px;
|
||||
box-shadow: 0 8px 18px rgba(138,43,43,0.12);
|
||||
font-weight: 700;
|
||||
}
|
||||
.section-text :deep(img) {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 8px auto;
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -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.Carousel;
|
||||
import com.amms.service.ICarouselService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 轮播图Controller
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/carousel")
|
||||
public class CarouselController {
|
||||
|
||||
@Autowired
|
||||
private ICarouselService carouselService;
|
||||
|
||||
/**
|
||||
* 查询轮播图列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public PageInfo list(Carousel carousel, @RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize) {
|
||||
PageHelper.startPage(pageNum, pageSize);
|
||||
List<Carousel> carousels = carouselService.selectCarouselList(carousel);
|
||||
return new PageInfo(carousels);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全部轮播图列表
|
||||
*/
|
||||
@GetMapping("/listAll")
|
||||
public List<Carousel> listAll(Carousel carousel) {
|
||||
return carouselService.selectCarouselList(carousel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取轮播图详细信息
|
||||
*/
|
||||
@GetMapping(value = "/info/{id}")
|
||||
public Result getInfo(@PathVariable("id") Long id) {
|
||||
return Result.success(carouselService.selectCarouselById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增轮播图
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public Result add(@RequestBody Carousel carousel) {
|
||||
return carouselService.insertCarousel(carousel) > 0 ? Result.success("新增成功") : Result.error("新增失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改轮播图
|
||||
*/
|
||||
@PutMapping
|
||||
public Result update(@RequestBody Carousel carousel) {
|
||||
return carouselService.updateCarousel(carousel) > 0 ? Result.success("修改成功") : Result.error("修改失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除轮播图
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
public Result delete(@PathVariable Long id) {
|
||||
return carouselService.deleteCarouselById(id) > 0 ? Result.success("删除成功") : Result.error("删除失败");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
package com.amms.controller;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 文件处理controller
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/files")
|
||||
public class FilesController {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(FilesController.class);
|
||||
|
||||
@Value("${files.path}")
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param file
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
@PostMapping("/upload")
|
||||
@ResponseBody
|
||||
public String upload(@RequestParam("file") MultipartFile file ,@RequestParam(name = "filePath" ,required = false) String filePath) throws IOException {
|
||||
logger.info("上传文件:{}", file.getName());
|
||||
File fileUploadPath = null;
|
||||
// 创建目标路径
|
||||
if (!filePath.equals("") && filePath != null) {
|
||||
fileUploadPath = new File(path, filePath);
|
||||
} else {
|
||||
fileUploadPath = new File(path);
|
||||
}
|
||||
if (!fileUploadPath.exists()) {
|
||||
fileUploadPath.mkdirs();
|
||||
}
|
||||
// 新文件名
|
||||
String newFileName = UUID.randomUUID().toString().replace("-", "") + "-" + file.getOriginalFilename();
|
||||
file.transferTo(new File(fileUploadPath, newFileName));
|
||||
// 判断参数中filePath时候为null 不为空则拼接到新文件名前
|
||||
if (!filePath.equals("") && filePath != null) {
|
||||
if (filePath.endsWith("/")) {
|
||||
newFileName = filePath + newFileName;
|
||||
} else {
|
||||
newFileName = filePath + "/" + newFileName;
|
||||
}
|
||||
}
|
||||
return newFileName;
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
BufferedInputStream bis = null;
|
||||
OutputStream os = null;
|
||||
|
||||
/**
|
||||
* 获取文件(图片)
|
||||
* @param fileName
|
||||
* @param response
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
@GetMapping("/get")
|
||||
public void getImage(@RequestParam("fileName") String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
|
||||
logger.debug("加载图片,文件名:" + fileName);
|
||||
File file = new File(path, fileName);
|
||||
// 判断文件是否存在
|
||||
if (!file.exists()) {
|
||||
logger.error("文件【" + file.getAbsolutePath() + "】不存在!");
|
||||
response.setStatus(404);
|
||||
return;
|
||||
}
|
||||
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") );
|
||||
response.setContentType("image/jpeg");
|
||||
response.setContentLength((int)file.length());
|
||||
FileInputStream is = null;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
is = new FileInputStream(file);
|
||||
os = response.getOutputStream();
|
||||
|
||||
byte[] buf = new byte[8192];
|
||||
int rd;
|
||||
while ((rd = is.read(buf)) > 0)
|
||||
os.write(buf, 0, rd);
|
||||
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (is!=null) is.close();
|
||||
if (os!=null) {
|
||||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param fileName
|
||||
* @param response
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
@GetMapping("/delete")
|
||||
public void delete(@RequestParam("fileName") String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
|
||||
logger.error("删除文件,文件名:" + fileName);
|
||||
File file = new File(path + fileName);
|
||||
if (!file.exists()) {
|
||||
logger.error("文件【" + fileName + "】不存在!");
|
||||
response.setStatus(404);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
file.delete();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
* @param fileName
|
||||
* @param request
|
||||
* @param response
|
||||
* @throws IOException
|
||||
*/
|
||||
@GetMapping("/download")
|
||||
public void download(String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
logger.info("下载文件:{}", fileName);
|
||||
File fileUploadPathFile = new File(path);
|
||||
if (!fileUploadPathFile.exists()) {
|
||||
fileUploadPathFile.mkdir();
|
||||
}
|
||||
File file = new File(fileUploadPathFile, fileName);
|
||||
|
||||
response.setContentType("application/octet-stream;charset=UTF-8");
|
||||
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
|
||||
response.setHeader("Content-Disposition","attachment;filename="+fileName);
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
os = response.getOutputStream();
|
||||
bis = new BufferedInputStream(new FileInputStream(file));
|
||||
while(bis.read(buffer) != -1){
|
||||
os.write(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package com.amms.domain;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 轮播图对象 carousel
|
||||
*/
|
||||
public class Carousel {
|
||||
|
||||
/** 轮播图id */
|
||||
private Long id;
|
||||
|
||||
/** 标题 */
|
||||
private String title;
|
||||
|
||||
/** 图片地址 */
|
||||
private String imageUrl;
|
||||
|
||||
/** 跳转链接 */
|
||||
private String link;
|
||||
|
||||
/** 排序序号 */
|
||||
private Integer sort;
|
||||
|
||||
/** 状态(0隐藏 1显示) */
|
||||
private Long status;
|
||||
|
||||
/** 创建时间 */
|
||||
@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;
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public void setLink(String link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public String getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setSort(Integer sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
public Integer getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public void setStatus(Long status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Long getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Carousel{" +
|
||||
"id=" + id +
|
||||
", title=" + title +
|
||||
", imageUrl=" + imageUrl +
|
||||
", link=" + link +
|
||||
", sort=" + sort +
|
||||
", status=" + status +
|
||||
", createTime=" + createTime +
|
||||
", updateTime=" + updateTime +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.amms.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.amms.domain.Carousel;
|
||||
|
||||
/**
|
||||
* 轮播图Mapper接口
|
||||
*/
|
||||
@Mapper
|
||||
public interface CarouselMapper {
|
||||
/**
|
||||
* 查询轮播图
|
||||
*
|
||||
* @param id 轮播图主键
|
||||
* @return 轮播图
|
||||
*/
|
||||
public Carousel selectCarouselById(Long id);
|
||||
|
||||
/**
|
||||
* 查询轮播图列表
|
||||
*
|
||||
* @param carousel 轮播图
|
||||
* @return 轮播图集合
|
||||
*/
|
||||
public List<Carousel> selectCarouselList(Carousel carousel);
|
||||
|
||||
/**
|
||||
* 新增轮播图
|
||||
*
|
||||
* @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,77 @@
|
|||
package com.amms.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.amms.mapper.CarouselMapper;
|
||||
import com.amms.domain.Carousel;
|
||||
import com.amms.service.ICarouselService;
|
||||
|
||||
/**
|
||||
* 轮播图Service业务层处理
|
||||
*/
|
||||
@Service
|
||||
public class CarouselServiceImpl implements ICarouselService {
|
||||
|
||||
@Autowired
|
||||
private CarouselMapper carouselMapper;
|
||||
|
||||
/**
|
||||
* 查询轮播图列表
|
||||
*
|
||||
* @param carousel 轮播图
|
||||
* @return 轮播图
|
||||
*/
|
||||
@Override
|
||||
public List<Carousel> selectCarouselList(Carousel carousel) {
|
||||
return carouselMapper.selectCarouselList(carousel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询轮播图
|
||||
*
|
||||
* @param id 轮播图主键
|
||||
* @return 轮播图
|
||||
*/
|
||||
@Override
|
||||
public Carousel selectCarouselById(Long id) {
|
||||
return carouselMapper.selectCarouselById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增轮播图
|
||||
*
|
||||
* @param carousel 轮播图
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertCarousel(Carousel carousel) {
|
||||
carousel.setCreateTime(new Date());
|
||||
return carouselMapper.insertCarousel(carousel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改轮播图
|
||||
*
|
||||
* @param carousel 轮播图
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateCarousel(Carousel carousel) {
|
||||
carousel.setUpdateTime(new Date());
|
||||
return carouselMapper.updateCarousel(carousel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除轮播图信息
|
||||
*
|
||||
* @param id 轮播图主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteCarouselById(Long id) {
|
||||
return carouselMapper.deleteCarouselById(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?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.CarouselMapper">
|
||||
|
||||
<resultMap type="com.amms.domain.Carousel" id="CarouselResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="title" column="title" />
|
||||
<result property="imageUrl" column="image_url" />
|
||||
<result property="link" column="link" />
|
||||
<result property="sort" column="sort" />
|
||||
<result property="status" column="status" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectCarouselVo">
|
||||
select id, title, image_url, link, sort, status, create_time, update_time from carousel
|
||||
</sql>
|
||||
|
||||
<select id="selectCarouselList" parameterType="com.amms.domain.Carousel" resultMap="CarouselResult">
|
||||
<include refid="selectCarouselVo"/>
|
||||
<where>
|
||||
<if test="title != null and title != ''"> and title = #{title}</if>
|
||||
<if test="imageUrl != null and imageUrl != ''"> and image_url = #{imageUrl}</if>
|
||||
<if test="link != null and link != ''"> and link = #{link}</if>
|
||||
<if test="sort != null "> and sort = #{sort}</if>
|
||||
<if test="status != null "> and status = #{status}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectCarouselById" parameterType="Long" resultMap="CarouselResult">
|
||||
<include refid="selectCarouselVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<insert id="insertCarousel" parameterType="com.amms.domain.Carousel" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into carousel
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="title != null and title != ''">title,</if>
|
||||
<if test="imageUrl != null and imageUrl != ''">image_url,</if>
|
||||
<if test="link != null">link,</if>
|
||||
<if test="sort != null">sort,</if>
|
||||
<if test="status != null">status,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="title != null and title != ''">#{title},</if>
|
||||
<if test="imageUrl != null and imageUrl != ''">#{imageUrl},</if>
|
||||
<if test="link != null">#{link},</if>
|
||||
<if test="sort != null">#{sort},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateCarousel" parameterType="com.amms.domain.Carousel">
|
||||
update carousel
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="title != null and title != ''">title = #{title},</if>
|
||||
<if test="imageUrl != null and imageUrl != ''">image_url = #{imageUrl},</if>
|
||||
<if test="link != null">link = #{link},</if>
|
||||
<if test="sort != null">sort = #{sort},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteCarouselById" parameterType="Long">
|
||||
delete from carousel where id = #{id}
|
||||
</delete>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue