224 lines
7.8 KiB
HTML
224 lines
7.8 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>约课漂流瓶</title>
|
||
<style>
|
||
*{box-sizing:border-box;margin:0;padding:0;font-family:system-ui}
|
||
body{background:#f5f7fa;padding:16px;max-width:480px;margin:0 auto}
|
||
.card{background:white;border-radius:12px;padding:14px;margin-bottom:10px;box-shadow:0 1px 3px rgba(0,0,0,0.1)}
|
||
.btn{width:100%;background:#409eff;color:white;padding:12px;border:none;border-radius:8px;margin:10px 0;font-size:16px}
|
||
.btn.gray{background:#ccc}
|
||
.btn.red{background:#ff7875}
|
||
.btn.green{background:#52c41a}
|
||
input,select,textarea{width:100%;padding:10px;margin:6px 0;border:1px solid #ddd;border-radius:6px}
|
||
.title{font-size:18px;font-weight:600;margin-bottom:10px}
|
||
.tag{display:inline-block;padding:4px 8px;border-radius:4px;font-size:12px;margin-right:6px}
|
||
.wait{background:#eee;color:#666}
|
||
.ing{background:#e6f7ff;color:#0096cc}
|
||
.ready{background:#f0f9ff;color:#0088cc}
|
||
.msg-item{padding:10px;background:#f9f9f9;border-radius:6px;margin-top:6px;font-size:14px}
|
||
.msg-status{font-size:12px;margin-top:4px}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div id="login" class="card">
|
||
<div class="title">角色登录</div>
|
||
<button class="btn" onclick="login('guardian')">我是管家</button>
|
||
<button class="btn gray" onclick="login('partner')">我是合作方</button>
|
||
</div>
|
||
|
||
<div id="guardian" style="display:none">
|
||
<div class="card">
|
||
<div class="title">管家首页</div>
|
||
<button class="btn" onclick="showPage('create')">扔一个新漂流瓶</button>
|
||
</div>
|
||
<div id="guardianList"></div>
|
||
</div>
|
||
|
||
<div id="partner" style="display:none">
|
||
<div class="card"><div class="title">需求池</div></div>
|
||
<div id="partnerList"></div>
|
||
</div>
|
||
|
||
<div id="create" style="display:none" class="card">
|
||
<div class="title">发布约课漂流瓶</div>
|
||
<input id="sname" placeholder="学生姓名/代号">
|
||
<select id="subject">
|
||
<option>数学</option><option>英语</option><option>语文</option><option>编程</option>
|
||
</select>
|
||
<input id="etime" type="datetime-local">
|
||
<textarea id="demand" placeholder="需求描述"></textarea>
|
||
<button class="btn" onclick="createBottle()">发布</button>
|
||
</div>
|
||
|
||
<div id="detail" style="display:none" class="card">
|
||
<div class="title">漂流瓶详情</div>
|
||
<div id="detailInfo"></div>
|
||
<button class="btn gray" id="takeBtn" onclick="takeBottle()" style="display:none">捞起瓶子</button>
|
||
<button class="btn" id="meetingBtn" onclick="showPage('meeting')" style="display:none">填写上课信息</button>
|
||
<button class="btn red" onclick="showPage('msg')">申请调课 / 留言</button>
|
||
<div id="msgList" style="margin-top:12px"></div>
|
||
</div>
|
||
|
||
<div id="meeting" style="display:none" class="card">
|
||
<div class="title">填写上课信息</div>
|
||
<input id="mid" placeholder="会议号">
|
||
<input id="mpwd" placeholder="密码">
|
||
<input id="tname" placeholder="老师姓名">
|
||
<button class="btn" onclick="fillMeeting()">提交</button>
|
||
</div>
|
||
|
||
<div id="msg" style="display:none" class="card">
|
||
<div class="title">申请调课</div>
|
||
<textarea id="msgContent" placeholder="调课原因/说明"></textarea>
|
||
<input id="newTime" type="datetime-local" placeholder="新上课时间">
|
||
<button class="btn red" onclick="sendMsg()">提交调课申请</button>
|
||
</div>
|
||
|
||
<script>
|
||
let role = ""
|
||
let currentId = 1
|
||
let list = JSON.parse(localStorage.getItem('bottle_list')) || []
|
||
let msgList = JSON.parse(localStorage.getItem('bottle_msg')) || {}
|
||
|
||
function saveData(){
|
||
localStorage.setItem('bottle_list', JSON.stringify(list))
|
||
localStorage.setItem('bottle_msg', JSON.stringify(msgList))
|
||
}
|
||
|
||
function login(r){
|
||
role = r
|
||
document.getElementById("login").style.display = "none"
|
||
r==="guardian" ? showPage("guardian") : showPage("partner")
|
||
refreshList()
|
||
}
|
||
|
||
function refreshList(){
|
||
let ghtml = "", phtml = ""
|
||
list.forEach(b=>{
|
||
let statusText = "", tag = "wait"
|
||
if(b.status===1){statusText="待处理";tag="wait"}
|
||
else if(b.status===2){statusText="安排中";tag="ing"}
|
||
else if(b.status===3){statusText="待上课";tag="ready"}
|
||
let item = `<div class="card" onclick="openDetail(${b.id})">
|
||
<div>学生:${b.sname}</div>
|
||
<div>学科:${b.subject}</div>
|
||
<div>时间:${b.etime}</div>
|
||
<div><span class="${tag}">${statusText}</span></div>
|
||
${b.mid?"<div>会议号:"+b.mid+"</div>":""}
|
||
</div>`
|
||
role==="guardian" ? ghtml+=item : phtml+=item
|
||
})
|
||
document.getElementById("guardianList").innerHTML = ghtml
|
||
document.getElementById("partnerList").innerHTML = phtml
|
||
}
|
||
|
||
function createBottle(){
|
||
const sname = document.getElementById("sname").value
|
||
const sub = document.getElementById("subject").value
|
||
const etime = document.getElementById("etime").value
|
||
const demand = document.getElementById("demand").value
|
||
const maxId = list.length ? Math.max(...list.map(x=>x.id)) : 0
|
||
list.unshift({id:maxId+1,sname,subject:sub,etime,demand,status:1,mid:"",mpwd:"",tname:""})
|
||
saveData()
|
||
showPage("guardian")
|
||
refreshList()
|
||
}
|
||
|
||
function openDetail(id){
|
||
currentId = id
|
||
const b = list.find(x=>x.id===id)
|
||
document.getElementById("detailInfo").innerHTML = `
|
||
<div>学生:${b.sname}</div>
|
||
<div>学科:${b.subject}</div>
|
||
<div>时间:${b.etime}</div>
|
||
<div>需求:${b.demand||"-"}</div>
|
||
${b.mid?"<div>会议号:"+b.mid+"</div>":""}
|
||
`
|
||
document.getElementById("takeBtn").style.display = role==="partner"&&b.status===1?"block":"none"
|
||
document.getElementById("meetingBtn").style.display = role==="partner"&&b.status===2?"block":"none"
|
||
refreshMsg()
|
||
showPage("detail")
|
||
}
|
||
|
||
function takeBottle(){
|
||
const b = list.find(x=>x.id===currentId)
|
||
b.status = 2
|
||
saveData()
|
||
refreshList()
|
||
openDetail(currentId)
|
||
}
|
||
|
||
function fillMeeting(){
|
||
const b = list.find(x=>x.id===currentId)
|
||
b.mid = document.getElementById("mid").value
|
||
b.mpwd = document.getElementById("mpwd").value
|
||
b.tname = document.getElementById("tname").value
|
||
b.status = 3
|
||
saveData()
|
||
showPage("detail")
|
||
refreshList()
|
||
}
|
||
|
||
function refreshMsg(){
|
||
const msgs = msgList[currentId] || []
|
||
let html = ""
|
||
msgs.forEach((m,idx)=>{
|
||
html += `<div class="msg-item">
|
||
<div>${m.role}:${m.content}</div>
|
||
${m.newTime?"<div style='color:red'>新时间:"+m.newTime+"</div>":""}
|
||
<div style='font-size:12px;color:#999'>${m.time}</div>
|
||
${m.type==="change"&&m.result==="pending"&&role==="partner"?`
|
||
<div class="msg-status">
|
||
<button class="btn green" onclick="handleChange(${idx},'agree')">同意</button>
|
||
<button class="btn gray" onclick="handleChange(${idx},'reject')">拒绝</button>
|
||
</div>
|
||
`:m.result?`<div class="msg-status" style="color:${m.result==='agree'?'green':'red'}">
|
||
结果:${m.result==='agree'?'已同意':'已拒绝'}
|
||
</div>`:""}
|
||
</div>`
|
||
})
|
||
document.getElementById("msgList").innerHTML = html
|
||
}
|
||
|
||
function sendMsg(){
|
||
const content = document.getElementById("msgContent").value
|
||
const newTime = document.getElementById("newTime").value
|
||
if(!content) return alert("请填写内容")
|
||
if(!msgList[currentId]) msgList[currentId] = []
|
||
msgList[currentId].unshift({
|
||
role: role==="guardian"?"管家":"合作方",
|
||
content, newTime,
|
||
time: new Date().toLocaleString(),
|
||
type: "change",
|
||
result: "pending"
|
||
})
|
||
saveData()
|
||
showPage("detail")
|
||
refreshMsg()
|
||
}
|
||
|
||
function handleChange(idx,res){
|
||
const msgs = msgList[currentId]
|
||
if(!msgs || !msgs[idx]) return
|
||
msgs[idx].result = res
|
||
if(res==="agree" && msgs[idx].newTime){
|
||
const b = list.find(x=>x.id===currentId)
|
||
b.etime = msgs[idx].newTime
|
||
}
|
||
saveData()
|
||
refreshMsg()
|
||
refreshList()
|
||
}
|
||
|
||
function showPage(page){
|
||
const all = ["login","guardian","partner","create","detail","meeting","msg"]
|
||
all.forEach(p=>document.getElementById(p).style.display="none")
|
||
document.getElementById(page).style.display="block"
|
||
}
|
||
</script>
|
||
</body>
|
||
</html> |