Merge branch 'develoop' of http://182.92.169.222:3000/dlsx/Teaching_integration_platform_admin_template into develoop
commit
63efc9bce9
42 changed files with 10237 additions and 10382 deletions
@ -1,15 +1,18 @@ |
||||
<!doctype html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
<title>教学一体化后师生后台</title> |
||||
</head> |
||||
<body> |
||||
<div id="app"></div> |
||||
<script type="module" src="/src/main.ts"></script> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script> |
||||
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> |
||||
</body> |
||||
</html> |
||||
|
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
<title>教学一体化后师生后台</title> |
||||
</head> |
||||
|
||||
<body> |
||||
<div id="app"></div> |
||||
<script type="module" src="/src/main.ts"></script> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script> |
||||
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> |
||||
</body> |
||||
|
||||
</html> |
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 66 KiB |
@ -0,0 +1,25 @@ |
||||
import request from '@/utils/request' |
||||
// 获取发件箱信息列表
|
||||
export const getSendMessagesListApi = (params) => { |
||||
return request.get('/user-inbox/page/sendmessages', { |
||||
params, |
||||
}) |
||||
} |
||||
// 获取收件箱信息列表
|
||||
export const getMessagesListApi = (params) => { |
||||
return request.get('/user-inbox/page/receivemessages', { |
||||
params, |
||||
}) |
||||
} |
||||
//删除收件箱
|
||||
export const deleteSendMessageApi = (params) => { |
||||
return request.delete('/user-inbox/deletereceivemessage', { |
||||
params, |
||||
}) |
||||
} |
||||
//发送邮件
|
||||
export const SendMessageApi = (params) => { |
||||
return request.post('/messages/addmessage', { |
||||
params, |
||||
}) |
||||
} |
@ -0,0 +1,25 @@ |
||||
import request from '@/utils/request' |
||||
// 获取栏目信息列表
|
||||
export function queryCategory() { |
||||
return request.get(`/api/cms-category/query`); |
||||
} |
||||
//删除栏目
|
||||
export function deleteCategory(ids) { |
||||
return request.delete(`/api/cms-category/delete?ids=${ids}`); |
||||
} |
||||
//添加栏目
|
||||
function parseParams(params){ |
||||
let str = '?' |
||||
try{ |
||||
for (const paramsKey in params) { |
||||
str+=`${paramsKey}=${params[paramsKey]}&` |
||||
} |
||||
return str.slice(0,-1) |
||||
}catch (e) { |
||||
return '' |
||||
} |
||||
} |
||||
export function addCategory(params) { |
||||
const str = parseParams(params) |
||||
return request.post(`/api/cms-category/add${str}`); |
||||
} |
@ -0,0 +1,7 @@ |
||||
import request from '@/utils/request' |
||||
//发送消息
|
||||
export const sendMessagesApi = (params) => { |
||||
return request.post('/messages/addmessage', { |
||||
params, |
||||
}) |
||||
} |
@ -0,0 +1,80 @@ |
||||
<template> |
||||
<div class="common-layout"> |
||||
<el-container> |
||||
<el-header class="header"> |
||||
<p>收到信息详情</p> |
||||
</el-header> |
||||
<el-main > |
||||
<el-card> |
||||
<template #header> |
||||
<div class="card-header"> |
||||
<el-button type="primary" style="width: 80px" @click="back" round plain>返回</el-button> |
||||
</div> |
||||
</template> |
||||
<div class="container"> |
||||
<div class="header_content"> |
||||
<span class="sender">发送人:{{ Message.senderName }}</span> |
||||
<span class="time">发送时间:{{ Message.sendTime }}</span> |
||||
<span class="read-status">是否阅读:{{Message.isRead}}</span> |
||||
</div> |
||||
<div class="recipient">标题:{{ Message.title }}</div> |
||||
<div class="content"> |
||||
内容:{{ Message.content }} |
||||
</div> |
||||
</div> |
||||
<!-- <template #footer>Footer content</template>--> |
||||
</el-card> |
||||
</el-main> |
||||
</el-container> |
||||
</div> |
||||
</template> |
||||
<script setup lang="ts"> |
||||
import {useRouter,useRoute} from "vue-router"; |
||||
const router = useRouter() |
||||
const route = useRoute() |
||||
//获取数据,如果失败返回上一级 |
||||
if(!Object.keys(route.query).length){ |
||||
router.go(-1) |
||||
} |
||||
//返回按钮 |
||||
const back = ()=>{ |
||||
router.push('/messageManagement/message') |
||||
} |
||||
import {ref} from "vue"; |
||||
//获取参数 |
||||
const Message = ref(route.query) |
||||
|
||||
</script> |
||||
|
||||
<style scoped> |
||||
.header{ |
||||
background: #7f98cb; |
||||
height: 50px; |
||||
font-size: 20px; |
||||
text-align: center; |
||||
padding: 15px; |
||||
} |
||||
.container { |
||||
padding: 10px; /* 容器内边距 */ |
||||
margin-top: 10px; /* 容器上边距 */ |
||||
height: 65vh; |
||||
} |
||||
.header_content { |
||||
margin-bottom: 10px; /* 与下面的收件人信息保持一定间距 */ |
||||
} |
||||
|
||||
.header_content span { |
||||
margin-right: 50px; /* 发件人和时间之间的间距 */ |
||||
} |
||||
|
||||
.header_content .read-status { |
||||
margin-right: 0; /* 已读状态右侧不需要间距 */ |
||||
} |
||||
|
||||
.recipient, .content { |
||||
font-size: 20px; |
||||
color: #333; |
||||
margin-top: 10px; |
||||
margin-bottom: 20px; |
||||
} |
||||
</style> |
@ -0,0 +1,196 @@ |
||||
<template> |
||||
<div class="common-layout"> |
||||
<el-container> |
||||
<el-header class="header"> |
||||
<p>写栈内信函</p> |
||||
</el-header> |
||||
<el-main class="mainContainer"> |
||||
<el-card> |
||||
<template #header> |
||||
<div class="card-header"> |
||||
<span>写栈内信函</span> |
||||
<div> |
||||
<el-button style="width: 100px;text-align: center" type="primary" round @click="back" plain>返回</el-button> |
||||
<el-button style="width: 100px;text-align: center" type="primary" round @click="send">发送</el-button> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<!-- 输入框内容--> |
||||
<el-input |
||||
v-model="inputPerson" |
||||
size="large" |
||||
placeholder="收件人:" |
||||
> |
||||
<template #append> |
||||
<el-button @click="addPerson = true"> |
||||
<el-icon><CirclePlus /></el-icon> |
||||
</el-button> |
||||
</template> |
||||
</el-input> |
||||
<el-input |
||||
v-model="inputText" |
||||
size="large" |
||||
placeholder="标题:" |
||||
> |
||||
</el-input> |
||||
<el-input |
||||
v-model="textarea" |
||||
:rows="15" |
||||
type="textarea" |
||||
placeholder="内容:" |
||||
/> |
||||
<!--添加收件人信息--> |
||||
<el-dialog class="dialogType" v-model="addPerson" title="选择收件人"> |
||||
<el-divider/> |
||||
<div class="content-container"> |
||||
<div class="left-panel" style="flex: 1; display: flex; align-items: center; justify-content: center;"> |
||||
<!-- <el-input--> |
||||
<!-- v-model="inputSearch"--> |
||||
<!-- style="max-width: 300px;--> |
||||
<!-- margin-bottom: 20px"--> |
||||
<!-- placeholder="搜索"--> |
||||
<!-- >--> |
||||
<!-- <template #append>--> |
||||
<!-- <el-button :icon="Search" @click="editSearch"/>--> |
||||
<!-- </template>--> |
||||
<!-- </el-input>--> |
||||
<!-- 组织架构--> |
||||
<div> |
||||
组织框架: |
||||
<el-tree-select |
||||
v-model="inputPerson" |
||||
:data="formattedData" |
||||
multiple |
||||
:render-after-expand="false" |
||||
show-checkbox |
||||
style="width: 240px" |
||||
/> |
||||
</div> |
||||
</div> |
||||
<div class="right-panel" style="flex: 1;"> |
||||
<p>已选人:</p> |
||||
<el-divider/> |
||||
<li v-for="item in inputPerson"> |
||||
<p>{{item}}</p> |
||||
</li> |
||||
</div> |
||||
</div> |
||||
<el-divider/> |
||||
<div style="text-align: right"> |
||||
<el-button type="primary" @click="disappoint" plain round>取消</el-button> |
||||
<el-button type="primary" @click="confirm" round>确定</el-button> |
||||
</div> |
||||
</el-dialog> |
||||
<template #footer> |
||||
<p>发送此站内信函即表示您已阅读并接受<el-link href="https://element-plus.org/zh-CN/component/button.html" target="_blank" type="primary">《用户协议》</el-link>,请遵守该协议</p> |
||||
</template> |
||||
</el-card> |
||||
</el-main> |
||||
</el-container> |
||||
</div> |
||||
</template> |
||||
<script setup lang="ts"> |
||||
import { ref} from 'vue' |
||||
// import { Search } from '@element-plus/icons-vue' |
||||
import { useRouter } from 'vue-router'; |
||||
import { userStudentListService } from '@/api/user/user' |
||||
import useUserStore from '@/store/modules/user' |
||||
import { ElMessageBox, ElMessage } from 'element-plus' |
||||
import {SendMessageApi} from "@/api/user/messag"; |
||||
|
||||
const inputPerson = ref([]) |
||||
const inputText = ref('') |
||||
const textarea = ref('') |
||||
// const inputSearch = ref('') |
||||
const addPerson = ref(false) |
||||
const router = useRouter() |
||||
//获取当前用户下的学生姓名 |
||||
const userStore = useUserStore() |
||||
const stuList = ref([]) |
||||
const formattedData = ref([]) |
||||
const getStuList = async () => { |
||||
const res = await userStudentListService(userStore.data.id) |
||||
stuList.value = res.data |
||||
// console.log(stuList.value, 'rrr') |
||||
dataForTree(stuList.value);//格式化数据 |
||||
}; |
||||
//树形化结构学生数据 |
||||
const dataForTree = (data) => { |
||||
// 假设每个学生对象都有name 属性 |
||||
const formatted = data.map(student => ({ |
||||
label: student.name, |
||||
value: student.name, // 如果需要的话,可以设置 value |
||||
// children: [], 只有嵌套数据时才需要 |
||||
})); |
||||
formattedData.value = formatted; |
||||
}; |
||||
getStuList() |
||||
|
||||
//返回 |
||||
const back= ()=>{ |
||||
router.push('/messageManagement/message') |
||||
} |
||||
//发送信息 |
||||
const send = async (id: any) => { |
||||
await ElMessageBox.confirm('您确定发送这条信息吗', '温馨提示', { |
||||
confirmButtonText: '确认', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
}) |
||||
await SendMessageApi({ |
||||
messageIds:id, |
||||
content:textarea, |
||||
userId:userStore.userInfo.id |
||||
}) |
||||
} |
||||
//选择收件人 |
||||
const confirm = ()=>{ |
||||
addPerson.value = false |
||||
} |
||||
//取消 |
||||
const disappoint = ()=>{ |
||||
addPerson.value = false |
||||
} |
||||
</script> |
||||
<style scoped> |
||||
|
||||
.header{ |
||||
background: steelblue; |
||||
text-align: center; |
||||
font-size: 18px; |
||||
line-height: 45px; |
||||
height: 45px; |
||||
width: 100%; |
||||
margin-bottom: 30px; |
||||
} |
||||
.header p{ |
||||
color: gainsboro; |
||||
} |
||||
li{ |
||||
list-style: none; |
||||
} |
||||
.mainContainer{ |
||||
width: 80%; |
||||
margin: auto; |
||||
} |
||||
.card-header{ |
||||
display: flex; /* 启用Flexbox布局 */ |
||||
justify-content: space-between; /* 在主轴上分布项目,这里让h2和button分布在两端 */ |
||||
align-items: center; /* 在交叉轴上居中项目,这里是垂直居中 */ |
||||
height: 30px; /* 示例高度,根据实际需求调整 */ |
||||
padding: 0 20px; /* 添加一些内边距以避免内容紧贴边缘 */ |
||||
} |
||||
.el-input{ |
||||
margin-bottom: 30px; |
||||
} |
||||
.content-container { |
||||
display: flex; |
||||
height: 100%; /* 根据需要调整高度 */ |
||||
} |
||||
.left-panel, .right-panel { |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; /* 垂直居中内容 */ |
||||
align-items: center; /* 水平居中内容 */ |
||||
} |
||||
</style> |
@ -0,0 +1,267 @@ |
||||
<template> |
||||
<el-card> |
||||
<template #header> |
||||
<div class="card-header"> |
||||
<el-button type="primary" @click="back" round plain>返回</el-button> |
||||
<el-button type="primary" @click="sendContent" round>写栈内信函</el-button> |
||||
</div> |
||||
</template> |
||||
<div class="container"> |
||||
<div class="checkboxHeader"> |
||||
<input type="checkbox" class="custom-checkbox" @change="toggleAll" :checked="allSelected" /> |
||||
<p class="selected-count">已选 {{ selectedCount }} 条记录</p> |
||||
</div> |
||||
<li v-for="item in sendMessage" |
||||
:key="item.title" |
||||
class="message-list-item" |
||||
> |
||||
<!--添加悬浮删除按钮--> |
||||
<!-- <div class="message-list" @mouseover="hoveringOver = item.id" @mouseleave="hoveringOver = null">--> |
||||
<div class="message-list"> |
||||
<!-- 添加勾选框 --> |
||||
<div class="message-check"> |
||||
<input type="checkbox" class="custom-checkbox" :value="item.id" @change="toggleSelection(item.id)" :checked="isSelected(item.id)"/> |
||||
</div> |
||||
<div class="message-icon"> |
||||
<el-icon><Comment /></el-icon> |
||||
</div> |
||||
<div class="message-content" @click="handleClick(item)"> |
||||
<h2 class="message-title">{{item.title}}</h2> |
||||
<div class="message-details"> |
||||
<span class="sender">收件人:{{item.receiverName}}</span> |
||||
<span class="read-status">阅读人数:{{item.readUserNum}}</span> |
||||
</div> |
||||
<div class="message-time">{{item.sendTime}}</div> |
||||
</div> |
||||
<!-- 删除按钮,默认不显示,hover时显示 --> |
||||
<!-- <el-button v-if="hoveringOver === item.id" class="delete-btn" @click="deleteSendMessage(item.id)" type="danger" round >删除</el-button>--> |
||||
</div> |
||||
<el-divider/> |
||||
</li> |
||||
</div> |
||||
<template #footer> |
||||
<!-- 分页--> |
||||
<el-pagination |
||||
v-model:current-page="params.pageNo" |
||||
v-model:page-size="params.pageSize" |
||||
:page-sizes="[2,3, 5, 7, 10]" |
||||
:background="true" |
||||
layout="jumper,total, sizes, prev, pager, next " |
||||
:total="total" |
||||
@size-change="handleSizeChange" |
||||
@current-change="handleCurrentChange" |
||||
style="margin-top: 10px; justify-content: center" |
||||
/> |
||||
</template> |
||||
</el-card> |
||||
</template> |
||||
<script setup lang="ts"> |
||||
import { ref,computed,onMounted} from 'vue'; |
||||
import { useRouter } from 'vue-router'; |
||||
import useUserStore from "@/store/modules/user"; |
||||
import {getSendMessagesListApi,deleteSendMessageApi} from "@/api/user/messag"; |
||||
import { ElMessageBox, ElMessage } from 'element-plus' |
||||
const userStore = useUserStore() |
||||
//传参 |
||||
const params = ref({ |
||||
userId: userStore.userInfo.id, |
||||
// userId: 4, |
||||
isAsc:true, |
||||
isDelete:0, |
||||
isRead:'', |
||||
isSend:1, |
||||
// messageId:false, |
||||
pageNo:1, |
||||
pageSize:3, |
||||
sortBy:false,//排序字段 |
||||
}) |
||||
const total = ref(0) |
||||
const sendMessage = ref([]) |
||||
const loading = ref(false) |
||||
// const hoveringOver = ref(null) |
||||
//复选框 |
||||
const selectedIds = ref([]); // 存储已选中的消息ID |
||||
const allSelected = computed(() => { |
||||
// 如果所有消息都被选中,则返回true |
||||
return sendMessage.value.length > 0 && sendMessage.value.every(item => selectedIds.value.includes(item.id)); |
||||
}); |
||||
|
||||
const selectedCount = computed(() => { |
||||
// 返回已选中的消息数量 |
||||
return selectedIds.value.length; |
||||
}); |
||||
|
||||
function toggleAll(event) { |
||||
// 切换所有消息的选中状态 |
||||
const target = event.target; |
||||
if (target.checked) { |
||||
// 如果全选框被选中,则将所有消息的ID添加到selectedIds中 |
||||
selectedIds.value = sendMessage.value.map(item => item.id); |
||||
} else { |
||||
// 如果全选框未被选中,则清空selectedIds |
||||
selectedIds.value = []; |
||||
} |
||||
} |
||||
|
||||
function toggleSelection(id: number) { |
||||
// 切换单个消息的选中状态 |
||||
const index = selectedIds.value.indexOf(id); |
||||
if (index > -1) { |
||||
selectedIds.value.splice(index, 1); |
||||
} else { |
||||
selectedIds.value.push(id); |
||||
} |
||||
} |
||||
function isSelected(id) { |
||||
return selectedIds.value.includes(id); |
||||
} |
||||
// 获取课程列表 |
||||
const getSendMessageList = async () => { |
||||
loading.value = true |
||||
const res = await getSendMessagesListApi(params.value) |
||||
sendMessage.value = res.data.list |
||||
total.value = res.data.total |
||||
loading.value = false |
||||
} |
||||
// 渲染 |
||||
onMounted(() => { |
||||
getSendMessageList() |
||||
}) |
||||
//删除当前记录 |
||||
// const deleteSendMessage = async (id: any) => { |
||||
// await ElMessageBox.confirm('您确定删除这条课程信息吗', '温馨提示', { |
||||
// confirmButtonText: '确认', |
||||
// cancelButtonText: '取消', |
||||
// type: 'warning', |
||||
// }) |
||||
// await deleteSendMessageApi({ |
||||
// messageIds:id, |
||||
// userId:userStore.userInfo.id |
||||
// }) |
||||
// .then(() => { |
||||
// console.log(id, '删除id') |
||||
// getSendMessageList() // 删除成功后重新获取列表数据以更新页面 |
||||
// ElMessage.success('删除成功') |
||||
// // console.log(res) |
||||
// }) |
||||
// .catch((err: any) => { |
||||
// console.log(id, 'id') |
||||
// ElMessage.error(err.response.data.message) |
||||
// }) |
||||
// |
||||
// await getSendMessageList() |
||||
// } |
||||
|
||||
// 分页 |
||||
const handleSizeChange = (size: any) => { |
||||
// loading.value = true |
||||
// console.log(size) |
||||
params.value.pageNo = 1 |
||||
params.value.pageSize = size |
||||
// 基于每页条数重新渲染 |
||||
getSendMessageList() |
||||
} |
||||
const handleCurrentChange = (page: any) => { |
||||
console.log(page) |
||||
params.value.pageNo = page |
||||
// 基于当前页渲染数据 |
||||
getSendMessageList() |
||||
} |
||||
const userId = userStore.userInfo.id |
||||
const router = useRouter() |
||||
//返回 |
||||
const back =()=>{ |
||||
router.push('/messageManagement/message') |
||||
} |
||||
//写栈内信函 |
||||
const sendContent = ()=>{ |
||||
router.push('/messageContent') |
||||
} |
||||
|
||||
// 消息事件点击 |
||||
const handleClick = (item)=> { |
||||
//带查询参数 |
||||
router.push({ path: '/sendMessageList', query: item }) |
||||
} |
||||
|
||||
</script> |
||||
<style scoped> |
||||
.container{ |
||||
margin: auto; |
||||
width: 95%; |
||||
padding: 15px; |
||||
} |
||||
.checkboxHeader { |
||||
width: 100%; |
||||
padding: 10px; |
||||
height: 50px; |
||||
display: flex; /* 使用Flex布局使子元素在同一行显示 */ |
||||
align-items: center; /* 垂直居中对齐子元素 */ |
||||
gap: 10px; /* 设置子元素之间的间距 */ |
||||
} |
||||
|
||||
.custom-checkbox { |
||||
transform: scale(1.5); /* 将勾选框放大1.5倍 */ |
||||
} |
||||
|
||||
.selected-count { |
||||
|
||||
} |
||||
.message-check{ |
||||
margin-right: 20px; |
||||
} |
||||
.message-list { |
||||
display: flex; |
||||
align-items: center; /* 垂直居中 */ |
||||
height: 80px; |
||||
/*background-color: #f2f2f2;*/ |
||||
padding: 0 10px; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
.message-icon { |
||||
margin-right: 30px; /* 图标右侧间距 */ |
||||
font-size: 34px; /* 图标大小 */ |
||||
} |
||||
li{ |
||||
list-style: none; |
||||
} |
||||
.message-content { |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; /* 标题和详情内容垂直居中 */ |
||||
flex: 1; /* 填充剩余空间 */ |
||||
} |
||||
|
||||
.message-title { |
||||
line-height: 30px; |
||||
font-size: 20px; |
||||
} |
||||
|
||||
.message-details { |
||||
display: flex; |
||||
align-items: center; /* 细节内容水平居中 */ |
||||
margin-top: 10px; /* 与标题的间距 */ |
||||
} |
||||
|
||||
.sender { |
||||
margin-right: 88px; /* 发件人和已读状态的间距 */ |
||||
} |
||||
|
||||
.read-status { |
||||
color: #888; /* 已读状态的颜色 */ |
||||
} |
||||
|
||||
.message-time { |
||||
margin-left: auto; /* 发送时间靠右显示 */ |
||||
font-size: 15px; /* 发送时间字体大小 */ |
||||
color: #666; /* 发送时间颜色 */ |
||||
} |
||||
|
||||
.message-list-item { |
||||
cursor: pointer; /* 鼠标悬停时显示手指形状,表示可点击 */ |
||||
} |
||||
.message-list-item:hover{ |
||||
background-image: linear-gradient(60deg,powderblue,darkgrey,snow); |
||||
} |
||||
</style> |
@ -0,0 +1,80 @@ |
||||
<template> |
||||
<div class="common-layout"> |
||||
<el-container> |
||||
<el-header class="header"> |
||||
<p>收到信息详情</p> |
||||
</el-header> |
||||
<el-main > |
||||
<el-card> |
||||
<template #header> |
||||
<div class="card-header"> |
||||
<el-button type="primary" style="width: 80px" @click="back" round plain>返回</el-button> |
||||
</div> |
||||
</template> |
||||
<div class="container"> |
||||
<div class="header_content"> |
||||
<span class="sender">收件人:{{ sendMessage.receiverName }}</span> |
||||
<span class="time">发送时间:{{ sendMessage.sendTime }}</span> |
||||
<span class="read-status">是否阅读:{{sendMessage.isRead}}</span> |
||||
</div> |
||||
<div class="recipient">标题:{{ sendMessage.title }}</div> |
||||
<div class="content"> |
||||
内容:{{ sendMessage.content }} |
||||
</div> |
||||
</div> |
||||
<!-- <template #footer>Footer content</template>--> |
||||
</el-card> |
||||
</el-main> |
||||
</el-container> |
||||
</div> |
||||
</template> |
||||
<script setup lang="ts"> |
||||
import {useRouter,useRoute} from "vue-router"; |
||||
const router = useRouter() |
||||
const route = useRoute() |
||||
//获取数据,如果失败返回上一级 |
||||
if(!Object.keys(route.query).length){ |
||||
router.go(-1) |
||||
} |
||||
//返回按钮 |
||||
const back = ()=>{ |
||||
router.push('/messageManagement/sendMessage') |
||||
} |
||||
import {ref} from "vue"; |
||||
//获取参数 |
||||
const sendMessage = ref(route.query) |
||||
|
||||
</script> |
||||
|
||||
<style scoped> |
||||
.header{ |
||||
background: #7f98cb; |
||||
height: 50px; |
||||
font-size: 20px; |
||||
text-align: center; |
||||
padding: 15px; |
||||
} |
||||
.container { |
||||
padding: 10px; /* 容器内边距 */ |
||||
margin-top: 10px; /* 容器上边距 */ |
||||
height: 65vh; |
||||
} |
||||
.header_content { |
||||
margin-bottom: 10px; /* 与下面的收件人信息保持一定间距 */ |
||||
} |
||||
|
||||
.header_content span { |
||||
margin-right: 50px; /* 发件人和时间之间的间距 */ |
||||
} |
||||
|
||||
.header_content .read-status { |
||||
margin-right: 0; /* 已读状态右侧不需要间距 */ |
||||
} |
||||
|
||||
.recipient, .content { |
||||
font-size: 20px; |
||||
color: #333; |
||||
margin-top: 10px; |
||||
margin-bottom: 20px; |
||||
} |
||||
</style> |
@ -1,5 +1,269 @@ |
||||
<template> |
||||
<div>消息</div> |
||||
<el-card> |
||||
<template #header> |
||||
<div class="card-header"> |
||||
<el-button type="primary" @click="editContent" round>写栈内信函</el-button> |
||||
<el-button type="primary" @click="sendContent" round>个人发出</el-button> |
||||
</div> |
||||
</template> |
||||
<div class="container"> |
||||
<div class="checkboxHeader"> |
||||
<input type="checkbox" class="custom-checkbox" @change="toggleAll" :checked="allSelected" /> |
||||
<p class="selected-count">已选 {{ selectedCount }} 条记录</p> |
||||
</div> |
||||
<li v-for="item in Message" |
||||
:key="item.title" |
||||
class="message-list-item" |
||||
> |
||||
<!--添加悬浮删除按钮--> |
||||
<div class="message-list" @mouseover="hoveringOver = item.id" @mouseleave="hoveringOver = null"> |
||||
<!-- 添加勾选框 --> |
||||
<div class="messageCheck"> |
||||
<input type="checkbox" class="custom-checkbox" :value="item.id" @change="toggleSelection(item.id)" :checked="isSelected(item.id)"/> |
||||
</div> |
||||
<!-- 图标 --> |
||||
<div class="message-icon"> |
||||
<el-icon><Comment /></el-icon> |
||||
</div> |
||||
<div class="message-content" @click="handleClick(item)"> |
||||
<h2 class="message-title">{{item.title}}</h2> |
||||
<div class="message-details"> |
||||
<span class="sender">发件人:{{item.sendPerson}}</span> |
||||
<span class="read-status">已读状态:{{item.isRead}}</span> |
||||
</div> |
||||
<div class="message-time">发送时间:{{item.sendTime}}</div> |
||||
</div> |
||||
<!-- 删除按钮,默认不显示,hover时显示 --> |
||||
<el-button v-if="hoveringOver === item.id" class="delete-btn" @click="deleteMessage(item.id)" type="danger" round>删除</el-button> |
||||
</div> |
||||
<el-divider/> |
||||
</li> |
||||
</div> |
||||
<template #footer> |
||||
<el-pagination |
||||
v-model:current-page="params.pageNo" |
||||
v-model:page-size="params.pageSize" |
||||
:page-sizes="[2,4, 5, 7, 10]" |
||||
:background="true" |
||||
layout="jumper,total, sizes, prev, pager, next " |
||||
:total="total" |
||||
@size-change="handleSizeChange" |
||||
@current-change="handleCurrentChange" |
||||
style="margin-top: 10px; justify-content: center" |
||||
/> |
||||
</template> |
||||
</el-card> |
||||
</template> |
||||
<script setup lang="ts"> |
||||
import { ref,computed,onMounted} from 'vue'; |
||||
import { useRouter } from 'vue-router'; |
||||
import useUserStore from "@/store/modules/user"; |
||||
import {getMessagesListApi,deleteSendMessageApi} from "@/api/user/messag"; |
||||
import { ElMessageBox, ElMessage } from 'element-plus' |
||||
const userStore = useUserStore() |
||||
const params = ref({ |
||||
userId: userStore.userInfo.id, |
||||
// userId: 4, |
||||
isAsc:true, |
||||
isDelete:0, |
||||
isRead:'', |
||||
isSend:1, |
||||
// messageId:false, |
||||
pageNo:1, |
||||
pageSize:4, |
||||
sortBy:false,//排序字段 |
||||
}) |
||||
const total = ref(0) |
||||
const Message = ref([]) |
||||
const loading = ref(false) |
||||
const hoveringOver = ref(null) |
||||
//复选框 |
||||
const selectedIds = ref([]); // 存储已选中的消息ID |
||||
const allSelected = computed(() => { |
||||
// 如果所有消息都被选中,则返回true |
||||
return Message.value.length > 0 && Message.value.every(item => selectedIds.value.includes(item.id)); |
||||
}); |
||||
|
||||
<script></script> |
||||
const selectedCount = computed(() => { |
||||
// 返回已选中的消息数量 |
||||
return selectedIds.value.length; |
||||
}); |
||||
|
||||
function toggleAll(event) { |
||||
// 切换所有消息的选中状态 |
||||
const target = event.target; |
||||
if (target.checked) { |
||||
// 如果全选框被选中,则将所有消息的ID添加到selectedIds中 |
||||
selectedIds.value = Message.value.map(item => item.id); |
||||
} else { |
||||
// 如果全选框未被选中,则清空selectedIds |
||||
selectedIds.value = []; |
||||
} |
||||
} |
||||
|
||||
function toggleSelection(id: number) { |
||||
// 切换单个消息的选中状态 |
||||
const index = selectedIds.value.indexOf(id); |
||||
if (index > -1) { |
||||
selectedIds.value.splice(index, 1); |
||||
} else { |
||||
selectedIds.value.push(id); |
||||
} |
||||
} |
||||
|
||||
function isSelected(id) { |
||||
return selectedIds.value.includes(id); |
||||
} |
||||
|
||||
// 获取课程列表 |
||||
const getMessageList = async () => { |
||||
loading.value = true |
||||
const res = await getMessagesListApi(params.value) |
||||
Message.value = res.data.list |
||||
total.value = res.data.total |
||||
loading.value = false |
||||
} |
||||
// 渲染 |
||||
onMounted(() => { |
||||
getMessageList() |
||||
}) |
||||
//删除当前记录 |
||||
const deleteMessage = async (id: any) => { |
||||
await ElMessageBox.confirm('您确定删除这条课程信息吗', '温馨提示', { |
||||
confirmButtonText: '确认', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
}) |
||||
await deleteSendMessageApi({ |
||||
messageIds:id, |
||||
userId:userStore.userInfo.id |
||||
}) |
||||
.then(() => { |
||||
console.log(id, '删除id') |
||||
getMessageList() // 删除成功后重新获取列表数据以更新页面 |
||||
ElMessage.success('删除成功') |
||||
// console.log(res) |
||||
}) |
||||
.catch((err: any) => { |
||||
console.log(id, 'id') |
||||
ElMessage.error(err.response.data.message) |
||||
}) |
||||
|
||||
await getMessageList() |
||||
} |
||||
// 分页 |
||||
const handleSizeChange = (size: any) => { |
||||
// loading.value = true |
||||
// console.log(size) |
||||
params.value.pageNo = 1 |
||||
params.value.pageSize = size |
||||
// 基于每页条数重新渲染 |
||||
getMessageList() |
||||
} |
||||
const handleCurrentChange = (page: any) => { |
||||
console.log(page) |
||||
params.value.pageNo = page |
||||
// 基于当前页渲染数据 |
||||
getMessageList() |
||||
} |
||||
const router = useRouter() |
||||
//写站内信函跳转 |
||||
const editContent =()=>{ |
||||
router.push('/messageContent') |
||||
} |
||||
//个人发出跳转 |
||||
const sendContent = ()=>{ |
||||
router.push('/messageManagement/sendMessage') |
||||
} |
||||
|
||||
// 消息事件点击 |
||||
const handleClick = (item)=> { |
||||
// console.log(item) |
||||
//带查询参数 |
||||
router.push({ path: '/messageContentList', query: item }) |
||||
} |
||||
|
||||
</script> |
||||
<style scoped> |
||||
.container{ |
||||
/*background: darkgray;*/ |
||||
margin: auto; |
||||
width: 95%; |
||||
padding: 15px; |
||||
} |
||||
.checkboxHeader { |
||||
/*background: lightgrey;*/ |
||||
width: 100%; |
||||
padding: 10px; |
||||
height: 50px; |
||||
display: flex; /* 使用Flex布局使子元素在同一行显示 */ |
||||
align-items: center; /* 垂直居中对齐子元素 */ |
||||
gap: 10px; /* 设置子元素之间的间距 */ |
||||
} |
||||
|
||||
.custom-checkbox { |
||||
transform: scale(1.5); /* 将勾选框放大1.5倍 */ |
||||
} |
||||
|
||||
.selected-count { |
||||
|
||||
} |
||||
.messageCheck{ |
||||
margin-right: 20px; |
||||
} |
||||
.message-list { |
||||
display: flex; |
||||
align-items: center; /* 垂直居中 */ |
||||
height: 80px; |
||||
/*background-color: #f2f2f2;*/ |
||||
padding: 0 10px; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
.message-icon { |
||||
margin-right: 30px; /* 图标右侧间距 */ |
||||
font-size: 34px; /* 图标大小 */ |
||||
} |
||||
li{ |
||||
list-style: none; |
||||
} |
||||
.message-content { |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; /* 标题和详情内容垂直居中 */ |
||||
flex: 1; /* 填充剩余空间 */ |
||||
} |
||||
|
||||
.message-title { |
||||
line-height: 30px; |
||||
font-size: 20px; |
||||
} |
||||
|
||||
.message-details { |
||||
display: flex; |
||||
align-items: center; /* 细节内容水平居中 */ |
||||
margin-top: 10px; /* 与标题的间距 */ |
||||
} |
||||
|
||||
.sender { |
||||
margin-right: 88px; /* 发件人和已读状态的间距 */ |
||||
} |
||||
|
||||
.read-status { |
||||
color: #888; /* 已读状态的颜色 */ |
||||
} |
||||
|
||||
.message-time { |
||||
margin-left: auto; /* 发送时间靠右显示 */ |
||||
font-size: 15px; /* 发送时间字体大小 */ |
||||
color: #666; /* 发送时间颜色 */ |
||||
} |
||||
|
||||
.message-list-item { |
||||
cursor: pointer; /* 鼠标悬停时显示手指形状,表示可点击 */ |
||||
} |
||||
|
||||
.message-list-item:hover{ |
||||
background-image: linear-gradient(60deg,powderblue,darkgrey,snow); |
||||
} |
||||
</style> |
||||
|
@ -0,0 +1,11 @@ |
||||
<template> |
||||
|
||||
</template> |
||||
|
||||
<script> |
||||
|
||||
</script> |
||||
|
||||
<style scoped> |
||||
|
||||
</style> |
@ -0,0 +1,236 @@ |
||||
<template> |
||||
<div class="header_title"> |
||||
<span>资讯</span> |
||||
</div> |
||||
<div> |
||||
<el-card shadow="always"> |
||||
<div class="header-flex-container"> |
||||
<ul class="header-list"> |
||||
<li v-for="item in column"> |
||||
<el-dropdown placement="bottom"> |
||||
<span>{{ item.categoryName }}</span> <!-- 使用span代替p --> |
||||
<template #dropdown> |
||||
<el-dropdown-menu> |
||||
<el-dropdown-item> |
||||
<router-link to="/newsDetails">{{ item.createTime }}</router-link> |
||||
</el-dropdown-item> |
||||
</el-dropdown-menu> |
||||
</template> |
||||
</el-dropdown> |
||||
</li> |
||||
</ul> |
||||
<div> |
||||
<el-link href="https://element-plus.org" target="_blank" style="margin-right: 30px;font-size: 19px">关于我们</el-link> |
||||
<el-button name="editColumnButton" @click="editHandle" round>栏目编辑</el-button> |
||||
</div> |
||||
</div> |
||||
</el-card> |
||||
</div> |
||||
<!-- 栏目编辑弹框--> |
||||
<el-drawer v-model="drawer" title="title" :with-header="false"> |
||||
<span>栏目编辑</span><br/> |
||||
<el-button type="success" round style="margin: 10px" @click="addFormVisible = true">添加</el-button> |
||||
<div> |
||||
<el-table :data="column" style="width: 100%"> |
||||
<el-table-column prop="categoryName" label="名称" width="200" /> |
||||
<el-table-column width="200" > |
||||
<template #header> |
||||
操作 |
||||
</template> |
||||
<template #default="{row}"> |
||||
<!-- 在这里定义你的删除按钮 --> |
||||
<el-button size="default" type="danger" @click="deleteHandle(row.id)">删除</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
</el-drawer> |
||||
<!-- 栏目添加对话框--> |
||||
<el-dialog v-model="addFormVisible" title="栏目添加" width="500"> |
||||
<el-form :model="form"> |
||||
<el-form-item label="栏目名称" label-width="140px"> |
||||
<el-input v-model="form.categoryName" autocomplete="off" /> |
||||
</el-form-item> |
||||
<el-form-item label="栏目父id" label-width="140px"> |
||||
<el-input v-model="form.categoryPid" autocomplete="off" /> |
||||
</el-form-item> |
||||
<el-form-item label="创建时间" label-width="140px"> |
||||
<el-input v-model="form.createTime" autocomplete="off" type="date"/> |
||||
</el-form-item> |
||||
<el-form-item label="创建盖栏目的用户id" label-width="140px"> |
||||
<el-input v-model="form.creatorId" autocomplete="off" /> |
||||
</el-form-item> |
||||
<el-form-item label="栏目id" label-width="140px"> |
||||
<el-input v-model="form.id" autocomplete="off" /> |
||||
</el-form-item> |
||||
<el-form-item label="排序" label-width="140px"> |
||||
<el-input v-model="form.sort" autocomplete="off" /> |
||||
</el-form-item> |
||||
<el-form-item label="是否显示" label-width="140px"> |
||||
<el-input v-model="form.status" autocomplete="off" /> |
||||
</el-form-item> |
||||
<el-form-item label="更新时间" label-width="140px"> |
||||
<el-input v-model="form.updateTime" autocomplete="off" type="date"/> |
||||
</el-form-item> |
||||
</el-form> |
||||
<template #footer> |
||||
<div class="dialog-footer"> |
||||
<el-button @click="addFormVisible = false">取消</el-button> |
||||
<el-button type="primary" @click="addFormConfirm"> |
||||
确定 |
||||
</el-button> |
||||
</div> |
||||
</template> |
||||
</el-dialog> |
||||
<!-- 新闻内容--> |
||||
<el-card class="container"> |
||||
<template #header> |
||||
<div class="card-header"> |
||||
<span class="contentTitle">Content Title</span> |
||||
<el-card shadow="hover"> |
||||
<div class="flex-container"> |
||||
<p>发布人:{{ }}</p> |
||||
<p>信息来源:{{ }}</p> |
||||
<p>日期:{{ }}</p> |
||||
</div> |
||||
</el-card> |
||||
</div> |
||||
</template> |
||||
<div style="text-align: center"> |
||||
<router-view></router-view> |
||||
</div> |
||||
<template #footer> |
||||
|
||||
</template> |
||||
</el-card> |
||||
</template> |
||||
|
||||
<script setup lang="ts"> |
||||
import {queryCategory,deleteCategory,addCategory} from "@/api/user/news.js" |
||||
import {ref,onMounted} from 'vue'; |
||||
import { ElMessageBox, ElMessage } from 'element-plus' |
||||
const drawer = ref(false) |
||||
const addFormVisible = ref(false) |
||||
const column =ref([]) |
||||
const form = ref( |
||||
{ |
||||
categoryName:'', |
||||
categoryPid:'', |
||||
createTime:'', |
||||
creatorId:'', |
||||
id:'', |
||||
sort:'', |
||||
status:'', |
||||
updateTime:'' |
||||
} |
||||
) |
||||
const params = ref({ |
||||
categoryName:form.value.categoryName, |
||||
createTime:form.value.createTime, |
||||
id:form.value.id |
||||
}) |
||||
//获取栏目信息 |
||||
const CategoryList = async () => { |
||||
const res = await queryCategory() |
||||
column.value = res.data |
||||
} |
||||
// 渲染 |
||||
onMounted(() => { |
||||
CategoryList() |
||||
}) |
||||
//编辑按钮 |
||||
const editHandle =() =>{ |
||||
drawer.value = true |
||||
} |
||||
//栏目添加 |
||||
const addFormConfirm = async ()=>{ |
||||
addFormVisible.value = false |
||||
await addCategory({ |
||||
categoryName:form.value.categoryName, |
||||
categoryPid:form.value.categoryPid, |
||||
createTime:form.value.createTime, |
||||
creatorId:form.value.creatorId, |
||||
id:form.value.id, |
||||
sort:form.value.sort, |
||||
status:form.value.status, |
||||
updateTime:form.value.updateTime |
||||
}) |
||||
} |
||||
//栏目删除 |
||||
const deleteHandle = async (row)=>{ |
||||
console.log(row,'row.id') |
||||
await ElMessageBox.confirm('您确定删除这条栏目信息吗', '温馨提示', { |
||||
confirmButtonText: '确认', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
}) |
||||
await deleteCategory(row.id).then(() => { |
||||
CategoryList() // 删除成功后重新获取列表数据以更新页面 |
||||
ElMessage({ |
||||
message: '删除成功', |
||||
type: 'success', |
||||
}) |
||||
}) |
||||
await CategoryList() |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.container{ |
||||
height: 65vh; |
||||
} |
||||
.header_title{ |
||||
font-size: 30px; |
||||
text-align: center; |
||||
padding: 20px; |
||||
margin: auto; |
||||
background-image: linear-gradient(60deg,honeydew,powderblue,honeydew); |
||||
} |
||||
.header-flex-container { |
||||
display: flex; |
||||
align-items: center; /* 垂直居中 */ |
||||
padding: 20px; |
||||
background: #4b81d7; |
||||
justify-content: space-between; /* 左边对齐和右边对齐 */ |
||||
} |
||||
.header-list { |
||||
display: flex; /* 使li元素水平排列 */ |
||||
flex-wrap: wrap; /* 如果需要换行 */ |
||||
align-items: center; /* 如果需要,也可以使li元素垂直居中 */ |
||||
margin: 0; /* 移除默认外边距 */ |
||||
padding: 0; /* 移除默认内边距 */ |
||||
} |
||||
.header-list span{ |
||||
font-size: 17px; |
||||
color: whitesmoke; |
||||
} |
||||
.header-list li { |
||||
list-style: none; |
||||
margin-right: 10px; |
||||
} |
||||
.el-dropdown { |
||||
margin-right: 30px; |
||||
} |
||||
.contentTitle{ |
||||
color: red; |
||||
font-size: 30px; |
||||
text-align: center; |
||||
display: block; |
||||
width: 100%; /* 或者设置一个具体的宽度 */ |
||||
line-height: 40px; |
||||
margin-bottom: 20px; |
||||
} |
||||
.flex-container { |
||||
display: flex; |
||||
justify-content: center; /* 水平居中 */ |
||||
align-items: center; /* 垂直居中*/ |
||||
flex-direction: row; /* 默认就是 row, */ |
||||
} |
||||
.flex-container p { |
||||
margin-right: 100px; |
||||
} |
||||
.flex-container p:last-child { |
||||
margin-right: 0; |
||||
} |
||||
|
||||
</style> |
@ -0,0 +1,14 @@ |
||||
<template> |
||||
<div> |
||||
<router-view></router-view> |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang='ts' setup> |
||||
// import { onMounted, reactive, ref, toRefs, watch } from 'vue' |
||||
|
||||
</script> |
||||
|
||||
<style lang='scss' scoped> |
||||
|
||||
</style> |
@ -0,0 +1,210 @@ |
||||
<script setup> |
||||
import { ref } from 'vue' |
||||
import { stuListService, updateStuService } from '@/api/user/stud' |
||||
import { tool, client } from '@/utils/alioss.js' |
||||
import { ElMessage } from 'element-plus' |
||||
const drawer = ref(false) |
||||
const formLabelWidth = '80px' |
||||
const emit = defineEmits(['success']) |
||||
const imgUrl = ref() |
||||
const formModel = ref({ |
||||
icon: '', |
||||
number: '', |
||||
name: '', |
||||
sex: '', |
||||
nickName: '', |
||||
username: '', |
||||
major: '', |
||||
yearAge: '', |
||||
createTime: '', |
||||
}) |
||||
|
||||
formModel.value.sex === '男' ? 0 : 1 |
||||
const open = async (row) => { |
||||
drawer.value = true |
||||
await stuListService(row.id).then((res) => { |
||||
formModel.value = res.data |
||||
imgUrl.value = formModel.value.icon |
||||
// console.log(formModel.value.icon, 'defauleForm.value') |
||||
}) |
||||
} |
||||
const beforeUpload = (file) => { |
||||
const validImageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp'] |
||||
if (!validImageTypes.includes(file.type)) { |
||||
ElMessage.error('请上传图片') |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
const upload = async (option) => { |
||||
const res = await tool.oss.upload(option.file) |
||||
// console.log(res, 'res') |
||||
formModel.value.icon = res.url |
||||
imgUrl.value = formModel.value.icon |
||||
} |
||||
const formRef = ref(null) |
||||
|
||||
//校验 |
||||
const rules = { |
||||
number: [ |
||||
{ required: true, message: '请输入学号', trigger: 'blur' }, |
||||
{ min: 2, max: 20, message: '长度在2-20之间', trigger: 'blur' }, |
||||
], |
||||
name: [ |
||||
{ required: true, message: '请输入姓名', trigger: 'blur' }, |
||||
{ min: 2, max: 5, message: '长度在2-5之间', trigger: 'blur' }, |
||||
], |
||||
sex: [ |
||||
{ |
||||
required: true, |
||||
message: '请选择性别', |
||||
trigger: 'change', |
||||
}, |
||||
], |
||||
nickName: [ |
||||
{ |
||||
message: '请输入昵称', |
||||
trigger: 'blur', |
||||
}, |
||||
], |
||||
username: [{ required: true }], |
||||
createTime: [{ required: true }], |
||||
major: [ |
||||
{ required: true, message: '专业不能为空', trigger: 'blur' }, |
||||
{ |
||||
min: 2, |
||||
max: 20, |
||||
message: '职位名称至少2个字符最多20个字符', |
||||
trigger: 'blur', |
||||
}, |
||||
], |
||||
yearAge: [ |
||||
{ |
||||
required: true, |
||||
trigger: 'change', |
||||
message: '请选择入学年份', |
||||
}, |
||||
], |
||||
} |
||||
|
||||
//提交 |
||||
const onSubmit = async () => { |
||||
await formRef.value.validate() |
||||
console.log(formModel.value, 'form') |
||||
await await updateStuService({ |
||||
id: formModel.value.id, |
||||
userId: formModel.value.userId, |
||||
icon: formModel.value.icon, |
||||
number: formModel.value.number, |
||||
name: formModel.value.name, |
||||
sex: formModel.value.sex, |
||||
nickName: formModel.value.nickName, |
||||
major: formModel.value.major, |
||||
}).then(() => { |
||||
ElMessage.success('修改成功') |
||||
drawer.value = false |
||||
|
||||
emit('success', 'edit') |
||||
}) |
||||
} |
||||
const onCancel = () => { |
||||
drawer.value = false |
||||
} |
||||
defineExpose({ |
||||
open, |
||||
}) |
||||
</script> |
||||
<template> |
||||
<el-drawer v-model="drawer" title="编辑信息" style=""> |
||||
<el-form |
||||
:model="formModel" |
||||
:rules="rules" |
||||
ref="formRef" |
||||
:label-width="formLabelWidth" |
||||
> |
||||
<el-form-item label="头像" prop="icon"> |
||||
<el-upload |
||||
v-model="formModel.icon" |
||||
class="avatar-uploader" |
||||
:http-request="upload" |
||||
:show-file-list="false" |
||||
:before-upload="beforeUpload" |
||||
> |
||||
<img v-if="imgUrl" :src="imgUrl" class="avatar" /> |
||||
<!-- <img v-if="imageUrl" :src="imageUrl" class="avatar" /> --> |
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon> |
||||
<template #tip> |
||||
<div class="el-upload__tip">图片文件要为jpg/png格式,小于500kb</div> |
||||
</template> |
||||
</el-upload> |
||||
</el-form-item> |
||||
<el-form-item label="学号" prop="number"> |
||||
<el-input v-model="formModel.number" placeholder="请输入学号" /> |
||||
</el-form-item> |
||||
<el-form-item label="姓名" prop="name"> |
||||
<el-input v-model="formModel.name" placeholder="请输入姓名" /> |
||||
</el-form-item> |
||||
<el-form-item label="性别" prop="sex"> |
||||
<el-radio-group v-model="formModel.sex"> |
||||
<el-radio value="男">男</el-radio> |
||||
<el-radio value="女">女</el-radio> |
||||
</el-radio-group> |
||||
</el-form-item> |
||||
<el-form-item label="用户名" prop="userName"> |
||||
<el-input v-model="formModel.username" readonly /> |
||||
</el-form-item> |
||||
<el-form-item label="昵称" prop="nickName"> |
||||
<el-input v-model="formModel.nickName" placeholder="请输入昵称" /> |
||||
</el-form-item> |
||||
|
||||
<el-form-item label="专业" prop="major"> |
||||
<el-input v-model="formModel.major" placeholder="请输入专业" /> |
||||
</el-form-item> |
||||
<el-form-item label="创建时间" prop="createTime"> |
||||
<el-input v-model="formModel.createTime" readonly /> |
||||
</el-form-item> |
||||
</el-form> |
||||
<div class="footer"> |
||||
<el-button @click="onCancel">取消</el-button> |
||||
<el-button type="primary" @click="onSubmit">确认</el-button> |
||||
</div> |
||||
</el-drawer> |
||||
</template> |
||||
<style scoped lang="scss"> |
||||
.avatar-uploader { |
||||
:deep() { |
||||
.avatar { |
||||
width: 178px; |
||||
height: 178px; |
||||
display: block; |
||||
} |
||||
|
||||
.el-upload { |
||||
border: 1px dashed var(--el-border-color); |
||||
border-radius: 6px; |
||||
cursor: pointer; |
||||
position: relative; |
||||
overflow: hidden; |
||||
transition: var(--el-transition-duration-fast); |
||||
} |
||||
|
||||
.el-upload:hover { |
||||
border-color: var(--el-color-primary); |
||||
} |
||||
|
||||
.el-icon.avatar-uploader-icon { |
||||
font-size: 28px; |
||||
color: #8c939d; |
||||
width: 178px; |
||||
height: 178px; |
||||
text-align: center; |
||||
} |
||||
} |
||||
} |
||||
.footer { |
||||
display: flex; |
||||
justify-content: end; |
||||
align-items: center; |
||||
margin-top: 100px; |
||||
} |
||||
</style> |
@ -0,0 +1,40 @@ |
||||
// vite.config.ts
|
||||
import vue from "file:///C:/project/Teaching_integration_platform_admin_template/node_modules/.pnpm/@vitejs+plugin-vue@5.1.2_vite@5.4.0_@types+node@22.2.0_sass@1.77.8__vue@3.4.37_typescript@5.5.4_/node_modules/@vitejs/plugin-vue/dist/index.mjs"; |
||||
import path from "path"; |
||||
import { viteMockServe } from "file:///C:/project/Teaching_integration_platform_admin_template/node_modules/.pnpm/vite-plugin-mock@3.0.2_esbuild@0.21.5_mockjs@1.1.0_vite@5.4.0_@types+node@22.2.0_sass@1.77.8_/node_modules/vite-plugin-mock/dist/index.mjs"; |
||||
import { createSvgIconsPlugin } from "file:///C:/project/Teaching_integration_platform_admin_template/node_modules/.pnpm/vite-plugin-svg-icons@2.0.1_vite@5.4.0_@types+node@22.2.0_sass@1.77.8_/node_modules/vite-plugin-svg-icons/dist/index.mjs"; |
||||
var vite_config_default = ({ command }) => { |
||||
return { |
||||
plugins: [ |
||||
vue(), |
||||
viteMockServe({ |
||||
enable: command === "serve" |
||||
}), |
||||
createSvgIconsPlugin({ |
||||
// Specify the icon folder to be cached
|
||||
iconDirs: [path.resolve(process.cwd(), "src/assets/icons")], |
||||
// Specify symbolId format
|
||||
symbolId: "icon-[dir]-[name]" |
||||
}) |
||||
], |
||||
resolve: { |
||||
alias: { |
||||
"@": path.resolve("./src") |
||||
// 相对路径别名配置,使用 @ 代替 src
|
||||
} |
||||
}, |
||||
// 配置scss
|
||||
css: { |
||||
preprocessorOptions: { |
||||
scss: { |
||||
javascriptEnabled: true, |
||||
additionalData: '@import "./src/styles/variable.scss";' |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
}; |
||||
export { |
||||
vite_config_default as default |
||||
}; |
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxwcm9qZWN0XFxcXFRlYWNoaW5nX2ludGVncmF0aW9uX3BsYXRmb3JtX2FkbWluX3RlbXBsYXRlXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJDOlxcXFxwcm9qZWN0XFxcXFRlYWNoaW5nX2ludGVncmF0aW9uX3BsYXRmb3JtX2FkbWluX3RlbXBsYXRlXFxcXHZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9DOi9wcm9qZWN0L1RlYWNoaW5nX2ludGVncmF0aW9uX3BsYXRmb3JtX2FkbWluX3RlbXBsYXRlL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHZ1ZSBmcm9tICdAdml0ZWpzL3BsdWdpbi12dWUnXHJcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXHJcbi8vIFx1NUJGQ1x1NTE2NW1vY2tcdTYzRDJcdTRFRjZcclxuaW1wb3J0IHsgdml0ZU1vY2tTZXJ2ZSB9IGZyb20gJ3ZpdGUtcGx1Z2luLW1vY2snXHJcbi8vIFx1NUJGQ1x1NTE2NXN2Z1x1OTE0RFx1N0Y2RVx1NjNEMlx1NEVGNlxyXG5pbXBvcnQgeyBjcmVhdGVTdmdJY29uc1BsdWdpbiB9IGZyb20gJ3ZpdGUtcGx1Z2luLXN2Zy1pY29ucydcclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgKHsgY29tbWFuZCB9OiBhbnkpID0+IHtcclxuICByZXR1cm4ge1xyXG4gICAgcGx1Z2luczogW1xyXG4gICAgICB2dWUoKSxcclxuICAgICAgdml0ZU1vY2tTZXJ2ZSh7XHJcbiAgICAgICAgZW5hYmxlOiBjb21tYW5kID09PSAnc2VydmUnLFxyXG4gICAgICB9KSxcclxuICAgICAgY3JlYXRlU3ZnSWNvbnNQbHVnaW4oe1xyXG4gICAgICAgIC8vIFNwZWNpZnkgdGhlIGljb24gZm9sZGVyIHRvIGJlIGNhY2hlZFxyXG4gICAgICAgIGljb25EaXJzOiBbcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksICdzcmMvYXNzZXRzL2ljb25zJyldLFxyXG4gICAgICAgIC8vIFNwZWNpZnkgc3ltYm9sSWQgZm9ybWF0XHJcbiAgICAgICAgc3ltYm9sSWQ6ICdpY29uLVtkaXJdLVtuYW1lXScsXHJcbiAgICAgIH0pLFxyXG4gICAgXSxcclxuICAgIHJlc29sdmU6IHtcclxuICAgICAgYWxpYXM6IHtcclxuICAgICAgICAnQCc6IHBhdGgucmVzb2x2ZSgnLi9zcmMnKSwgLy8gXHU3NkY4XHU1QkY5XHU4REVGXHU1Rjg0XHU1MjJCXHU1NDBEXHU5MTREXHU3RjZFXHVGRjBDXHU0RjdGXHU3NTI4IEAgXHU0RUUzXHU2NkZGIHNyY1xyXG4gICAgICB9LFxyXG4gICAgfSxcclxuICAgIC8vIFx1OTE0RFx1N0Y2RXNjc3NcclxuICAgIGNzczoge1xyXG4gICAgICBwcmVwcm9jZXNzb3JPcHRpb25zOiB7XHJcbiAgICAgICAgc2Nzczoge1xyXG4gICAgICAgICAgamF2YXNjcmlwdEVuYWJsZWQ6IHRydWUsXHJcbiAgICAgICAgICBhZGRpdGlvbmFsRGF0YTogJ0BpbXBvcnQgXCIuL3NyYy9zdHlsZXMvdmFyaWFibGUuc2Nzc1wiOycsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0sXHJcbiAgfVxyXG59XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFDQSxPQUFPLFNBQVM7QUFDaEIsT0FBTyxVQUFVO0FBRWpCLFNBQVMscUJBQXFCO0FBRTlCLFNBQVMsNEJBQTRCO0FBRXJDLElBQU8sc0JBQVEsQ0FBQyxFQUFFLFFBQVEsTUFBVztBQUNuQyxTQUFPO0FBQUEsSUFDTCxTQUFTO0FBQUEsTUFDUCxJQUFJO0FBQUEsTUFDSixjQUFjO0FBQUEsUUFDWixRQUFRLFlBQVk7QUFBQSxNQUN0QixDQUFDO0FBQUEsTUFDRCxxQkFBcUI7QUFBQTtBQUFBLFFBRW5CLFVBQVUsQ0FBQyxLQUFLLFFBQVEsUUFBUSxJQUFJLEdBQUcsa0JBQWtCLENBQUM7QUFBQTtBQUFBLFFBRTFELFVBQVU7QUFBQSxNQUNaLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFDQSxTQUFTO0FBQUEsTUFDUCxPQUFPO0FBQUEsUUFDTCxLQUFLLEtBQUssUUFBUSxPQUFPO0FBQUE7QUFBQSxNQUMzQjtBQUFBLElBQ0Y7QUFBQTtBQUFBLElBRUEsS0FBSztBQUFBLE1BQ0gscUJBQXFCO0FBQUEsUUFDbkIsTUFBTTtBQUFBLFVBQ0osbUJBQW1CO0FBQUEsVUFDbkIsZ0JBQWdCO0FBQUEsUUFDbEI7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRjsiLAogICJuYW1lcyI6IFtdCn0K
|
Loading…
Reference in new issue