清理了不需要的文件,阻止了 GERP 的编译文件的上传
No files matched your search
@@ -15,5 +15,7 @@
|
||||
|
||||
# GERP 新前端工程(独立 git 仓库)
|
||||
/GERP/
|
||||
# GERP 的编译文件
|
||||
/TempLate/GERP/
|
||||
|
||||
/gvsdsdk/
|
||||
@@ -1,108 +0,0 @@
|
||||
from flask import Flask, render_template, request, session, redirect, url_for
|
||||
from flask_socketio import SocketIO, join_room, leave_room
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['SECRET_KEY'] = 'jjj'
|
||||
|
||||
socketio = SocketIO()
|
||||
socketio.init_app(app)
|
||||
|
||||
|
||||
online_user = []
|
||||
room_user = {}
|
||||
|
||||
|
||||
@app.route('/', methods=['GET', 'POST'])
|
||||
def index():
|
||||
if request.method == 'GET':
|
||||
if 'username' in session:
|
||||
return redirect(url_for('chat'))
|
||||
return render_template('index.html')
|
||||
else:
|
||||
username = request.form.get('username')
|
||||
room = request.form.get('room')
|
||||
session['username'] = username
|
||||
session['room'] = room
|
||||
return redirect(url_for('chat'))
|
||||
|
||||
|
||||
@app.route('/chat/')
|
||||
def chat():
|
||||
if 'username' in session and 'room' in session:
|
||||
username = session['username']
|
||||
room = session['room']
|
||||
return render_template('chat.html', username=username, room=room)
|
||||
else:
|
||||
return redirect(url_for('index'))
|
||||
|
||||
|
||||
@app.route('/logout/')
|
||||
def logout():
|
||||
if 'username' in session:
|
||||
session.clear()
|
||||
return redirect(url_for('index'))
|
||||
|
||||
|
||||
# # 连接
|
||||
@socketio.on('connect')
|
||||
def handle_connect():
|
||||
username = session.get('username')
|
||||
online_user.append(username)
|
||||
# print('connect info: ' + f'{username} connect')
|
||||
# print(online_user)
|
||||
# socketio.emit('connect info', f'{username} connect')
|
||||
|
||||
|
||||
# 断开连接
|
||||
@socketio.on('disconnect')
|
||||
def handle_disconnect():
|
||||
username = session.get('username')
|
||||
print('connect info: ' + f'{username} disconnect')
|
||||
# socketio.emit('connect info', f'{username} disconnect')
|
||||
|
||||
|
||||
# @socketio.on('connect info')
|
||||
# def handle_connect_info(info):
|
||||
# print('connect info' + str(info))
|
||||
# room = session.get('room')
|
||||
# socketio.emit('connect info', info, to=room)
|
||||
|
||||
|
||||
@socketio.on('send msg')
|
||||
def handle_message(data):
|
||||
print('sendMsg' + str(data))
|
||||
room = session.get('room')
|
||||
data['message'] = data.get('message').replace('<', '<').replace('>', '>').replace(' ', ' ')
|
||||
socketio.emit('send msg', data, to=room)
|
||||
|
||||
|
||||
@socketio.on('join')
|
||||
def on_join(data):
|
||||
username = data.get('username')
|
||||
room = data.get('room')
|
||||
try:
|
||||
room_user[room].append(username)
|
||||
except:
|
||||
room_user[room] = []
|
||||
room_user[room].append(username)
|
||||
|
||||
join_room(room)
|
||||
print('join room: ' + str(data))
|
||||
print(room_user)
|
||||
socketio.emit('connect info', username + '加入房间', to=room)
|
||||
|
||||
|
||||
@socketio.on('leave')
|
||||
def on_leave(data):
|
||||
username = data.get('username')
|
||||
room = data.get('room')
|
||||
room_user[room].remove(username)
|
||||
leave_room(room)
|
||||
print('leave room ' + str(data))
|
||||
print(room_user)
|
||||
socketio.emit('connect info', username + '离开房间', to=room)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, host='0.0.0.0', port=5000, debug=True)
|
||||
@@ -1,169 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!--Import Google Icon Font-->
|
||||
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<!--Import materialize.css-->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css">
|
||||
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<link rel="shortcut icon" href="/static/1.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>CGY's ChatRoom</title>
|
||||
<style>
|
||||
div.col.s12.m8.l9.white {
|
||||
overflow-y: scroll;
|
||||
word-wrap: break-word;
|
||||
height: 700px;
|
||||
width: 650px;
|
||||
margin-top: 2em;
|
||||
padding: 2em 3em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
text-align: center;
|
||||
}
|
||||
.tag {
|
||||
padding: 6px 10px;
|
||||
border-radius: 9px;
|
||||
max-width: 15em;
|
||||
}
|
||||
.connect-info {
|
||||
margin:0 auto ;
|
||||
padding: 4px 10px;
|
||||
border-radius: 9px;
|
||||
width: 15em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="blue-grey lighten-5">
|
||||
<!--Import jQuery before materialize.js-->
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script>
|
||||
<nav>
|
||||
<div class="nav-wrapper teal">
|
||||
<a href="" class="brand-logo center">聊天室({{ room }} 房间)</a>
|
||||
<ul id="nav-mobile" class="right hide-on-med-and-down">
|
||||
<li><a id="leaveroom" href="{{ url_for('Chat.ChatLogout') }}">退出房间</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12 m4 l3">
|
||||
<div class="input-field col s12 z-depth-5">
|
||||
<h5 id="username">{{ username }}</h5>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input id="send-msg-inp" type="text" class="validate">
|
||||
<button id="send-msg-btn" class="btn waves-effect waves-light teal right" type="button"
|
||||
name="action">
|
||||
send
|
||||
<i class="material-icons right">send</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="message-box" class="col s12 m8 l9 white z-depth-1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.1/socket.io.js"></script>
|
||||
<script>
|
||||
let room = '{{ room }}'
|
||||
let username = '{{ username }}'
|
||||
let inp = document.querySelector('#send-msg-inp')
|
||||
let sendMsgBtn = document.querySelector('#send-msg-btn')
|
||||
let messageBox = document.querySelector('#message-box')
|
||||
let leaveroom = document.querySelector('#leaveroom')
|
||||
let socket = io();
|
||||
// 连接
|
||||
socket.connect(location.protocol + '//' + document.domain + ':' + location.port);
|
||||
// 加入房间
|
||||
socket.emit('join', {
|
||||
username: username,
|
||||
room: room
|
||||
})
|
||||
// 退出房间
|
||||
leaveroom.onclick = function () {
|
||||
socket.emit('leave', {
|
||||
username: username,
|
||||
room: room
|
||||
})
|
||||
}
|
||||
// 发送消息
|
||||
sendMsgBtn.onclick = function () {
|
||||
let inp = document.querySelector('#send-msg-inp')
|
||||
let msg = inp.value
|
||||
let user = document.querySelector('#username').innerHTML
|
||||
inp.value = ''
|
||||
if(msg){
|
||||
socket.emit('send msg', {
|
||||
user: user,
|
||||
message: msg,
|
||||
})
|
||||
messageBox.scrollTop = messageBox.scrollHeight
|
||||
}else {
|
||||
alert('消息不能为空')
|
||||
}
|
||||
}
|
||||
// 回车发送消息
|
||||
inp.addEventListener("keyup", function(event) {
|
||||
event.preventDefault();
|
||||
if (event.keyCode === 13) {
|
||||
sendMsgBtn.click();
|
||||
}
|
||||
});
|
||||
function escapeHtml(text) {
|
||||
return text.replace(/[&<>"']/g, function(m) {
|
||||
return {'&': '&', '<': '<', '>': '>', '"': '"', "'": '''}[m];
|
||||
});
|
||||
}
|
||||
// 连接的信息
|
||||
socket.on('connect info', function (data) {
|
||||
console.log(data)
|
||||
let connectInfo = document.createElement('div')
|
||||
connectInfo.className = 'row'
|
||||
let msg = `
|
||||
<div class="col s4 offset-s4">
|
||||
<div class="connect-info grey lighten-4 center" >
|
||||
<span class="black-text">${escapeHtml(data)}
|
||||
</span>
|
||||
</div>
|
||||
</div>`
|
||||
connectInfo.innerHTML = msg
|
||||
messageBox.appendChild(connectInfo)
|
||||
})
|
||||
// 接受消息
|
||||
socket.on('send msg', function (data) {
|
||||
console.log(data)
|
||||
console.log(socket.id)
|
||||
let msg = null
|
||||
let msgbox = document.createElement('div')
|
||||
msgbox.className = 'row'
|
||||
if (data.user === document.querySelector('#username').innerHTML) {
|
||||
msg = `
|
||||
<div class="col right">
|
||||
<div class="tag teal z-depth-3" >
|
||||
<span class="white-text">${escapeHtml(data.message)}
|
||||
</span>
|
||||
</div>
|
||||
</div>`
|
||||
} else {
|
||||
msg = `
|
||||
<div class="col">
|
||||
<div class="tag z-depth-3">
|
||||
<span class="teal-text"><b>${data.user}</b>: ${data.message}
|
||||
</span>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
msgbox.innerHTML = msg
|
||||
messageBox.appendChild(msgbox)
|
||||
messageBox.scrollTop = messageBox.scrollHeight
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,65 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!--Import Google Icon Font-->
|
||||
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<!--Import materialize.css-->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css">
|
||||
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<link rel="shortcut icon" href="/static/1.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>register</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--Import jQuery before materialize.js-->
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script>
|
||||
<nav>
|
||||
<div class="nav-wrapper teal">
|
||||
<a href="#" class="brand-logo center">聊天室</a>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container">
|
||||
<div class="row"></div>
|
||||
<div class="row"></div>
|
||||
<div class="row">
|
||||
<div class="col s4 offset-s4 ">
|
||||
<form class="col s12" method="post" action="{{ url_for('Chat.ChatIndex') }}">
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input value="" id="username" type="text" class="validate" name="username">
|
||||
<label class="active" for="username">昵称</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<input value="默认" id="room" type="text" class="validate" name="room">
|
||||
<label class="active" for="room">房间</label>
|
||||
</div>
|
||||
</div>
|
||||
<button id="submit" class="btn waves-effect waves-light teal z-depth-3 right" type="submit"
|
||||
name="action">开始聊天
|
||||
<i class="material-icons right">send</i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let inp = document.querySelector('#username');
|
||||
let roominp = document.querySelector('#room');
|
||||
let btn = document.querySelector('#submit');
|
||||
setInterval(function () {
|
||||
if (inp.value && roominp.value) {
|
||||
btn.classList.remove('disabled');
|
||||
} else {
|
||||
if (!btn.classList.contains('disabled')) {
|
||||
btn.classList.add('disabled');
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,48 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDjTCCAxOgAwIBAgISBTV8t4ABCVIR2ONpNFnjoS0AMAoGCCqGSM49BAMDMDIx
|
||||
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
|
||||
NjAeFw0yNTA2MTcwMzQxNTNaFw0yNTA5MTUwMzQxNTJaMBYxFDASBgNVBAMMCyou
|
||||
Z3ZzZHMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiiQo5+oVGkXCZyqY
|
||||
c0OoKgrhze+29pbAQG+cCRE5gy+jPzURiLhTHBd1ceB973k3EUQv1gPkNV9u32bH
|
||||
ujl/76OCAiMwggIfMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcD
|
||||
AQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUZ8UMmWhguY+Dwezm
|
||||
XtgeMg4UUuwwHwYDVR0jBBgwFoAUkydGmAOpUWiOmNbEQkjbI79YlNIwMgYIKwYB
|
||||
BQUHAQEEJjAkMCIGCCsGAQUFBzAChhZodHRwOi8vZTYuaS5sZW5jci5vcmcvMCEG
|
||||
A1UdEQQaMBiCCyouZ3ZzZHMuY29tgglndnNkcy5jb20wEwYDVR0gBAwwCjAIBgZn
|
||||
gQwBAgEwLAYDVR0fBCUwIzAhoB+gHYYbaHR0cDovL2U2LmMubGVuY3Iub3JnLzEu
|
||||
Y3JsMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYA7TxL1ugGwqSiAFfbyyTiOAHf
|
||||
US/txIbFcA8g3bc+P+AAAAGXfDA1jQAABAMARzBFAiBQjVnBQipFwx8zN95aqyKM
|
||||
2kaSQ9xyAnwjBSV3hTDAowIhANRFJ3GxbszEggL45PKW5Fv5JefrKMMihqBGCEHQ
|
||||
ic6wAHYA3dzKNJXX4RYF55Uy+sef+D0cUN/bADoUEnYKLKy7yCoAAAGXfDA9lQAA
|
||||
BAMARzBFAiBZw+3FvIiMzX+BZfK8xd+AfQ1BeuiqqNAmHc1qnOh+VQIhAPxnB8SD
|
||||
spB0y7ggOvuUiWmKXbRhs2cAOp4ek6xP2DdmMAoGCCqGSM49BAMDA2gAMGUCMEMc
|
||||
XjnlFEUQ0pjoYCk4juJ3y6j0rJLTMGuwtH96viOQyC2RTU8CPP2s7oxYvlVKyAIx
|
||||
AJoroV4iK5QUaRUhQ4adUkIsypz6WUO+AO7Xa7siP8GbfX63NfjBbIGrcW8KzXBP
|
||||
FA==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw
|
||||
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
|
||||
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
|
||||
RW5jcnlwdDELMAkGA1UEAxMCRTYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATZ8Z5G
|
||||
h/ghcWCoJuuj+rnq2h25EqfUJtlRFLFhfHWWvyILOR/VvtEKRqotPEoJhC6+QJVV
|
||||
6RlAN2Z17TJOdwRJ+HB7wxjnzvdxEP6sdNgA1O1tHHMWMxCcOrLqbGL0vbijgfgw
|
||||
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
|
||||
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSTJ0aYA6lRaI6Y1sRCSNsj
|
||||
v1iU0jAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
|
||||
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
|
||||
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
|
||||
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAfYt7SiA1sgWGCIpunk46r4AExIRc
|
||||
MxkKgUhNlrrv1B21hOaXN/5miE+LOTbrcmU/M9yvC6MVY730GNFoL8IhJ8j8vrOL
|
||||
pMY22OP6baS1k9YMrtDTlwJHoGby04ThTUeBDksS9RiuHvicZqBedQdIF65pZuhp
|
||||
eDcGBcLiYasQr/EO5gxxtLyTmgsHSOVSBcFOn9lgv7LECPq9i7mfH3mpxgrRKSxH
|
||||
pOoZ0KXMcB+hHuvlklHntvcI0mMMQ0mhYj6qtMFStkF1RpCG3IPdIwpVCQqu8GV7
|
||||
s8ubknRzs+3C/Bm19RFOoiPpDkwvyNfvmQ14XkyqqKK5oZ8zhD32kFRQkxa8uZSu
|
||||
h4aTImFxknu39waBxIRXE4jKxlAmQc4QjFZoq1KmQqQg0J/1JF8RlFvJas1VcjLv
|
||||
YlvUB2t6npO6oQjB3l+PNf0DpQH7iUx3Wz5AjQCi6L25FjyE06q6BZ/QlmtYdl/8
|
||||
ZYao4SRqPEs/6cAiF+Qf5zg2UkaWtDphl1LKMuTNLotvsX99HP69V2faNyegodQ0
|
||||
LyTApr/vT01YPE46vNsDLgK+4cL6TrzC/a4WcmF5SRJ938zrv/duJHLXQIku5v0+
|
||||
EwOy59Hdm0PT/Er/84dDV0CSjdR/2XuZM3kpysSKLgD1cKiDA+IRguODCxfO9cyY
|
||||
Ig46v9mFmBvyH04=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,5 +0,0 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgHnavAJ1RXA37EqxY
|
||||
fOqm6dGuXxZlaNil1jX7bYtjqgehRANCAASKJCjn6hUaRcJnKphzQ6gqCuHN77b2
|
||||
lsBAb5wJETmDL6M/NRGIuFMcF3Vx4H3veTcRRC/WA+Q1X27fZse6OX/v
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -1,223 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Helvetica Neue', Arial, 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
body {
|
||||
background-color: #f5f7fa;
|
||||
padding: 40px 20px;
|
||||
color: #333;
|
||||
}
|
||||
.email-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
.header {
|
||||
background-color: #2c3e50;
|
||||
padding: 25px 30px;
|
||||
color: white;
|
||||
}
|
||||
.company-name {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.email-body {
|
||||
padding: 30px;
|
||||
}
|
||||
.email-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.sender-info, .recipient-info {
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.sender-info {
|
||||
margin-right: 15px;
|
||||
}
|
||||
.header-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.info-label {
|
||||
width: 80px;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
.info-value {
|
||||
flex: 1;
|
||||
color: #333;
|
||||
}
|
||||
.email-content {
|
||||
line-height: 1.8;
|
||||
font-size: 15px;
|
||||
color: #444;
|
||||
}
|
||||
.greeting {
|
||||
margin-bottom: 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.main-content {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.signature {
|
||||
margin-top: 30px;
|
||||
}
|
||||
.signature-name {
|
||||
font-weight: 600;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.signature-title {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.footer {
|
||||
background-color: #f1f3f6;
|
||||
padding: 20px 30px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
.footer-logo {
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 10px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.footer-links {
|
||||
margin: 15px 0;
|
||||
}
|
||||
.footer-links a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
margin: 0 10px;
|
||||
}
|
||||
.copyright {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.divider {
|
||||
color: #ccc;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 15px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
th, td {
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background-color: #f2f2f2;
|
||||
font-weight: 600;
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.warning-text {
|
||||
color: #d9534f;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="email-container">
|
||||
<div class="header">
|
||||
<div class="company-name">银河锋锐软件开发工作室</div>
|
||||
</div>
|
||||
<div class="email-body">
|
||||
<div class="email-header">
|
||||
<div class="sender-info">
|
||||
<div class="header-title">发件人信息</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">姓名:</div>
|
||||
<div class="info-value">GVSDS-SYSTEM</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">类型:</div>
|
||||
<div class="info-value">系统动态回复</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">邮箱:</div>
|
||||
<div class="info-value">support@gvsds.com</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">日期:</div>
|
||||
<div class="info-value">2025年7月9日</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="recipient-info">
|
||||
<div class="header-title">收件人信息</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">姓名:</div>
|
||||
<div class="info-value">裴雨辰</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">公司:</div>
|
||||
<div class="info-value">GVSDS</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">邮箱:</div>
|
||||
<div class="info-value">pvc5206210006@outlook.com</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="email-content">
|
||||
<div class="greeting">您好,裴雨辰:</div>
|
||||
<div class="main-content">
|
||||
<p style="margin-top: 15px;">感谢您的回信。我们已经对于本事做出处罚,已无后续事项。</p>
|
||||
<p style="margin-top: 15px;">希望日后您能对于我们的工作多加配合,档案在一段时间过后会更新,届时该档案会被设为失效。</p>
|
||||
<p style="margin-top: 15px;">如果您对于此消息有任何问题,请随时与我们联系。</p>
|
||||
</div>
|
||||
<div class="signature">
|
||||
<div class="signature-name">祝 顺颂时祺。</div>
|
||||
<div class="signature-title">银河锋锐软件开发工作室 管理系统</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="footer-logo">GALAXY VANTONG SOFTWARE DEVELOPMENT STUDIO</div>
|
||||
<div class="footer-links">
|
||||
<a href="https://www.gvsds.com">官网</a>
|
||||
<span class="divider">|</span>
|
||||
<a href="mailto:support@gvsds.com">反馈</a>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
© 2025 银河锋锐软件开发工作室 版权所有
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,262 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Helvetica Neue', Arial, 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
body {
|
||||
background-color: #f5f7fa;
|
||||
padding: 40px 20px;
|
||||
color: #333;
|
||||
}
|
||||
.email-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
.header {
|
||||
background-color: #2c3e50;
|
||||
padding: 25px 30px;
|
||||
color: white;
|
||||
}
|
||||
.company-name {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.email-body {
|
||||
padding: 30px;
|
||||
}
|
||||
.email-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.sender-info, .recipient-info {
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.sender-info {
|
||||
margin-right: 15px;
|
||||
}
|
||||
.header-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.info-label {
|
||||
width: 80px;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
.info-value {
|
||||
flex: 1;
|
||||
color: #333;
|
||||
}
|
||||
.email-content {
|
||||
line-height: 1.8;
|
||||
font-size: 15px;
|
||||
color: #444;
|
||||
}
|
||||
.greeting {
|
||||
margin-bottom: 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.main-content {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.signature {
|
||||
margin-top: 30px;
|
||||
}
|
||||
.signature-name {
|
||||
font-weight: 600;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.signature-title {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.footer {
|
||||
background-color: #f1f3f6;
|
||||
padding: 20px 30px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
.footer-logo {
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 10px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.footer-links {
|
||||
margin: 15px 0;
|
||||
}
|
||||
.footer-links a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
margin: 0 10px;
|
||||
}
|
||||
.copyright {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.divider {
|
||||
color: #ccc;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 15px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
th, td {
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background-color: #f2f2f2;
|
||||
font-weight: 600;
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.warning-text {
|
||||
color: #d9534f;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="email-container">
|
||||
<div class="header">
|
||||
<div class="company-name">银河锋锐软件开发工作室</div>
|
||||
</div>
|
||||
<div class="email-body">
|
||||
<div class="email-header">
|
||||
<div class="sender-info">
|
||||
<div class="header-title">发件人信息</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">姓名:</div>
|
||||
<div class="info-value">GVSDS-SYSTEM</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">类型:</div>
|
||||
<div class="info-value">系统自动发送</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">邮箱:</div>
|
||||
<div class="info-value">manage@gvsds.com</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">日期:</div>
|
||||
<div class="info-value">2025年7月9日</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="recipient-info">
|
||||
<div class="header-title">收件人信息</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">姓名:</div>
|
||||
<div class="info-value">张可迪</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">公司:</div>
|
||||
<div class="info-value">GVSDS</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">邮箱:</div>
|
||||
<div class="info-value">zhangcodey@126.com</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="email-content">
|
||||
<div class="greeting">您好,张可迪:</div>
|
||||
<div class="main-content">
|
||||
<p style="margin-top: 15px;">鉴于您复制由“悠然自得”或“裴雨辰”在【银河锋锐软件开发工作室第五次全体会议】后发表的带有侮辱性言论(图片、文字)信息,现已对您做出如下处罚:</p>
|
||||
<ul style="margin-top: 15px;">
|
||||
<li style="margin-left: 15px;">
|
||||
1. 工作群内通报批评
|
||||
</li>
|
||||
<li style="margin-left: 15px;">
|
||||
2. 记入工作室档案:
|
||||
<table>
|
||||
<tr>
|
||||
<td width="30%">档案模板UUID:</td>
|
||||
<td>e2c0e5a95b073b7c84fd4419fbfcfb5c</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>档案UUID:</td>
|
||||
<td>334f93d7d0ba340293746f2b52074526</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>档案模板名称:</td>
|
||||
<td>不当言论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>档案模板描述:</td>
|
||||
<td>在工作室群聊发表包含但不限于 "反动"、"人身攻击" 等等言论,必要情况报警处理</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>档案记录名称:</td>
|
||||
<td>不当言论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>档案记录描述:</td>
|
||||
<td>复制由“悠然自得”在【银河锋锐软件开发工作室第五次全体会议】中发表的带有侮辱性言论(图片、文字)信息</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>影响考核分数:</td>
|
||||
<td class="warning-text">-20</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
<p style="margin-top: 15px;">鉴于已造成的恶劣影响,我们建议您立即撤回消息并最大程度降低影响,以减少后续问题的产生。</p>
|
||||
<p style="margin-top: 15px;">收到本邮件后,请立即发送回复。</p>
|
||||
<p style="margin-top: 15px;">如果您对于此消息有任何问题,请随时与我们联系。</p>
|
||||
</div>
|
||||
<div class="signature">
|
||||
<div class="signature-name">此致,<b>以儆效尤</b></div>
|
||||
<div class="signature-title">银河锋锐软件开发工作室 管理系统</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="footer-logo">GALAXY VANTONG SOFTWARE DEVELOPMENT STUDIO</div>
|
||||
<div class="footer-links">
|
||||
<a href="https://www.gvsds.com">官网</a>
|
||||
<span class="divider">|</span>
|
||||
<a href="mailto:support@gvsds.com">反馈</a>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
© 2025 银河锋锐软件开发工作室 版权所有
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,842 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>全球攻防态势监控平台</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Tailwind配置 -->
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#165DFF',
|
||||
secondary: '#36CFC9',
|
||||
danger: '#FF4D4F',
|
||||
warning: '#FF7D00',
|
||||
success: '#52C41A',
|
||||
dark: '#1D2129',
|
||||
'dark-light': '#272E3B',
|
||||
'dark-lighter': '#374151',
|
||||
'light-gray': '#F2F3F5',
|
||||
'gray-medium': '#86909C',
|
||||
},
|
||||
fontFamily: {
|
||||
inter: ['Inter', 'sans-serif'],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="text/tailwindcss">
|
||||
@layer utilities {
|
||||
.content-auto {
|
||||
content-visibility: auto;
|
||||
}
|
||||
.text-shadow {
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.text-shadow-lg {
|
||||
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
.glow {
|
||||
box-shadow: 0 0 15px rgba(22, 93, 255, 0.5);
|
||||
}
|
||||
.pulse {
|
||||
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
.grid-dots {
|
||||
background-image: radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px);
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
.gradient-bg {
|
||||
background: linear-gradient(135deg, #1D2129 0%, #272E3B 100%);
|
||||
}
|
||||
.attack-line {
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 1000;
|
||||
animation: dash 3s linear forwards;
|
||||
}
|
||||
@keyframes dash {
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="font-inter bg-dark text-white min-h-screen grid-dots overflow-hidden">
|
||||
<!-- 顶部导航栏 -->
|
||||
<header class="bg-dark-light/80 backdrop-blur-md border-b border-dark-lighter z-50">
|
||||
<div class="container mx-auto px-4 py-3 flex justify-between items-center">
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="h-8 w-8 rounded-lg bg-gradient-to-br from-primary to-secondary flex items-center justify-center">
|
||||
<i class="fa fa-shield text-white"></i>
|
||||
</div>
|
||||
<h1 class="text-xl font-bold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">全球攻防态势监控平台</h1>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-6">
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="h-2 w-2 rounded-full bg-success animate-pulse"></div>
|
||||
<span class="text-sm text-gray-300">系统运行中</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<button class="text-gray-300 hover:text-white transition-colors">
|
||||
<i class="fa fa-refresh"></i>
|
||||
</button>
|
||||
<button class="text-gray-300 hover:text-white transition-colors">
|
||||
<i class="fa fa-question-circle"></i>
|
||||
</button>
|
||||
<button class="text-gray-300 hover:text-white transition-colors">
|
||||
<i class="fa fa-user-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<main class="container mx-auto px-4 py-4 flex flex-col lg:flex-row gap-4 h-[calc(100vh-80px)]">
|
||||
<!-- 左侧控制面板 -->
|
||||
<div class="w-full lg:w-1/5 flex flex-col gap-4">
|
||||
<!-- 服务器信息卡片 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<h2 class="text-lg font-semibold">服务器信息</h2>
|
||||
<span class="px-2 py-1 bg-primary/20 text-primary text-xs rounded-full">在线</span>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400 text-sm">位置</span>
|
||||
<span class="text-white">天津</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400 text-sm">IP地址</span>
|
||||
<span class="text-white">121.58.245.100</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400 text-sm">系统负载</span>
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="w-20 bg-dark-lighter rounded-full h-2">
|
||||
<div class="bg-success h-2 rounded-full" style="width: 35%"></div>
|
||||
</div>
|
||||
<span class="text-white">35%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400 text-sm">响应时间</span>
|
||||
<span class="text-white">24ms</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 攻击统计卡片 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg">
|
||||
<h2 class="text-lg font-semibold mb-3">攻击统计</h2>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div class="bg-dark-lighter/50 rounded-lg p-3">
|
||||
<p class="text-gray-400 text-sm">今日攻击</p>
|
||||
<p class="text-2xl font-bold text-danger">2,583</p>
|
||||
<p class="text-xs text-warning mt-1"><i class="fa fa-arrow-up"></i> 12.5%</p>
|
||||
</div>
|
||||
<div class="bg-dark-lighter/50 rounded-lg p-3">
|
||||
<p class="text-gray-400 text-sm">防护成功率</p>
|
||||
<p class="text-2xl font-bold text-success">99.8%</p>
|
||||
<p class="text-xs text-success mt-1"><i class="fa fa-arrow-up"></i> 0.3%</p>
|
||||
</div>
|
||||
<div class="bg-dark-lighter/50 rounded-lg p-3">
|
||||
<p class="text-gray-400 text-sm">活跃攻击源</p>
|
||||
<p class="text-2xl font-bold text-warning">128</p>
|
||||
<p class="text-xs text-danger mt-1"><i class="fa fa-arrow-up"></i> 8.2%</p>
|
||||
</div>
|
||||
<div class="bg-dark-lighter/50 rounded-lg p-3">
|
||||
<p class="text-gray-400 text-sm">流量峰值</p>
|
||||
<p class="text-2xl font-bold text-primary">42.6 Gbps</p>
|
||||
<p class="text-xs text-gray-400 mt-1"><i class="fa fa-minus"></i> 0.0%</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 攻击类型分布 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg flex-grow">
|
||||
<h2 class="text-lg font-semibold mb-3">攻击类型分布</h2>
|
||||
<div class="h-48">
|
||||
<canvas id="attackTypesChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 最近攻击记录 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg flex-grow">
|
||||
<h2 class="text-lg font-semibold mb-3">最近攻击记录</h2>
|
||||
<div class="space-y-2 max-h-60 overflow-y-auto pr-1">
|
||||
<div class="bg-dark-lighter/30 rounded-lg p-2 flex justify-between items-center">
|
||||
<div>
|
||||
<p class="text-sm font-medium">182.168.123.45</p>
|
||||
<p class="text-xs text-gray-400">DDOS攻击 · 3分钟前</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 bg-danger/20 text-danger text-xs rounded-full">高风险</span>
|
||||
</div>
|
||||
<div class="bg-dark-lighter/30 rounded-lg p-2 flex justify-between items-center">
|
||||
<div>
|
||||
<p class="text-sm font-medium">203.0.113.78</p>
|
||||
<p class="text-xs text-gray-400">SQL注入 · 15分钟前</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 bg-warning/20 text-warning text-xs rounded-full">中风险</span>
|
||||
</div>
|
||||
<div class="bg-dark-lighter/30 rounded-lg p-2 flex justify-between items-center">
|
||||
<div>
|
||||
<p class="text-sm font-medium">54.176.101.202</p>
|
||||
<p class="text-xs text-gray-400">XSS攻击 · 28分钟前</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 bg-warning/20 text-warning text-xs rounded-full">中风险</span>
|
||||
</div>
|
||||
<div class="bg-dark-lighter/30 rounded-lg p-2 flex justify-between items-center">
|
||||
<div>
|
||||
<p class="text-sm font-medium">192.168.1.100</p>
|
||||
<p class="text-xs text-gray-400">暴力破解 · 42分钟前</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 bg-warning/20 text-warning text-xs rounded-full">中风险</span>
|
||||
</div>
|
||||
<div class="bg-dark-lighter/30 rounded-lg p-2 flex justify-between items-center">
|
||||
<div>
|
||||
<p class="text-sm font-medium">104.236.209.25</p>
|
||||
<p class="text-xs text-gray-400">端口扫描 · 1小时前</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 bg-gray-medium/20 text-gray-medium text-xs rounded-full">低风险</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中间地图区域 -->
|
||||
<div class="w-full lg:w-3/5 flex flex-col gap-4">
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg flex-grow relative overflow-hidden">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<h2 class="text-lg font-semibold">全球攻击态势</h2>
|
||||
<div class="flex space-x-2">
|
||||
<button class="px-3 py-1 bg-primary/20 text-primary text-sm rounded-lg hover:bg-primary/30 transition-colors">
|
||||
<i class="fa fa-play mr-1"></i>实时
|
||||
</button>
|
||||
<button class="px-3 py-1 bg-dark-lighter text-gray-300 text-sm rounded-lg hover:bg-dark-lighter/70 transition-colors">
|
||||
<i class="fa fa-history mr-1"></i>历史
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 地图容器 -->
|
||||
<div id="map-container" class="w-full h-[calc(100%-40px)] rounded-lg overflow-hidden relative">
|
||||
<!-- 瓦片地图将在这里通过JS加载 -->
|
||||
<div id="map" class="w-full h-full relative">
|
||||
<!-- 地图加载指示器 -->
|
||||
<div id="map-loading" class="absolute inset-0 flex items-center justify-center bg-dark-light/80 z-10">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="w-12 h-12 border-4 border-primary border-t-transparent rounded-full animate-spin"></div>
|
||||
<p class="mt-2 text-gray-300">加载地图数据...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 服务器位置标记 -->
|
||||
<div id="server-marker" class="absolute" style="left: 75%; top: 45%; transform: translate(-50%, -50%);">
|
||||
<div class="w-4 h-4 rounded-full bg-primary shadow-lg glow pulse"></div>
|
||||
<div class="absolute -inset-1 bg-primary/20 rounded-full animate-ping"></div>
|
||||
<div class="absolute -inset-3 bg-primary/10 rounded-full animate-ping" style="animation-delay: 1s;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 攻击线路将通过JS动态添加 -->
|
||||
<svg id="attack-lines" class="absolute inset-0 w-full h-full pointer-events-none"></svg>
|
||||
|
||||
<!-- 攻击信息卡片将通过JS动态添加 -->
|
||||
<div id="attack-info-card" class="hidden absolute bg-dark-light/90 backdrop-blur-md rounded-lg p-3 shadow-xl border border-dark-lighter min-w-[200px] z-20">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="font-semibold text-white">攻击详情</h3>
|
||||
<span id="attack-severity" class="px-2 py-0.5 bg-danger/20 text-danger text-xs rounded-full">高风险</span>
|
||||
</div>
|
||||
<div class="space-y-1 text-sm">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400">源IP:</span>
|
||||
<span id="attack-ip" class="text-white">182.168.123.45</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400">地区:</span>
|
||||
<span id="attack-region" class="text-white">美国</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400">攻击类型:</span>
|
||||
<span id="attack-type" class="text-white">DDOS</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400">攻击次数:</span>
|
||||
<span id="attack-count" class="text-white">245</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-400">首次检测:</span>
|
||||
<span id="attack-first-detected" class="text-white">2023-05-15 14:30</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 pt-2 border-t border-dark-lighter">
|
||||
<button class="w-full py-1.5 bg-danger/20 text-danger text-sm rounded-lg hover:bg-danger/30 transition-colors">
|
||||
<i class="fa fa-shield mr-1"></i>加强防护
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧数据面板 -->
|
||||
<div class="w-full lg:w-1/5 flex flex-col gap-4">
|
||||
<!-- 攻击趋势 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg">
|
||||
<h2 class="text-lg font-semibold mb-3">攻击趋势</h2>
|
||||
<div class="h-48">
|
||||
<canvas id="attackTrendChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 攻击源分布 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg">
|
||||
<h2 class="text-lg font-semibold mb-3">攻击源分布</h2>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<div class="flex justify-between mb-1">
|
||||
<span class="text-sm text-gray-300">美国</span>
|
||||
<span class="text-sm font-medium">32%</span>
|
||||
</div>
|
||||
<div class="w-full bg-dark-lighter rounded-full h-2">
|
||||
<div class="bg-danger h-2 rounded-full" style="width: 32%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between mb-1">
|
||||
<span class="text-sm text-gray-300">俄罗斯</span>
|
||||
<span class="text-sm font-medium">24%</span>
|
||||
</div>
|
||||
<div class="w-full bg-dark-lighter rounded-full h-2">
|
||||
<div class="bg-warning h-2 rounded-full" style="width: 24%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between mb-1">
|
||||
<span class="text-sm text-gray-300">中国</span>
|
||||
<span class="text-sm font-medium">18%</span>
|
||||
</div>
|
||||
<div class="w-full bg-dark-lighter rounded-full h-2">
|
||||
<div class="bg-primary h-2 rounded-full" style="width: 18%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between mb-1">
|
||||
<span class="text-sm text-gray-300">印度</span>
|
||||
<span class="text-sm font-medium">12%</span>
|
||||
</div>
|
||||
<div class="w-full bg-dark-lighter rounded-full h-2">
|
||||
<div class="bg-secondary h-2 rounded-full" style="width: 12%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between mb-1">
|
||||
<span class="text-sm text-gray-300">其他</span>
|
||||
<span class="text-sm font-medium">14%</span>
|
||||
</div>
|
||||
<div class="w-full bg-dark-lighter rounded-full h-2">
|
||||
<div class="bg-gray-medium h-2 rounded-full" style="width: 14%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 防护效果 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg">
|
||||
<h2 class="text-lg font-semibold mb-3">防护效果</h2>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div class="bg-dark-lighter/50 rounded-lg p-3 text-center">
|
||||
<div class="text-2xl font-bold text-success mb-1">99.8%</div>
|
||||
<p class="text-xs text-gray-400">拦截成功率</p>
|
||||
</div>
|
||||
<div class="bg-dark-lighter/50 rounded-lg p-3 text-center">
|
||||
<div class="text-2xl font-bold text-danger mb-1">0.2%</div>
|
||||
<p class="text-xs text-gray-400">漏报率</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统状态 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg flex-grow">
|
||||
<h2 class="text-lg font-semibold mb-3">系统状态</h2>
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div class="w-2 h-2 rounded-full bg-success mr-2"></div>
|
||||
<span class="text-sm">Web应用防火墙</span>
|
||||
</div>
|
||||
<span class="text-xs text-gray-400">正常</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div class="w-2 h-2 rounded-full bg-success mr-2"></div>
|
||||
<span class="text-sm">入侵检测系统</span>
|
||||
</div>
|
||||
<span class="text-xs text-gray-400">正常</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div class="w-2 h-2 rounded-full bg-success mr-2"></div>
|
||||
<span class="text-sm">流量清洗系统</span>
|
||||
</div>
|
||||
<span class="text-xs text-gray-400">正常</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div class="w-2 h-2 rounded-full bg-warning mr-2"></div>
|
||||
<span class="text-sm">威胁情报更新</span>
|
||||
</div>
|
||||
<span class="text-xs text-gray-400">延迟</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div class="w-2 h-2 rounded-full bg-success mr-2"></div>
|
||||
<span class="text-sm">日志分析系统</span>
|
||||
</div>
|
||||
<span class="text-xs text-gray-400">正常</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="bg-dark-light/50 backdrop-blur-md rounded-xl p-4 border border-dark-lighter shadow-lg">
|
||||
<div class="space-y-3">
|
||||
<button class="w-full py-2 bg-primary rounded-lg hover:bg-primary/90 transition-colors flex items-center justify-center">
|
||||
<i class="fa fa-refresh mr-2"></i>刷新数据
|
||||
</button>
|
||||
<button class="w-full py-2 bg-dark-lighter text-gray-300 rounded-lg hover:bg-dark-lighter/70 transition-colors flex items-center justify-center">
|
||||
<i class="fa fa-history mr-2"></i>历史记录
|
||||
</button>
|
||||
<button class="w-full py-2 bg-dark-lighter text-gray-300 rounded-lg hover:bg-dark-lighter/70 transition-colors flex items-center justify-center">
|
||||
<i class="fa fa-cog mr-2"></i>系统设置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- API调用示例区域 -->
|
||||
<div class="fixed bottom-4 right-4 bg-dark-light/80 backdrop-blur-md rounded-lg p-4 border border-dark-lighter shadow-lg z-50">
|
||||
<h3 class="text-sm font-semibold mb-2">API调用示例</h3>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center space-x-2">
|
||||
<input type="text" id="api-region" placeholder="地区编号" class="px-3 py-1 bg-dark-lighter rounded-lg text-sm w-24 focus:outline-none focus:ring-1 focus:ring-primary">
|
||||
<input type="text" id="api-count" placeholder="攻击数量" class="px-3 py-1 bg-dark-lighter rounded-lg text-sm w-24 focus:outline-none focus:ring-1 focus:ring-primary">
|
||||
<select id="api-type" class="px-3 py-1 bg-dark-lighter rounded-lg text-sm w-32 focus:outline-none focus:ring-1 focus:ring-primary">
|
||||
<option value="ddos">DDOS</option>
|
||||
<option value="sql">SQL注入</option>
|
||||
<option value="xss">XSS攻击</option>
|
||||
<option value="brute">暴力破解</option>
|
||||
<option value="scan">端口扫描</option>
|
||||
</select>
|
||||
</div>
|
||||
<button id="api-simulate" class="w-full py-1.5 bg-primary/20 text-primary text-sm rounded-lg hover:bg-primary/30 transition-colors">
|
||||
模拟攻击
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 全球各地区坐标映射(示例数据)
|
||||
const regionCoordinates = {
|
||||
"US": { name: "美国", x: 20, y: 40, ip: "182.168.123.45" },
|
||||
"RU": { name: "俄罗斯", x: 70, y: 30, ip: "203.0.113.78" },
|
||||
"CN": { name: "中国", x: 85, y: 45, ip: "54.176.101.202" },
|
||||
"IN": { name: "印度", x: 75, y: 55, ip: "192.168.1.100" },
|
||||
"DE": { name: "德国", x: 50, y: 35, ip: "104.236.209.25" },
|
||||
"JP": { name: "日本", x: 90, y: 40, ip: "172.16.254.1" },
|
||||
"BR": { name: "巴西", x: 30, y: 70, ip: "198.51.100.1" },
|
||||
"UK": { name: "英国", x: 48, y: 32, ip: "203.0.113.25" },
|
||||
"AU": { name: "澳大利亚", x: 90, y: 75, ip: "192.0.2.1" },
|
||||
"FR": { name: "法国", x: 50, y: 35, ip: "198.51.100.25" }
|
||||
};
|
||||
|
||||
// 攻击类型配置
|
||||
const attackTypes = {
|
||||
"ddos": { name: "DDOS", color: "#FF4D4F", severity: "高风险" },
|
||||
"sql": { name: "SQL注入", color: "#FF7D00", severity: "中风险" },
|
||||
"xss": { name: "XSS攻击", color: "#FF7D00", severity: "中风险" },
|
||||
"brute": { name: "暴力破解", color: "#FF7D00", severity: "中风险" },
|
||||
"scan": { name: "端口扫描", color: "#86909C", severity: "低风险" }
|
||||
};
|
||||
|
||||
// 服务器位置
|
||||
const serverPosition = { x: 75, y: 45 };
|
||||
|
||||
// 地图元素
|
||||
const mapContainer = document.getElementById('map-container');
|
||||
const mapElement = document.getElementById('map');
|
||||
const attackLines = document.getElementById('attack-lines');
|
||||
const attackInfoCard = document.getElementById('attack-info-card');
|
||||
const mapLoading = document.getElementById('map-loading');
|
||||
|
||||
// 初始化地图
|
||||
function initMap() {
|
||||
// 模拟地图加载
|
||||
setTimeout(() => {
|
||||
// 创建地图瓦片
|
||||
const mapWidth = mapElement.offsetWidth;
|
||||
const mapHeight = mapElement.offsetHeight;
|
||||
|
||||
// 使用BBBike extracts的瓦片地图
|
||||
const tileSize = 256;
|
||||
const zoom = 2;
|
||||
const tilesX = Math.ceil(mapWidth / tileSize) + 2;
|
||||
const tilesY = Math.ceil(mapHeight / tileSize) + 2;
|
||||
|
||||
// 这里应该使用真实的瓦片地图URL,例如OpenStreetMap或BBBike extracts
|
||||
// 为了演示,我们使用模拟的瓦片
|
||||
for (let x = 0; x < tilesX; x++) {
|
||||
for (let y = 0; y < tilesY; y++) {
|
||||
const tile = document.createElement('div');
|
||||
tile.className = 'absolute w-[256px] h-[256px] opacity-80';
|
||||
tile.style.left = `${x * tileSize - 256}px`;
|
||||
tile.style.top = `${y * tileSize - 256}px`;
|
||||
|
||||
// 使用BBBike extracts的瓦片地图
|
||||
// 注意:实际使用时需要替换为有效的瓦片服务器URL
|
||||
tile.style.backgroundImage = `url(https://tile.openstreetmap.org/${zoom}/${x}/${y}.png)`;
|
||||
tile.style.backgroundSize = 'cover';
|
||||
tile.style.filter = 'brightness(0.5)';
|
||||
|
||||
mapElement.appendChild(tile);
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏加载指示器
|
||||
mapLoading.classList.add('hidden');
|
||||
|
||||
// 模拟一些初始攻击线路
|
||||
simulateInitialAttacks();
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
// 模拟初始攻击
|
||||
function simulateInitialAttacks() {
|
||||
const regions = Object.keys(regionCoordinates);
|
||||
const attackTypes = Object.keys(attackTypes);
|
||||
|
||||
// 随机生成3-5条初始攻击线路
|
||||
const attackCount = Math.floor(Math.random() * 3) + 3;
|
||||
for (let i = 0; i < attackCount; i++) {
|
||||
const randomRegion = regions[Math.floor(Math.random() * regions.length)];
|
||||
const randomType = attackTypes[Math.floor(Math.random() * attackTypes.length)];
|
||||
const count = Math.floor(Math.random() * 300) + 50;
|
||||
|
||||
setTimeout(() => {
|
||||
addAttackLine(randomRegion, count, randomType);
|
||||
}, i * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加攻击线路
|
||||
function addAttackLine(regionCode, count, type) {
|
||||
const region = regionCoordinates[regionCode];
|
||||
const attackType = attackTypes[type];
|
||||
|
||||
if (!region || !attackType) {
|
||||
console.error("无效的地区或攻击类型");
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算攻击强度(基于攻击数量)
|
||||
const maxCount = 500;
|
||||
const intensity = Math.min(count / maxCount, 1);
|
||||
|
||||
// 创建SVG路径
|
||||
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||
|
||||
// 计算路径
|
||||
const mapWidth = mapElement.offsetWidth;
|
||||
const mapHeight = mapElement.offsetHeight;
|
||||
|
||||
const startX = (region.x / 100) * mapWidth;
|
||||
const startY = (region.y / 100) * mapHeight;
|
||||
const endX = (serverPosition.x / 100) * mapWidth;
|
||||
const endY = (serverPosition.y / 100) * mapHeight;
|
||||
|
||||
// 添加曲线效果
|
||||
const controlX = (startX + endX) / 2 + (Math.random() - 0.5) * 100;
|
||||
const controlY = (startY + endY) / 2 + (Math.random() - 0.5) * 100;
|
||||
|
||||
// 创建渐变
|
||||
const gradientId = `gradient-${Date.now()}`;
|
||||
const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
||||
const linearGradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
|
||||
linearGradient.setAttribute("id", gradientId);
|
||||
linearGradient.setAttribute("x1", "0%");
|
||||
linearGradient.setAttribute("y1", "0%");
|
||||
linearGradient.setAttribute("x2", "100%");
|
||||
linearGradient.setAttribute("y2", "0%");
|
||||
|
||||
const stop1 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
|
||||
stop1.setAttribute("offset", "0%");
|
||||
stop1.setAttribute("stop-color", attackType.color);
|
||||
stop1.setAttribute("stop-opacity", intensity);
|
||||
|
||||
const stop2 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
|
||||
stop2.setAttribute("offset", "100%");
|
||||
stop2.setAttribute("stop-color", attackType.color);
|
||||
stop2.setAttribute("stop-opacity", 0);
|
||||
|
||||
linearGradient.appendChild(stop1);
|
||||
linearGradient.appendChild(stop2);
|
||||
defs.appendChild(linearGradient);
|
||||
|
||||
// 设置路径
|
||||
path.setAttribute("d", `M ${startX},${startY} Q ${controlX},${controlY} ${endX},${endY}`);
|
||||
path.setAttribute("stroke", `url(#${gradientId})`);
|
||||
path.setAttribute("stroke-width", 2);
|
||||
path.setAttribute("fill", "none");
|
||||
path.setAttribute("class", "attack-line");
|
||||
path.setAttribute("data-region", regionCode);
|
||||
path.setAttribute("data-count", count);
|
||||
path.setAttribute("data-type", type);
|
||||
|
||||
// 添加到SVG
|
||||
attackLines.appendChild(defs);
|
||||
attackLines.appendChild(path);
|
||||
|
||||
// 添加攻击源标记
|
||||
const attackMarker = document.createElement('div');
|
||||
attackMarker.className = 'absolute w-2 h-2 rounded-full bg-danger shadow-lg animate-pulse';
|
||||
attackMarker.style.left = `${startX - 1}px`;
|
||||
attackMarker.style.top = `${startY - 1}px`;
|
||||
attackMarker.setAttribute("data-path-id", attackLines.children.length - 1);
|
||||
|
||||
mapElement.appendChild(attackMarker);
|
||||
|
||||
// 添加点击事件
|
||||
path.addEventListener('mouseover', () => showAttackInfo(region, count, attackType, startX, startY));
|
||||
path.addEventListener('mouseout', () => hideAttackInfo());
|
||||
|
||||
// 清理旧的攻击线(保留最近的10条)
|
||||
cleanupOldAttacks();
|
||||
}
|
||||
|
||||
// 显示攻击信息卡片
|
||||
function showAttackInfo(region, count, attackType, x, y) {
|
||||
// 更新卡片内容
|
||||
document.getElementById('attack-ip').textContent = region.ip;
|
||||
document.getElementById('attack-region').textContent = region.name;
|
||||
document.getElementById('attack-type').textContent = attackType.name;
|
||||
document.getElementById('attack-count').textContent = count;
|
||||
document.getElementById('attack-severity').textContent = attackType.severity;
|
||||
document.getElementById('attack-severity').className = `px-2 py-0.5 ${
|
||||
attackType.severity === '高风险' ? 'bg-danger/20 text-danger' :
|
||||
attackType.severity === '中风险' ? 'bg-warning/20 text-warning' :
|
||||
'bg-gray-medium/20 text-gray-medium'
|
||||
} text-xs rounded-full`;
|
||||
|
||||
// 设置当前时间
|
||||
const now = new Date();
|
||||
const timeString = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
|
||||
document.getElementById('attack-first-detected').textContent = timeString;
|
||||
|
||||
// 定位卡片
|
||||
const cardWidth = attackInfoCard.offsetWidth;
|
||||
const cardHeight = attackInfoCard.offsetHeight;
|
||||
const mapWidth = mapElement.offsetWidth;
|
||||
const mapHeight = mapElement.offsetHeight;
|
||||
|
||||
// 确保卡片在地图内显示
|
||||
let left = x + 20;
|
||||
let top = y - cardHeight / 2;
|
||||
|
||||
if (left + cardWidth > mapWidth) {
|
||||
left = x - cardWidth - 20;
|
||||
}
|
||||
|
||||
if (top < 0) {
|
||||
top = 0;
|
||||
} else if (top + cardHeight > mapHeight) {
|
||||
top = mapHeight - cardHeight;
|
||||
}
|
||||
|
||||
attackInfoCard.style.left = `${left}px`;
|
||||
attackInfoCard.style.top = `${top}px`;
|
||||
|
||||
// 显示卡片
|
||||
attackInfoCard.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 隐藏攻击信息卡片
|
||||
function hideAttackInfo() {
|
||||
attackInfoCard.classList.add('hidden');
|
||||
}
|
||||
|
||||
// 清理旧的攻击线路
|
||||
function cleanupOldAttacks() {
|
||||
// 保留最近的10条攻击线路
|
||||
const paths = attackLines.querySelectorAll('path');
|
||||
if (paths.length > 10) {
|
||||
const countToRemove = paths.length - 10;
|
||||
for (let i = 0; i < countToRemove; i++) {
|
||||
attackLines.removeChild(paths[i]);
|
||||
}
|
||||
|
||||
// 清理对应的标记
|
||||
const markers = mapElement.querySelectorAll('.animate-pulse');
|
||||
if (markers.length > 10) {
|
||||
const markersToRemove = markers.length - 10;
|
||||
for (let i = 0; i < markersToRemove; i++) {
|
||||
mapElement.removeChild(markers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化图表
|
||||
function initCharts() {
|
||||
// 攻击类型分布图表
|
||||
const attackTypesCtx = document.getElementById('attackTypesChart').getContext('2d');
|
||||
new Chart(attackTypesCtx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: ['DDOS', 'SQL注入', 'XSS攻击', '暴力破解', '端口扫描'],
|
||||
datasets: [{
|
||||
data: [35, 25, 15, 10, 15],
|
||||
backgroundColor: [
|
||||
'#FF4D4F',
|
||||
'#FF7D00',
|
||||
'#36CFC9',
|
||||
'#165DFF',
|
||||
'#86909C'
|
||||
],
|
||||
borderWidth: 0,
|
||||
cutout: '70%'
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
color: '#F2F3F5',
|
||||
font: {
|
||||
size: 10
|
||||
},
|
||||
padding: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 攻击趋势图表
|
||||
const attackTrendCtx = document.getElementById('attackTrendChart').getContext('2d');
|
||||
new Chart(attackTrendCtx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'],
|
||||
datasets: [{
|
||||
label: '攻击次数',
|
||||
data: [120, 90, 180, 150, 200, 170],
|
||||
borderColor: '#165DFF',
|
||||
backgroundColor: 'rgba(22, 93, 255, 0.1)',
|
||||
fill: true,
|
||||
tension: 0.4,
|
||||
borderWidth: 2
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
grid: {
|
||||
color: 'rgba(255, 255, 255, 0.05)'
|
||||
},
|
||||
ticks: {
|
||||
color: '#86909C',
|
||||
font: {
|
||||
size: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
x: {
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
color: '#86909C',
|
||||
font: {
|
||||
size: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化事件监听
|
||||
function initEventListeners() {
|
||||
// API模拟按钮
|
||||
document.getElementById('api-simulate').addEventListener('click', () => {
|
||||
const regionCode = document.getElementById('api-region').value;
|
||||
const count = parseInt(document.getElementById('api-count').value);
|
||||
const type = document.getElementById('api-type').value;
|
||||
|
||||
if (!regionCode || isNaN(count) || count <= 0) {
|
||||
alert('请输入有效的地区编号和攻击数量');
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionCoordinates[regionCode]) {
|
||||
addAttackLine(regionCode, count, type);
|
||||
} else {
|
||||
alert('无效的地区编号');
|
||||
}
|
||||
});
|
||||
|
||||
// 窗口大小变化时重新计算地图尺寸
|
||||
window.addEventListener('resize', () => {
|
||||
// 简单处理:刷新页面
|
||||
// 实际应用中应更优雅地处理地图重绘
|
||||
if (mapElement.children.length > 0) {
|
||||
mapElement.innerHTML = '';
|
||||
attackLines.innerHTML = '';
|
||||
initMap();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 页面加载完成后初始化
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
initMap();
|
||||
initCharts();
|
||||
initEventListeners();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,466 +0,0 @@
|
||||
/**
|
||||
* 高性能跨iframe资源共享系统 - 通用版
|
||||
* 修复了资源处理和消息传递的问题
|
||||
*/
|
||||
class ResourceShareManager {
|
||||
constructor() {
|
||||
this.cache = new Map();
|
||||
this.pendingRequests = new Map();
|
||||
this.blobUrls = new Set();
|
||||
this.isTopLevel = !window.parent || window.parent === window;
|
||||
this.myOrigin = window.location.origin;
|
||||
|
||||
// 配置阈值
|
||||
this.POST_MESSAGE_LIMIT = 1 * 1024 * 1024; // 1MB
|
||||
this.BLOB_LIMIT = 1024 * 1024 * 1024; // 1GB
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.log(`系统初始化 - ${this.isTopLevel ? '顶级页面' : '子页面'}`, 'info');
|
||||
this.log(`传输阈值: PM=${this.formatBytes(this.POST_MESSAGE_LIMIT)}, Blob=${this.formatBytes(this.BLOB_LIMIT)}`, 'info');
|
||||
|
||||
if (this.isTopLevel) {
|
||||
window.addEventListener('message', (event) => {
|
||||
this.handleChildRequest(event);
|
||||
});
|
||||
this.log('顶级页面:监听同源子页面请求', 'success');
|
||||
} else {
|
||||
this.log('子页面:准备向同源父页面请求资源', 'info');
|
||||
}
|
||||
|
||||
// 页面卸载时清理Blob URL
|
||||
window.addEventListener('beforeunload', () => {
|
||||
this.cleanupBlobUrls();
|
||||
});
|
||||
|
||||
this.updateStatus();
|
||||
}
|
||||
|
||||
async loadResource(type, url) {
|
||||
const cacheKey = `${type}:${url}`;
|
||||
|
||||
if (this.cache.has(cacheKey)) {
|
||||
const cachedData = this.cache.get(cacheKey);
|
||||
this.log(`本地缓存命中: ${cacheKey}`, 'cache');
|
||||
return this.processCachedData(cachedData, type);
|
||||
}
|
||||
|
||||
if (this.isTopLevel) {
|
||||
const content = await this.fetchAndCache(type, url);
|
||||
return this.processContent(content, type);
|
||||
} else {
|
||||
try {
|
||||
const parentResponse = await this.requestFromParent(type, url);
|
||||
if (parentResponse !== undefined && parentResponse !== null) {
|
||||
this.log(`从父页面获取资源: ${cacheKey}`, 'response');
|
||||
return this.processParentResponse(parentResponse, type);
|
||||
}
|
||||
} catch (error) {
|
||||
this.log(`父页面请求失败: ${error.message}`, 'warning');
|
||||
}
|
||||
|
||||
const content = await this.fetchAndCache(type, url);
|
||||
const processedContent = this.processContent(content, type);
|
||||
this.sendToParent(type, url, content);
|
||||
return processedContent;
|
||||
}
|
||||
}
|
||||
|
||||
async fetchAndCache(type, url) {
|
||||
const cacheKey = `${type}:${url}`;
|
||||
|
||||
if (this.pendingRequests.has(cacheKey)) {
|
||||
this.log(`等待已有请求: ${cacheKey}`, 'request');
|
||||
return await this.pendingRequests.get(cacheKey);
|
||||
}
|
||||
|
||||
this.log(`发起网络请求: ${cacheKey}`, 'request');
|
||||
|
||||
const requestPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const content = await response.text();
|
||||
const size = new Blob([content]).size;
|
||||
|
||||
// 超过1GB的资源不缓存
|
||||
if (size > this.BLOB_LIMIT) {
|
||||
this.log(`资源过大 (${this.formatBytes(size)}),跳过缓存: ${cacheKey}`, 'large');
|
||||
resolve(content);
|
||||
return;
|
||||
}
|
||||
|
||||
this.cache.set(cacheKey, content);
|
||||
this.log(`资源已缓存 (${this.formatBytes(size)}): ${cacheKey}`, 'cache');
|
||||
this.updateStatus();
|
||||
resolve(content);
|
||||
} catch (error) {
|
||||
this.log(`请求失败: ${cacheKey} - ${error.message}`, 'danger');
|
||||
reject(error);
|
||||
} finally {
|
||||
this.pendingRequests.delete(cacheKey);
|
||||
}
|
||||
});
|
||||
|
||||
this.pendingRequests.set(cacheKey, requestPromise);
|
||||
return await requestPromise;
|
||||
}
|
||||
|
||||
processContent(content, type) {
|
||||
if (!content) {
|
||||
this.log('警告:处理空内容', 'warning');
|
||||
return content;
|
||||
}
|
||||
|
||||
const size = new Blob([content]).size;
|
||||
|
||||
if (size <= this.POST_MESSAGE_LIMIT) {
|
||||
// 小文件:直接返回内容
|
||||
return content;
|
||||
} else {
|
||||
// 大文件:创建Blob URL
|
||||
const blob = new Blob([content], { type: type === 'script' ? 'text/javascript' : 'text/css' });
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
this.blobUrls.add(blobUrl);
|
||||
this.log(`创建Blob URL (${this.formatBytes(size)}): ${blobUrl}`, 'blob');
|
||||
this.updateStatus();
|
||||
return blobUrl;
|
||||
}
|
||||
}
|
||||
|
||||
processCachedData(cachedData, type) {
|
||||
if (!cachedData) {
|
||||
this.log('警告:缓存数据为空', 'warning');
|
||||
return cachedData;
|
||||
}
|
||||
|
||||
// 如果缓存的是Blob URL,直接返回
|
||||
if (typeof cachedData === 'string' && cachedData.startsWith('blob:')) {
|
||||
return cachedData;
|
||||
}
|
||||
// 否则按内容处理
|
||||
return this.processContent(cachedData, type);
|
||||
}
|
||||
|
||||
processParentResponse(response, type) {
|
||||
if (!response) {
|
||||
this.log('警告:父页面响应为空', 'warning');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (response.contentType === 'blob') {
|
||||
// 收到Blob URL
|
||||
if (response.content) {
|
||||
this.blobUrls.add(response.content);
|
||||
this.updateStatus();
|
||||
}
|
||||
return response.content;
|
||||
} else {
|
||||
// 收到直接内容
|
||||
return this.processContent(response.content, type);
|
||||
}
|
||||
}
|
||||
|
||||
async requestFromParent(type, url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const messageId = Date.now() + Math.random();
|
||||
const timeout = setTimeout(() => {
|
||||
reject(new Error('请求超时'));
|
||||
}, 10000); // 增加超时时间以适应大文件
|
||||
|
||||
const handleMessage = (event) => {
|
||||
if (event.origin !== this.myOrigin) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.data.type === 'resource-response' && event.data.messageId === messageId) {
|
||||
clearTimeout(timeout);
|
||||
window.removeEventListener('message', handleMessage);
|
||||
if (event.data.success) {
|
||||
resolve({
|
||||
contentType: event.data.contentType || 'direct',
|
||||
content: event.data.content
|
||||
});
|
||||
} else {
|
||||
reject(new Error(event.data.error));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', handleMessage);
|
||||
|
||||
window.parent.postMessage({
|
||||
type: 'resource-request',
|
||||
messageId,
|
||||
resourceType: type,
|
||||
url: url
|
||||
}, this.myOrigin);
|
||||
});
|
||||
}
|
||||
|
||||
sendToParent(type, url, content) {
|
||||
if (!content) {
|
||||
this.log('警告:发送空内容到父页面', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const size = new Blob([content]).size;
|
||||
let messageData;
|
||||
|
||||
if (size <= this.POST_MESSAGE_LIMIT) {
|
||||
// 小文件:直接发送内容
|
||||
messageData = {
|
||||
type: 'resource-cache-update',
|
||||
resourceType: type,
|
||||
url: url,
|
||||
contentType: 'direct',
|
||||
content: content
|
||||
};
|
||||
} else {
|
||||
// 大文件:创建Blob并发送URL
|
||||
const blob = new Blob([content], { type: type === 'script' ? 'text/javascript' : 'text/css' });
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
this.blobUrls.add(blobUrl);
|
||||
|
||||
messageData = {
|
||||
type: 'resource-cache-update',
|
||||
resourceType: type,
|
||||
url: url,
|
||||
contentType: 'blob',
|
||||
content: blobUrl
|
||||
};
|
||||
}
|
||||
|
||||
window.parent.postMessage(messageData, this.myOrigin);
|
||||
this.log(`发送缓存到父页面 (${this.formatBytes(size)}): ${type}:${url}`, 'response');
|
||||
}
|
||||
|
||||
handleChildRequest(event) {
|
||||
if (event.origin !== this.myOrigin) {
|
||||
this.log(`🚨 安全拦截:拒绝来自非同源 (${event.origin}) 的消息`, 'security');
|
||||
return;
|
||||
}
|
||||
|
||||
const { type, messageId, resourceType, url } = event.data;
|
||||
|
||||
if (type === 'resource-request') {
|
||||
const cacheKey = `${resourceType}:${url}`;
|
||||
|
||||
if (this.cache.has(cacheKey)) {
|
||||
const content = this.cache.get(cacheKey);
|
||||
const size = new Blob([content]).size;
|
||||
let responseData;
|
||||
|
||||
if (size <= this.POST_MESSAGE_LIMIT) {
|
||||
// 小文件:直接发送
|
||||
responseData = {
|
||||
type: 'resource-response',
|
||||
messageId,
|
||||
success: true,
|
||||
contentType: 'direct',
|
||||
content: content
|
||||
};
|
||||
} else {
|
||||
// 大文件:创建Blob并发送URL
|
||||
const blob = new Blob([content], { type: resourceType === 'script' ? 'text/javascript' : 'text/css' });
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
this.blobUrls.add(blobUrl);
|
||||
|
||||
responseData = {
|
||||
type: 'resource-response',
|
||||
messageId,
|
||||
success: true,
|
||||
contentType: 'blob',
|
||||
content: blobUrl
|
||||
};
|
||||
}
|
||||
|
||||
event.source.postMessage(responseData, event.origin);
|
||||
this.log(`响应子页面请求 (${this.formatBytes(size)}): ${cacheKey}`, 'response');
|
||||
} else {
|
||||
event.source.postMessage({
|
||||
type: 'resource-response',
|
||||
messageId,
|
||||
success: false,
|
||||
error: 'Resource not cached'
|
||||
}, event.origin);
|
||||
}
|
||||
} else if (type === 'resource-cache-update') {
|
||||
const cacheKey = `${resourceType}:${url}`;
|
||||
|
||||
// 根据内容类型处理
|
||||
if (event.data.contentType === 'blob') {
|
||||
// 存储Blob URL的引用(注意:这里不存储实际内容)
|
||||
this.cache.set(cacheKey, event.data.content);
|
||||
this.blobUrls.add(event.data.content);
|
||||
} else {
|
||||
// 直接存储内容
|
||||
this.cache.set(cacheKey, event.data.content);
|
||||
}
|
||||
|
||||
this.log(`更新缓存: ${cacheKey}`, 'cache');
|
||||
this.updateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
cleanupBlobUrls() {
|
||||
this.blobUrls.forEach(url => {
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
this.blobUrls.clear();
|
||||
this.log('已清理所有Blob URL', 'info');
|
||||
this.updateStatus();
|
||||
}
|
||||
|
||||
formatBytes(bytes) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
log(message, category = 'info') {
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
const logMessage = `[${timestamp}] ${message}`;
|
||||
|
||||
// 尝试更新UI(如果存在)
|
||||
const logContainer = document.getElementById('logContainer');
|
||||
if (logContainer) {
|
||||
const logEntry = document.createElement('div');
|
||||
logEntry.className = `log-entry ${category}`;
|
||||
logEntry.textContent = logMessage;
|
||||
logContainer.appendChild(logEntry);
|
||||
logContainer.scrollTop = logContainer.scrollHeight;
|
||||
}
|
||||
|
||||
// 始终输出到控制台
|
||||
console.log(`[ResourceShare] ${message}`);
|
||||
}
|
||||
|
||||
updateStatus() {
|
||||
// 尝试更新UI状态(如果存在)
|
||||
const pageTypeEl = document.getElementById('pageType');
|
||||
const cacheCountEl = document.getElementById('cacheCount');
|
||||
const blobCountEl = document.getElementById('blobCount');
|
||||
const currentOriginEl = document.getElementById('currentOrigin');
|
||||
|
||||
if(pageTypeEl) pageTypeEl.textContent = this.isTopLevel ? '顶级页面' : '子页面';
|
||||
if(cacheCountEl) cacheCountEl.textContent = this.cache.size;
|
||||
if(blobCountEl) blobCountEl.textContent = this.blobUrls.size;
|
||||
if(currentOriginEl) currentOriginEl.textContent = this.myOrigin;
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
this.cache.clear();
|
||||
this.cleanupBlobUrls();
|
||||
this.log('缓存已清空', 'warning');
|
||||
this.updateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义元素实现
|
||||
class ResourceShareElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.manager = window.resourceShareManager;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const type = this.getAttribute('type');
|
||||
const url = this.getAttribute('src') || this.getAttribute('href');
|
||||
|
||||
if (!type || !url) {
|
||||
console.error('ResourceShare: 缺少必要的 type 或 url 属性');
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadResource(type, url);
|
||||
}
|
||||
|
||||
async loadResource(type, url) {
|
||||
try {
|
||||
const content = await this.manager.loadResource(type, url);
|
||||
|
||||
if (content) {
|
||||
if (type === 'script') {
|
||||
this.executeScript(content);
|
||||
} else if (type === 'style') {
|
||||
this.injectStyle(content);
|
||||
}
|
||||
} else {
|
||||
this.manager.log(`资源内容为空: ${url}`, 'warning');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`ResourceShare 加载失败: ${url}`, error);
|
||||
this.manager.log(`加载失败: ${url} - ${error.message}`, 'danger');
|
||||
}
|
||||
}
|
||||
|
||||
executeScript(content) {
|
||||
if (!content) {
|
||||
this.manager.log('警告:尝试执行空脚本', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是Blob URL,使用src方式加载
|
||||
if (content.startsWith('blob:')) {
|
||||
const script = document.createElement('script');
|
||||
script.src = content;
|
||||
script.onload = () => {
|
||||
this.manager.log(`JavaScript (Blob) 已执行`, 'success');
|
||||
};
|
||||
script.onerror = (error) => {
|
||||
this.manager.log(`JavaScript (Blob) 执行失败: ${error}`, 'danger');
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
} else {
|
||||
// 直接内容
|
||||
const script = document.createElement('script');
|
||||
script.textContent = content;
|
||||
document.head.appendChild(script);
|
||||
this.manager.log(`JavaScript 已执行`, 'success');
|
||||
}
|
||||
}
|
||||
|
||||
injectStyle(content) {
|
||||
if (!content) {
|
||||
this.manager.log('警告:尝试注入空样式', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是Blob URL,使用link方式加载
|
||||
if (content.startsWith('blob:')) {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = content;
|
||||
link.onload = () => {
|
||||
this.manager.log(`CSS (Blob) 已注入`, 'success');
|
||||
};
|
||||
link.onerror = (error) => {
|
||||
this.manager.log(`CSS (Blob) 注入失败: ${error}`, 'danger');
|
||||
};
|
||||
document.head.appendChild(link);
|
||||
} else {
|
||||
// 直接内容
|
||||
const style = document.createElement('style');
|
||||
style.textContent = content;
|
||||
document.head.appendChild(style);
|
||||
this.manager.log(`CSS 已注入`, 'success');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化系统
|
||||
window.resourceShareManager = new ResourceShareManager();
|
||||
customElements.define('resource-share', ResourceShareElement);
|
||||
|
||||
// 导出管理器供外部使用
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = { ResourceShareManager, ResourceShareElement };
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
import{Nn as e,_ as t,hn as n,ln as r,mn as i}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a}from"./serverScope-O8Rw8SFk.js";import{t as o}from"./CrudTable-B49nrpUt.js";var s={class:`wo-admin-page`},c=t(n({__name:`Admin`,setup(t){return a(`工单管理`),(t,n)=>(e(),r(`div`,s,[i(o,{table:`WorkOrder`,title:`工单管理`,searchable:``,pageable:``,selectable:``,stretch:``})]))}}),[[`__scopeId`,`data-v-7d410849`]]);export{c as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Nn as i,Yn as a,_ as o,an as s,cn as c,en as l,hn as u,ir as d,ln as f,mn as p,on as m,pn as h,sn as g}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as _}from"./serverScope-O8Rw8SFk.js";import{t as v}from"./date-picker-CM_15T0u.js";import{r as y,t as b}from"./select-BGsfCDCJ.js";import{n as ee,t as te}from"./table-DPU4-geg.js";import{r as x,s as S}from"./router-CMu0lceh.js";import{t as ne}from"./button-CPx9BSuo.js";import{t as re}from"./tag-BSnLMVgs.js";import{t as ie}from"./dialog-_5VhSQg5.js";import{t as ae}from"./empty-CnQTxkvl.js";import{t as oe}from"./pagination-DOGDdUWm.js";import{t as se}from"./directive-CY41a6pJ.js";/* empty css */import"./css-CY4c3_XL.js";import"./css-yeo4Q6aC.js";import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-Cy-4mdDD.js";import"./css-DMLZMbB9.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./css-fhPIiYtD.js";import{t as C}from"./AdminBadge-Z72F8Boy.js";import"./css-ByqxgOA-.js";import"./css-D4jab2ni2.js";var ce={class:`audit-log-page`},w={class:`audit-log-header`},T={class:`audit-log-filters`},le={class:`mono`},ue={class:`mono`},de={key:0,style:{color:`var(--el-color-danger)`,padding:`20px`}},fe={class:`audit-log-pagination`},pe={class:`detail-section`},me={class:`detail-base`},he={class:`mono`},ge={class:`mono`},_e={key:0,class:`detail-section`},E={class:`detail-json`},D={key:1,class:`detail-section`},O={class:`detail-json`},k=20,A=o(u({__name:`AuditLog`,setup(o){_(`操作审计日志`);let u=x(),A=s(()=>u.isAdmin),j=d(!1),M=[`User`,`Role`,`Permission`,`Tenant`,`Company`],N=[{value:`add`,label:`新增`},{value:`modify`,label:`修改`},{value:`delete`,label:`删除`}],P=d(``),F=d(``),I=d(null),L=d(1),R=d(0),z=d([]),B=d(!1),V=d(``),H=d(!1),U=d(null);function W(e){return e&&{add:`新增`,modify:`修改`,delete:`删除`}[e]||e||`-`}function G(e){return e&&{add:`success`,modify:`warning`,delete:`danger`}[e]||`info`}function K(e){return e?String(e).replace(`T`,` `).substring(0,19):`-`}function q(e){if(typeof e!=`string`)return e;try{return JSON.parse(e)}catch{return e}}function J(e){if(!e)return null;if(typeof e==`string`){let t=q(e);return typeof t==`object`&&t?t:null}return typeof e==`object`?e:null}let Y=s(()=>J(U.value?.OldData)),X=s(()=>J(U.value?.NewData));function Z(){let e={page:L.value,page_size:k,ordering:`-CreateTime`};return P.value&&(e.TableName=P.value),F.value&&(e.Action=F.value),I.value&&I.value.length===2&&(e.CreateTime__gte=I.value[0]+` 00:00:00`,e.CreateTime__lte=I.value[1]+` 23:59:59`),e}async function Q(){B.value=!0,V.value=``;try{let e=await S(`/API/FormAPI/Get/AuditLog`,Z());Array.isArray(e)?(z.value=e,R.value=e.length):e&&Array.isArray(e.records)?(z.value=e.records,R.value=e.total??z.value.length):(z.value=[],R.value=0)}catch(e){V.value=`加载审计日志失败:`+(e instanceof Error?e.message:String(e)),z.value=[],R.value=0}finally{B.value=!1}}function ve(){L.value=1,Q()}function ye(){P.value=``,F.value=``,I.value=null,L.value=1,Q()}function be(e){L.value=e,Q()}function xe(e){U.value=e,H.value=!0}function $(e){if(!e)return``;try{return JSON.stringify(e,null,2)}catch{return String(e)}}return e(()=>{if(!A.value){j.value=!0;return}Q()}),(e,o)=>{let s=ae,u=ne,d=b,_=y,x=v,S=ee,A=re,q=te,J=oe,Z=ie,Se=se;return i(),f(`div`,ce,[p(C),j.value?(i(),g(s,{key:0,description:`无权访问:该页面仅管理员可查看,请切换至管理员角色或联系管理员`},{image:r(()=>[...o[4]||=[m(`i`,{class:`fas fa-lock`,style:{"font-size":`48px`,color:`var(--el-color-danger)`}},null,-1)]]),_:1})):(i(),f(l,{key:1},[m(`div`,w,[o[6]||=m(`h1`,{class:`page-title`},[m(`i`,{class:`fas fa-history icon-primary`}),m(`span`,null,`操作审计日志`)],-1),p(u,{icon:`Refresh`,onClick:Q},{default:r(()=>[...o[5]||=[h(`刷新`,-1)]]),_:1})]),m(`div`,T,[o[9]||=m(`span`,{class:`filter-label`},`表名:`,-1),p(_,{modelValue:P.value,"onUpdate:modelValue":o[0]||=e=>P.value=e,placeholder:`全部`,clearable:``,style:{width:`140px`}},{default:r(()=>[(i(),f(l,null,n(M,e=>p(d,{key:e,label:e,value:e},null,8,[`label`,`value`])),64))]),_:1},8,[`modelValue`]),o[10]||=m(`span`,{class:`filter-label`},`操作:`,-1),p(_,{modelValue:F.value,"onUpdate:modelValue":o[1]||=e=>F.value=e,placeholder:`全部`,clearable:``,style:{width:`120px`}},{default:r(()=>[(i(),f(l,null,n(N,e=>p(d,{key:e.value,label:e.label,value:e.value},null,8,[`label`,`value`])),64))]),_:1},8,[`modelValue`]),o[11]||=m(`span`,{class:`filter-label`},`时间范围:`,-1),p(x,{modelValue:I.value,"onUpdate:modelValue":o[2]||=e=>I.value=e,type:`daterange`,"range-separator":`至`,"start-placeholder":`开始日期`,"end-placeholder":`结束日期`,"value-format":`YYYY-MM-DD`,style:{width:`280px`}},null,8,[`modelValue`]),p(u,{type:`primary`,icon:`Search`,onClick:ve},{default:r(()=>[...o[7]||=[h(`查询`,-1)]]),_:1}),p(u,{icon:`RefreshLeft`,onClick:ye},{default:r(()=>[...o[8]||=[h(`重置`,-1)]]),_:1})]),a((i(),g(q,{data:z.value,border:``,stripe:``,style:{width:`100%`}Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Nn as e,_ as t,h as n,hn as r,ln as i,mn as a}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as o}from"./serverScope-O8Rw8SFk.js";import{t as s}from"./AdminBadge-Z72F8Boy.js";import{t as c}from"./CrudTable-B49nrpUt.js";var l={class:`company-page`},u=t(r({__name:`Company`,setup(t){o(`公司管理`);let r=n();function u(e){r.push({path:`/company/company-detail`,query:{CompanyUUID:e.CompanyUUID||``}})}return(t,n)=>(e(),i(`div`,l,[a(s),a(c,{table:`Company`,title:`公司管理`,"pk-field":`CompanyUUID`,searchable:``,pageable:``,stretch:``,selectable:``,"on-view":u})]))}}),[[`__scopeId`,`data-v-6eb2ef38`]]);export{u as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as ee,Nn as i,_ as a,an as o,cn as s,en as c,h as l,hn as u,ir as d,ln as f,m as p,mn as m,nr as h,pn as g,pr as _,sn as v}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as y,o as b,u as te}from"./serverScope-O8Rw8SFk.js";import{t as x}from"./date-picker-CM_15T0u.js";import{u as S}from"./use-global-config-D-dPcPvU.js";import{n as C}from"./descriptions-Cq_aE9sg.js";import{r as w,t as T}from"./select-BGsfCDCJ.js";import{n as E,t as D}from"./form-F--u6XQJ.js";import{t as O}from"./alert-BpFV-0dO.js";import{t as k}from"./button-CPx9BSuo.js";import{t as A}from"./tag-BSnLMVgs.js";import{t as j}from"./card-Dj_UeWcA.js";import{t as M}from"./dialog-_5VhSQg5.js";import{t as ne}from"./input-number-CiNOxXL6.js";import{t as re}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-CysIl0tz.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./AdminBadge-Z72F8Boy.js";import"./css-BLJI5-W_.js";import{t as N}from"./CrudTable-B49nrpUt.js";import"./css-ByqxgOA-.js";import{t as P}from"./form-B2Pzr8Vf.js";import{t as ie}from"./DetailPage-m11wfvkM.js";import{t as ae}from"./InfoGrid-C1it9Z2Y.js";import{t as F}from"./useResolveUUIDs-ipmPZLo4.js";var I=`CompanyUUID`,L=a(u({__name:`CompanyDetail`,setup(a){let u=p(),L=l(),{resolveUUIDs:R}=F(),z=d(!1),B=d(null),V=d({}),H=d(``),U=u.query.CompanyUUID||``,W={0:{text:`禁用`,type:`danger`},1:{text:`启用`,type:`success`}};function G(e){return e==null||e===``?``:String(e)}function K(e){if(!e)return`-`;let t=String(e),n=new Date(t);if(isNaN(n.getTime()))return t;let r=e=>String(e).padStart(2,`0`);return`${n.getFullYear()}-${r(n.getMonth()+1)}-${r(n.getDate())} ${r(n.getHours())}:${r(n.getMinutes())}:${r(n.getSeconds())}`}function q(e){return Array.isArray(e)?e:e?.list||[]}async function J(){if(!U){H.value=`缺少 CompanyUUID 参数,无法加载公司详情。`;return}z.value=!0,H.value=``;try{let e=q(await P.list(`Company`,{CompanyUUID:U,pageSize:1})),t=e.find(e=>e.CompanyUUID===U)||e[0];if(!t){H.value=`未找到公司数据`;return}B.value=t,y(G(t.CompanyName)||`公司详情`);let n={};t.ParentCompanyUUID&&(n.parentCompany={table:`Company`,uuids:[t.ParentCompanyUUID]}),t.TenantUUID&&(n.tenant={table:`Tenant`,uuids:[t.TenantUUID]}),Object.keys(n).length&&(V.value=await R(n))}catch(e){H.value=`加载失败: ${e instanceof Error?e.message:String(e)}`}finally{z.value=!1}}function oe(e){L.push({path:`/company/department-detail`,query:{DeptUUID:G(e.DeptUUID)}})}function se(e){L.push({path:`/company/workgroup-detail`,query:{WorkgroupUUID:G(e.WorkgroupUUID)}})}function ce(e){L.push({path:`/company/employee-detail`,query:{UserUUID:G(e.UserUUID)}})}let Y=d(!1),X=d(!1),Z=d([]),Q=h({}),le=o(()=>Z.value.filter(e=>e.editable!==!1&&!e.hideInForm&&e.type!==`hidden`&&e.type!==`divider`&&e.type!==`html`&&e.field!==I));async function $(){if(B.value){try{Z.value.length||(Z.value=await P.getColumns(`Company`))}catch{Z.value=[]}Object.keys(Q).forEach(e=>delete Q[e]),Object.assign(Q,B.value),Y.value=!0}}async function ue(){if(B.value){X.value=!0;try{await P.update(`Company`,B.value[I],{...Q}),b.success(`保存成功`),Y.value=!1,await J()}catch{}finally{X.value=!1}}}return e(J),(e,a)=>{let o=ee(`Edit`),l=S,u=k,d=O,p=C,h=A,y=j,b=te,P=ne,F=T,I=w,L=x,R=re,q=E,J=D,Z=M;return i(),v(ie,{title:B.value?.CompanyName||`公司详情`,loading:z.value},{actions:r(()=>[m(u,{type:`primary`,disabled:!B.value,onClick:$},{default:r(()=>[m(l,null,{default:r(()=>[m(o)]),_:1}),a[2]||=g(`编辑 `,-1)]),_:1},8,[`disabled`])]),default:r(()=>[H.value?(i(),v(d,{key:0,type:`error`,title:H.value,"show-icon":``,closable:!1},null,8,[`title`])):s(``,!0),B.value?(i(),v(ae,{key:1,title:`基本信息`,columns:2},{default:r(()=>[m(p,{label:`公司名称`},{default:r(()=>[g(t(G(B.value.CompanyName)||`-`),1)]),_:1}),m(p,{label:`公司简称`},{default:r(()=>[g(t(G(B.value.CompanyShort)||`-`),1)]),_:1}),m(p,{label:`公司状态`},{default:r(()=>[m(h,{type:W[String(B.value.CompanyStatus)]?.type||`info`,size:`small`},{default:r(()=>[g(t(W[String(B.value.CompanyStatus)]?.text??B.value.CompanyStatus),1)]),_:1},8,[`type`])]),_:1}),m(p,{label:`上级公司`},{default:r(()=>[g(t(V.value.parentCompany?.[B.value.ParentCompanyUUID]||G(B.value.ParentCompanyUUID)||`-`),1)]),_:1}),m(p,{label:`租户`},{default:r(()=>[g(t(V.value.tenant?.[B.value.TenantUUID]||G(B.value.TenantUUID)||`-`),1)]),_:1}),m(p,{label:`创建时间`},{default:r(()=>[g(t(K(B.value.CompanyCreateTime)),1)]),_:1})]),_:1})):s(``,!0),B.value?(i(),v(y,{key:2,shadow:`never`},{default:r(()=>[m(N,{table:`Department`,title:`部门`,query:{CompanyUUID:_(U)},selectable:!0,pageable:!0,"pk-field":`DeptUUID`,"on-view":oe},null,8,[`query`])]),_:1})):s(``,!0),B.value?(i(),v(y,{key:3,shadow:`never`},{default:r(()=>[m(N,{table:`Workgroup`,title:`工作组`,query:{CLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{$n as e,An as t,Br as n,Dn as r,Fn as i,Jn as a,Kn as o,Ln as s,Lr as c,Nn as l,Yn as u,_ as d,an as f,cn as p,en as m,hn as h,ir as g,ln as _,mn as v,nr as y,on as b,pn as x,pr as S,sn as C}from"./useApi-CROJJdhE-mMpa5RAf.js";import{l as w}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{o as T,u as E}from"./serverScope-O8Rw8SFk.js";import{t as D}from"./date-picker-CM_15T0u.js";import{u as O}from"./use-global-config-D-dPcPvU.js";import{r as k,t as A}from"./select-BGsfCDCJ.js";import{t as j}from"./time-picker-DcDLR-nT.js";import{_ as M,l as N,n as P,s as F}from"./router-CMu0lceh.js";import{n as I,t as L}from"./form-F--u6XQJ.js";import{t as R}from"./button-CPx9BSuo.js";import{t as z}from"./tag-BSnLMVgs.js";import{t as B}from"./card-Dj_UeWcA.js";import{r as V,t as ee}from"./checkbox-CdKclTX1.js";import{r as te,t as ne}from"./radio-Cb0vAm4I.js";import{t as re}from"./dialog-_5VhSQg5.js";import{t as ie}from"./input-number-CiNOxXL6.js";import{t as ae}from"./pagination-DOGDdUWm.js";import{t as oe}from"./switch-7puThziV.js";import{t as se}from"./directive-CY41a6pJ.js";/* empty css */import"./css-CY4c3_XL.js";import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-Cy-4mdDD.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DMLZMbB9.js";import"./css-DmmbJMxg.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./css-fhPIiYtD.js";import"./css-BLJI5-W_.js";import"./css-ByqxgOA-.js";import"./css-0wcCNliC.js";import{t as H}from"./form-B2Pzr8Vf.js";function U(e){let{table:n,query:r={}}=e,i=g(!1),a=g(!1),o=g([]),s=g([]),c=g(0),l=g(1),u=g(20),d=g(``),f=g(`asc`),p=g(``),m=g([]),h=g(!1),_=g(`新增`),v=y({}),b=g(!1);function x(){return e.pkField?e.pkField:o.value.find(e=>e.isPrimary||e.primaryKey)?.field||`Id`}async function S(){try{o.value=await H.getColumns(n)}catch{}}async function C(){i.value=!0;try{let e={page:l.value,pageSize:u.value,sortField:d.value||void 0,sortOrder:f.value,keyword:p.value||void 0,...r},t=await H.list(n,e);if(Array.isArray(t))s.value=t,c.value=t.length;else{let e=t;s.value=e.list||[],c.value=e.total??0}}finally{i.value=!1}}function w(){b.value=!1,_.value=`新增`;let e={};for(let t of o.value)t.defaultValue!==void 0&&(e[t.field]=t.defaultValue);Object.keys(v).forEach(e=>delete v[e]),Object.assign(v,e),h.value=!0}async function E(t){e.beforeEdit&&!await e.beforeEdit(t)||(b.value=!0,_.value=`编辑`,Object.keys(v).forEach(e=>delete v[e]),Object.assign(v,t),h.value=!0)}function D(t){e.onView&&e.onView(t)}function O(t){e.onRowClick&&e.onRowClick(t)}async function k(){if(!(e.beforeCreate&&!b.value&&!await e.beforeCreate(v))){a.value=!0;try{if(b.value){let e=x(),t=v[e];await H.update(n,t,v),T.success(`更新成功`)}else await H.create(n,v),T.success(`新增成功`);h.value=!1,await C()}finally{a.value=!1}}}async function A(t){if(e.beforeDelete&&!await e.beforeDelete(t))return;try{await M.confirm(`确认删除该记录?删除后不可恢复`,`提示`,{type:`warning`,confirmButtonText:`确认删除`,cancelButtonText:`取消`})}catch{return}let r=t[x()];await H.remove(n,r),T.success(`删除成功`),await C()}async function j(){if(m.value.length===0){T.warning(`请先选择要删除的记录`);return}if(e.beforeBatchDelete&&!await e.beforeBatchDelete(m.value))return;try{await M.confirm(`确认删除选中的 ${m.value.length} 条记录?删除后不可恢复`,`提示`,{type:`warning`,confirmButtonText:`确认删除`,cancelButtonText:`取消`})}catch{return}let t=x();for(let e of m.value){let r=e[t];await H.remove(n,r)}T.success(`批量删除成功`),m.value=[],await C()}function N(e){m.value=e}function F(){return m.value}function I(){m.value=[]}function L(){l.value=1,C()}function R(){p.value=``,l.value=1,C()}function z(e){l.value=e,C()}function B(e){u.value=e,l.value=1,C()}function V(e,t){s.value=e,c.value=t??e.length}return t(async()=>{try{await Promise.all([S(),C()])}finally{P().done()}}),{loading:i,submitting:a,columns:o,dataList:s,total:c,currentPage:l,pageSize:u,sortField:d,sortOrder:f,searchKeyword:p,selectedRows:m,dialogVisible:h,dialogTitle:_,editingRow:v,isEdit:b,getPkField:x,fetchColumns:S,fetchData:C,handleCreate:w,handleEdit:E,handleView:D,handleRowClick:O,handleSubmit:k,handleDelete:A,handleBatchDelete:j,handleSelectionChange:N,getSelectedRows:F,clearSelection:I,handleSearch:L,handleReset:R,handlePageChange:z,handleSizeChange:B,setData:V}}var W={key:0,class:`entity-picker-secondary`},G=d(h({__name:`EntityPicker`,props:{modelValue:{default:``},config:{},disabled:{type:Boolean,default:!1},placeholder:{default:``},existingLabel:{default:``},clearable:{type:Boolean,default:!1}},emits:[`update:modelValue`,`update:label`],setup(e,{emit:t}){let s=e,c=t,u=g([]),d=g(!1),h=g(!1),v=g(``),y=f(()=>s.placeholder||s.config.placeholder||`请选择`),x=null;function S(e){x&&clearTimeout(x),x=setTimeout(()=>{w(e)},300)}async function w(e){let t=s.config,n=t.searchParam||`keyword`,r=t.method||`GET`;d.valLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Jn as n,Ln as r,Nn as i,Yn as a,_ as o,hn as s,ir as c,ln as l,mn as u,on as d}from"./useApi-CROJJdhE-mMpa5RAf.js";import{u as f}from"./use-global-config-D-dPcPvU.js";import{s as p}from"./router-CMu0lceh.js";import{t as m}from"./card-Dj_UeWcA.js";import{n as h,t as g}from"./col-BXlaMgkQ.js";import{t as _}from"./directive-CY41a6pJ.js";/* empty css */import"./css-CttyGzET.js";import"./css-Cy-4mdDD.js";import"./css-D-a1H3t1.js";var v={class:`dashboard`},y={class:`stat-content`},b={class:`stat-icon user`},x={class:`stat-info`},S={class:`stat-value`},C={class:`stat-content`},w={class:`stat-icon order`},T={class:`stat-info`},E={class:`stat-value`},D={class:`stat-content`},O={class:`stat-icon revenue`},k={class:`stat-info`},A={class:`stat-value`},j={class:`stat-content`},M={class:`stat-icon tenant`},N={class:`stat-info`},P={class:`stat-value`},F=o(s({__name:`Dashboard`,setup(o){let s=c({UserCount:0,OrderCount:0,TodayRevenue:0,ActiveTenants:0}),F=c(!1);return e(async()=>{F.value=!0;try{let e=await p(`/API/Dashboard/Stats`);s.value={...s.value,...e}}finally{F.value=!1}}),(e,o)=>{let c=r(`User`),p=f,I=m,L=g,R=r(`ShoppingCart`),z=r(`Money`),B=r(`OfficeBuilding`),V=h,H=_;return a((i(),l(`div`,v,[u(V,{gutter:16},{default:n(()=>[u(L,{xs:24,sm:12,lg:6},{default:n(()=>[u(I,{shadow:`hover`,class:`stat-card`},{default:n(()=>[d(`div`,y,[d(`div`,b,[u(p,{size:32},{default:n(()=>[u(c)]),_:1})]),d(`div`,x,[d(`div`,S,t(s.value.UserCount),1),o[0]||=d(`div`,{class:`stat-label`},`用户总数`,-1)])])]),_:1})]),_:1}),u(L,{xs:24,sm:12,lg:6},{default:n(()=>[u(I,{shadow:`hover`,class:`stat-card`},{default:n(()=>[d(`div`,C,[d(`div`,w,[u(p,{size:32},{default:n(()=>[u(R)]),_:1})]),d(`div`,T,[d(`div`,E,t(s.value.OrderCount),1),o[1]||=d(`div`,{class:`stat-label`},`订单总数`,-1)])])]),_:1})]),_:1}),u(L,{xs:24,sm:12,lg:6},{default:n(()=>[u(I,{shadow:`hover`,class:`stat-card`},{default:n(()=>[d(`div`,D,[d(`div`,O,[u(p,{size:32},{default:n(()=>[u(z)]),_:1})]),d(`div`,k,[d(`div`,A,`¥`+t((Number(s.value.TodayRevenue)||0).toFixed(2)),1),o[2]||=d(`div`,{class:`stat-label`},`今日收入`,-1)])])]),_:1})]),_:1}),u(L,{xs:24,sm:12,lg:6},{default:n(()=>[u(I,{shadow:`hover`,class:`stat-card`},{default:n(()=>[d(`div`,j,[d(`div`,M,[u(p,{size:32},{default:n(()=>[u(B)]),_:1})]),d(`div`,N,[d(`div`,P,t(s.value.ActiveTenants),1),o[3]||=d(`div`,{class:`stat-label`},`活跃租户`,-1)])])]),_:1})]),_:1})]),_:1}),u(I,{class:`welcome-card`,shadow:`never`},{header:n(()=>[...o[4]||=[d(`span`,null,`欢迎使用 GERP 管理系统`,-1)]]),default:n(()=>[o[5]||=d(`p`,null,`当前技术栈:Vue 3 + TypeScript + Vite + Element Plus + vxe-table + FormKit`,-1),o[6]||=d(`p`,null,`后端:Django + DRF(已就绪,无需修改)`,-1),o[7]||=d(`p`,null,`路由模式:SPA(已移除 iframe)`,-1)]),_:1})])),[[H,F.value]])}}}),[[`__scopeId`,`data-v-29b7fb49`]]);export{F as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Nn as i,Yn as a,_ as o,an as s,cn as c,en as l,h as u,hn as d,ir as f,ln as p,mn as m,on as h,pn as g,pr as _,sn as v}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as y,i as b,t as x}from"./serverScope-O8Rw8SFk.js";import{r as S,s as C}from"./router-CMu0lceh.js";import{t as w}from"./button-CPx9BSuo.js";import{t as T}from"./empty-CnQTxkvl.js";import{t as E}from"./directive-CY41a6pJ.js";/* empty css */import"./css-DsD2Typt.js";import"./css-Cy-4mdDD.js";import{t as D}from"./AdminBadge-Z72F8Boy.js";import"./css-D4jab2ni2.js";var O={class:`db-page`},k={class:`db-header`},A={class:`page-title`},j={key:1,class:`db-section`},M={class:`db-list`},N={class:`db-table-name`},P={class:`db-table-meta`},F={class:`db-section`},I={class:`db-list`},L={class:`db-table-name`},R={class:`db-table-meta`},z=o(d({__name:`Database`,setup(o){let d=u(),z=S(),B=s(()=>z.isAdmin),V=f(!1),H=x(),U=b(),W=f(!1),G=f([]),K=f([]),q=s(()=>U?`数据库管理`:`${H} — 数据库管理`);y(q.value);async function J(){W.value=!0;try{let e=await C(`/API/FormAPI/Tables`),t=Array.isArray(e)?e:[];G.value=t.filter(e=>e.type===`static`),K.value=t.filter(e=>e.type===`dynamic`)}catch{}finally{W.value=!1}}async function Y(){W.value=!0;try{let e=await C(`/api/gerp/msync/servers/${encodeURIComponent(H)}/form/`,{Action:`tables`});K.value=Array.isArray(e)?e:[]}catch{K.value=[]}finally{W.value=!1}}function X(e){let t={table:e.name,title:e.title||e.name};U||(t.server=H),d.push({path:`/system/dbtable`,query:t})}function Z(){d.push({path:`/system/msync-servers`})}function Q(e){return e.title&&e.title!==e.name?`${e.title}(${e.name})`:e.name}function $(e){return typeof e.count==`number`&&e.count>=0?`${e.count} 条记录`:e.type===`dynamic`?`系统表`:`自定义表`}return e(()=>{if(!B.value){V.value=!0;return}U?J():Y()}),(e,o)=>{let s=T,u=w,d=E;return i(),p(`div`,O,[m(D),V.value?(i(),v(s,{key:0,description:`无权访问:该页面仅管理员可查看,请切换至管理员角色或联系管理员`},{image:r(()=>[...o[0]||=[h(`i`,{class:`fas fa-lock`,style:{"font-size":`48px`,color:`var(--el-color-danger)`}},null,-1)]]),_:1})):(i(),p(l,{key:1},[_(U)?c(``,!0):(i(),p(`div`,{key:0,class:`db-back`,onClick:Z},[...o[1]||=[h(`i`,{class:`fas fa-arrow-left`},null,-1),g(),h(`span`,null,`返回服务器列表`,-1)]])),h(`div`,k,[h(`h1`,A,[o[2]||=h(`i`,{class:`fas fa-database icon-primary`},null,-1),h(`span`,null,t(q.value),1)])]),_(U)?(i(),p(`div`,j,[o[4]||=h(`h3`,null,`静态表`,-1),a((i(),p(`div`,M,[(i(!0),p(l,null,n(G.value,e=>(i(),p(`div`,{key:e.name,class:`db-table-item`},[h(`span`,N,t(Q(e)),1),h(`span`,P,t($(e)),1),m(u,{size:`small`,type:`primary`,onClick:t=>X(e)},{default:r(()=>[...o[3]||=[h(`i`,{class:`fas fa-table`},null,-1),g(` 查看 `,-1)]]),_:1},8,[`onClick`])]))),128)),!W.value&&G.value.length===0?(i(),v(s,{key:0,description:`暂无数据`,"image-size":60})):c(``,!0)])),[[d,W.value]])])):c(``,!0),h(`div`,F,[h(`h3`,null,t(_(U)?`系统表`:`数据表`),1),a((i(),p(`div`,I,[(i(!0),p(l,null,n(K.value,e=>(i(),p(`div`,{key:e.name,class:`db-table-item`},[h(`span`,L,t(Q(e)),1),h(`span`,R,t($(e)),1),m(u,{size:`small`,type:`primary`,onClick:t=>X(e)},{default:r(()=>[...o[5]||=[h(`i`,{class:`fas fa-table`},null,-1),g(` 查看 `,-1)]]),_:1},8,[`onClick`])]))),128)),!W.value&&K.value.length===0?(i(),v(s,{key:0,description:`暂无数据表`,"image-size":60})):c(``,!0)])),[[d,W.value]])])],64))])}}}),[[`__scopeId`,`data-v-2477c93a`]]);export{z as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Jn as n,Nn as r,_ as i,an as a,en as o,h as s,hn as c,ir as l,ln as u,m as d,mn as f,on as p,pn as m,pr as h,sn as g}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as _,i as v,t as y}from"./serverScope-O8Rw8SFk.js";import{r as b}from"./router-CMu0lceh.js";import{t as x}from"./alert-BpFV-0dO.js";import{t as S}from"./empty-CnQTxkvl.js";/* empty css */import{t as C}from"./AdminBadge-Z72F8Boy.js";import{t as w}from"./CrudTable-B49nrpUt.js";import"./css-D4jab2ni2.js";var T={class:`dbtable-page`},E={class:`dbtable-header`},D={class:`page-title`},O={class:`dbtable-info`},k={class:`dbtable-container`},A=i(c({__name:`DbTable`,setup(i){let c=d(),A=s(),j=b(),M=a(()=>j.isAdmin),N=l(!1),P=y(),F=v(),I=c.query.table||``,L=c.query.title||I,R=a(()=>F?L:`${P} — ${L}`);_(R.value);function z(){let e={};F||(e.server=P),A.push({path:`/system/database`,query:e})}return e(()=>{M.value||(N.value=!0)}),(e,i)=>{let a=S,s=x;return r(),u(`div`,T,[f(C),N.value?(r(),g(a,{key:0,description:`无权访问:该页面仅管理员可查看,请切换至管理员角色或联系管理员`},{image:n(()=>[...i[0]||=[p(`i`,{class:`fas fa-lock`,style:{"font-size":`48px`,color:`var(--el-color-danger)`}},null,-1)]]),_:1})):h(I)?(r(),u(o,{key:2},[p(`div`,E,[p(`div`,{class:`dbtable-back`,onClick:z},[...i[2]||=[p(`i`,{class:`fas fa-arrow-left`},null,-1),m(` 返回数据库 `,-1)]]),p(`h1`,D,[i[3]||=p(`i`,{class:`fas fa-table icon-primary`},null,-1),p(`span`,null,t(R.value),1)])]),p(`div`,O,[p(`span`,null,[i[4]||=p(`i`,{class:`fas fa-server`},null,-1),m(` 服务器: `+t(h(F)?`主实例`:h(P)),1)]),p(`span`,null,[i[5]||=p(`i`,{class:`fas fa-table`},null,-1),m(` 表名: `+t(h(I)),1)])]),p(`div`,k,[h(F)?(r(),g(w,{key:0,table:h(I),title:h(L),searchable:``,pageable:``,selectable:``,stretch:``},null,8,[`table`,`title`])):(r(),g(s,{key:1,type:`warning`,closable:!1,"show-icon":``,title:`子服务器表浏览待迁移`,description:`子服务器 subproxy 代理模式(/api/gerp/msync/servers/{server}/form/)暂未迁移,待 DbTableHelper 完整迁移后接入。`}))])],64)):(r(),g(a,{key:1,description:`未指定表名`},{image:n(()=>[...i[1]||=[p(`i`,{class:`fas fa-table`,style:{"font-size":`48px`,opacity:`0.3`}},null,-1)]]),_:1}))])}}}),[[`__scopeId`,`data-v-cf6eab3f`]]);export{A as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Dn as n,Fn as r,Jn as i,Kn as a,Ln as o,Lr as s,Nn as c,Yn as l,_ as u,an as d,cn as f,en as p,h as m,hn as h,ir as g,ln as _,m as v,mn as y,on as b,pn as x,pr as S,sn as C,tn as w,zn as T,zr as E}from"./useApi-CROJJdhE-mMpa5RAf.js";import{c as D,t as O,u as k}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{l as A,o as j}from"./serverScope-O8Rw8SFk.js";import{u as M}from"./use-global-config-D-dPcPvU.js";import{a as N,i as P,n as F,p as I,r as L}from"./router-CMu0lceh.js";import{n as R}from"./click-outside-bcMsT2om.js";import{t as ee}from"./button-CPx9BSuo.js";import{t as te}from"./tag-BSnLMVgs.js";import{a as ne,i as re,n as ie,o as ae,s as oe,t as se}from"./menu-BLdj5hCm.js";/* empty css */import"./css-CY4c3_XL.js";import"./css-yeo4Q6aC.js";import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-6qaeDme6.js";import"./css-CttyGzET.js";import"./favicon-CjgOoDgN.js";import{t as ce}from"./app-Bqwt3qVF.js";var z={class:`tab-bar`},B={class:`tab-list`},V=[`onClick`,`onContextmenu`],H={class:`tab-title`},le=u(h({__name:`TabBar`,setup(e){let a=I(),l=m(),u=g(!1),d=g(0),h=g(0),v=g(``);function D(e){if(a.activePath===e)return;let t=a.tabs.find(t=>t.path===e);t&&l.push(t.fullPath)}function O(e,t){t.stopPropagation();let n=a.removeTab(e);n&&l.push(n)}function k(e,t){t.preventDefault(),a.tabs.find(t=>t.path===e)?.closable&&(v.value=e,d.value=t.clientX,h.value=t.clientY,u.value=!0,document.addEventListener(`click`,A))}function A(){u.value=!1,document.removeEventListener(`click`,A)}function j(){a.removeOthers(v.value);let e=a.tabs.find(e=>e.path===v.value);e&&l.push(e.fullPath),A()}function N(){a.removeAll(),l.push(`/dashboard`),A()}return n(()=>{document.removeEventListener(`click`,A)}),(e,n)=>{let l=M,m=o(`Close`),g=R,v=o(`CircleClose`),A=o(`Delete`);return c(),_(`div`,z,[y(g,{class:`tab-scroll`},{default:i(()=>[b(`div`,B,[(c(!0),_(p,null,r(S(a).tabs,e=>(c(),_(`div`,{key:e.path,class:s([`tab-item`,{active:S(a).activePath===e.path}]),onClick:t=>D(e.path),onContextmenu:t=>k(e.path,t)},[e.icon&&!S(a).isFaIcon(e.icon)?(c(),C(l,{key:0,class:`tab-icon`},{default:i(()=>[(c(),C(T(e.icon)))]),_:2},1024)):e.icon&&S(a).isFaIcon(e.icon)?(c(),_(`i`,{key:1,class:s([e.icon,`tab-icon-fa`])},null,2)):f(``,!0),b(`span`,H,t(e.title),1),e.closable?(c(),C(l,{key:2,class:`tab-close`,onClick:t=>O(e.path,t)},{default:i(()=>[y(m)]),_:1},8,[`onClick`])):f(``,!0)],42,V))),128))])]),_:1}),(c(),C(w,{to:`body`},[u.value?(c(),_(`ul`,{key:0,class:`tab-ctx-menu`,style:E({left:d.value+`px`,top:h.value+`px`})},[b(`li`,{onClick:j},[y(l,null,{default:i(()=>[y(v)]),_:1}),n[0]||=x(`关闭其他 `,-1)]),b(`li`,{onClick:N},[y(l,null,{default:i(()=>[y(A)]),_:1}),n[1]||=x(`关闭所有 `,-1)])],4)):f(``,!0)]))])}}}),[[`__scopeId`,`data-v-e1c867fe`]]),ue=u(h({__name:`RouteProgress`,setup(e){let t=F();return(e,n)=>(c(),_(`div`,{class:s([`route-progress`,{"is-visible":S(t).visible}])},[b(`div`,{class:`route-progress-bar`,style:E({width:S(t).percent+`%`})},null,4)],2))}}),[[`__scopeId`,`data-v-85523620`]]),U={class:`page-mask-content`},de=u(h({__name:`PageMask`,setup(e){let t=F();return(e,n)=>{let r=o(`Loading`),a=M;return c(),_(`div`,{class:s([`page-mask`,{show:S(t).visible}])},[b(`div`,U,[y(a,{class:`page-mask-icon is-loading`},{default:i(()=>[y(r)]),_:1}),n[0]||=b(`span`,{class:`page-mask-text`},`加载中`,-1)])],2)}}}),[[`__scopeId`,`data-v-7f6076a1`]]),W={class:`role-switcher-content`},G={class:`role-switcher-body`},K={class:`role-grid`},q=[`title`,`onClick`],J={class:`role-info`},Y={class:`role-name`},X={class:`role-desc`},fe={key:0,class:`role-badge role-badge-active`},Z={key:1,class:`role-badge role-badge-disabled`},Q={key:2,class:`role-check`},pe={class:`role-switcher-footer`},me=[`disabled`],he={key:0,class:`role-switching`},$={key:1},ge=u(h({__name:`RoleSwitcher`,props:{modelValue:{type:Boolean},roles:{}},emits:[`update:modelValue`,`switched`],setup(e,{emit:n}){let a=n,o=L(),l=I(),u=m(),d=g(null),h=g(!1),v=e=>e.RoleStatus===1||e.RoleStatus===`1`;function S(e){e.active||!v(e)||(d.value=e)}function T(){a(`update:modelValue`,!1),d.value=null}async function E(){if(!(!d.value||h.value)){h.value=!0;try{await N(d.value),await o.fetchUserInfo(),await o.fetchMenus(),await o.fetchRoles(),l.reset(),j.success(`已切换为 "${d.value.RoleName}"`),a(`switched`,d.value),T(),u.push(`/dashboard`)}catch{j.error(`身份切换失败,请重试`)}finally{h.value=!1}}}function D(e){return e.CompanyName?e.CompanyShort?`${e.CompanyName} (${e.CompanyShort})`:e.CompanyName:`无所属公司`}return(n,a)=>(c(),C(w,{to:`body`},[y(O,{name:`role-switcher`},{default:i(()=>[e.modelValue?(c(),_(`div`,{key:0,class:`role-switcher`,onClick:k(T,[`self`])},[b(`div`,{class:`role-switcher-overlay`,onClick:T}),b(`div`,W,[b(`div`,{class:`role-switcher-header`},[a[1]||=b(`h3`,{class:`role-switcher-title`},`切换角色`,-1),b(`button`,{class:`role-switcher-close`,onClick:T},[...a[0]||=[b(`svg`,{viewBox:`0 0 1024 1024`,width:`14`,height:`14`},[b(`path
Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Nn as e,_ as t,h as n,hn as r,ln as i,mn as a}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as o}from"./serverScope-O8Rw8SFk.js";import{t as s}from"./CrudTable-B49nrpUt.js";var c={class:`department-page`},l=t(r({__name:`Department`,setup(t){o(`部门管理`);let r=n();function l(e){r.push({path:`/company/department-detail`,query:{DeptUUID:e.DeptUUID||``}})}return(t,n)=>(e(),i(`div`,c,[a(s,{table:`Department`,title:`部门管理`,"pk-field":`DeptUUID`,searchable:``,pageable:``,stretch:``,selectable:``,"on-view":l})]))}}),[[`__scopeId`,`data-v-570e4d75`]]);export{l as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as i,Nn as a,an as o,cn as s,en as c,h as l,hn as u,ir as d,ln as f,m as p,mn as m,nr as h,pn as g,pr as _,sn as v}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as y,o as b,u as x}from"./serverScope-O8Rw8SFk.js";import{t as S}from"./date-picker-CM_15T0u.js";import{u as C}from"./use-global-config-D-dPcPvU.js";import{n as w}from"./descriptions-Cq_aE9sg.js";import{r as T,t as E}from"./select-BGsfCDCJ.js";import{n as D,t as O}from"./form-F--u6XQJ.js";import{t as k}from"./button-CPx9BSuo.js";import{t as A}from"./tag-BSnLMVgs.js";import{t as j}from"./card-Dj_UeWcA.js";import{t as M}from"./dialog-_5VhSQg5.js";import{t as ee}from"./input-number-CiNOxXL6.js";import{t as te}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-CysIl0tz.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./css-BLJI5-W_.js";import{n as ne,t as N}from"./CrudTable-B49nrpUt.js";import"./css-ByqxgOA-.js";import{t as P}from"./form-B2Pzr8Vf.js";import{t as F}from"./DetailPage-m11wfvkM.js";import{t as I}from"./InfoGrid-C1it9Z2Y.js";import{t as L}from"./useResolveUUIDs-ipmPZLo4.js";var R=`DeptUUID`,z=u({__name:`DepartmentDetail`,setup(u){let z=p(),B=l(),{resolveUUIDs:V}=L(),H=z.query.DeptUUID||``,U=d(!1),W=d(null),G=d(``),K=d(!1),q=d(!1),J=d([]),Y=h({}),X=o(()=>W.value?.DeptName||`部门详情`);function Z(e){return e===1||e===`1`?{text:`启用`,type:`success`}:e===0||e===`0`?{text:`禁用`,type:`danger`}:{text:String(e??`-`),type:`info`}}function re(e){if(!e)return`-`;let t=new Date(e);if(isNaN(t.getTime()))return String(e);let n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}async function Q(){if(!H){b.warning(`缺少 DeptUUID 参数,无法加载部门详情`);return}U.value=!0;try{let e=await P.list(`Department`,{[R]:H,pageSize:1}),t=Array.isArray(e)?e:e?.list||[],n=t.find(e=>e[R]===H)||t[0];if(!n){b.error(`未找到部门数据`);return}W.value=n,y(n.DeptName||`部门详情`),await $(n.ParentDeptUUID)}finally{U.value=!1}}async function $(e){if(!e){G.value=``;return}try{let t=await V({parentDept:{table:`Department`,uuids:[e]}});G.value=t.parentDept?.[e]||e}catch{G.value=e}}async function ie(){try{J.value=await P.getColumns(`Department`)}catch{}}let ae=o(()=>J.value.filter(e=>e.editable!==!1&&!e.hideInForm&&e.type!==`hidden`&&e.type!==`divider`&&e.type!==`html`&&e.field!==R));function oe(){W.value&&(Object.keys(Y).forEach(e=>delete Y[e]),Object.assign(Y,W.value),K.value=!0)}async function se(){q.value=!0;try{await P.update(`Department`,Y[R],Y),b.success(`保存成功`),K.value=!1,await Q()}finally{q.value=!1}}function ce(e){B.push({path:`/system/user-detail`,query:{UserUUID:e.UserUUID||``}})}return e(async()=>{await Promise.all([Q(),ie()])}),(e,o)=>{let l=i(`Edit`),u=C,d=k,p=w,h=A,y=j,b=x,P=ee,L=E,R=T,z=S,B=te,V=D,J=O,Q=M;return a(),v(F,{title:X.value,loading:U.value},{actions:r(()=>[m(d,{type:`primary`,onClick:oe},{default:r(()=>[m(u,null,{default:r(()=>[m(l)]),_:1}),o[2]||=g(`编辑 `,-1)]),_:1})]),default:r(()=>[m(I,{title:`基本信息`,columns:2},{default:r(()=>[m(p,{label:`部门名称`},{default:r(()=>[g(t(W.value?.DeptName||`-`),1)]),_:1}),m(p,{label:`部门状态`},{default:r(()=>[m(h,{type:Z(W.value?.DeptStatus).type,size:`small`},{default:r(()=>[g(t(Z(W.value?.DeptStatus).text),1)]),_:1},8,[`type`])]),_:1}),m(p,{label:`上级部门`},{default:r(()=>[g(t(G.value||W.value?.ParentDeptUUID||`-`),1)]),_:1}),m(p,{label:`排序`},{default:r(()=>[g(t(W.value?.DeptSort??`-`),1)]),_:1}),m(p,{label:`创建时间`},{default:r(()=>[g(t(re(W.value?.DeptCreateTime)),1)]),_:1})]),_:1}),m(y,{shadow:`never`},{header:r(()=>[...o[3]||=[g(`部门员工`,-1)]]),default:r(()=>[_(H)?(a(),v(N,{key:0,table:`UserRole`,title:`部门员工`,query:{DeptUUID:_(H)},"pk-field":`UserRoleUUID`,selectable:``,pageable:``,"on-view":ce},null,8,[`query`])):s(``,!0)]),_:1}),m(Q,{modelValue:K.value,"onUpdate:modelValue":o[1]||=e=>K.value=e,title:`编辑部门`,width:`600px`,"destroy-on-close":``},{footer:r(()=>[m(d,{onClick:o[0]||=e=>K.value=!1},{default:r(()=>[...o[4]||=[g(`取消`,-1)]]),_:1}),m(d,{type:`primary`,loading:q.value,onClick:se},{default:r(()=>[...o[5]||=[g(`保存`,-1)]]),_:1},8,[`loading`])]),default:r(()=>[m(J,{model:Y,"label-width":`120px`,"label-position":`right`},{default:r(()=>[(a(!0),f(c,null,n(ae.value,e=>(a(),v(V,{key:e.field,label:e.title,required:e.required},{default:r(()=>[e.type===`entityPicker`&&e.entityPicker?(a(),v(ne,{key:0,modelValue:Y[e.field],"onUpdate:modelValue":t=>Y[e.field]=t,config:e.entityPicker,"existing-label":Y[e.field+`_label`],placeholder:e.placeholder,disabled:e.disabled,"onUpdate:label":t=>Y[e.field+`_label`]=t},null,8,[`modelValue`,`onUpdate:modelValue`,`config`,`existing-label`,`placeholder`,Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Dn as n,Fn as r,Jn as i,Ln as a,Lr as o,Nn as s,Yn as ee,_ as c,an as l,cn as u,en as d,hn as f,ir as p,ln as m,mn as h,on as g,pn as _,sn as v,sr as y,zr as te}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as b,o as x,u as S}from"./serverScope-O8Rw8SFk.js";import{u as C}from"./use-global-config-D-dPcPvU.js";import{_ as w,d as T,l as E}from"./router-CMu0lceh.js";import{t as ne}from"./button-CPx9BSuo.js";import{t as re}from"./directive-CY41a6pJ.js";/* empty css */import"./css-DsD2Typt.js";import"./css-CttyGzET.js";import"./css-Cy-4mdDD.js";import"./css-DmmbJMxg.js";import{t as ie}from"./AdminBadge-Z72F8Boy.js";var ae={class:`gerp-page`},oe={class:`doc-page`},se={class:`doc-header`},ce={class:`doc-title`},le={class:`doc-toolbar`},ue={class:`doc-body`},de={class:`doc-sidebar`},fe={class:`sidebar-header`},pe={class:`doc-list`},D={key:0,class:`doc-empty`},O={key:1,class:`doc-empty`},k=[`onClick`],A={class:`doc-item-title`},j={class:`doc-item-time`},M={class:`doc-editor`},N={class:`doc-title-bar`},P={class:`editor-container`},F={key:0,class:`doc-loading`},I=c(f({__name:`Editor`,setup(c){b(`文档编辑器`);let f=p([]),I=p(!1),L=p(``),R=p(``),z=null,B=p(null),V=p(``),H=p(``),U=p(!1),W=p(``),me=l(()=>{switch(W.value){case`已保存`:case`导出成功`:return`#10b981`;case`未保存`:return`#f59e0b`;case`保存失败`:case`导出失败`:return`#ef4444`;default:return`#6b7280`}}),G=y(null),K=l(()=>!!B.value&&U.value),he=l(()=>!!B.value),ge=l(()=>!!B.value);async function q(e,t={}){return E(`/API/doc/doc/${e}`,t)}async function J(e=``){I.value=!0,L.value=``;try{let t=await q(`GetDocs`,e?{keyword:e}:{});f.value=Array.isArray(t)?t:[]}catch(e){L.value=e?.message||`加载失败`,f.value=[]}finally{I.value=!1}}async function Y(e){if(U.value&&B.value)try{await w.confirm(`当前文档未保存,是否丢弃改动?`,`提示`,{type:`warning`,confirmButtonText:`丢弃`,cancelButtonText:`取消`})}catch{return}B.value=e,U.value=!1;try{let t=await q(`GetDoc`,{DocUUID:e});V.value=t.DocTitle||``,H.value=t.DocContent||``,W.value=``}catch(e){x.error(`加载文档失败: `+(e?.message||``))}}async function X(){if(U.value&&B.value)try{await w.confirm(`当前文档未保存,是否丢弃改动?`,`提示`,{type:`warning`,confirmButtonText:`丢弃`,cancelButtonText:`取消`})}catch{return}let e;try{e=(await w.prompt(`请输入文档标题:`,`新建文档`,{confirmButtonText:`确定`,cancelButtonText:`取消`,inputValue:`未命名文档`,inputValidator:e=>e&&e.trim()?!0:`标题不能为空`})).value.trim()}catch{return}try{let t=await q(`AddDoc`,{DocTitle:e,DocContent:``});await J(R.value),t?.DocUUID&&await Y(t.DocUUID)}catch(e){x.error(`新建失败: `+(e?.message||``))}}async function Z(){if(!B.value||!G.value)return;let e=V.value.trim();if(!e){x.warning(`请输入文档标题`);return}let t=G.value.getContent();W.value=`保存中...`;try{await q(`ModifyDocSettings`,{DocUUID:B.value,DocTitle:e,DocContent:t}),U.value=!1,W.value=`已保存`,await J(R.value)}catch(e){W.value=`保存失败`,x.error(`保存失败: `+(e?.message||``))}}async function _e(){if(B.value){W.value=`导出中...`;try{let e=await T.post(`/API/doc/doc/ExportDocx`,{DocUUID:B.value},{responseType:`blob`}),t=e.data,n=e.headers[`content-disposition`]||``,r=`document.docx`,i=n.match(/filename="?([^"]+)"?/);i&&(r=decodeURIComponent(i[1]));let a=URL.createObjectURL(t),o=document.createElement(`a`);o.href=a,o.download=r,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(a),W.value=`导出成功`}catch(e){W.value=`导出失败`,x.error(`导出失败: `+(e?.message||``))}}}async function ve(){if(B.value){try{await w.confirm(`确定删除此文档?此操作不可撤销。`,`危险操作`,{type:`error`,confirmButtonText:`删除`,cancelButtonText:`取消`,confirmButtonClass:`el-button--danger`})}catch{return}try{await q(`DeleteDoc`,{DocUUID:B.value}),B.value=null,V.value=``,H.value=``,U.value=!1,W.value=``,await J(R.value)}catch(e){x.error(`删除失败: `+(e?.message||``))}}}function Q(){U.value=!0,W.value=`未保存`}function ye(){z&&clearTimeout(z),z=setTimeout(()=>{J(R.value.trim())},300)}function be(){J(R.value.trim())}function $(e){(e.ctrlKey||e.metaKey)&&e.key===`s`&&(e.preventDefault(),K.value&&Z())}e(()=>{J(),document.addEventListener(`keydown`,$)}),n(()=>{document.removeEventListener(`keydown`,$),z&&clearTimeout(z),G.value&&=(G.value.remove(),null)});function xe(e){return e?new Date(e).toLocaleString(`zh-CN`):``}return(e,n)=>{let c=a(`Document`),l=C,p=a(`Plus`),y=ne,b=a(`Save`),x=a(`Download`),w=a(`Delete`),T=a(`Search`),E=S,z=a(`Refresh`),U=re;return s(),m(`div`,ae,[h(ie),g(`div`,oe,[g(`div`,se,[g(`h1`,ce,[h(l,null,{default:i(()=>[h(c)]),_:1}),n[3]||=_(` 文档编辑器 `,-1)]),n[8]||=g(`div`,{class:`spacer`},null,-1),g(`div`,le,[h(y,{type:`primary`,onClick:X},{default:i(()=>[h(l,null,{default:i(()=>[h(p)]),_:1}),n[4]||=_(`\xA0新建 `,-1)]),_:1}),h(y,{disabled:!K.value,onClick:Z},{default:i(Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as i,Nn as a,_ as o,an as s,cn as c,en as l,h as u,hn as d,ir as f,ln as p,m,mn as h,nr as g,on as _,pn as v,pr as y,sn as b,zr as x}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as S,n as C,o as w,u as ee}from"./serverScope-O8Rw8SFk.js";import{t as te}from"./date-picker-CM_15T0u.js";import{u as ne}from"./use-global-config-D-dPcPvU.js";import{n as re,t as ie}from"./descriptions-Cq_aE9sg.js";import{r as ae,t as oe}from"./select-BGsfCDCJ.js";import{s as T}from"./router-CMu0lceh.js";import{n as E,t as se}from"./form-F--u6XQJ.js";import{t as D}from"./alert-BpFV-0dO.js";import{t as ce}from"./avatar-DXM6bmhO.js";import{t as le}from"./button-CPx9BSuo.js";import{t as O}from"./tag-BSnLMVgs.js";import{t as k}from"./card-Dj_UeWcA.js";import{t as A}from"./dialog-_5VhSQg5.js";import{t as ue}from"./input-number-CiNOxXL6.js";import{t as de}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-CysIl0tz.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./AdminBadge-Z72F8Boy.js";import"./css-BLJI5-W_.js";import{t as j}from"./CrudTable-B49nrpUt.js";import"./css-ByqxgOA-.js";import{t as M}from"./form-B2Pzr8Vf.js";import{t as fe}from"./DetailPage-m11wfvkM.js";import{t as pe}from"./InfoGrid-C1it9Z2Y.js";var N={key:1,class:`profile-row`},P={class:`profile-info`},F={key:1,style:{color:`#6b7280`}},I={key:1},L=`UserUUID`,R=o(d({__name:`EmployeeDetail`,setup(o){let d=m(),R=u(),z=f(!1),B=f(null),V=f(null),H=f(``),U=d.query.UserUUID||``,W={0:{text:`禁用`,type:`danger`},1:{text:`启用`,type:`success`}},me=s(()=>{let e=new URLSearchParams;e.set(`UserUUID`,U);let t=C();return t.server&&e.set(`server`,t.server),t.admin_verify&&e.set(`admin_verify`,t.admin_verify),`/Query/GetELTUserAvatar?${e.toString()}`});function G(e){return e==null||e===``?``:String(e)}function K(e){if(!e)return`-`;let t=String(e),n=new Date(t);if(isNaN(n.getTime()))return t;let r=e=>String(e).padStart(2,`0`);return`${n.getFullYear()}-${r(n.getMonth()+1)}-${r(n.getDate())} ${r(n.getHours())}:${r(n.getMinutes())}:${r(n.getSeconds())}`}function q(e){return Array.isArray(e)?e:e?.list||[]}function J(e){return e===1||e===!0||e===`1`||e===`true`}async function Y(){if(!U){H.value=`缺少 UserUUID 参数,无法加载员工详情。`;return}z.value=!0,H.value=``,V.value=null;try{let e=q(await M.list(`User`,{UserUUID:U,pageSize:1})),t=e.find(e=>e.UserUUID===U)||e[0];if(!t){H.value=`未找到用户数据`;return}B.value=t,S(G(t.UserName)||`员工详情`);try{V.value=await T(`/API/SiteUserManagement/GetUser2FAInfo`,{UserUUID:U})}catch{V.value=null}}catch(e){H.value=`加载失败: ${e instanceof Error?e.message:String(e)}`}finally{z.value=!1}}function he(e){R.push({path:`/company/department-detail`,query:{DeptUUID:G(e.DeptUUID)}})}let X=f(!1),Z=f(!1),Q=f([]),$=g({}),ge=s(()=>Q.value.filter(e=>e.editable!==!1&&!e.hideInForm&&e.type!==`hidden`&&e.type!==`divider`&&e.type!==`html`&&e.field!==L));async function _e(){if(B.value){try{Q.value.length||(Q.value=await M.getColumns(`User`))}catch{Q.value=[]}Object.keys($).forEach(e=>delete $[e]),Object.assign($,B.value),X.value=!0}}async function ve(){if(B.value){Z.value=!0;try{await M.update(`User`,B.value[L],{...$}),w.success(`保存成功`),X.value=!1,await Y()}catch{}finally{Z.value=!1}}}return e(Y),(e,o)=>{let s=i(`Edit`),u=ne,d=le,f=D,m=i(`User`),g=ce,S=re,C=O,w=ie,T=k,M=ee,L=ue,R=oe,q=ae,Y=te,Q=de,ye=E,be=se,xe=A;return a(),b(fe,{title:B.value?.UserName||`员工详情`,loading:z.value},{actions:r(()=>[h(d,{type:`primary`,disabled:!B.value,onClick:_e},{default:r(()=>[h(u,null,{default:r(()=>[h(s)]),_:1}),o[2]||=v(`编辑 `,-1)]),_:1},8,[`disabled`])]),default:r(()=>[H.value?(a(),b(f,{key:0,type:`error`,title:H.value,"show-icon":``,closable:!1},null,8,[`title`])):c(``,!0),B.value?(a(),p(`div`,N,[h(g,{size:96,src:me.value,class:`profile-avatar`},{default:r(()=>[h(u,{size:32},{default:r(()=>[h(m)]),_:1})]),_:1},8,[`src`]),_(`div`,P,[h(w,{title:`基本信息`,column:2,border:``},{default:r(()=>[h(S,{label:`用户名`},{default:r(()=>[v(t(G(B.value.UserName)||`-`),1)]),_:1}),h(S,{label:`真实姓名`},{default:r(()=>[v(t(G(B.value.UserRealName)||`-`),1)]),_:1}),h(S,{label:`邮箱`},{default:r(()=>[v(t(G(B.value.UserEmail)||`-`),1)]),_:1}),h(S,{label:`电话`},{default:r(()=>[v(t(G(B.value.UserTele)||`-`),1)]),_:1}),h(S,{label:`账号状态`},{default:r(()=>[h(C,{type:W[String(B.value.UserAccountLicense)]?.type||`info`,size:`small`},{default:r(()=>[v(t(W[String(B.value.UserAccountLicense)]?.text??B.value.UserAccountLicense),1)]),_:1},8,[`type`])]),_:1}),h(S,{label:`是否员工`},{default:r(()=>[_(`span`,{style:x({color:J(B.value.IsStaff)?`#166534`:`#991b1b`})},t(J(B.value.IsStaff)?`是`:`否`),5)]),_:1}),h(S,{label:`创建时间`},{default:r(()=>[v(t(K(B.value.UserCreateTime)),1)]),_:1})]),_:1Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Lr as i,Nn as a,_ as o,an as s,cn as c,en as l,fn as ee,hn as u,ir as d,ln as f,mn as p,nr as m,on as h,pn as g,pr as _,sn as v}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as y,o as b,u as x}from"./serverScope-O8Rw8SFk.js";import{t as S}from"./date-picker-CM_15T0u.js";import{r as te,t as ne}from"./select-BGsfCDCJ.js";import{t as re}from"./button-CPx9BSuo.js";import{t as ie}from"./input-number-CiNOxXL6.js";import{n as ae,t as oe}from"./steps-C4-7Ybf-.js";/* empty css */import"./css-DsD2Typt.js";import"./css-DmmbJMxg.js";import"./css-w8-s2aei.js";import"./css-Dmy6QwIc.js";import"./css-ByqxgOA-.js";import{t as C}from"./form-B2Pzr8Vf.js";var se={class:`ep-create-page`},ce={class:`step-card`},w={key:0,class:`start-page`},T={key:1,class:`step-form`},E={class:`step-header`},D={class:`step-title`},O={class:`step-desc`},k={class:`form-body`},A={class:`section-title`},j={class:`section-grid`},M={class:`form-label`},N={key:0,class:`required`},P={class:`step-actions`},F={key:2,class:`preview-page`},I={class:`preview-body`},L={class:`preview-section-title`},R={class:`preview-grid`},z={class:`preview-label`},le={class:`preview-value`},B={class:`step-actions`},V={key:3,class:`success-page`},H={class:`success-actions`},U=o(u({__name:`EpCreate`,setup(o){let u=[{title:`企业名称`,icon:`fa-font`,desc:`填写企业名称和品牌信息`,sections:[{name:`名称信息`,fields:[{id:`EnterpriseName`,label:`企业全称`,type:`text`,required:!0,placeholder:`请输入营业执照上的企业全称`},{id:`EnterpriseShortName`,label:`企业简称`,type:`text`,placeholder:`请输入企业简称`},{id:`EnterpriseAbbr`,label:`企业缩写`,type:`text`,placeholder:`请输入企业英文缩写`},{id:`FormerName`,label:`曾用名`,type:`text`,placeholder:`请输入企业曾用名(如有)`}]},{name:`品牌信息`,fields:[{id:`BrandName`,label:`品牌名称`,type:`text`,placeholder:`请输入品牌名称`},{id:`EnglishName`,label:`英文名称`,type:`text`,placeholder:`请输入英文名称`},{id:`BrandLogo`,label:`品牌Logo链接`,type:`text`,placeholder:`请输入品牌Logo URL`},{id:`BrandSlogan`,label:`品牌口号`,type:`text`,placeholder:`请输入品牌口号`}]},{name:`企业简介`,fields:[{id:`EnterpriseIntro`,label:`企业简介`,type:`textarea`,fullWidth:!0,placeholder:`请输入企业简介(200字以内)`}]}]},{title:`企业编码`,icon:`fa-barcode`,desc:`填写企业各类编码信息`,sections:[{name:`工商编码`,fields:[{id:`CreditCode`,label:`统一社会信用代码`,type:`text`,required:!0,maxlength:18,placeholder:`请输入18位信用代码`},{id:`OrgCode`,label:`组织机构代码`,type:`text`,placeholder:`请输入组织机构代码`},{id:`RegistrationNo`,label:`工商注册号`,type:`text`,placeholder:`请输入工商注册号`},{id:`BusinessLicenseNo`,label:`营业执照编号`,type:`text`,placeholder:`请输入营业执照编号`}]},{name:`税务编码`,fields:[{id:`TaxpayerId`,label:`纳税人识别号`,type:`text`,placeholder:`请输入纳税人识别号`},{id:`TaxRegNo`,label:`税务登记号`,type:`text`,placeholder:`请输入税务登记号`},{id:`TaxpayerType`,label:`纳税人类型`,type:`select`,options:[{value:`general`,label:`一般纳税人`},{value:`small`,label:`小规模纳税人`},{value:`individual`,label:`个体工商户`}]},{id:`TaxAuthority`,label:`主管税务机关`,type:`text`,placeholder:`请输入主管税务机关`}]},{name:`其他编码`,fields:[{id:`ImportExportCode`,label:`进出口企业代码`,type:`text`,placeholder:`请输入进出口企业代码`},{id:`CustomsCode`,label:`海关编码`,type:`text`,placeholder:`请输入海关编码`},{id:`SocialSecurityNo`,label:`社保登记号`,type:`text`,placeholder:`请输入社保登记号`},{id:`HousingFundNo`,label:`公积金登记号`,type:`text`,placeholder:`请输入公积金登记号`}]},{name:`资质证书`,fields:[{id:`CertificateType`,label:`资质类型`,type:`select`,options:[{value:`iso9001`,label:`ISO9001质量管理体系`},{value:`iso14001`,label:`ISO14001环境管理体系`},{value:`iso45001`,label:`ISO45001职业健康安全`},{value:`highTech`,label:`高新技术企业`},{value:`other`,label:`其他`}]},{id:`CertificateNo`,label:`证书编号`,type:`text`,placeholder:`请输入证书编号`},{id:`CertificateExpiry`,label:`证书有效期`,type:`date`}]}]},{title:`企业分类`,icon:`fa-tags`,desc:`选择企业类型、行业和规模`,sections:[{name:`企业类型`,fields:[{id:`EnterpriseType`,label:`企业类型`,type:`select`,required:!0,options:[{value:`limited`,label:`有限责任公司`},{value:`joint`,label:`股份有限公司`},{value:`private`,label:`个人独资企业`},{value:`partnership`,label:`合伙企业`},{value:`state`,label:`国有企业`},{value:`collective`,label:`集体企业`},{value:`foreign`,label:`外商投资企业`},{value:`hkMacaoTaiwan`,label:`港澳台投资企业`}]},{id:`OwnershipType`,label:`所有制性质`,type:`select`,options:[Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Jn as e,Nn as t,_ as n,h as r,hn as i,ir as a,ln as o,m as s,mn as c,nr as l,on as u,pn as d}from"./useApi-CROJJdhE-mMpa5RAf.js";import{l as f,u as p}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{o as m,u as h}from"./serverScope-O8Rw8SFk.js";import{r as g}from"./router-CMu0lceh.js";import{n as _,t as v}from"./form-F--u6XQJ.js";import{t as y}from"./button-CPx9BSuo.js";import{t as b}from"./checkbox-CdKclTX1.js";/* empty css */import"./css-DsD2Typt.js";import"./favicon-CjgOoDgN.js";import"./css-49fsIjk3.js";import"./css-DMLZMbB9.js";import"./css-DmmbJMxg.js";var x={class:`login-page`},S={class:`login-card`},C=n(i({__name:`Login`,setup(n){let i=r(),C=s(),w=g(),T=a(!1),E=l({UserName:``,UserPassword:``,RememberMe:!1}),D={UserName:[{required:!0,message:`请输入用户名`,trigger:`blur`}],UserPassword:[{required:!0,message:`请输入密码`,trigger:`blur`}]};async function O(){if(!E.UserName||!E.UserPassword){m.warning(`请输入用户名和密码`);return}T.value=!0;try{await w.login(E);let e=C.query.redirect||`/dashboard`;i.push(e)}catch{}finally{T.value=!1}}return(n,r)=>{let i=h,a=_,s=b,l=y,m=v;return t(),o(`div`,x,[u(`div`,S,[r[5]||=u(`div`,{class:`login-header`},[u(`img`,{src:`/favicon.svg`,alt:`logo`,class:`login-logo`}),u(`h1`,{class:`login-title`},`GERP 管理系统`),u(`p`,{class:`login-subtitle`},`登录到后台管理`)],-1),c(m,{model:E,rules:D,"label-position":`top`,size:`large`,onSubmit:p(O,[`prevent`])},{default:e(()=>[c(a,{label:`用户名`,prop:`UserName`},{default:e(()=>[c(i,{modelValue:E.UserName,"onUpdate:modelValue":r[0]||=e=>E.UserName=e,placeholder:`请输入用户名`,"prefix-icon":`User`,clearable:``},null,8,[`modelValue`])]),_:1}),c(a,{label:`密码`,prop:`UserPassword`},{default:e(()=>[c(i,{modelValue:E.UserPassword,"onUpdate:modelValue":r[1]||=e=>E.UserPassword=e,type:`password`,placeholder:`请输入密码`,"prefix-icon":`Lock`,"show-password":``,onKeyup:f(O,[`enter`])},null,8,[`modelValue`])]),_:1}),c(a,null,{default:e(()=>[c(s,{modelValue:E.RememberMe,"onUpdate:modelValue":r[2]||=e=>E.RememberMe=e},{default:e(()=>[...r[3]||=[d(`记住我`,-1)]]),_:1},8,[`modelValue`])]),_:1}),c(l,{type:`primary`,size:`large`,class:`login-btn`,loading:T.value,onClick:O},{default:e(()=>[...r[4]||=[d(` 登 录 `,-1)]]),_:1},8,[`loading`])]),_:1},8,[`model`])])])}}}),[[`__scopeId`,`data-v-e370fea4`]]);export{C as default};
|
||||
@@ -1,2 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as i,Lr as a,Nn as o,Yn as ee,_ as s,an as c,cn as l,en as u,hn as d,ir as f,ln as p,mn as m,nr as h,on as g,pn as _,sn as v,zr as y}from"./useApi-CROJJdhE-mMpa5RAf.js";import{u as b}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{a as x,o as S,u as te}from"./serverScope-O8Rw8SFk.js";import{u as ne}from"./use-global-config-D-dPcPvU.js";import{_ as C,f as w,l as T,o as E,s as D}from"./router-CMu0lceh.js";import{t as re}from"./image-HD4q5QFa.js";import{t as ie}from"./button-CPx9BSuo.js";import{t as ae}from"./checkbox-CdKclTX1.js";import{t as oe}from"./dialog-_5VhSQg5.js";import{t as se}from"./pagination-DOGDdUWm.js";import{t as ce}from"./progress-CJYzD9Cp.js";import{t as le}from"./directive-CY41a6pJ.js";/* empty css */import"./css-DsD2Typt.js";import"./css-CttyGzET.js";import"./css-Cy-4mdDD.js";import"./css-DMLZMbB9.js";import"./css-DmmbJMxg.js";import"./css-B0rEpZpL.js";import"./css-DMOjom7l.js";import"./css-fhPIiYtD.js";import{t as ue}from"./AdminBadge-Z72F8Boy.js";var de={class:`asset-manager-page`},fe={class:`asset-header`},pe={class:`header-left`},me={class:`asset-count`},he={class:`header-right`},ge={class:`filter-group`},_e={class:`asset-body`},ve={class:`asset-timeline`},ye={class:`timeline-track`},be={class:`timeline-labels`},xe={class:`timeline-sort`},Se={class:`asset-main`},Ce={key:0,class:`batch-bar`},we={class:`batch-count`},Te={class:`batch-actions`},Ee={class:`asset-grid-wrap`},De={key:0,class:`asset-empty`},Oe={key:1,class:`asset-empty`},ke={key:2,class:`asset-grid`},Ae=[`onClick`],je=[`onClick`],Me={class:`card-thumb`},Ne=[`src`,`alt`],Pe={class:`card-info`},Fe=[`title`],Ie={class:`card-meta`},Le={class:`card-actions`},Re={key:1,class:`asset-pagination`},ze={class:`preview-content`},Be=[`src`],Ve={key:2,class:`preview-unsupported`},He={key:0,class:`upload-panel`},Ue={class:`upload-panel-header`},We={class:`upload-file-list`},Ge=[`title`],Ke={class:`upload-file-size`},qe={class:`upload-file-status`},O=24,k=5242880,A=5242880,j=`https://api.gvsds.com/API/Asset/Download`,M=s(d({__name:`Manager`,setup(s){x(`资产管理`);let d=f([]),M=f(0),N=f(1),P=f(``),F=f(``),I=f(`desc`),L=f(!1),R=f(``),z=f(null),B=f(null),V=null,H=f(new Set),U=f(!1),W=f(!1),G=f(null),Je=f(null),K=f(!1),q=f([]),J=h({left:0,top:0,width:0,height:0}),Ye=f(!1),Xe=[{label:`全部`,value:``},{label:`图片`,value:`image`},{label:`视频`,value:`video`},{label:`文档`,value:`document`},{label:`其他`,value:`other`}],Ze=c(()=>Math.ceil(M.value/O)||1),Qe=c(()=>d.value.length>0&&d.value.every(e=>H.value.has(e.sha1))),$e=c(()=>d.value.some(e=>H.value.has(e.sha1))&&!Qe.value),et=c(()=>H.value.size),tt=c(()=>et.value>0||U.value),nt=c(()=>!!z.value&&!!B.value);async function Y(){L.value=!0,R.value=``;try{let e=await D(`/API/Asset/List`,{page:N.value,pageSize:O,orderDir:I.value,type:P.value||void 0,keyword:F.value||void 0});d.value=e.assets||[],M.value=e.total||0,N.value=e.page||1,z.value=e.minTime||null,B.value=e.maxTime||null,St()}catch(e){let t=e?.response?.status||0,n=e?.response?.data?.msg||e?.message||`加载资产列表失败`;t===401?R.value=`未登录,请先登录后查看资产`:t===403?R.value=`权限不足,需要 admin:fileasset_read 权限`:R.value=n,d.value=[],M.value=0,S.error(n)}finally{L.value=!1}}async function rt(e){try{await C.confirm(`确定删除此文件?`,`危险操作`,{type:`error`,confirmButtonText:`删除`,cancelButtonText:`取消`,confirmButtonClass:`el-button--danger`})}catch{return}try{await E(`/API/Asset/Delete/${e}`),H.value.delete(e),S.success(`删除成功`),await Y()}catch(e){S.error(`删除失败: `+(e?.message||``))}}function it(e){let t=`${j}/${e}`;navigator.clipboard.writeText(t).then(()=>S.success(`引用链接已复制`)).catch(()=>S.error(`复制失败,请手动复制`))}function at(e){window.open(`${j}/${e}?download=1`,`_blank`)}function ot(e){U.value||(G.value=e,W.value=!0)}function st(){W.value=!1,G.value=null}function X(e){return`${j}/${e}`}function ct(e){let t=new Set(H.value);t.has(e)?(t.delete(e),t.size===0&&(U.value=!1)):(t.add(e),U.value=!0),H.value=t}function lt(e){let t=new Set(H.value);e?(d.value.forEach(e=>t.add(e.sha1)),U.value=!0):d.value.forEach(e=>t.delete(e.sha1)),H.value=t}function ut(){H.value=new Set,U.value=!1}async function dt(){if(H.value.size===0)return;try{await C.confirm(`确定删除 ${H.value.size} 个文件?`,`批量删除`,{type:`error`,confirmButtonText:`删除`,cancelButtonText:`取消`,confirmButtonClass:`el-button--danger`})}catch{return}let e=Array.from(H.value),t=0,n=0;for(let r of e)try{await E(`/API/Asset/Delete/${r}`),H.value.delete(r),t++}catch{n++}S.success(`删除完成: ${t} 成功, ${n} 失败`),await Y()}function ft(){if(H.value.size===0)return;let e=Array.from(H.value).map(e=>`${j}/${e}`).join(`
|
||||
`);navigator.clipboard.writeText(e).then(()=>S.success(`已复制 ${H.value.size} 个链接`)).catch(()=>S.error(`复制失败`))}function pt(){H.value.size!==0&&Array.from(H.value).forEach(e=>{window.open(`${j}/${e}?download=1`,`_blank`)})}function mt(e){P.value=e,N.value=1,Y()}function Z(e){I.value=e,N.value=1,Y()}function ht(e){N.value=e,Y()}function gt(){V&&clearTimeout(V),V=setTimeout(()=>{N.value=1,Y()},300)}function _t(){Je.value?.click()}async function vt(e){let t=e.target;t.files?.length&&(await Q(Array.from(t.files)),t.value=``)}async function Q(e){K.value=!0,q.value=e.map(e=>({name:e.name,size:e.size,status:`等待中`,progress:0}));for(let t=0;t<e.length;t++){let n=e[t],r=q.value[t];try{n.size<=A?(r.status=`上传中`,await yt(n,e=>{r.progress=e})):(r.status=`分片上传中`,await bt(n,(e,t)=>{r.progress=e,t&&(r.status=t)})),r.status=`完成`,r.progress=100}catch(e){r.status=`失败: `+(e?.message||``)}}await Y(),setTimeout(()=>{K.value=!1},2e3)}async function yt(e,t){let n=new FormData;n.append(`file`,e),await new Promise((e,r)=>{let i=new XMLHttpRequest;i.open(`POST`,`/API/Asset/Upload`),i.withCredentials=!0,i.upload.onprogress=e=>{e.lengthComputable&&t(Math.round(e.loaded/e.total*100))},i.onload=()=>{try{let t=JSON.parse(i.responseText);t.code===0?e():r(Error(t.msg||`上传失败`))}catch{r(Error(`解析响应失败`))}},i.onerror=()=>r(Error(`网络错误`)),i.send(n)})}async function bt(e,t){let n=Math.ceil(e.size/k),r=e.type||`application/octet-stream`;t(0,`初始化上传...`);let i=(await T(`/API/Asset/UploadInit`,{fileName:e.name,fileSize:e.size,mimeType:r,totalChunks:n})).uploadId;if(!i)throw Error(`UploadInit 未返回 uploadId`);for(let r=0;r<n;r++){let a=e.slice(r*k,Math.min((r+1)*k,e.size)),o=new FormData;o.append(`uploadId`,i),o.append(`chunkIndex`,String(r)),o.append(`chunk`,a,e.name),await w(`/API/Asset/UploadChunk`,o),t(Math.round((r+1)/n*100),`分片 ${r+1}/${n}`)}t(99,`合并文件...`),await T(`/API/Asset/UploadComplete`,{uploadId:i}),t(100,`上传完成`)}let xt=f(0),$=f([]);function St(){if(!z.value||!B.value){$.value=[];return}let e=new Date(z.value).getTime(),t=new Date(B.value).getTime(),n=t-e||1,r=[];for(let i=0;i<=5;i++){let a=I.value===`asc`?new Date(e+i/5*n):new Date(t-i/5*n);r.push(`${a.getMonth()+1}/${a.getDate()}`)}$.value=r}function Ct(e){return e<1024?e+` B`:e<1048576?(e/1024).toFixed(1)+` KB`:e<1073741824?(e/1048576).toFixed(1)+` MB`:(e/1073741824).toFixed(1)+` GB`}function wt(e){return e.startsWith(`video/`)?`fa-file-video`:e===`application/pdf`?`fa-file-pdf`:e.includes(`word`)||e.includes(`document`)?`fa-file-word`:e.includes(`sheet`)||e.includes(`excel`)?`fa-file-excel`:e.includes(`zip`)||e.includes(`rar`)||e.includes(`compressed`)?`fa-file-archive`:`fa-file`}return e(()=>{Y()}),(e,s)=>{let c=i(`Search`),f=ne,h=te,x=ie,S=i(`Upload`),C=ae,w=i(`Link`),T=i(`Download`),E=i(`Delete`),D=i(`Close`),k=i(`Warning`),A=i(`FolderOpened`),j=i(`Check`),z=se,B=re,V=i(`Document`),U=oe,Y=ce,Q=le;return o(),p(`div`,de,[m(ue),g(`div`,fe,[g(`div`,pe,[s[4]||=g(`h2`,{class:`asset-title`},`资产管理`,-1),g(`span`,me,t(M.value)+` 个文件`,1)]),g(`div`,he,[m(h,{modelValue:F.value,"onUpdate:modelValue":s[0]||=e=>F.value=e,placeholder:`搜索文件名...`,clearable:``,class:`search-input`,onInput:gt},{prefix:r(()=>[m(f,null,{default:r(()=>[m(c)]),_:1})]),_:1},8,[`modelValue`]),g(`div`,ge,[(o(),p(u,null,n(Xe,e=>m(x,{key:e.value,size:`small`,type:P.value===e.value?`primary`:`default`,onClick:t=>mt(e.value)},{default:r(()=>[_(t(e.label),1)]),_:2},1032,[`type`,`onClick`])),64))]),m(x,{type:`primary`,onClick:_t},{default:r(()=>[m(f,null,{default:r(()=>[m(S)]),_:1}),s[5]||=_(`\xA0上传 `,-1)]),_:1})])]),g(`input`,{ref_key:`FileInput`,ref:Je,type:`file`,multiple:``,style:{display:`none`},accept:`image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.zip,.rar`,onChange:vt},null,544),g(`div`,_e,[g(`div`,ve,[g(`div`,ye,[nt.value?(o(),p(`div`,{key:0,class:`timeline-thumb`,style:y({top:xt.value+`px`})},null,4)):l(``,!0)]),g(`div`,be,[(o(!0),p(u,null,n($.value,(e,n)=>(o(),p(`span`,{key:n},t(e),1))),128))]),g(`div`,xe,[m(x,{size:`small`,type:I.value===`desc`?`primary`:`default`,onClick:s[1]||=e=>Z(`desc`)},{default:r(()=>[...s[6]||=[_(` 最新优先 `,-1)]]),_:1},8,[`type`]),m(x,{size:`small`,type:I.value===`asc`?`primary`:`default`,onClick:s[2]||=e=>Z(`asc`)},{default:r(()=>[...s[7]||=[_(` 最早优先 `,-1)]]),_:1},8,[`type`])])]),g(`div`,Se,[tt.value?(o(),p(`div`,Ce,[m(C,{"model-value":Qe.value,indeterminate:$e.value,onChange:lt},{default:r(()=>[...s[8]||=[_(` 全选 `,-1)]]),_:1},8,[`model-value`,`indeterminate`]),g(`span`,we,`已选 `+t(et.value)+` 项`,1),g(`div`,Te,[m(x,{size:`small`,onClick:ft},{default:r(()=>[m(f,null,{default:r(()=>[m(w)]),_:1}),s[9]||=_(`\xA0复制链接 `,-1)]),_:1}),m(x,{size:`small`,onClick:pt},{default:r(()=>[m(f,null,{default:r(()=>[m(T)]),_:1}),s[10]||=_(`\xA0下载 `,-1)]),_:1}),m(x,{size:`small`,type:`danger`,onClick:dt},{default:r(()=>[m(f,null,{default:r(()=>[m(E
Line truncated
|
||||
@@ -1,4 +0,0 @@
|
||||
import{An as e,Br as t,Dn as n,Fn as r,Jn as i,Lr as a,Nn as o,_ as s,an as c,cn as l,en as u,hn as d,ir as f,ln as p,mn as m,on as h,pn as g,sn as _,zr as ee}from"./useApi-CROJJdhE-mMpa5RAf.js";import{u as v}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{a as y,o as b,u as te}from"./serverScope-O8Rw8SFk.js";import{_ as x,d as S,r as C}from"./router-CMu0lceh.js";import{n as ne,t as re}from"./form-F--u6XQJ.js";import{t as ie}from"./button-CPx9BSuo.js";import{t as ae}from"./tag-BSnLMVgs.js";import{n as oe,t as se}from"./tabs-BSMusFE5.js";import{r as ce,t as le}from"./radio-Cb0vAm4I.js";import{t as ue}from"./empty-CnQTxkvl.js";import{t as de}from"./input-number-CiNOxXL6.js";import{t as fe}from"./tree-DqeBDBpX.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-w8-s2aei.js";import{t as pe}from"./AdminBadge-Z72F8Boy.js";import"./css-0wcCNliC.js";import"./css-D4jab2ni2.js";import"./css-CLuE7SsA.js";import"./css-DcINL9JV2.js";var me={class:`menu-editor`},he={class:`menu-header`},ge={class:`company-search-wrap`},_e={key:0,class:`company-search-dropdown`},ve=[`onClick`],ye={class:`menu-body`},be=[`innerHTML`],xe={class:`node-title`},Se={class:`node-actions`},Ce={class:`menu-form`},we={style:{display:`flex`,gap:`8px`,width:`100%`}},Te=[`innerHTML`],Ee={class:`form-actions`},De={key:2,class:`ctx-sep`},Oe={key:5,class:`ctx-sep`},w=s(d({__name:`Menu`,setup(s){y(`菜单编辑器`);let d=C(),w=c(()=>d.isAdmin),T=f(!1),E=f([]),D=f(-1),O=c(()=>D.value>=0?E.value[D.value]:null),k=f(``),A=f([]),j=f(!1),M=null,N=f(!1),P=f(0),F=f(0),I=f(null),L=f(null),R=f({MenuUUID:``,MenuName:``,MenuTitle:``,MenuIcon:``,MenuLink:``,MenuType:0,MenuSort:0,PermissionLevel:1,PermissionAttr:``,MenuStatus:1,visibility:`public`}),z=c(()=>{let e=O.value;return e?B(e.menus):[]}),ke=c(()=>{let e=O.value;return!e||!e.selectedUUID?null:e.menus.find(t=>t.MenuUUID===e.selectedUUID)||null});function B(e){let t={},n=[];e.forEach(e=>{t[e.MenuUUID]={...e,children:[]}}),e.forEach(e=>{e.ParentMenuUUID&&t[e.ParentMenuUUID]?t[e.ParentMenuUUID].children.push(t[e.MenuUUID]):n.push(t[e.MenuUUID])});let r=(e,t)=>(e.MenuSort||0)-(t.MenuSort||0),i=e=>{e.sort(r),e.forEach(e=>i(e.children||[]))};return i(n),n}function V(e,t){let n=e.find(e=>e.MenuUUID===t);if(!n)return null;let r={...n,children:[]},i=e.filter(e=>e.ParentMenuUUID===t);for(let t of i){let n=V(e,t.MenuUUID);n&&r.children.push(n)}return r.children.sort((e,t)=>(e.MenuSort||0)-(t.MenuSort||0)),r}function Ae(){M&&clearTimeout(M);let e=k.value.trim();if(!e){A.value=[],j.value=!1;return}M=setTimeout(async()=>{try{let t=await S.get(`/API/FormAPI/CompanySearch`,{params:{keyword:e,limit:10}});A.value=Array.isArray(t)?t:[],j.value=A.value.length>0}catch{A.value=[],j.value=!1}},300)}function je(e){k.value=e.CompanyName,j.value=!1;let t=E.value.findIndex(t=>t.companyUUID===e.CompanyUUID);t>=0?H(t):(E.value.push({companyUUID:e.CompanyUUID,companyName:e.CompanyName,menus:[],selectedUUID:null}),H(E.value.length-1),U())}function H(e){e<0||e>=E.value.length||(D.value=e,W())}function Me(e){E.value.splice(e,1),E.value.length===0?D.value=-1:D.value>=E.value.length?D.value=E.value.length-1:D.value>e?D.value--:D.value===e&&(D.value=Math.min(e,E.value.length-1)),W()}async function U(){let e=O.value;if(e)try{let t=await S.get(`/API/Menu/AdminList`,{params:{CompanyUUID:e.companyUUID}});e.menus=Array.isArray(t)?t:[]}catch{e.menus=[]}}function Ne(e){let t=O.value;t&&(t.selectedUUID=e.MenuUUID,W())}function Pe(){let e=O.value;e&&(e.selectedUUID=null,W())}function W(){let e=O.value;if(!e||!e.selectedUUID)return;let t=e.menus.find(t=>t.MenuUUID===e.selectedUUID);if(!t){e.selectedUUID=null;return}R.value={...t,visibility:t.CompanyUUID?`private`:`public`}}async function Fe(){let e=O.value;if(!e||!e.selectedUUID)return;let t=e.menus.find(t=>t.MenuUUID===e.selectedUUID);if(!t)return;let n={MenuUUID:e.selectedUUID,MenuTitle:R.value.MenuTitle||``,MenuName:R.value.MenuName||``,MenuIcon:R.value.MenuIcon||``,MenuLink:R.value.MenuLink||``,MenuType:String(R.value.MenuType??0),MenuSort:String(R.value.MenuSort||0),PermissionLevel:String(R.value.PermissionLevel??1),PermissionAttr:R.value.PermissionAttr||``,MenuStatus:String(R.value.MenuStatus??1),CompanyUUID:R.value.visibility===`public`?``:e.companyUUID,ParentMenuUUID:t.ParentMenuUUID||``};try{await S.post(`/API/Menu/Save`,new URLSearchParams(n),{headers:{"Content-Type":`application/x-www-form-urlencoded`}}),Object.assign(t,n,{CompanyUUID:n.CompanyUUID||void 0}),b.success(`保存成功`)}catch{}}async function Ie(e){let t=O.value;if(!t)return;let n=e?t.menus.filter(t=>t.ParentMenuUUID===e):t.menus.filter(e=>!e.ParentMenuUUID),r=n.length>0?Math.max(...n.map(e=>e.MenuSort||0)):-1,i={CompanyUUID:t.companyUUID,ParentMenuUUID:e||``,MenuName:`new-menu`,MenuTitle:`新菜单`,MenuIcon:``,MenuLink:``,MenuType:`1`,MenuSort:String(r+1),PermissionLevel:`1.0`,PermissionAttr:``,MenuStatus:`1`};try{let e=G(await S.poLine truncated
|
||||
<menus>
|
||||
`;t.forEach(e=>{n+=Q(e,1)}),n+=`</menus>`,await navigator.clipboard.writeText(n),b.success(`XML 已复制到剪贴板`)}async function Ke(){let e=O.value;if(!e||!I.value)return;let t=J.value?null:I.value;if(!t)return;let n=V(e.menus,t);if(!n)return;let r=`<?xml version="1.0" encoding="UTF-8"?>
|
||||
`+Q(n);await navigator.clipboard.writeText(r),b.success(`XML 已复制到剪贴板`),q()}async function qe(e){let t=e.target,n=t.files?.[0];if(!n)return;t.value=``;let r=O.value;if(r)try{let e=await n.text(),t=new DOMParser().parseFromString(e,`text/xml`).querySelectorAll(`:scope > menus > menu, :scope > menu`);if(t.length===0){b.error(`未找到有效的菜单结构`);return}let i=r.menus.filter(e=>!e.ParentMenuUUID),a=i.length>0?Math.max(...i.map(e=>e.MenuSort||0))+1:0;for(let e of Array.from(t))await Je(e,``,a++,r.companyUUID);await U(),b.success(`导入成功`)}catch(e){b.error(`导入失败: `+(e instanceof Error?e.message:String(e)))}}async function Je(e,t,n,r){let i={CompanyUUID:r,ParentMenuUUID:t||``,MenuName:e.getAttribute(`name`)||`imported`,MenuTitle:e.getAttribute(`title`)||`导入菜单`,MenuIcon:e.getAttribute(`icon`)||``,MenuLink:e.getAttribute(`link`)||``,MenuType:String(parseInt(e.getAttribute(`type`)||`1`)||1),MenuSort:String(n),PermissionLevel:String(parseFloat(e.getAttribute(`permLevel`)||`1.0`)||1),PermissionAttr:e.getAttribute(`permAttr`)||``,MenuStatus:String(parseInt(e.getAttribute(`status`)||`1`)||1)},a=null;try{a=G(await S.post(`/API/Menu/Save`,new URLSearchParams(i),{headers:{"Content-Type":`application/x-www-form-urlencoded`}}))}catch{return}let o=e.querySelectorAll(`:scope > menu`);if(o.length>0&&a)for(let e=0;e<o.length;e++)await Je(o[e],a,e,r)}function Ye(e){let t=e.target?.tagName;if(t===`INPUT`||t===`TEXTAREA`||t===`SELECT`)return;let n=O.value;if(n){if((e.ctrlKey||e.metaKey)&&(e.key===`c`||e.key===`C`)){if(!n.selectedUUID)return;if(e.preventDefault(),n.menus.find(e=>e.MenuUUID===n.selectedUUID)){let e=V(n.menus,n.selectedUUID);L.value=e?JSON.parse(JSON.stringify(e)):null,b.success(`已复制子树`)}}else if((e.ctrlKey||e.metaKey)&&(e.key===`v`||e.key===`V`))e.preventDefault(),n.selectedUUID?(I.value=n.selectedUUID,X(!0)):(I.value=`__ROOT__`,X(!1));else if(e.key===`Delete`||e.key===`Backspace`){if(!n.selectedUUID)return;e.preventDefault(),K(n.selectedUUID)}}}function Xe(e){if(!e)return``;let t=e.trim();return t.startsWith(`<`)?t:`<i class="${t}"></i>`}e(()=>{if(!w.value){T.value=!0;return}document.addEventListener(`keydown`,Ye),document.addEventListener(`click`,$)}),n(()=>{document.removeEventListener(`keydown`,Ye),document.removeEventListener(`click`,$)});function $(e){let t=e.target;t.closest(`.menu-ctx-panel`)||(N.value=!1),t.closest(`.company-search-wrap`)||(j.value=!1)}return(e,n)=>{let s=ue,c=te,d=ie,f=se,y=oe,b=ae,x=fe,S=ne,C=le,w=ce,M=de,I=re;return o(),p(`div`,me,[m(pe),T.value?(o(),_(s,{key:0,description:`无权访问:该页面仅管理员可查看,请切换至管理员角色或联系管理员`},{image:i(()=>[...n[24]||=[h(`i`,{class:`fas fa-lock`,style:{"font-size":`48px`,color:`var(--el-color-danger)`}},null,-1)]]),_:1})):(o(),p(u,{key:1},[h(`div`,he,[n[28]||=h(`h1`,{class:`page-title`},[h(`i`,{class:`fas fa-bars icon-primary`}),h(`span`,null,`菜单编辑器`)],-1),h(`div`,ge,[m(c,{modelValue:k.value,"onUpdate:modelValue":n[0]||=e=>k.value=e,placeholder:`搜索公司添加标签页...`,clearable:``,style:{width:`240px`},onInput:Ae},null,8,[`modelValue`]),j.value?(o(),p(`div`,_e,[(o(!0),p(u,null,r(A.value,e=>(o(),p(`div`,{key:e.CompanyUUID,class:`company-search-item`,onClick:t=>je(e)},[h(`strong`,null,t(e.CompanyName),1),h(`span`,null,t(e.CompanyShort||``),1)],8,ve))),128))])):l(``,!0)]),m(d,{type:`primary`,disabled:!O.value,onClick:Le},{default:i(()=>[...n[25]||=[h(`i`,{class:`fas fa-plus`},null,-1),g(` 新增根菜单 `,-1)]]),_:1},8,[`disabled`]),m(d,{disabled:!O.value,onClick:Ge},{default:i(()=>[...n[26]||=[h(`i`,{class:`fas fa-file-export`},null,-1),g(` 导出XML `,-1)]]),_:1},8,[`disabled`]),m(d,{disabled:!O.value,onClick:n[1]||=t=>e.$refs.importInput.click()},{default:i(()=>[...n[27]||=[h(`i`,{class:`fas fa-file-import`},null,-1),g(` 导入XML `,-1)]]),_:1},8,[`disabled`]),h(`input`,{ref:`importInput`,type:`file`,accept:`.xml,.json`,style:{display:`none`},onChange:qe},null,544)]),E.value.length>0?(o(),_(y,{key:0,modelValue:D.value,"onUpdate:modelValue":n[2]||=e=>D.value=e,type:`card`,closable:``,onTabClick:n[3]||=e=>H(e.index),onTabRemove:n[4]||=e=>Me(Number(e))},{default:i(()=>[(o(!0),p(u,null,r(E.value,(e,t)=>(o(),_(f,{key:e.companyUUID,label:e.companyName,name:t},null,8,[`label`,`name`]))),128))]),_:1},8,[`modelValue`])):l(``,!0),h(`div`,ye,[h(`div`,{class:`menu-preview`,onContextmenu:n[6]||=e=>Ve(e,!1)},[O.value?(o(),p(u,{key:0},[h(`div`,{class:a([`menu-root-node`,{selected:!O.value.selectedUUID}]),onClick:Pe,onContextmenu:n[5]||=e=>Ve(e,!0)},[...n[29]||=[h(`span`,{class:`node-icon`},[h(`i`,{class:`fas fa-folder-open`})],-1),h(`span`,null,`根目录`,-1)]],34),z.value.length>0?(o(),_(x,{key:0,data:z.value,props:{children:`children`,label:`MenuTitle`},"node-key":`MenuUUID`,"expand-on-click-node":!1,"default-expand-all":!0,"highlight-current":``,onNodeClick:Ne,onNodeContextmenu:Be},{default:i(({data:e})=>[h(`div`,{class:a([`menu-node`,{selected:O.vLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Dn as n,Fn as r,Jn as i,Lr as a,Nn as o,Yn as ee,_ as s,cn as c,en as l,hn as u,ir as d,ln as f,m as p,mn as m,nr as h,on as g,pn as _,sn as v,zr as te}from"./useApi-CROJJdhE-mMpa5RAf.js";import{u as ne}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{a as y,l as re,o as b,u as ie}from"./serverScope-O8Rw8SFk.js";import{_ as x,c as S,d as C,l as w,o as T}from"./router-CMu0lceh.js";import{n as ae,t as oe}from"./form-F--u6XQJ.js";import{t as se}from"./button-CPx9BSuo.js";import{t as ce}from"./tag-BSnLMVgs.js";import{n as le,t as ue}from"./tabs-BSMusFE5.js";import{t as de}from"./dialog-_5VhSQg5.js";import{t as fe}from"./empty-CnQTxkvl.js";import{t as pe}from"./pagination-DOGDdUWm.js";import{t as me}from"./directive-CY41a6pJ.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-6qaeDme6.js";import"./css-Cy-4mdDD.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-DMOjom7l.js";import"./css-fhPIiYtD.js";import"./css-D4jab2ni2.js";import"./css-DcINL9JV2.js";var he={class:`message-page`},ge={key:0},_e={key:1},ve={class:`msg-toolbar`},ye={class:`msg-list`},be=[`onClick`],xe={class:`msg-item-body`},Se={class:`msg-item-title`},Ce={class:`msg-item-content`},we={class:`msg-item-meta`},Te={class:`msg-item-actions`},Ee={key:0,class:`msg-pagination`},De={class:`detail-title`},Oe={key:0,class:`detail-body`},ke={class:`detail-meta`},Ae={class:`detail-content`},je={class:`detail-footer`},Me={class:`recipient-search`},Ne={key:0,class:`recipient-dropdown`},Pe=[`onClick`],Fe={key:0,class:`selected-recipient`},E=20,D=s(u({__name:`Message`,setup(s){let u={0:`fa-info-circle`,1:`fa-clipboard-check`,2:`fa-tools`,3:`fa-envelope`},D={0:`系统通知`,1:`审核通知`,2:`工单通知`,3:`个人消息`},O={0:{bg:`rgba(37,99,235,0.1)`,color:`#2563eb`},1:{bg:`rgba(34,197,94,0.1)`,color:`#16a34a`},2:{bg:`rgba(234,179,8,0.1)`,color:`#ca8a04`},3:{bg:`rgba(139,92,246,0.1)`,color:`#8b5cf6`}},Ie=[{name:`all`,label:`全部`},{name:`unread`,label:`未读`},{name:`0`,label:`系统通知`},{name:`1`,label:`审核通知`},{name:`2`,label:`工单通知`},{name:`3`,label:`个人消息`}],k=p(),A=d(`all`),j=d(1),M=d([]),N=d(0),P=d(0),F=d(!1),I=d(!1),L=d(null),R=d(!1),z=h({title:``,content:``}),B=d(null),V=d(``),H=d([]),U=d(!1),W=d(!1),G=null;async function K(e,t){let n=await C.get(e,{params:t,responseType:`text`});return JSON.parse(n.data)}async function q(){F.value=!0;try{let e={action:`list`,PageIndex:j.value,PageSize:E};A.value===`unread`?e.IsRead=0:A.value!==`all`&&(e.MsgType=A.value);let t=await K(`/API/Message`,e);t.code===0?(M.value=t.data||[],N.value=t.total||0):(M.value=[],N.value=0)}catch{M.value=[],N.value=0}finally{F.value=!1}}async function J(){try{let e=await K(`/API/Message`,{action:`unread_count`});e.code===0&&(P.value=e.UnreadCount||0)}catch{}}function Le(e){A.value=String(e),j.value=1,q()}function Y(e){j.value=e,q()}async function X(e){try{let t=await K(`/API/Message`,{action:`detail`,MessageUUID:e});t.code===0&&t.data&&(L.value=t.data,I.value=!0,q(),J())}catch{}}function Z(){I.value=!1,L.value=null}async function Q(e,t=!1){try{await x.confirm(`确定要删除这条消息吗?此操作不可撤销。`,`删除消息`,{type:`warning`,confirmButtonText:`删除`,cancelButtonText:`取消`})}catch{return}try{await T(`/API/Message`,void 0,{data:{MessageUUID:e}}),b.success(`已删除`),t&&Z(),q(),J()}catch{}}async function Re(){try{await S(`/API/Message`,`action=read_all`,{headers:{"Content-Type":`application/x-www-form-urlencoded`}}),b.success(`已全部标记为已读`),q(),J()}catch{}}function $(){B.value=null,V.value=``,z.title=``,z.content=``,H.value=[],U.value=!1,R.value=!0}function ze(e,t){$(),B.value={type:`user`,uuid:e,name:t,label:t},V.value=t}function Be(e){if(G&&clearTimeout(G),!e){H.value=[],U.value=!1;return}G=setTimeout(()=>{Ve(e)},300)}async function Ve(e){try{let t=await K(`/API/Message`,{action:`search_recipients`,keyword:e,limit:10});t.code===0&&t.data?(H.value=t.data,U.value=t.data.length>0):(H.value=[],U.value=!1)}catch{H.value=[],U.value=!1}}function He(e){B.value=e,V.value=e.name,U.value=!1}function Ue(){B.value=null,V.value=``}async function We(){if(!B.value){b.warning(`请选择收件人`);return}if(!z.title.trim()){b.warning(`请输入标题`);return}let e={ReceiverUUID:B.value.uuid,ReceiverType:B.value.type,Title:z.title.trim(),Content:z.content.trim(),MsgType:`3`};W.value=!0;try{await w(`/API/Message`,new URLSearchParams(e).toString(),{headers:{"Content-Type":`application/x-www-form-urlencoded`}}),b.success(`发送成功`),R.value=!1,(A.value===`3`||A.value===`all`)&&q()}catch{}finally{W.value=!1}}return e(()=>{y(`站内信`),q(),J();let e=k.query.id;e&&X(e)}),n(()=>{G&&clearTimeout(G)}),(e,n)=>{let s=re,d=ue,p=le,h=se,y=fe,b=pe,x=de,S=ie,C=ce,w=ae,T=oe,k=me;return ee((o(),f(`div`,he,[n[22]||=g(`h1`,{class:`page-title`},[g(`i`,{class:`fas fa-envelope icon-primary`}),_(`站内信 `)],-1),m(p,{modelValue:A.value,"onUpdate:modelValue":nLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Nn as e,_ as t,an as n,hn as r,ln as i,mn as a}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as o}from"./serverScope-O8Rw8SFk.js";import{r as s}from"./router-CMu0lceh.js";import{t as c}from"./CrudTable-B49nrpUt.js";var l={class:`wo-my-page`},u=t(r({__name:`My`,setup(t){let r=s();o(`我的工单`);let u=n(()=>{let e=r.userInfo?.UserUUID;return e?{CreatorUUID:e}:{}});return(t,n)=>(e(),i(`div`,l,[a(c,{table:`WorkOrder`,title:`我的工单`,query:u.value,searchable:``,pageable:``,stretch:``,selectable:!1},null,8,[`query`])]))}}),[[`__scopeId`,`data-v-b1c4d29e`]]);export{u as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{Br as e,Lr as t,Nn as n,_ as r,an as i,h as a,hn as o,ln as s,mn as c,on as l}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as u}from"./serverScope-O8Rw8SFk.js";import{r as d}from"./router-CMu0lceh.js";import{t as f}from"./AdminBadge-Z72F8Boy.js";import{t as p}from"./CrudTable-B49nrpUt.js";var m={class:`order-page`},h=r(o({__name:`Orders`,setup(r){let o=d(),h=a();u(`销售订单`);let g=i(()=>o.isAdmin),_=i(()=>`scope-banner ${g.value?`admin`:`normal`}`),v=i(()=>g.value?`管理员视图:可查看全公司订单,含跨公司特权模式。`:`普通组员视图:仅可查看自己的订单。`);function y(e){h.push({path:`/sales/order-detail`,query:{OrderUUID:e.OrderUUID||``}})}return(r,i)=>(n(),s(`div`,m,[c(f),l(`div`,{class:t(_.value)},[l(`i`,{class:t([`fas`,g.value?`fa-shield-alt`:`fa-info-circle`])},null,2),l(`span`,null,e(v.value),1)],2),c(p,{table:`Order`,title:`销售订单`,"pk-field":`OrderUUID`,searchable:``,pageable:``,stretch:``,selectable:``,"on-view":y})]))}}),[[`__scopeId`,`data-v-d8a23658`]]);export{h as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Lr as i,Nn as a,Yn as o,_ as s,an as c,cn as l,en as u,hn as d,ir as f,ln as p,mn as m,nr as h,on as g,pn as _,sn as v}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as y,o as b,u as x}from"./serverScope-O8Rw8SFk.js";import{r as ee,t as te}from"./select-BGsfCDCJ.js";import{_ as S,l as C,r as w,s as T}from"./router-CMu0lceh.js";import{n as ne,t as re}from"./form-F--u6XQJ.js";import{t as ie}from"./button-CPx9BSuo.js";import{t as ae}from"./tag-BSnLMVgs.js";import{t as oe}from"./checkbox-CdKclTX1.js";import{t as se}from"./dialog-_5VhSQg5.js";import{t as ce}from"./empty-CnQTxkvl.js";import{t as le}from"./directive-CY41a6pJ.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-Cy-4mdDD.js";import"./css-49fsIjk3.js";import"./css-DMLZMbB9.js";import"./css-DmmbJMxg.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import{t as ue}from"./AdminBadge-Z72F8Boy.js";import"./css-D4jab2ni2.js";var de={class:`payment-config-page`},fe={class:`pc-header`},E={class:`pc-grid`},D={key:0,class:`pc-error`},O={class:`pc-card-header`},k={class:`platform`},A={class:`pc-card-body`},j={class:`row`},M={class:`value`},N={class:`row`},P={class:`value`},F={class:`row`},I={class:`row`},L={class:`row`},R={key:0,class:`row`},z={class:`value`},B={class:`pc-card-actions`},pe={key:0,class:`secret-hint`},me={key:0,class:`secret-hint`},he={key:0,class:`secret-hint`},V=s(d({__name:`PaymentConfig`,setup(s){let d=w(),V=[{value:`wechat`,label:`微信支付`},{value:`alipay`,label:`支付宝`},{value:`bank`,label:`银行直连`},{value:`other`,label:`其他`}],H={wechat:`微信支付`,alipay:`支付宝`,bank:`银行直连`,other:`其他`};function U(){return{Platform:`wechat`,AppID:``,MchID:``,APIKey:``,PrivateKey:``,PublicKey:``,NotifyURL:``,ReturnURL:``,CertPath:``,CertKeyPath:``,ConfigDefault:!1,ConfigStatus:!0}}let W=f([]),G=f(!1),K=f(``),q=f(!1),J=f(null),Y=c(()=>J.value!==null),X=h(U()),Z=f(!1),ge=c(()=>d.isAdmin);async function Q(){if(!ge.value){K.value=`无权访问:仅管理员可查看支付网关配置`,W.value=[];return}G.value=!0,K.value=``;try{let e=await T(`/API/Payment/Configs`);W.value=Array.isArray(e)?e:[]}catch(e){W.value=[],K.value=e instanceof Error?e.message:`加载失败`}finally{G.value=!1}}function _e(){J.value=null,Object.assign(X,U()),q.value=!0}function ve(e){J.value=e.ConfigUUID,Object.assign(X,{Platform:e.Platform,AppID:e.AppID||``,MchID:e.MchID||``,APIKey:``,PrivateKey:``,PublicKey:``,NotifyURL:e.NotifyURL||``,ReturnURL:e.ReturnURL||``,CertPath:e.CertPath||``,CertKeyPath:e.CertKeyPath||``,ConfigDefault:!!e.ConfigDefault,ConfigStatus:e.ConfigStatus===1}),q.value=!0}function $(e){return e||(Y.value?`***`:``)}async function ye(){let e={ConfigUUID:J.value||null,Platform:X.Platform,AppID:X.AppID,MchID:X.MchID,APIKey:$(X.APIKey),PrivateKey:$(X.PrivateKey),PublicKey:$(X.PublicKey),NotifyURL:X.NotifyURL,ReturnURL:X.ReturnURL,CertPath:X.CertPath,CertKeyPath:X.CertKeyPath,ConfigDefault:X.ConfigDefault,ConfigStatus:+!!X.ConfigStatus};Z.value=!0;try{await C(`/API/Payment/SaveConfig`,e),b.success(`保存成功`),q.value=!1,Q()}catch{}finally{Z.value=!1}}async function be(e,t){let n=H[t]||t;try{await S.confirm(`确认删除 ${n} 网关配置?`,`提示`,{type:`warning`,confirmButtonText:`确认删除`,cancelButtonText:`取消`})}catch{return}try{await C(`/API/Payment/DeleteConfig/${e}`),b.success(`已删除`),Q()}catch{}}return e(()=>{y(`支付网关配置`),Q()}),(e,s)=>{let c=ie,d=ce,f=ae,h=te,y=ee,b=ne,S=x,C=oe,w=re,T=se,U=le;return a(),p(`div`,de,[m(ue),g(`div`,fe,[s[16]||=g(`h1`,{class:`page-title`},[g(`i`,{class:`fas fa-credit-card icon-primary`}),g(`span`,null,`支付网关配置`)],-1),m(c,{type:`primary`,onClick:_e},{default:r(()=>[...s[14]||=[g(`i`,{class:`fas fa-plus`},null,-1),_(` 新增配置 `,-1)]]),_:1}),m(c,{onClick:Q},{default:r(()=>[...s[15]||=[g(`i`,{class:`fas fa-sync`},null,-1),_(` 刷新 `,-1)]]),_:1})]),o((a(),p(`div`,E,[K.value?(a(),p(`div`,D,[s[17]||=g(`i`,{class:`fas fa-exclamation-triangle`},null,-1),g(`div`,null,t(K.value),1)])):!G.value&&W.value.length===0?(a(),v(d,{key:1,description:`暂无支付网关配置`,"image-size":60})):l(``,!0),(a(!0),p(u,null,n(W.value,e=>(a(),p(`div`,{key:e.ConfigUUID,class:`pc-card`},[g(`div`,O,[g(`span`,k,t(H[e.Platform]||e.Platform),1),e.ConfigDefault?(a(),v(f,{key:0,type:`primary`,size:`small`},{default:r(()=>[...s[18]||=[_(`默认`,-1)]]),_:1})):l(``,!0),m(f,{type:e.ConfigStatus===1?`success`:`danger`,size:`small`},{default:r(()=>[_(t(e.ConfigStatus===1?`启用`:`停用`),1)]),_:2},1032,[`type`])]),g(`div`,A,[g(`div`,j,[s[19]||=g(`span`,{class:`label`},`AppID`,-1),g(`span`,M,t(e.AppID||`-`),1)]),g(`div`,N,[s[20]||=g(`span`,{class:`label`},`商户号`,-1),g(`span`,P,t(e.MchID||`-`),1)]),g(`div`,F,[s[21]||=g(`span`,{class:`label`},`APIKey`,-1),g(`span`,{class:i([`value`,e.APIKeySet?`secret-set`:`secret-unset`])},t(e.APIKeySet?`已设置 ***`:`未设置`),3)]),g(`div`,I,[s[22]||=g(`span`,{cLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Br as e,Lr as t,Nn as n,_ as r,an as i,h as a,hn as o,ln as s,mn as c,on as l}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as u}from"./serverScope-O8Rw8SFk.js";import{r as d}from"./router-CMu0lceh.js";import{t as f}from"./AdminBadge-Z72F8Boy.js";import{t as p}from"./CrudTable-B49nrpUt.js";var m={class:`product-page`},h=r(o({__name:`Products`,setup(r){let o=d(),h=a();u(`产品管理`);let g=i(()=>o.isAdmin),_=i(()=>`scope-banner ${g.value?`admin`:`normal`}`),v=i(()=>g.value?`管理员视图:可查看和管理全公司产品模板,含跨公司特权模式。`:`普通组员视图:可查看可用产品列表。`);function y(e){h.push({path:`/inventory/product-detail`,query:{TemplateUUID:e.TemplateUUID||``}})}return(r,i)=>(n(),s(`div`,m,[c(f),l(`div`,{class:t(_.value)},[l(`i`,{class:t([`fas`,g.value?`fa-shield-alt`:`fa-info-circle`])},null,2),l(`span`,null,e(v.value),1)],2),c(p,{table:`OrderTemplate`,title:`产品管理`,"pk-field":`TemplateUUID`,searchable:``,pageable:``,stretch:``,selectable:g.value,"on-view":y},null,8,[`selectable`])]))}}),[[`__scopeId`,`data-v-2c36b7b7`]]);export{h as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{Br as e,Jn as t,Nn as n,_ as r,hn as i,mn as a,on as o,pn as s,pr as c,sn as l}from"./useApi-CROJJdhE-mMpa5RAf.js";import{n as u,t as d}from"./descriptions-Cq_aE9sg.js";import{i as f,r as p}from"./router-CMu0lceh.js";import{t as m}from"./tag-BSnLMVgs.js";import{t as h}from"./card-Dj_UeWcA.js";/* empty css */import"./css-BEipSTAx.js";import"./css-D-a1H3t1.js";import"./css-CysIl0tz.js";var g={class:`profile`},_=[`src`],v=r(i({__name:`Profile`,setup(r){let i=p(),v=f();return(r,f)=>{let p=u,y=m,b=d,x=h;return n(),l(x,{shadow:`never`},{header:t(()=>[...f[0]||=[o(`span`,null,`个人中心`,-1)]]),default:t(()=>[o(`div`,g,[o(`img`,{src:c(v),alt:`头像`,class:`avatar`},null,8,_),a(b,{column:1,border:``},{default:t(()=>[a(p,{label:`用户名`},{default:t(()=>[s(e(c(i).userInfo?.UserName||`-`),1)]),_:1}),a(p,{label:`显示名`},{default:t(()=>[s(e(c(i).userInfo?.DisplayName||`-`),1)]),_:1}),a(p,{label:`邮箱`},{default:t(()=>[s(e(c(i).userInfo?.Email||`-`),1)]),_:1}),a(p,{label:`当前角色`},{default:t(()=>[s(e(c(i).currentRole||`-`),1)]),_:1}),a(p,{label:`是否管理员`},{default:t(()=>[a(y,{type:c(i).isAdmin?`danger`:`info`},{default:t(()=>[s(e(c(i).isAdmin?`是`:`否`),1)]),_:1},8,[`type`])]),_:1})]),_:1})])]),_:1})}}}),[[`__scopeId`,`data-v-0032e664`]]);export{v as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{Nn as e,_ as t,h as n,hn as r,ln as i,mn as a}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as o}from"./serverScope-O8Rw8SFk.js";import{t as s}from"./AdminBadge-Z72F8Boy.js";import{t as c}from"./CrudTable-B49nrpUt.js";var l={class:`role-page`},u=t(r({__name:`Role`,setup(t){o(`角色管理`);let r=n();function u(e){r.push({path:`/company/role-detail`,query:{RoleUUID:e.RoleUUID||``}})}return(t,n)=>(e(),i(`div`,l,[a(s),a(c,{table:`Role`,title:`角色管理`,"pk-field":`RoleUUID`,searchable:``,pageable:``,stretch:``,selectable:``,"on-view":u})]))}}),[[`__scopeId`,`data-v-fe35ce37`]]);export{u as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as ee,Nn as i,_ as a,an as o,cn as s,en as c,hn as l,ir as u,ln as d,m as f,mn as p,nr as m,pn as h,pr as g,sn as _}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as v,i as y,o as b,r as x,u as S}from"./serverScope-O8Rw8SFk.js";import{t as C}from"./date-picker-CM_15T0u.js";import{u as w}from"./use-global-config-D-dPcPvU.js";import{n as T}from"./descriptions-Cq_aE9sg.js";import{r as E,t as D}from"./select-BGsfCDCJ.js";import{n as O,t as k}from"./form-F--u6XQJ.js";import{t as A}from"./alert-BpFV-0dO.js";import{t as te}from"./button-CPx9BSuo.js";import{t as ne}from"./tag-BSnLMVgs.js";import{t as re}from"./card-Dj_UeWcA.js";import{t as ie}from"./dialog-_5VhSQg5.js";import{t as ae}from"./input-number-CiNOxXL6.js";import{t as oe}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-CysIl0tz.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./AdminBadge-Z72F8Boy.js";import"./css-BLJI5-W_.js";import{t as j}from"./CrudTable-B49nrpUt.js";import"./css-ByqxgOA-.js";import{t as M}from"./form-B2Pzr8Vf.js";import{t as N}from"./DetailPage-m11wfvkM.js";import{t as P}from"./InfoGrid-C1it9Z2Y.js";var F=`RoleUUID`,I=a(l({__name:`RoleDetail`,setup(a){let l=f(),I=u(!1),L=u(null),R=u(``),z=l.query.RoleUUID||``,B={0:`组员`,1:`组长`,2:`其他`},V={0:`全租户`,1:`公司`,2:`部门`},H={0:{text:`禁用`,type:`danger`},1:{text:`启用`,type:`success`}},U=o(()=>!y()||x()),W=o(()=>U.value?`特权模式:显示该角色在所有公司的关联记录(无公司隔离)`:`仅显示当前公司数据。如需查看所有公司记录,需管理员特权。`);function G(e){return e==null||e===``?``:String(e)}function K(e){if(!e)return`-`;let t=String(e),n=new Date(t);if(isNaN(n.getTime()))return t;let r=e=>String(e).padStart(2,`0`);return`${n.getFullYear()}-${r(n.getMonth()+1)}-${r(n.getDate())} ${r(n.getHours())}:${r(n.getMinutes())}:${r(n.getSeconds())}`}function q(e){return Array.isArray(e)?e:e?.list||[]}async function J(){if(!z){R.value=`缺少 RoleUUID 参数,无法加载角色详情。`;return}I.value=!0,R.value=``;try{let e=q(await M.list(`Role`,{RoleUUID:z,pageSize:1})),t=e.find(e=>e.RoleUUID===z)||e[0];if(!t){R.value=`未找到角色数据`;return}L.value=t,v(G(t.RoleName)||`角色详情`)}catch(e){R.value=`加载失败: ${e instanceof Error?e.message:String(e)}`}finally{I.value=!1}}let Y=u(!1),X=u(!1),Z=u([]),Q=m({}),se=o(()=>Z.value.filter(e=>e.editable!==!1&&!e.hideInForm&&e.type!==`hidden`&&e.type!==`divider`&&e.type!==`html`&&e.field!==F));async function ce(){if(L.value){try{Z.value.length||(Z.value=await M.getColumns(`Role`))}catch{Z.value=[]}Object.keys(Q).forEach(e=>delete Q[e]),Object.assign(Q,L.value),Y.value=!0}}async function le(){if(L.value){X.value=!0;try{await M.update(`Role`,L.value[F],{...Q}),b.success(`保存成功`),Y.value=!1,await J()}catch{}finally{X.value=!1}}}return e(J),(e,a)=>{let o=ee(`Edit`),l=w,u=te,f=A,m=T,v=ne,y=re,b=S,x=ae,M=D,F=E,q=C,J=oe,Z=O,$=k,ue=ie;return i(),_(N,{title:L.value?.RoleName||`角色详情`,loading:I.value},{actions:r(()=>[p(u,{type:`primary`,disabled:!L.value,onClick:ce},{default:r(()=>[p(l,null,{default:r(()=>[p(o)]),_:1}),a[2]||=h(`编辑 `,-1)]),_:1},8,[`disabled`])]),default:r(()=>[R.value?(i(),_(f,{key:0,type:`error`,title:R.value,"show-icon":``,closable:!1},null,8,[`title`])):s(``,!0),L.value?(i(),_(P,{key:1,title:`基本信息`,columns:2},{default:r(()=>[p(m,{label:`角色名称`},{default:r(()=>[h(t(G(L.value.RoleName)||`-`),1)]),_:1}),p(m,{label:`角色类型`},{default:r(()=>[h(t(B[String(L.value.RoleType)]??`-`),1)]),_:1}),p(m,{label:`状态`},{default:r(()=>[p(v,{type:H[String(L.value.RoleStatus)]?.type||`info`,size:`small`},{default:r(()=>[h(t(H[String(L.value.RoleStatus)]?.text??L.value.RoleStatus),1)]),_:1},8,[`type`])]),_:1}),p(m,{label:`分配范围`},{default:r(()=>[h(t(V[String(L.value.AssignScope)]??`-`),1)]),_:1}),p(m,{label:`角色描述`},{default:r(()=>[h(t(G(L.value.RoleDesc)||`-`),1)]),_:1}),p(m,{label:`创建时间`},{default:r(()=>[h(t(K(L.value.CreateTime)),1)]),_:1})]),_:1})):s(``,!0),L.value?(i(),_(f,{key:2,type:U.value?`warning`:`info`,closable:!1,"show-icon":``,class:`scope-banner`},{default:r(()=>[h(t(W.value),1)]),_:1},8,[`type`])):s(``,!0),L.value?(i(),_(y,{key:3,shadow:`never`},{default:r(()=>[p(j,{table:`RolePermission`,title:`权限列表`,query:{RoleUUID:g(z)},selectable:!0,pageable:!0,"pk-field":`RolePermUUID`},null,8,[`query`])]),_:1})):s(``,!0),L.value?(i(),_(y,{key:4,shadow:`never`},{default:r(()=>[p(j,{table:`UserRole`,title:`关联用户`,query:{RoleUUID:g(z)},selectable:!0,pageable:!0,"pk-field":`UserRoleUUID`},null,8,[`query`])]),_:1})):s(``,!0),p(ue,{modelValue:Y.value,"onUpdate:modelValue":a[1]||=e=>Y.value=e,title:`编辑角色`,width:`600px`,"destroy-on-close":``},{footer:r(()=Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as i,Nn as a,_ as o,an as s,cn as c,en as l,h as u,hn as d,ir as f,ln as p,m,mn as h,nr as g,on as _,pn as v,pr as y,sn as b}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as x,o as S,u as C}from"./serverScope-O8Rw8SFk.js";import{t as ee}from"./date-picker-CM_15T0u.js";import{u as w}from"./use-global-config-D-dPcPvU.js";import{n as T}from"./descriptions-Cq_aE9sg.js";import{r as E,t as D}from"./select-BGsfCDCJ.js";import{r as O}from"./router-CMu0lceh.js";import{n as k,t as A}from"./form-F--u6XQJ.js";import{t as j}from"./alert-BpFV-0dO.js";import{t as M}from"./button-CPx9BSuo.js";import{t as N}from"./tag-BSnLMVgs.js";import{t as te}from"./card-Dj_UeWcA.js";import{t as ne}from"./dialog-_5VhSQg5.js";import{t as re}from"./input-number-CiNOxXL6.js";import{t as ie}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-CysIl0tz.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./AdminBadge-Z72F8Boy.js";import"./css-BLJI5-W_.js";import{n as ae,t as P}from"./CrudTable-B49nrpUt.js";import"./css-ByqxgOA-.js";import{t as F}from"./form-B2Pzr8Vf.js";import{t as I}from"./DetailPage-m11wfvkM.js";import{t as L}from"./InfoGrid-C1it9Z2Y.js";var R={class:`perm-hint`},z=`RoleUUID`,B=o(d({__name:`RoleDetail`,setup(o){let d=m(),B=u(),V=O(),H=d.query.RoleUUID||``,U=f(!1),W=f(null),G=f(!1),K=f(!1),q=f([]),J=g({}),oe=s(()=>W.value?.RoleName||`角色详情`),se=s(()=>V.isAdmin?`特权模式:显示该角色在所有公司的关联记录(无公司隔离)`:`仅显示当前公司数据。如需查看所有公司记录,需管理员特权。`);function ce(e){return e===0||e===`0`?`组员`:e===1||e===`1`?`组长`:`-`}function Y(e){return e===1||e===`1`?{text:`启用`,type:`success`}:e===0||e===`0`?{text:`禁用`,type:`danger`}:{text:String(e??`-`),type:`warning`}}function X(e){return e===0||e===`0`?{text:`全租户可分发`,type:`success`}:e===1||e===`1`?{text:`指定公司可分发`,type:`primary`}:e===2||e===`2`?{text:`指定部门可分发`,type:`warning`}:{text:`-`,type:`info`}}function Z(e){if(!e)return`-`;let t=new Date(e);if(isNaN(t.getTime()))return String(e);let n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}let le=s(()=>q.value.filter(e=>e.editable!==!1&&!e.hideInForm&&e.type!==`hidden`&&e.type!==`divider`&&e.type!==`html`&&e.field!==z));async function Q(){if(!H){S.warning(`缺少 RoleUUID 参数,无法加载角色详情`);return}U.value=!0;try{let e=await F.list(`Role`,{[z]:H,pageSize:1}),t=Array.isArray(e)?e:e?.list||[],n=t.find(e=>e[z]===H)||t[0];if(!n){S.error(`未找到角色数据`);return}W.value=n,x(n.RoleName||`角色详情`)}finally{U.value=!1}}async function $(){try{q.value=await F.getColumns(`Role`)}catch{}}function ue(){W.value&&(Object.keys(J).forEach(e=>delete J[e]),Object.assign(J,W.value),G.value=!0)}async function de(){K.value=!0;try{await F.update(`Role`,J[z],J),S.success(`保存成功`),G.value=!1,await Q()}finally{K.value=!1}}function fe(){if(!H){S.warning(`缺少 RoleUUID`);return}B.push({path:`/system/role-permissions`,query:{RoleUUID:H}})}function pe(e){B.push({path:`/system/user-detail`,query:{UserUUID:e.UserUUID||``}})}return e(async()=>{await Promise.all([Q(),$()])}),(e,o)=>{let s=i(`Edit`),u=w,d=M,f=i(`Connection`),m=j,g=T,x=N,S=te,O=i(`InfoFilled`),F=C,z=re,B=D,q=E,Q=ee,$=ie,me=k,he=A,ge=ne;return a(),b(I,{title:oe.value,loading:U.value},{actions:r(()=>[h(d,{type:`primary`,onClick:ue},{default:r(()=>[h(u,null,{default:r(()=>[h(s)]),_:1}),o[2]||=v(`编辑 `,-1)]),_:1}),h(d,{onClick:fe,title:`按权限组勾选分配权限`},{default:r(()=>[h(u,null,{default:r(()=>[h(f)]),_:1}),o[3]||=v(`权限树分配 `,-1)]),_:1})]),default:r(()=>[h(m,{type:y(V).isAdmin?`warning`:`info`,closable:!1,"show-icon":``},{default:r(()=>[v(t(se.value),1)]),_:1},8,[`type`]),h(L,{title:`基本信息`,columns:2},{default:r(()=>[h(g,{label:`角色名称`},{default:r(()=>[v(t(W.value?.RoleName||`-`),1)]),_:1}),h(g,{label:`角色类型`},{default:r(()=>[v(t(ce(W.value?.RoleType)),1)]),_:1}),h(g,{label:`角色状态`},{default:r(()=>[h(x,{type:Y(W.value?.RoleStatus).type,size:`small`},{default:r(()=>[v(t(Y(W.value?.RoleStatus).text),1)]),_:1},8,[`type`])]),_:1}),h(g,{label:`分配范围`},{default:r(()=>[h(x,{type:X(W.value?.AssignScope).type,size:`small`},{default:r(()=>[v(t(X(W.value?.AssignScope).text),1)]),_:1},8,[`type`])]),_:1}),h(g,{label:`角色描述`},{default:r(()=>[v(t(W.value?.RoleDesc||`-`),1)]),_:1}),h(g,{label:`创建时间`},{default:r(()=>[v(t(Z(W.value?.CreateTime)),1)]),_:1})]),_:1}),h(S,{shadow:`never`},{header:r(()=>[...o[4]||=[v(`关联用户`,-1)]]),default:r(()=>[y(H)?(a(),b(P,{key:0,table:`UserRole`,title:`角色用户`,query:{RoleUUID:y(H)},"pk-field":`UserRoleUUID`Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Dn as n,Fn as r,Jn as i,Ln as a,Nn as o,_ as s,an as c,cn as l,en as u,hn as d,ir as f,ln as p,m,mn as h,on as g,pn as _,sn as v,wn as y}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as b,o as x}from"./serverScope-O8Rw8SFk.js";import{u as ee}from"./use-global-config-D-dPcPvU.js";import{r as te,t as S}from"./select-BGsfCDCJ.js";import{g as C,l as w,r as ne,s as re}from"./router-CMu0lceh.js";import{t as T}from"./button-CPx9BSuo.js";import{t as E}from"./tag-BSnLMVgs.js";import{t as D}from"./card-Dj_UeWcA.js";import{t as O}from"./empty-CnQTxkvl.js";import{t as k}from"./tree-DqeBDBpX.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-Dmy6QwIc.js";import{t as A}from"./form-B2Pzr8Vf.js";import{t as ie}from"./DetailPage-m11wfvkM.js";import"./css-D4jab2ni2.js";import"./css-CLuE7SsA.js";var ae={key:0,class:`denied-state`},oe={class:`toolbar-row`},se={class:`toolbar-stat`},ce={class:`toolbar-actions`},le={key:0,class:`empty-state`},ue={class:`perm-row`},de={class:`perm-name`},fe={key:1,class:`perm-desc`},j=s(d({__name:`RolePermissions`,setup(s){let d=m(),j=ne(),M=d.query.RoleUUID||``,N=d.query.CompanyUUID||``,P=f(M),F=f(N),I=f([]),L=f([]),R=f([]),z=f(!1),B=f(!1),V=f(!1),H=f(!1),U=f(new Set),W=f([]),G=f(!1),K=f(0),q=f(null),pe=c(()=>j.isAdmin),J=c(()=>R.value.map((e,t)=>({_nodeKey:`group_${t}`,label:e.Category,children:e.Permissions.map(e=>({_nodeKey:e.PermUUID,label:e.PermName,permCode:e.PermCode,permDesc:e.PermDesc||``,isLeaf:!0}))}))),me=c(()=>R.value.reduce((e,t)=>e+t.Permissions.length,0)),he=c(()=>W.value.length),ge=c(()=>!!P.value&&!!F.value&&!B.value);async function _e(){try{let e=await A.list(`Role`,{pageSize:500});I.value=Array.isArray(e)?e:e?.list||[]}catch{}}async function Y(){try{let e=await A.list(`Company`,{pageSize:500});L.value=Array.isArray(e)?e:e?.list||[]}catch{}}async function X(){let e=P.value,t=F.value;if(!e||!t){R.value=[];return}z.value=!0,H.value=!1;try{let n=await re(`/API/Role/PermissionsTree`,{RoleUUID:e,CompanyUUID:t});R.value=n?.Groups||[];let r=R.value.flatMap(e=>e.Permissions.filter(e=>e.Checked).map(e=>e.PermUUID));U.value=new Set(r),W.value=[...r],K.value++,await y(),Q()}finally{z.value=!1}}function ve(){F.value&&X()}function ye(){P.value&&X()}function Z(){let e=q.value?.getCheckedKeys?.(!0);W.value=e||[],Q()}function Q(){let e=new Set(W.value);H.value=!(e.size===U.value.size&&[...e].every(e=>U.value.has(e)))}function be(){G.value=!0,K.value++,y(()=>Z())}function xe(){G.value=!1,K.value++,y(()=>Z())}function Se(){let e=R.value.flatMap(e=>e.Permissions.map(e=>e.PermUUID));q.value?.setCheckedKeys?.(e),W.value=e,Q()}function Ce(){q.value?.setCheckedKeys?.([]),W.value=[],Q()}async function we(){let e=P.value,t=F.value;if(!e||!t){x.warning(`请先选择角色和公司`);return}B.value=!0;try{let n=await w(`/API/Role/SavePermissions`,{RoleUUID:e,CompanyUUID:t,PermUUIDs:W.value})||{};x.success(`保存成功(新增 ${n.Added||0},移除 ${n.Removed||0},保留 ${n.Kept||0})`),U.value=new Set(W.value),H.value=!1}finally{B.value=!1}}function $(e){H.value&&(e.preventDefault(),e.returnValue=``)}return C((e,t,n)=>{if(!H.value){n();return}window.confirm(`有未保存的权限变更,确定离开?`)?n():n(!1)}),e(async()=>{if(b(`角色权限分配`),!pe.value){V.value=!0;return}await Promise.all([_e(),Y()]),M&&(P.value=M),N&&(F.value=N),M&&N&&await X()}),n(()=>{window.removeEventListener(`beforeunload`,$)}),window.addEventListener(`beforeunload`,$),(e,n)=>{let s=a(`Lock`),c=ee,d=S,f=te,m=T,y=D,b=O,x=E,C=k,w=a(`Select`);return o(),v(ie,{title:`角色权限分配`,loading:z.value},{default:i(()=>[V.value?(o(),p(`div`,ae,[h(c,{class:`denied-icon`},{default:i(()=>[h(s)]),_:1}),n[2]||=g(`div`,{class:`denied-title`},`无权访问`,-1),n[3]||=g(`div`,{class:`denied-desc`},`该页面仅管理员可查看,请切换至管理员角色或联系管理员。`,-1)])):(o(),p(u,{key:1},[h(y,{shadow:`never`,class:`toolbar`},{default:i(()=>[g(`div`,oe,[n[11]||=g(`span`,{class:`toolbar-label`},`角色:`,-1),h(f,{modelValue:P.value,"onUpdate:modelValue":n[0]||=e=>P.value=e,placeholder:`请选择角色`,filterable:``,style:{"min-width":`200px`},onChange:ve},{default:i(()=>[h(d,{label:`请选择角色`,value:``}),(o(!0),p(u,null,r(I.value,e=>(o(),v(d,{key:e.RoleUUID,label:e.RoleName,value:e.RoleUUID},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`]),n[12]||=g(`span`,{class:`toolbar-label`},`公司:`,-1),h(f,{modelValue:F.value,"onUpdate:modelValue":n[1]||=e=>F.value=e,placeholder:`请选择公司`,filterable:``,style:{"min-width":`200px`},onChange:ye},{default:i(()=>[h(d,{label:`请选择公司`,value:``}),(o(!0),p(u,null,r(L.value,e=>(o(),v(d,{key:e.CompanyUUID,label:e.CompanyName,value:e.CompanyUUID},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`]),g(`div`,se,[n[4]||=_(` 共 `,-1),g(`strong`,null,t(me.value),1),n[5]||=_(` 项权限,已勾选 `,-1),g(`strong`,null,t(he.valLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Nn as e,_ as t,h as n,hn as r,ln as i,mn as a}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as o}from"./serverScope-O8Rw8SFk.js";import{t as s}from"./CrudTable-B49nrpUt.js";var c={class:`role-page`},l=t(r({__name:`Roles`,setup(t){o(`角色管理`);let r=n();function l(e){r.push({path:`/system/role-detail`,query:{RoleUUID:e.RoleUUID||``}})}return(t,n)=>(e(),i(`div`,c,[a(s,{table:`Role`,title:`角色管理`,"pk-field":`RoleUUID`,searchable:``,pageable:``,stretch:``,selectable:``,"on-view":l})]))}}),[[`__scopeId`,`data-v-4d1d8792`]]);export{l as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Fn as t,Jn as n,Kn as r,Nn as i,_ as a,en as ee,hn as o,ir as s,ln as c,mn as l,nr as u,on as d,pn as f}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as p,o as m}from"./serverScope-O8Rw8SFk.js";import{r as h,t as te}from"./select-BGsfCDCJ.js";import{_ as g,l as _,s as v}from"./router-CMu0lceh.js";import{t as y}from"./button-CPx9BSuo.js";import{t as b}from"./input-number-CiNOxXL6.js";import{t as ne}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import{t as re}from"./app-Bqwt3qVF.js";import"./css-w8-s2aei.js";import"./css-Dmy6QwIc.js";import"./css-BLJI5-W_.js";var ie={class:`settings-page`},ae={class:`settings-section`},oe={class:`settings-item`},se={class:`settings-item-control`},x={class:`settings-item`},S={class:`settings-item-control`},C={class:`settings-section`},w={class:`settings-item`},T={class:`settings-item-control`},E={class:`settings-item`},D={class:`settings-item-control`},O={class:`settings-item`},k={class:`settings-item-control`},A={class:`settings-section`},j={class:`settings-item`},M={class:`settings-item-control`},N={class:`settings-item`},P={class:`settings-item-control`},F={class:`settings-section`},I={class:`settings-item`},L={class:`settings-item-control`},R={class:`settings-item`},z={class:`settings-item-control`},ce={class:`settings-section danger-zone`},B={class:`settings-item`},V={class:`settings-item-control`},H={class:`settings-item`},U={class:`settings-item-control`},W=`GERPSettings`,G=`/API/Settings`,K=a(o({__name:`Settings`,setup(a){p(`系统设置`);let o=re(),K={themeMode:`default`,sidebarExpanded:!0,maxTabs:20,allowDuplicate:!1,confirmClose:!1,desktopNotify:!0,notifySound:!0,animations:!0,preload:!0},le=[{value:`default`,label:`默认主题`},{value:`light`,label:`浅色主题`},{value:`dark`,label:`深色主题`},{value:`green`,label:`绿色主题`},{value:`purple`,label:`紫色主题`},{value:`red`,label:`红色主题`}],q=u({...K}),J=s(!1);async function Y(){let e={...K};try{let t=await v(G);t&&Object.keys(t).length>0&&Object.assign(e,t)}catch{let t=localStorage.getItem(W);if(t)try{Object.assign(e,JSON.parse(t))}catch{}}return e}let X=null;function Z(e=200){J.value&&(X&&clearTimeout(X),X=setTimeout(()=>ue(!0),e))}async function ue(e=!1){localStorage.setItem(W,JSON.stringify(q));try{await _(G,q),e||m.success(`已保存`)}catch{e||m.warning(`保存到服务器失败`)}}function Q(e){let t=document.documentElement;t.style.setProperty(`--TransitionSpeed`,e.animations?`0.2s`:`0s`),t.style.setProperty(`--AnimationDuration`,e.animations?`0.3s`:`0s`),t.classList.toggle(`GERPNoAnimations`,!e.animations),o.sidebarCollapsed===e.sidebarExpanded&&(o.sidebarCollapsed=!e.sidebarExpanded),$(e.themeMode)}function $(e){if(e===`light`||e===`dark`){o.setTheme(e);return}e==="default"&&o.setTheme(`light`)}function de(e){$(e),Z(300)}function fe(e){o.sidebarCollapsed=!e,Z(200)}function pe(e){let t=document.documentElement;t.style.setProperty(`--TransitionSpeed`,e?`0.2s`:`0s`),t.style.setProperty(`--AnimationDuration`,e?`0.3s`:`0s`),t.classList.toggle(`GERPNoAnimations`,!e),Z(200)}async function me(){try{await g.confirm(`确定要清除所有缓存吗?`,`清除缓存`,{type:`warning`,confirmButtonText:`确定`,cancelButtonText:`取消`})}catch{return}localStorage.removeItem(W);try{await _(G,{})}catch{}let e=await Y();Object.assign(q,e),Q(q),m.success(`缓存已清除`)}async function he(){try{await g.confirm(`确定要重置所有设置为默认值吗?`,`重置设置`,{type:`error`,confirmButtonText:`确定重置`,cancelButtonText:`取消`})}catch{return}Object.assign(q,K),localStorage.setItem(W,JSON.stringify(q));try{await _(G,q)}catch{}$(`default`),Q(q),m.success(`设置已重置`)}return r(()=>[q.maxTabs,q.allowDuplicate,q.confirmClose,q.desktopNotify,q.notifySound,q.preload],()=>Z(200)),e(async()=>{let e=await Y();Object.assign(q,e),Q(q),J.value=!0}),(e,r)=>{let a=te,o=h,s=ne,u=b,p=y;return i(),c(`div`,ie,[r[24]||=d(`div`,{class:`settings-header`},[d(`h1`,{class:`settings-title`},[d(`i`,{class:`fas fa-cog icon-primary`}),d(`span`,null,`系统设置`)]),d(`p`,{class:`settings-desc`},`管理系统外观、行为和功能配置`)],-1),d(`div`,ae,[r[8]||=d(`h2`,{class:`settings-section-title`},`外观设置`,-1),d(`div`,oe,[r[6]||=d(`div`,{class:`settings-item-info`},[d(`div`,{class:`settings-item-title`},`主题模式`),d(`div`,{class:`settings-item-desc`},`选择系统的主题风格`)],-1),d(`div`,se,[l(o,{"model-value":q.themeMode,style:{width:`160px`},"onUpdate:modelValue":de},{default:n(()=>[(i(),c(ee,null,t(le,e=>l(a,{key:e.value,label:e.label,value:e.value},null,8,[`label`,`value`])),64))]),_:1},8,[`model-value`])])]),d(`div`,x,[r[7]||=d(`div`,{class:`settings-item-info`},[d(`div`,{class:`settings-item-title`},`侧边栏默认展开`),d(`div`,{class:`settings-item-desc`},`启动时是否默认展开侧边栏`)],-1),d(`div`,S,[l(s,{"model-value":q.sidebarExpanded,"onUpdate:modelValue":fe},null,8,[`model-value`])])])]),d(`div`,C,[r[12]||=d(`Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Nn as e,_ as t,h as n,hn as r,ln as i,mn as a}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as o}from"./serverScope-O8Rw8SFk.js";import{t as s}from"./AdminBadge-Z72F8Boy.js";import{t as c}from"./CrudTable-B49nrpUt.js";var l={class:`tenant-page`},u=t(r({__name:`Tenant`,setup(t){o(`租户管理`);let r=n();function u(e){r.push({path:`/company/tenant-detail`,query:{TenantUUID:e.TenantUUID||``}})}return(t,n)=>(e(),i(`div`,l,[a(s),a(c,{table:`Tenant`,title:`租户管理`,"pk-field":`TenantUUID`,searchable:``,pageable:``,stretch:``,selectable:``,"on-view":u})]))}}),[[`__scopeId`,`data-v-4b7a75c4`]]);export{u as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Jn as t,Nn as n,_ as r,h as i,hn as a,ir as o,ln as s,mn as c,nr as l,on as u,pn as d}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as f,o as p,u as m}from"./serverScope-O8Rw8SFk.js";import{t as h}from"./date-picker-CM_15T0u.js";import{l as g}from"./router-CMu0lceh.js";import{n as _,t as v}from"./form-F--u6XQJ.js";import{t as y}from"./button-CPx9BSuo.js";/* empty css */import"./css-DsD2Typt.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-ByqxgOA-.js";var b={class:`tenant-create-page`},x={class:`tenant-create-card`},S={key:0,class:`form-section`},C={class:`card-actions`},w={key:1,class:`success-section`},T={class:`success-actions`},E=r(a({__name:`TenantCreate`,setup(r){let a=i(),E=o(),D=l({TenantName:``,TenantExpireTime:``,ReviewRemark:``}),O={TenantName:[{required:!0,message:`请输入租户名称`,trigger:`blur`}],TenantExpireTime:[{required:!0,message:`请选择有效期`,trigger:`change`}]},k=o(!1),A=o(!1);async function j(){if(E.value){try{await E.value.validate()}catch{return}k.value=!0;try{await g(`/API/Tenant/Apply`,{TenantName:D.TenantName.trim(),TenantExpireTime:D.TenantExpireTime,ReviewRemark:D.ReviewRemark.trim()}),A.value=!0,p.success(`申请已提交`)}catch{}finally{k.value=!1}}}function M(){A.value=!1,D.TenantName=``,D.TenantExpireTime=``,D.ReviewRemark=``,E.value?.clearValidate()}function N(){a.back()}return e(()=>{f(`租户入驻申请`)}),(e,r)=>{let i=m,a=_,o=h,l=v,f=y;return n(),s(`div`,b,[u(`div`,x,[A.value?(n(),s(`div`,w,[r[9]||=u(`i`,{class:`fas fa-check-circle success-icon`},null,-1),r[10]||=u(`h3`,null,`申请已提交`,-1),r[11]||=u(`p`,null,`租户入驻申请已提交,等待审核通过后激活。`,-1),u(`div`,T,[c(f,{type:`primary`,onClick:M},{default:t(()=>[...r[7]||=[d(`继续申请`,-1)]]),_:1}),c(f,{onClick:N},{default:t(()=>[...r[8]||=[d(`返回`,-1)]]),_:1})])])):(n(),s(`div`,S,[r[5]||=u(`div`,{class:`card-title`},[u(`i`,{class:`fas fa-key icon-primary`}),u(`span`,null,`租户入驻申请`)],-1),r[6]||=u(`div`,{class:`card-desc`},`提交租户入驻申请,等待超管或审核员审核通过后激活。`,-1),c(l,{ref_key:`formRef`,ref:E,model:D,rules:O,"label-position":`top`,class:`tenant-form`},{default:t(()=>[c(a,{label:`租户名称`,prop:`TenantName`},{default:t(()=>[c(i,{modelValue:D.TenantName,"onUpdate:modelValue":r[0]||=e=>D.TenantName=e,placeholder:`请输入租户名称`},null,8,[`modelValue`])]),_:1}),c(a,{label:`有效期`,prop:`TenantExpireTime`},{default:t(()=>[c(o,{modelValue:D.TenantExpireTime,"onUpdate:modelValue":r[1]||=e=>D.TenantExpireTime=e,type:`datetime`,format:`YYYY-MM-DD HH:mm:ss`,"value-format":`YYYY-MM-DD HH:mm:ss`,placeholder:`请选择有效期`,style:{width:`100%`}},null,8,[`modelValue`])]),_:1}),c(a,{label:`申请说明`},{default:t(()=>[c(i,{modelValue:D.ReviewRemark,"onUpdate:modelValue":r[2]||=e=>D.ReviewRemark=e,type:`textarea`,rows:3,placeholder:`可选,填写申请理由或备注`},null,8,[`modelValue`])]),_:1})]),_:1},8,[`model`]),u(`div`,C,[c(f,{onClick:N},{default:t(()=>[...r[3]||=[d(`取消`,-1)]]),_:1}),c(f,{type:`primary`,loading:k.value,onClick:j},{default:t(()=>[...r[4]||=[d(`提交申请`,-1)]]),_:1},8,[`loading`])])]))])])}}}),[[`__scopeId`,`data-v-1b563c9c`]]);export{E as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as ee,Nn as i,an as a,cn as o,en as s,h as c,hn as l,ir as u,ln as d,m as f,mn as p,nr as m,pn as h,pr as g,sn as _}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as v,o as y,u as b}from"./serverScope-O8Rw8SFk.js";import{t as x}from"./date-picker-CM_15T0u.js";import{u as S}from"./use-global-config-D-dPcPvU.js";import{n as C}from"./descriptions-Cq_aE9sg.js";import{r as w,t as te}from"./select-BGsfCDCJ.js";import{n as T,t as ne}from"./form-F--u6XQJ.js";import{t as E}from"./button-CPx9BSuo.js";import{t as D}from"./tag-BSnLMVgs.js";import{t as O}from"./card-Dj_UeWcA.js";import{t as k}from"./dialog-_5VhSQg5.js";import{t as A}from"./input-number-CiNOxXL6.js";import{t as j}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-CysIl0tz.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./css-BLJI5-W_.js";import{n as M,t as N}from"./CrudTable-B49nrpUt.js";import"./css-ByqxgOA-.js";import{t as P}from"./form-B2Pzr8Vf.js";import{t as F}from"./DetailPage-m11wfvkM.js";import{t as I}from"./InfoGrid-C1it9Z2Y.js";var L=`TenantUUID`,R=l({__name:`TenantDetail`,setup(l){let R=f(),z=c(),B=R.query.TenantUUID||``,V=u(!1),H=u(null),U=u(!1),W=u(!1),G=u([]),K=m({}),q=a(()=>H.value?.TenantName||`租户详情`);function J(e){return e===1||e===`1`?{text:`启用`,type:`success`}:e===0||e===`0`?{text:`禁用`,type:`danger`}:{text:String(e??`-`),type:`info`}}function Y(e){return e===0||e===`0`?{text:`待审核`,type:`warning`}:e===1||e===`1`?{text:`已通过`,type:`success`}:e===2||e===`2`?{text:`已拒绝`,type:`danger`}:{text:String(e??`-`),type:`info`}}function X(e){if(!e)return`-`;let t=new Date(e);if(isNaN(t.getTime()))return String(e);let n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}let Z=a(()=>G.value.filter(e=>e.editable!==!1&&!e.hideInForm&&e.type!==`hidden`&&e.type!==`divider`&&e.type!==`html`&&e.field!==L));async function Q(){if(!B){y.warning(`缺少 TenantUUID 参数,无法加载租户详情`);return}V.value=!0;try{let e=await P.list(`Tenant`,{[L]:B,pageSize:1}),t=Array.isArray(e)?e:e?.list||[],n=t.find(e=>e[L]===B)||t[0];if(!n){y.error(`未找到租户数据`);return}H.value=n,v(n.TenantName||`租户详情`)}finally{V.value=!1}}async function $(){try{G.value=await P.getColumns(`Tenant`)}catch{}}function re(){H.value&&(Object.keys(K).forEach(e=>delete K[e]),Object.assign(K,H.value),U.value=!0)}async function ie(){W.value=!0;try{await P.update(`Tenant`,K[L],K),y.success(`保存成功`),U.value=!1,await Q()}finally{W.value=!1}}function ae(e){z.push({path:`/company/company-detail`,query:{CompanyUUID:e.CompanyUUID||``}})}return e(async()=>{await Promise.all([Q(),$()])}),(e,a)=>{let c=ee(`Edit`),l=S,u=E,f=C,m=D,v=O,y=b,P=A,L=te,R=w,z=x,G=j,Q=T,$=ne,oe=k;return i(),_(F,{title:q.value,loading:V.value},{actions:r(()=>[p(u,{type:`primary`,onClick:re},{default:r(()=>[p(l,null,{default:r(()=>[p(c)]),_:1}),a[2]||=h(`编辑 `,-1)]),_:1})]),default:r(()=>[p(I,{title:`基本信息`,columns:2},{default:r(()=>[p(f,{label:`租户名称`},{default:r(()=>[h(t(H.value?.TenantName||`-`),1)]),_:1}),p(f,{label:`租户状态`},{default:r(()=>[p(m,{type:J(H.value?.TenantStatus).type,size:`small`},{default:r(()=>[h(t(J(H.value?.TenantStatus).text),1)]),_:1},8,[`type`])]),_:1}),p(f,{label:`到期时间`},{default:r(()=>[h(t(X(H.value?.TenantExpireTime)),1)]),_:1}),p(f,{label:`创建时间`},{default:r(()=>[h(t(X(H.value?.CreateTime)),1)]),_:1})]),_:1}),p(I,{title:`审核信息`,columns:2},{default:r(()=>[p(f,{label:`审核状态`},{default:r(()=>[p(m,{type:Y(H.value?.ReviewStatus).type,size:`small`},{default:r(()=>[h(t(Y(H.value?.ReviewStatus).text),1)]),_:1},8,[`type`])]),_:1}),p(f,{label:`审核时间`},{default:r(()=>[h(t(X(H.value?.ReviewTime)),1)]),_:1}),p(f,{label:`审核备注`},{default:r(()=>[h(t(H.value?.ReviewRemark||`-`),1)]),_:1})]),_:1}),p(v,{shadow:`never`},{header:r(()=>[...a[3]||=[h(`关联公司`,-1)]]),default:r(()=>[g(B)?(i(),_(N,{key:0,table:`Company`,title:`租户公司`,query:{TenantUUID:g(B)},"pk-field":`CompanyUUID`,selectable:``,pageable:``,"on-view":ae},null,8,[`query`])):o(``,!0)]),_:1}),p(oe,{modelValue:U.value,"onUpdate:modelValue":a[1]||=e=>U.value=e,title:`编辑租户`,width:`600px`,"destroy-on-close":``},{footer:r(()=>[p(u,{onClick:a[0]||=e=>U.value=!1},{default:r(()=>[...a[4]||=[h(`取消`,-1)]]),_:1}),p(u,{type:`primary`,loading:W.value,onClick:ie},{default:r(()=>[...a[5]||=[h(`保存`,-1)]]),_:1},8,[`loading`])]),default:r(()=>[p($,{model:K,"label-width":`120px`,"label-position":`right`},{default:r(()=>[(i(!0),d(s,null,n(Z.value,e=>(i(),_(Q,{key:e.field,label:e.title,required:e.required},{default:r(()=>[e.type===`entityPicker`&&e.entityPicker?(i(),_(M,{key:0,modelValue:K[e.field],"onLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Nn as i,Yn as a,_ as o,cn as s,en as c,hn as l,ir as u,ln as d,mn as f,on as p,pn as m,sn as h}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as g,o as _,u as v}from"./serverScope-O8Rw8SFk.js";import{_ as y,l as b,s as x}from"./router-CMu0lceh.js";import{t as S}from"./button-CPx9BSuo.js";import{t as C}from"./dialog-_5VhSQg5.js";import{t as w}from"./empty-CnQTxkvl.js";import{t as T}from"./directive-CY41a6pJ.js";/* empty css */import"./css-DsD2Typt.js";import"./css-Cy-4mdDD.js";import"./css-DmmbJMxg.js";import"./css-DMOjom7l.js";import"./css-D4jab2ni2.js";var E={class:`tenant-review-page`},D={class:`review-header`},O={class:`review-container`},k={key:0,class:`error-state`},A={key:2,class:`review-list`},j={class:`info`},M={class:`name`},N={class:`meta`},P={key:0,class:`remark`},F={class:`actions`},I={class:`reject-target`},L=o(l({__name:`TenantReview`,setup(o){let l=u([]),L=u(!1),R=u(``),z=u(!1),B=u(``),V=u(``),H=u(``),U=u(!1);function W(e){return e?e.replace(`T`,` `).substring(0,19):`-`}async function G(){L.value=!0,R.value=``;try{let e=await x(`/API/Tenant/Pending`);l.value=Array.isArray(e)?e:[]}catch(e){l.value=[],R.value=e instanceof Error?e.message:`加载失败`}finally{L.value=!1}}async function K(e){try{await y.confirm(`确认批准该租户入驻申请?`,`提示`,{type:`warning`,confirmButtonText:`确认批准`,cancelButtonText:`取消`})}catch{return}try{await b(`/API/Tenant/Approve/${e}`),_.success(`审核通过`),G()}catch{}}function q(e,t){B.value=e,V.value=t,H.value=``,z.value=!0}async function J(){if(!H.value.trim()){_.warning(`请输入拒绝理由`);return}U.value=!0;try{await b(`/API/Tenant/Reject/${B.value}`,{ReviewRemark:H.value.trim()}),_.success(`已拒绝申请`),z.value=!1,G()}catch{}finally{U.value=!1}}return e(()=>{g(`租户审核工作台`),G()}),(e,o)=>{let u=S,g=w,_=v,y=C,b=T;return i(),d(`div`,E,[p(`div`,D,[o[4]||=p(`h1`,{class:`page-title`},[p(`i`,{class:`fas fa-clipboard-check icon-primary`}),p(`span`,null,`租户审核工作台`)],-1),f(u,{onClick:G},{default:r(()=>[...o[3]||=[p(`i`,{class:`fas fa-sync`},null,-1),m(` 刷新 `,-1)]]),_:1})]),a((i(),d(`div`,O,[R.value?(i(),d(`div`,k,[o[5]||=p(`i`,{class:`fas fa-exclamation-triangle`},null,-1),p(`div`,null,t(R.value),1)])):!L.value&&l.value.length===0?(i(),h(g,{key:1,description:`暂无待审核的租户申请`,"image-size":60})):(i(),d(`div`,A,[(i(!0),d(c,null,n(l.value,e=>(i(),d(`div`,{key:e.TenantUUID,class:`review-card`},[p(`div`,j,[p(`div`,M,t(e.TenantName),1),p(`div`,N,[p(`span`,null,[o[6]||=p(`i`,{class:`fas fa-calendar`},null,-1),m(` 有效期: `+t(W(e.TenantExpireTime)),1)]),p(`span`,null,[o[7]||=p(`i`,{class:`fas fa-clock`},null,-1),m(` 申请时间: `+t(W(e.CreateTime)),1)])]),e.ReviewRemark?(i(),d(`div`,P,[o[8]||=p(`i`,{class:`fas fa-comment`},null,-1),m(` `+t(e.ReviewRemark),1)])):s(``,!0)]),p(`div`,F,[f(u,{type:`primary`,onClick:t=>K(e.TenantUUID)},{default:r(()=>[...o[9]||=[p(`i`,{class:`fas fa-check`},null,-1),m(` 批准 `,-1)]]),_:1},8,[`onClick`]),f(u,{type:`danger`,onClick:t=>q(e.TenantUUID,e.TenantName)},{default:r(()=>[...o[10]||=[p(`i`,{class:`fas fa-times`},null,-1),m(` 拒绝 `,-1)]]),_:1},8,[`onClick`])])]))),128))]))])),[[b,L.value]]),f(y,{modelValue:z.value,"onUpdate:modelValue":o[2]||=e=>z.value=e,title:`拒绝入驻申请`,width:`420px`},{footer:r(()=>[f(u,{onClick:o[1]||=e=>z.value=!1},{default:r(()=>[...o[12]||=[m(`取消`,-1)]]),_:1}),f(u,{type:`danger`,loading:U.value,onClick:J},{default:r(()=>[...o[13]||=[m(`确认拒绝`,-1)]]),_:1},8,[`loading`])]),default:r(()=>[p(`p`,I,[o[11]||=m(`租户:`,-1),p(`span`,null,t(V.value),1)]),f(_,{modelValue:H.value,"onUpdate:modelValue":o[0]||=e=>H.value=e,type:`textarea`,rows:4,placeholder:`请输入拒绝理由`},null,8,[`modelValue`])]),_:1},8,[`modelValue`])])}}}),[[`__scopeId`,`data-v-2b23f899`]]);export{L as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as i,Nn as a,_ as o,an as s,cn as c,en as l,h as u,hn as d,ir as f,ln as p,m,mn as h,nr as g,on as ee,pn as _,pr as v,sn as y}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as b,o as x,u as S}from"./serverScope-O8Rw8SFk.js";import{t as C}from"./date-picker-CM_15T0u.js";import{u as w}from"./use-global-config-D-dPcPvU.js";import{n as te}from"./descriptions-Cq_aE9sg.js";import{r as ne,t as re}from"./select-BGsfCDCJ.js";import{r as T,s as E}from"./router-CMu0lceh.js";import{n as D,t as ie}from"./form-F--u6XQJ.js";import{t as O}from"./alert-BpFV-0dO.js";import{t as k}from"./button-CPx9BSuo.js";import{t as A}from"./tag-BSnLMVgs.js";import{t as j}from"./card-Dj_UeWcA.js";import{t as M}from"./dialog-_5VhSQg5.js";import{t as N}from"./input-number-CiNOxXL6.js";import{t as ae}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import"./css-BEipSTAx.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-CysIl0tz.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./AdminBadge-Z72F8Boy.js";import"./css-BLJI5-W_.js";import{n as oe,t as P}from"./CrudTable-B49nrpUt.js";import"./css-ByqxgOA-.js";import{t as F}from"./form-B2Pzr8Vf.js";import{t as se}from"./DetailPage-m11wfvkM.js";import{t as I}from"./InfoGrid-C1it9Z2Y.js";var L=`UserUUID`,R=o(d({__name:`UserDetail`,setup(o){let d=m(),R=u(),z=T(),B=d.query.UserUUID||``,V=f(!1),H=f(null),U=f(null),W=f(!1),G=f(!1),K=f([]),q=g({}),ce=s(()=>H.value?.UserName||`用户详情`),le=s(()=>z.isAdmin?`特权模式:显示该用户在所有公司、所有部门的关联记录(无公司隔离)`:`仅显示当前公司数据。如需查看所有公司记录,需管理员特权。`);function ue(e){return e===1||e===`1`?`男`:e===0||e===`0`?`女`:`-`}function J(e){return e?`是`:`否`}function Y(e){return e===1||e===`1`?{text:`启用`,type:`success`}:e===0||e===`0`?{text:`禁用`,type:`danger`}:{text:String(e??`-`),type:`warning`}}function X(e){if(!e)return`-`;let t=new Date(e);if(isNaN(t.getTime()))return String(e);let n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}let de=s(()=>K.value.filter(e=>e.editable!==!1&&!e.hideInForm&&e.type!==`hidden`&&e.type!==`divider`&&e.type!==`html`&&e.field!==L));async function Z(){if(!B){x.warning(`缺少 UserUUID 参数,无法加载用户详情`);return}V.value=!0;try{let e=await F.list(`User`,{[L]:B,pageSize:1}),t=Array.isArray(e)?e:e?.list||[],n=t.find(e=>e[L]===B)||t[0];if(!n){x.error(`未找到用户数据`);return}H.value=n,b(n.UserName||`用户详情`)}finally{V.value=!1}}async function Q(){if(B)try{U.value=await E(`/API/SiteUserManagement/GetUser2FAInfo`,{UserUUID:B})}catch{U.value=null}}async function $(){try{K.value=await F.getColumns(`User`)}catch{}}function fe(){H.value&&(Object.keys(q).forEach(e=>delete q[e]),Object.assign(q,H.value),W.value=!0)}async function pe(){G.value=!0;try{await F.update(`User`,q[L],q),x.success(`保存成功`),W.value=!1,await Z()}finally{G.value=!1}}function me(e){R.push({path:`/system/role-detail`,query:{RoleUUID:e.RoleUUID||``}})}function he(e){R.push({path:`/company/department-detail`,query:{DeptUUID:e.DeptUUID||``}})}return e(async()=>{await Promise.all([Z(),$()]),Q()}),(e,o)=>{let s=i(`Edit`),u=w,d=k,f=O,m=te,g=A,b=j,x=S,T=N,E=re,F=ne,L=C,R=ae,K=D,Z=ie,Q=M;return a(),y(se,{title:ce.value,loading:V.value},{actions:r(()=>[h(d,{type:`primary`,onClick:fe},{default:r(()=>[h(u,null,{default:r(()=>[h(s)]),_:1}),o[2]||=_(`编辑 `,-1)]),_:1})]),default:r(()=>[h(f,{type:v(z).isAdmin?`warning`:`info`,closable:!1,"show-icon":``},{default:r(()=>[_(t(le.value),1)]),_:1},8,[`type`]),h(I,{title:`基本信息`,columns:2},{default:r(()=>[h(m,{label:`用户名`},{default:r(()=>[_(t(H.value?.UserName||`-`),1)]),_:1}),h(m,{label:`邮箱`},{default:r(()=>[_(t(H.value?.UserEmail||`-`),1)]),_:1}),h(m,{label:`电话`},{default:r(()=>[_(t(H.value?.UserTele||`-`),1)]),_:1}),h(m,{label:`性别`},{default:r(()=>[_(t(ue(H.value?.UserGender)),1)]),_:1}),h(m,{label:`账号状态`},{default:r(()=>[h(g,{type:Y(H.value?.UserAccountLicense).type,size:`small`},{default:r(()=>[_(t(Y(H.value?.UserAccountLicense).text),1)]),_:1},8,[`type`])]),_:1}),h(m,{label:`是否员工`},{default:r(()=>[_(t(J(H.value?.IsStaff)),1)]),_:1}),h(m,{label:`是否超级用户`},{default:r(()=>[_(t(J(H.value?.IsSuperuser)),1)]),_:1}),h(m,{label:`创建时间`},{default:r(()=>[_(t(X(H.value?.UserCreateTime)),1)]),_:1}),h(m,{label:`最后登录`},{default:r(()=>[_(t(X(H.value?.UserLastLoginDate)),1)]),_:1})]),_:1}),h(I,{title:`双因素认证 (2FA)`,columns:2},{default:r(()=>[h(m,{label:`2FA 状态`},{default:r(()=>[U.value?(a(),y(g,{key:0,type:`success`,size:`small`},{default:r(()=>[...o[3]||=[_(`已加载`,-1)]]),_:1})):(a(),y(g,{key:1,type:`info`,size:`small`},{default:r(()=>[...o[4]||=[_(`未启用 / 未加
Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Br as e,Lr as t,Nn as n,_ as r,an as i,h as a,hn as o,ln as s,mn as c,on as l}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as u}from"./serverScope-O8Rw8SFk.js";import{r as d}from"./router-CMu0lceh.js";import{t as f}from"./AdminBadge-Z72F8Boy.js";import{t as p}from"./CrudTable-B49nrpUt.js";var m={class:`user-page`},h=r(o({__name:`Users`,setup(r){let o=d(),h=a();u(`用户管理`);let g=i(()=>o.isAdmin?`admin`:`member`),_=i(()=>{switch(g.value){case`admin`:return`管理员视图:可查看和管理全公司用户,含跨公司特权模式。`;default:return`普通组员视图:仅可查看和编辑自己的资料,无法查看他人数据。`}}),v=i(()=>`user-scope-banner ${g.value}`),y=i(()=>g.value===`member`);function b(e){h.push({path:`/system/user-detail`,query:{UserUUID:e.UserUUID||``}})}return(r,i)=>(n(),s(`div`,m,[c(f),l(`div`,{class:t(v.value)},[l(`i`,{class:t([`fas`,y.value?`fa-user`:`fa-shield-alt`])},null,2),l(`span`,null,e(_.value),1)],2),c(p,{table:`User`,title:`用户管理`,"pk-field":`UserUUID`,searchable:``,pageable:``,stretch:``,selectable:!y.value,"on-view":b},null,8,[`selectable`])]))}}),[[`__scopeId`,`data-v-ab31be72`]]);export{h as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{Nn as e,_ as t,h as n,hn as r,ln as i,mn as a}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as o}from"./serverScope-O8Rw8SFk.js";import{t as s}from"./CrudTable-B49nrpUt.js";var c={class:`workgroup-page`},l=t(r({__name:`Workgroup`,setup(t){o(`工作组管理`);let r=n();function l(e){r.push({path:`/company/workgroup-detail`,query:{WorkgroupUUID:e.WorkgroupUUID||``}})}return(t,n)=>(e(),i(`div`,c,[a(s,{table:`Workgroup`,title:`工作组管理`,"pk-field":`WorkgroupUUID`,searchable:``,pageable:``,stretch:``,selectable:``,"on-view":l})]))}}),[[`__scopeId`,`data-v-5b07f6a7`]]);export{l as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,Br as t,Fn as n,Jn as r,Ln as i,Nn as a,an as o,cn as s,en as c,h as l,hn as u,ir as d,ln as f,m as p,mn as m,nr as h,pn as g,pr as _,sn as v}from"./useApi-CROJJdhE-mMpa5RAf.js";import{a as y,o as b,u as x}from"./serverScope-O8Rw8SFk.js";import{t as S}from"./date-picker-CM_15T0u.js";import{u as C}from"./use-global-config-D-dPcPvU.js";import{n as w}from"./descriptions-Cq_aE9sg.js";import{r as T,t as E}from"./select-BGsfCDCJ.js";import{n as D,t as O}from"./form-F--u6XQJ.js";import{t as k}from"./button-CPx9BSuo.js";import{t as A}from"./card-Dj_UeWcA.js";import{t as j}from"./dialog-_5VhSQg5.js";import{t as M}from"./input-number-CiNOxXL6.js";import{t as N}from"./switch-7puThziV.js";/* empty css */import"./css-DsD2Typt.js";import"./css-CttyGzET.js";import"./css-D-a1H3t1.js";import"./css-49fsIjk3.js";import"./css-DmmbJMxg.js";import"./css-CysIl0tz.js";import"./css-w8-s2aei.js";import"./css-DMOjom7l.js";import"./css-Dmy6QwIc.js";import"./css-BLJI5-W_.js";import{n as P,t as F}from"./CrudTable-B49nrpUt.js";import"./css-ByqxgOA-.js";import{t as I}from"./form-B2Pzr8Vf.js";import{t as L}from"./DetailPage-m11wfvkM.js";import{t as R}from"./InfoGrid-C1it9Z2Y.js";import{t as z}from"./useResolveUUIDs-ipmPZLo4.js";var B=`WorkgroupUUID`,V=u({__name:`WorkgroupDetail`,setup(u){let V=p(),H=l(),{resolveUUIDs:U}=z(),W=V.query.WorkgroupUUID||``,G=d(!1),K=d(null),q=d(``),J=d(!1),Y=d(!1),X=d([]),Z=h({}),Q=o(()=>K.value?.WorkgroupName||`工作组详情`);async function $(){if(!W){b.warning(`缺少 WorkgroupUUID 参数,无法加载工作组详情`);return}G.value=!0;try{let e=await I.list(`Workgroup`,{[B]:W,pageSize:1}),t=Array.isArray(e)?e:e?.list||[],n=t.find(e=>e[B]===W)||t[0];if(!n){b.error(`未找到工作组数据`);return}K.value=n,y(n.WorkgroupName||`工作组详情`),await ee(n.CompanyUUID)}finally{G.value=!1}}async function ee(e){if(!e){q.value=``;return}try{let t=await U({company:{table:`Company`,uuids:[e]}});q.value=t.company?.[e]||e}catch{q.value=e}}async function te(){try{X.value=await I.getColumns(`Workgroup`)}catch{}}let ne=o(()=>X.value.filter(e=>e.editable!==!1&&!e.hideInForm&&e.type!==`hidden`&&e.type!==`divider`&&e.type!==`html`&&e.field!==B));function re(){K.value&&(Object.keys(Z).forEach(e=>delete Z[e]),Object.assign(Z,K.value),J.value=!0)}async function ie(){Y.value=!0;try{await I.update(`Workgroup`,Z[B],Z),b.success(`保存成功`),J.value=!1,await $()}finally{Y.value=!1}}function ae(e){H.push({path:`/system/role-detail`,query:{RoleUUID:e.RoleUUID||``}})}return e(async()=>{await Promise.all([$(),te()])}),(e,o)=>{let l=i(`Edit`),u=C,d=k,p=w,h=A,y=x,b=M,I=E,z=T,B=S,V=N,H=D,U=O,X=j;return a(),v(L,{title:Q.value,loading:G.value},{actions:r(()=>[m(d,{type:`primary`,onClick:re},{default:r(()=>[m(u,null,{default:r(()=>[m(l)]),_:1}),o[2]||=g(`编辑 `,-1)]),_:1})]),default:r(()=>[m(R,{title:`基本信息`,columns:2},{default:r(()=>[m(p,{label:`工作组名称`},{default:r(()=>[g(t(K.value?.WorkgroupName||`-`),1)]),_:1}),m(p,{label:`英文名称`},{default:r(()=>[g(t(K.value?.WorkgroupEnglishName||`-`),1)]),_:1}),m(p,{label:`所属公司`},{default:r(()=>[g(t(q.value||K.value?.CompanyUUID||`-`),1)]),_:1}),m(p,{label:`工作组介绍`},{default:r(()=>[g(t(K.value?.WorkgroupIntroduction||`-`),1)]),_:1})]),_:1}),m(h,{shadow:`never`},{header:r(()=>[...o[3]||=[g(`工作组角色`,-1)]]),default:r(()=>[_(W)?(a(),v(F,{key:0,table:`WorkgroupRole`,title:`工作组角色`,query:{WorkgroupUUID:_(W)},"pk-field":`WorkgroupRoleUUID`,selectable:``,pageable:``,"on-view":ae},null,8,[`query`])):s(``,!0)]),_:1}),m(X,{modelValue:J.value,"onUpdate:modelValue":o[1]||=e=>J.value=e,title:`编辑工作组`,width:`600px`,"destroy-on-close":``},{footer:r(()=>[m(d,{onClick:o[0]||=e=>J.value=!1},{default:r(()=>[...o[4]||=[g(`取消`,-1)]]),_:1}),m(d,{type:`primary`,loading:Y.value,onClick:ie},{default:r(()=>[...o[5]||=[g(`保存`,-1)]]),_:1},8,[`loading`])]),default:r(()=>[m(U,{model:Z,"label-width":`120px`,"label-position":`right`},{default:r(()=>[(a(!0),f(c,null,n(ne.value,e=>(a(),v(H,{key:e.field,label:e.title,required:e.required},{default:r(()=>[e.type===`entityPicker`&&e.entityPicker?(a(),v(P,{key:0,modelValue:Z[e.field],"onUpdate:modelValue":t=>Z[e.field]=t,config:e.entityPicker,"existing-label":Z[e.field+`_label`],placeholder:e.placeholder,disabled:e.disabled,"onUpdate:label":t=>Z[e.field+`_label`]=t},null,8,[`modelValue`,`onUpdate:modelValue`,`config`,`existing-label`,`placeholder`,`disabled`,`onUpdate:label`])):!e.type||e.type===`text`||e.type===`string`?(a(),v(y,{key:1,modelValue:Z[e.field],"onUpdate:modelValue":t=>Z[e.field]=t,placeholder:e.placeholder,maxlength:e.maxLength,disabled:e.disabled},null,8,[`modelValue`,`onUpdate:modelValue`,`placeholder`,`maxlength`,`disabled`])):e.type===`textarea`?(a(),v(y,{key:2,modelValue:Z[e.field],"onUpdate:modelValue":t=>Z[e.field]=t,type:`textarea`,rows:e.rows||3,disabled:e.disabled},null,8,[`modelValue`,`onUpdate:modelValue`,`rows`,`disabled`])):e.type===`number`?(a(),v(b,Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{ir as e}from"./useApi-CROJJdhE-mMpa5RAf.js";import{h as t}from"./router-CMu0lceh.js";var n=t(`app`,()=>{let t=e(!1),n=e(`light`),r=e(`zh-CN`);function i(){t.value=!t.value}function a(e){n.value=e,document.documentElement.classList.toggle(`dark`,e===`dark`),localStorage.setItem(`gerp-theme`,e)}function o(){let e=localStorage.getItem(`gerp-theme`);e&&a(e)}function s(){a(n.value===`light`?`dark`:`light`)}return{sidebarCollapsed:t,theme:n,locale:r,toggleSidebar:i,setTheme:a,initTheme:o,toggleTheme:s}});export{n as t};
|
||||
@@ -1 +0,0 @@
|
||||
import{Br as e,Cn as t,Ct as n,In as r,Jn as i,Lr as a,Nn as o,Pn as s,Wn as c,Yn as l,_t as u,an as d,cn as f,dn as p,hn as m,ir as h,ln as g,mn as _,on as v,pr as y,sn as b,tn as x,xn as S,zn as C,zr as w}from"./useApi-CROJJdhE-mMpa5RAf.js";import{c as T,t as E}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{h as D,p as O,s as k,y as A}from"./serverScope-O8Rw8SFk.js";import{C as j,R as M,d as N,u as P}from"./use-global-config-D-dPcPvU.js";import{y as F}from"./router-CMu0lceh.js";import{a as I,i as L,n as R,o as z,r as B,t as V}from"./use-dialog-BxrOdCc2.js";import{t as H}from"./refs-Cc5FwKWV.js";var U=[`aria-level`],W=[`aria-label`],G=[`id`],K=m({name:`ElDialogContent`,__name:`dialog-content`,props:z,emits:I,setup(t,{expose:n}){let{t:s}=j(),{Close:c}=N,l=t,{dialogRef:u,headerRef:p,bodyId:m,ns:h,style:x}=S(R),{focusTrapRef:T}=S(D),E=H(T,u),O=d(()=>!!l.draggable),{resetPosition:k,updatePosition:A,isDragging:M}=F(u,p,O,d(()=>!!l.overflow)),I=d(()=>[h.b(),h.is(`fullscreen`,l.fullscreen),h.is(`draggable`,O.value),h.is(`dragging`,M.value),h.is(`align-center`,!!l.alignCenter),{[h.m(`center`)]:l.center}]);return n({resetPosition:k,updatePosition:A}),(n,l)=>(o(),g(`div`,{ref:y(E),class:a(I.value),style:w(y(x)),tabindex:`-1`},[v(`header`,{ref_key:`headerRef`,ref:p,class:a([y(h).e(`header`),t.headerClass,{"show-close":t.showClose}])},[r(n.$slots,`header`,{},()=>[v(`span`,{role:`heading`,"aria-level":t.ariaLevel,class:a(y(h).e(`title`))},e(t.title),11,U)]),t.showClose?(o(),g(`button`,{key:0,"aria-label":y(s)(`el.dialog.close`),class:a(y(h).e(`headerbtn`)),type:`button`,onClick:l[0]||=e=>n.$emit(`close`)},[_(y(P),{class:a(y(h).e(`close`))},{default:i(()=>[(o(),b(C(t.closeIcon||y(c))))]),_:1},8,[`class`])],10,W)):f(`v-if`,!0)],2),v(`div`,{id:y(m),class:a([y(h).e(`body`),t.bodyClass])},[r(n.$slots,`default`)],10,G),n.$slots.footer?(o(),g(`footer`,{key:0,class:a([y(h).e(`footer`),t.footerClass])},[r(n.$slots,`footer`)],2)):f(`v-if`,!0)],6))}}),q=[`aria-label`,`aria-labelledby`,`aria-describedby`],J=u(m({name:`ElDialog`,inheritAttrs:!1,__name:`dialog`,props:L,emits:B,setup(e,{expose:u}){let m=e,g=c();M({scope:`el-dialog`,from:`the title slot`,replacement:`the header slot`,version:`3.0.0`,ref:`https://element-plus.org/en-US/component/dialog.html#slots`},d(()=>!!g.title));let S=n(`dialog`),C=h(),D=h(),j=h(),{visible:N,titleId:P,bodyId:F,style:I,overlayDialogStyle:L,rendered:z,transitionConfig:B,zIndex:H,_draggable:U,_alignCenter:W,_overflow:G,penetrable:J,handleClose:Y,onModalClick:X,onOpenAutoFocus:Z,onCloseAutoFocus:Q,onCloseRequested:ee,onFocusoutPrevented:te,bringToFront:ne,closing:re}=V(m,C);s(R,{dialogRef:C,headerRef:D,bodyId:F,ns:S,rendered:z,style:I});let $=A(X);return u({visible:N,dialogContentRef:j,resetPosition:()=>{j.value?.resetPosition()},handleClose:Y}),(n,s)=>(o(),b(x,{to:e.appendTo,disabled:e.appendTo===`body`&&!e.appendToBody},[_(E,t(y(B),{persisted:``}),{default:i(()=>[l(_(y(k),{"custom-mask-event":``,mask:e.modal,"overlay-class":[e.modalClass??``,`${y(S).namespace.value}-modal-dialog`,y(S).is(`penetrable`,y(J))],"z-index":y(H)},{default:i(()=>[v(`div`,{role:`dialog`,"aria-modal":`true`,"aria-label":e.title||void 0,"aria-labelledby":e.title?void 0:y(P),"aria-describedby":y(F),class:a([`${y(S).namespace.value}-overlay-dialog`,y(S).is(`closing`,y(re))]),style:w(y(L)),onClick:s[0]||=(...e)=>y($).onClick&&y($).onClick(...e),onMousedown:s[1]||=(...e)=>y($).onMousedown&&y($).onMousedown(...e),onMouseup:s[2]||=(...e)=>y($).onMouseup&&y($).onMouseup(...e)},[_(y(O),{loop:``,trapped:y(N),"focus-start-el":`container`,onFocusAfterTrapped:y(Z),onFocusAfterReleased:y(Q),onFocusoutPrevented:y(te),onReleaseRequested:y(ee)},{default:i(()=>[y(z)?(o(),b(K,t({key:0,ref_key:`dialogContentRef`,ref:j},n.$attrs,{center:e.center,"align-center":y(W),"close-icon":e.closeIcon,draggable:y(U),overflow:y(G),fullscreen:e.fullscreen,"header-class":e.headerClass,"body-class":e.bodyClass,"footer-class":e.footerClass,"show-close":e.showClose,title:e.title,"aria-level":e.headerAriaLevel,onClose:y(Y),onMousedown:y(ne)}),p({header:i(()=>[n.$slots.title?r(n.$slots,`title`,{key:1}):r(n.$slots,`header`,{key:0,close:y(Y),titleId:y(P),titleClass:y(S).e(`title`)})]),default:i(()=>[r(n.$slots,`default`)]),_:2},[n.$slots.footer?{name:`footer`,fn:i(()=>[r(n.$slots,`footer`)]),key:`0`}:void 0]),1040,[`center`,`align-center`,`close-icon`,`draggable`,`overflow`,`fullscreen`,`header-class`,`body-class`,`footer-class`,`show-close`,`title`,`aria-level`,`onClose`,`onMousedown`])):f(`v-if`,!0)]),_:3},8,[`trapped`,`onFocusAfterTrapped`,`onFocusAfterReleased`,`onFocusoutPrevented`,`onReleaseRequested`])],46,q)]),_:3},8,[`mask`,`overlay-class`,`z-index`]),[[T,y(N)]])]),_:3},16)],8,[`to`,`disabled`]))}}));export{J as t};
|
||||
@@ -1 +0,0 @@
|
||||
import{c as e,l as t,o as n,s as r,u as i}from"./router-CMu0lceh.js";var a={getColumns:e=>r(`/API/FormAPI/Columns/${e}`),list:(e,t)=>r(`/API/FormAPI/Get/${e}`,t),get:(e,t)=>r(`/API/FormAPI/Get/${e}`,{id:t}),create:(e,n)=>t(`/API/FormAPI/Add/${e}`,n),update:(e,t,n)=>i(`/API/FormAPI/Modify/${e}/${t}`,n),modifyItem:(e,n,r)=>t(`/API/FormAPI/ModifyItem/${e}/${n}`,r),patchItem:(t,n,r)=>e(`/API/FormAPI/ModifyItem/${t}/${n}`,r),remove:(e,t)=>n(`/API/FormAPI/Delete/${e}/${t}`),search:(e,t)=>r(`/API/FormAPI/${e}Search`,{keyword:t})};export{a as t};
|
||||
@@ -1,29 +0,0 @@
|
||||
import{$ as e,$n as t,$t as n,A as r,An as i,At as a,B as o,Br as s,Cn as c,Cr as l,Ct as u,Dn as d,Dt as f,E as p,Er as m,Et as h,F as g,Fn as _,Ft as v,Gr as y,I as b,In as x,Jn as S,Kn as C,Ln as w,Lr as T,Mn as E,Mr as D,N as O,Nn as k,Nt as A,On as j,Or as M,Ot as N,Pn as P,Pt as ee,Qn as F,Rn as I,Rr as te,S as ne,Sn as re,Sr as L,T as ie,Tn as ae,Tt as R,Un as oe,V as z,Vr as se,Wn as ce,Wr as le,Yn as ue,_ as de,_t as fe,an as B,b as pe,bt as me,cn as V,cr as he,ct as ge,dn as _e,en as ve,er as ye,fr as be,gn as xe,hn as Se,ht as Ce,ir as H,j as we,jn as Te,jt as Ee,kn as De,kr as Oe,kt as ke,ln as U,lr as Ae,lt as je,mn as W,mr as Me,nr as Ne,on as G,pn as Pe,pr as K,q as Fe,qn as Ie,rt as Le,sn as q,sr as Re,st as ze,tn as Be,ur as Ve,ut as He,v as Ue,vn as We,vr as Ge,vt as Ke,wn as J,wr as qe,wt as Je,x as Ye,xn as Xe,y as Ze,yn as Y,yt as Qe,z as $e,zn as et,zr as tt}from"./useApi-CROJJdhE-mMpa5RAf.js";import{c as nt,i as rt,l as it,n as at,r as ot,s as st,t as ct,u as lt}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{$ as ut,A as dt,B as ft,D as pt,E as mt,F as ht,G as gt,H as _t,J as vt,K as yt,L as bt,M as xt,N as St,O as Ct,P as wt,R as Tt,T as Et,V as Dt,W as Ot,X as kt,Y as At,_ as jt,at as Mt,c as Nt,ct as Pt,d as Ft,et as It,f as Lt,g as Rt,j as zt,k as Bt,l as Vt,m as Ht,o as Ut,ot as Wt,p as Gt,st as Kt,u as qt,v as Jt,w as Yt,x as Xt}from"./serverScope-O8Rw8SFk.js";import{h as Zt,i as Qt,m as $t,n as en,p as tn,r as nn,t as rn,v as an}from"./date-picker-CM_15T0u.js";import{C as on,E as sn,H as cn,Kt as ln,M as un,N as dn,Ot as fn,P as X,R as pn,S as mn,T as hn,W as gn,Y as _n,_ as vn,a as yn,at as bn,b as xn,ct as Sn,d as Cn,et as wn,g as Tn,h as En,i as Dn,it as On,j as kn,k as An,l as jn,m as Mn,n as Nn,nt as Pn,o as Fn,ot as In,p as Ln,r as Rn,s as zn,t as Bn,tt as Vn,u as Hn,ut as Un,wt as Wn,x as Gn,y as Kn,z as qn}from"./use-global-config-D-dPcPvU.js";import{n as Jn,t as Yn}from"./descriptions-Cq_aE9sg.js";import{a as Xn,c as Zn,i as Qn,l as $n,n as er,o as tr,r as nr,s as rr,t as ir}from"./select-BGsfCDCJ.js";import{t as ar}from"./omit-zqi_K1DB.js";import{t as or}from"./time-picker-DcDLR-nT.js";import{n as sr,t as cr}from"./table-DPU4-geg.js";import{t as lr}from"./castArray-CpgoCob_.js";import{_ as ur,b as dr,m as fr,t as pr}from"./router-CMu0lceh.js";import{n as mr,r as hr,t as gr}from"./form-F--u6XQJ.js";import{t as _r}from"./debounce-DcxdqJyS.js";import{t as vr}from"./numbers-cik3maFd.js";import{n as yr,r as br,t as xr}from"./image-HD4q5QFa.js";import{n as Sr}from"./strings-B6ImqFWg.js";import{a as Cr,c as wr,d as Tr,i as Er,l as Dr,m as Or,n as kr,o as Ar,r as jr,s as Mr,t as Nr}from"./click-outside-bcMsT2om.js";import{n as Pr,t as Fr}from"./skeleton-DGDficlh.js";import{a as Ir,i as Lr,t as Rr}from"./vnode-SMLE-MKY.js";import{t as zr}from"./use-ordered-children-DGQ-CQup.js";import{t as Br}from"./alert-BpFV-0dO.js";import{n as Vr,t as Hr}from"./avatar-DXM6bmhO.js";import{i as Ur,n as Wr,r as Gr,t as Kr}from"./button-CPx9BSuo.js";import{n as qr,t as Jr}from"./tag-BSnLMVgs.js";import{t as Yr}from"./card-Dj_UeWcA.js";import{n as Xr,r as Zr,t as Qr}from"./drawer-Cu-arLgK.js";import{a as $r,i as ei,n as ti,r as ni,t as ri}from"./tabs-BSMusFE5.js";import{n as ii,r as ai,t as oi}from"./checkbox-CdKclTX1.js";import{n as si,r as ci,t as li}from"./radio-Cb0vAm4I.js";import{n as ui,t as di}from"./col-BXlaMgkQ.js";import{t as fi}from"./collapse-transition-D5PfF1iI.js";import{t as pi}from"./dialog-_5VhSQg5.js";import{a as mi,c as hi,i as gi,n as _i,o as vi,r as yi,s as bi,t as xi}from"./menu-BLdj5hCm.js";import{t as Si}from"./empty-CnQTxkvl.js";import{t as Ci}from"./input-number-CiNOxXL6.js";import{t as wi}from"./pagination-DOGDdUWm.js";import{t as Ti}from"./progress-CJYzD9Cp.js";import{t as Ei}from"./result-gkzjWpF7.js";import{n as Di,t as Oi}from"./steps-C4-7Ybf-.js";import{t as ki}from"./switch-7puThziV.js";import{n as Ai,r as ji,t as Mi}from"./tree-DqeBDBpX.js";import{n as Ni,t as Pi}from"./directive-CY41a6pJ.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var Fi=Symbol(`INSTALLED_KEY`),Ii=1/0;function Li(e){return e!=null&&e.length?It(e,Ii):[]}var Ri=R({zIndex:{type:h([Number,String]),default:100},target:{type:String,default:``},offset:{type:Number,default:0},position:{type:String,values:[`top`,`bottom`],default:`top`},teleported:Boolean,appendTo:{type:h([String,Line truncated
|
||||
You should set
|
||||
width/height
|
||||
to number when your layout is
|
||||
horizontal/vertical
|
||||
`);let l=Math.max(0,t*n-c),u=Math.min(l,a*n),d=Math.max(0,(a+1)*n-c);switch(o===`smart`&&(o=s>=d-c&&s<=u+c?As:Ms),o){case js:return u;case`end`:return d;case Ms:{let e=Math.round(d+(u-d)/2);return e<Math.ceil(c/2)?0:e>l+Math.floor(c/2)?l:e}case As:default:return s>=d&&s<=u?s:s<d?d:u}},getStartIndexForOffset:({total:e,itemSize:t},n)=>Math.max(0,Math.min(e-1,Math.floor(n/t))),getStopIndexForStartIndex:({height:e,total:t,itemSize:n,layout:r,width:i},a,o)=>{let s=a*n,c=ec(r)?i:e,l=Math.ceil((c+o-s)/n);return Math.max(0,Math.min(t-1,a+l-1))},initCache(){},clearCache:!0,validateProps(){}}),pc=`ElDynamicSizeList`,mc=(e,t,n)=>{let{itemSize:r}=e,{items:i,lastVisitedIndex:a}=n;if(t>a){let e=0;if(a>=0){let t=i[a];e=t.offset+t.size}for(let n=a+1;n<=t;n++){let t=r(n);i[n]={offset:e,size:t},e+=t}n.lastVisitedIndex=t}return i[t]},hc=(e,t,n)=>{let{items:r,lastVisitedIndex:i}=t;return(i>0?r[i].offset:0)>=n?gc(e,t,0,i,n):_c(e,t,Math.max(0,i),n)},gc=(e,t,n,r,i)=>{for(;n<=r;){let a=n+Math.floor((r-n)/2),o=mc(e,a,t).offset;if(o===i)return a;o<i?n=a+1:o>i&&(r=a-1)}return Math.max(0,n-1)},_c=(e,t,n,r)=>{let{total:i}=e,a=1;for(;n<i&&mc(e,n,t).offset<r;)n+=a,a*=2;return gc(e,t,Math.floor(n/2),Math.min(n,i-1),r)},vc=({total:e},{items:t,estimatedItemSize:n,lastVisitedIndex:r})=>{let i=0;if(r>=e&&(r=e-1),r>=0){let e=t[r];i=e.offset+e.size}let a=(e-r-1)*n;return i+a},yc=dc({name:`ElDynamicSizeList`,getItemOffset:(e,t,n)=>mc(e,t,n).offset,getItemSize:(e,t,{items:n})=>n[t].size,getEstimatedTotalSize:vc,getOffset:(e,t,n,r,i)=>{let{height:a,layout:o,width:s}=e,c=ec(o)?s:a,l=mc(e,t,i),u=vc(e,i),d=Math.max(0,Math.min(u-c,l.offset)),f=Math.max(0,l.offset-c+l.size);switch(n===`smart`&&(n=r>=f-c&&r<=d+c?As:Ms),n){case js:return d;case`end`:return f;case Ms:return Math.round(f+(d-f)/2);case As:default:return r>=f&&r<=d?r:r<f?f:d}},getStartIndexForOffset:(e,t,n)=>hc(e,n,t),getStopIndexForStartIndex:(e,t,n,r)=>{let{height:i,total:a,layout:o,width:s}=e,c=ec(o)?s:i,l=mc(e,t,r),u=n+c,d=l.offset+l.size,f=t;for(;f<a-1&&d<u;)f++,d+=mc(e,f,r).size;return f},initCache({estimatedItemSize:e=50},t){let n={items:{},estimatedItemSize:e,lastVisitedIndex:-1};return n.clearCacheAfterIndex=(e,r=!0)=>{n.lastVisitedIndex=Math.min(n.lastVisitedIndex,e-1),t.exposed?.getItemStyleCache(-1),r&&t.proxy?.$forceUpdate()},n},clearCache:!1,validateProps:({itemSize:e})=>{typeof e!=`function`&&bn(pc,`
|
||||
itemSize is required as function, but the given value was ${typeof e}
|
||||
`)}}),bc=({atXEndEdge:e,atXStartEdge:t,atYEndEdge:n,atYStartEdge:r},i)=>{let a=null,o=0,s=0,c=(i,a)=>{let o=i<0&&t.value||i>0&&e.value,s=a<0&&r.value||a>0&&n.value;return o||s};return{hasReachedEdge:c,onWheel:e=>{zt(a);let t=e.deltaX,n=e.deltaY;if(Math.abs(t)>Math.abs(n)?n=0:t=0,e.shiftKey&&n!==0&&(t=n,n=0),c(t,n)){e.deltaX!==0&&t===0&&e.preventDefault();return}o+=t,s+=n,e.preventDefault(),a=xt(()=>{i(o,s),o=0,s=0})}}},xc=(e,t,n,r,i,a,o)=>{let s=H(0),c=H(0),l,u=0,d=0,f=e=>{zt(l),s.value=e.touches[0].clientX,c.value=e.touches[0].clientY,u=0,d=0},p=e=>{e.preventDefault(),zt(l),u+=s.value-e.touches[0].clientX,d+=c.value-e.touches[0].clientY,s.value=e.touches[0].clientX,c.value=e.touches[0].clientY,l=xt(()=>{let e=r.value-K(a),s=i.value-K(o);n({scrollLeft:Math.min(t.value.scrollLeft+u,e),scrollTop:Math.min(t.value.scrollTop+d,s)}),u=0,d=0})};return _t(e,`touchstart`,f,{passive:!0}),_t(e,`touchmove`,p,{passive:!1}),{touchStartX:s,touchStartY:c,handleTouchStart:f,handleTouchMove:p}},Sc=({name:e,clearCache:t,getColumnPosition:n,getColumnStartIndexForOffset:r,getColumnStopIndexForStartIndex:o,getEstimatedTotalHeight:s,getEstimatedTotalWidth:l,getColumnOffset:d,getRowOffset:f,getRowPosition:p,getRowStartIndexForOffset:m,getRowStopIndexForStartIndex:h,initCache:g,injectToInstance:_,validateProps:v})=>Se({name:e??`ElVirtualList`,props:Zs,emits:[Ts,Es],setup(e,{emit:y,expose:b,slots:x}){let S=u(`vl`);v(e);let C=xe(),w=H(g(e,C));_?.(C,w);let T=H(),E=H(),O=H(),k=H(),A=H({isScrolling:!1,scrollLeft:a(e.initScrollLeft)?e.initScrollLeft:0,scrollTop:a(e.initScrollTop)?e.initScrollTop:0,updateRequested:!1,xAxisScrollDir:Os,yAxisScrollDir:Os}),j=lc(),M=B(()=>Number.parseInt(`${e.height}`,10)),N=B(()=>Number.parseInt(`${e.width}`,10)),P=B(()=>{let{totalColumn:t,totalRow:n,columnCache:i}=e,{isScrolling:a,xAxisScrollDir:s,scrollLeft:c}=K(A);if(t===0||n===0)return[0,0,0,0];let l=r(e,c,K(w)),u=o(e,l,c,K(w)),d=!a||s===`backward`?Math.max(1,i):1,f=!a||s===`forward`?Math.max(1,i):1;return[Math.max(0,l-d),Math.max(0,Math.min(t-1,u+f)),l,u]}),ee=B(()=>{let{totalColumn:t,totalRow:n,rowCache:r}=e,{isScrolling:i,yAxisScrollDir:a,scrollTop:o}=K(A);if(t===0||n===0)return[0,0,0,0];let s=m(e,o,K(w)),c=h(e,s,o,K(w)),l=!i||a===`backward`?Math.max(1,r):1,u=!i||a===`forward`?Math.max(1,r):1;return[Math.max(0,s-l),Math.max(0,Math.min(n-1,c+u)),s,c]}),F=B(()=>s(e,K(w))),I=B(()=>l(e,K(w))),te=B(()=>[{position:`relative`,overflow:`hidden`,WebkitOverflowScrolling:`touch`,willChange:`transform`},{direction:e.direction,height:a(e.height)?`${e.height}px`:e.height,width:a(e.width)?`${e.width}px`:e.width},e.style??{}]),ne=B(()=>{let e=`${K(I)}px`;return{height:`${K(F)}px`,pointerEvents:K(A).isScrolling?`none`:void 0,width:e,margin:0,boxSizing:`border-box`}}),re=()=>{let{totalColumn:t,totalRow:n}=e;if(t>0&&n>0){let[e,t,n,r]=K(P),[i,a,o,s]=K(ee);y(Ts,{columnCacheStart:e,columnCacheEnd:t,rowCacheStart:i,rowCacheEnd:a,columnVisibleStart:n,columnVisibleEnd:r,rowVisibleStart:o,rowVisibleEnd:s})}let{scrollLeft:r,scrollTop:i,updateRequested:a,xAxisScrollDir:o,yAxisScrollDir:s}=K(A);y(Es,{xAxisScrollDir:o,scrollLeft:r,yAxisScrollDir:s,scrollTop:i,updateRequested:a})},L=t=>{let{clientHeight:n,clientWidth:r,scrollHeight:i,scrollLeft:a,scrollTop:o,scrollWidth:s}=t.currentTarget,c=K(A);if(c.scrollTop===o&&c.scrollLeft===a)return;let l=a;if(tc(e.direction))switch(rc()){case Fs:l=-a;break;case Ls:l=s-r-a;break}A.value={...c,isScrolling:!0,scrollLeft:l,scrollTop:Math.max(0,Math.min(o,i-n)),updateRequested:!0,xAxisScrollDir:$s(c.scrollLeft,l),yAxisScrollDir:$s(c.scrollTop,o)},J(()=>fe()),pe(),re()},ie=(e,t)=>{let n=K(M),r=(F.value-n)/t*e;oe({scrollTop:Math.min(F.value-n,r)})},ae=(e,t)=>{let n=K(N),r=(I.value-n)/t*e;oe({scrollLeft:Math.min(I.value-n,r)})},{onWheel:R}=bc({atXStartEdge:B(()=>A.value.scrollLeft<=0),atXEndEdge:B(()=>A.value.scrollLeft>=I.value-K(N)),atYStartEdge:B(()=>A.value.scrollTop<=0),atYEndEdge:B(()=>A.value.scrollTop>=F.value-K(M))},(e,t)=>{E.value?.onMouseUp?.(),O.value?.onMouseUp?.();let n=K(N),r=K(M);oe({scrollLeft:Math.min(A.value.scrollLeft+e,I.value-n),scrollTop:Math.min(A.value.scrollTop+t,F.value-r)})});_t(T,`wheel`,R,{passive:!1});let oe=({scrollLeft:e=A.value.scrollLeft,scrollTop:t=A.value.scrollTop})=>{e=Math.max(e,0),t=Math.max(t,0);let n=K(A);(t!==n.scrollTop||e!==n.scrollLeft)&&(A.value={...n,xAxisScrollDir:$s(n.scrollLeft,e),yAxisScrollDir:$s(n.scrollTop,t),scrollLeft:e,scrollTop:t,updateRequested:!0},J(()=>fe()),pe(),re())},{touchStartX:z,touchStartY:se,handleTouchStart:ce,handleTouchMove:le}=xc(T,A,oe,I,F,N,M),ue=(t=0,n=0,r=As)=>{let i=K(A);n=Math.max(0,Math.min(n,e.totalColumn-1)),t=Math.max(0,Math.min(t,e.totalRow-1));let a=mt(S.namespace.value),o=K(w),c=s(e,o),u=l(e,o);oe({scrollLeft:d(e,n,r,i.scrollLeft,o,u>e.width?a:0),scrollTop:f(e,t,r,i.scrollTop,o,c>e.height?a:0)})},de=(r,i)=>{let{columnWidth:a,direction:o,rowHeight:s}=e,c=j.value(t&&a,t&&s,t&&o),l=`${r},${i}`;if(Ge(c,l))return c[l];{let[,t]=n(e,i,K(w)),a=K(w),s=tc(o),[u,d
Line truncated
|
||||
"columnWidth" must be passed as number,
|
||||
instead ${typeof e} was given.
|
||||
`),a(t)||bn(Cc,`
|
||||
"columnWidth" must be passed as number,
|
||||
instead ${typeof t} was given.
|
||||
`)}}),{max:Tc,min:Ec,floor:Dc}=Math,Oc=`ElDynamicSizeGrid`,kc={column:`columnWidth`,row:`rowHeight`},Ac={column:`lastVisitedColumnIndex`,row:`lastVisitedRowIndex`},jc=(e,t,n,r)=>{let[i,a,o]=[n[r],e[kc[r]],n[Ac[r]]];if(t>o){let e=0;if(o>=0){let t=i[o];e=t.offset+t.size}for(let n=o+1;n<=t;n++){let t=a(n);i[n]={offset:e,size:t},e+=t}n[Ac[r]]=t}return i[t]},Mc=(e,t,n,r,i,a)=>{for(;n<=r;){let o=n+Dc((r-n)/2),s=jc(e,o,t,a).offset;if(s===i)return o;s<i?n=o+1:r=o-1}return Tc(0,n-1)},Nc=(e,t,n,r,i)=>{let a=i===`column`?e.totalColumn:e.totalRow,o=1;for(;n<a&&jc(e,n,t,i).offset<r;)n+=o,o*=2;return Mc(e,t,Dc(n/2),Ec(n,a-1),r,i)},Pc=(e,t,n,r)=>{let[i,a]=[t[r],t[Ac[r]]];return(a>0?i[a].offset:0)>=n?Mc(e,t,0,a,n,r):Nc(e,t,Tc(0,a),n,r)},Fc=({totalRow:e},{estimatedRowHeight:t,lastVisitedRowIndex:n,row:r})=>{let i=0;if(n>=e&&(n=e-1),n>=0){let e=r[n];i=e.offset+e.size}let a=(e-n-1)*t;return i+a},Ic=({totalColumn:e},{column:t,estimatedColumnWidth:n,lastVisitedColumnIndex:r})=>{let i=0;if(r>e&&(r=e-1),r>=0){let e=t[r];i=e.offset+e.size}let a=(e-r-1)*n;return i+a},Lc={column:Ic,row:Fc},Rc=(e,t,n,r,i,a,o)=>{let[s,c]=[a===`row`?e.height:e.width,Lc[a]],l=jc(e,t,i,a),u=Tc(0,Ec(c(e,i)-s,l.offset)),d=Tc(0,l.offset-s+o+l.size);switch(n===`smart`&&(n=r>=d-s&&r<=u+s?As:Ms),n){case js:return u;case`end`:return d;case Ms:return Math.round(d+(u-d)/2);case As:default:return r>=d&&r<=u?r:d>u||r<d?d:u}},zc=Sc({name:`ElDynamicSizeGrid`,getColumnPosition:(e,t,n)=>{let r=jc(e,t,n,`column`);return[r.size,r.offset]},getRowPosition:(e,t,n)=>{let r=jc(e,t,n,`row`);return[r.size,r.offset]},getColumnOffset:(e,t,n,r,i,a)=>Rc(e,t,n,r,i,`column`,a),getRowOffset:(e,t,n,r,i,a)=>Rc(e,t,n,r,i,`row`,a),getColumnStartIndexForOffset:(e,t,n)=>Pc(e,n,t,`column`),getColumnStopIndexForStartIndex:(e,t,n,r)=>{let i=jc(e,t,r,`column`),a=n+e.width,o=i.offset+i.size,s=t;for(;s<e.totalColumn-1&&o<a;)s++,o+=jc(e,t,r,`column`).size;return s},getEstimatedTotalHeight:Fc,getEstimatedTotalWidth:Ic,getRowStartIndexForOffset:(e,t,n)=>Pc(e,n,t,`row`),getRowStopIndexForStartIndex:(e,t,n,r)=>{let{totalRow:i,height:a}=e,o=jc(e,t,r,`row`),s=n+a,c=o.size+o.offset,l=t;for(;l<i-1&&c<s;)l++,c+=jc(e,l,r,`row`).size;return l},injectToInstance:(e,t)=>{let n=({columnIndex:n,rowIndex:r},i)=>{i=A(i)?!0:i,a(n)&&(t.value.lastVisitedColumnIndex=Math.min(t.value.lastVisitedColumnIndex,n-1)),a(r)&&(t.value.lastVisitedRowIndex=Math.min(t.value.lastVisitedRowIndex,r-1)),e.exposed?.getItemStyleCache.value(-1,null,null),i&&e.proxy?.$forceUpdate()};Object.assign(e.proxy,{resetAfterColumnIndex:(e,t)=>{n({columnIndex:e},t)},resetAfterRowIndex:(e,t)=>{n({rowIndex:e},t)},resetAfter:n})},initCache:({estimatedColumnWidth:e=50,estimatedRowHeight:t=50})=>({column:{},estimatedColumnWidth:e,estimatedRowHeight:t,lastVisitedColumnIndex:-1,lastVisitedRowIndex:-1,row:{}}),clearCache:!1,validateProps:({columnWidth:e,rowHeight:t})=>{qe(e)||bn(Oc,`
|
||||
"columnWidth" must be passed as function,
|
||||
instead ${typeof e} was given.
|
||||
`),qe(t)||bn(Oc,`
|
||||
"rowHeight" must be passed as function,
|
||||
instead ${typeof t} was given.
|
||||
`)}}),Bc=Symbol();function Vc(e){return!!(L(e)?e.every(({type:e})=>e===n):e?.type===n)}var Hc=Se({name:`NodeContent`,props:{node:{type:Object,required:!0}},setup(e){let t=u(`cascader-node`),{renderLabelFn:n}=Xe(Bc),{node:r}=e,{data:i,label:a}=r,o=()=>{let e=n?.({node:r,data:i});return Vc(e)?a:e??a};return()=>W(`span`,{class:t.e(`label`)},[o()])}}),Uc=[`id`,`aria-haspopup`,`aria-owns`,`aria-expanded`,`tabindex`],Wc=Se({name:`ElCascaderNode`,__name:`node`,props:{node:{type:Object,required:!0},menuId:{type:String,required:!1}},emits:[`expand`],setup(e,{emit:t}){let n=e,i=t,a=Xe(Bc),o=u(`cascader-node`),s=B(()=>a.isHoverMenu),c=B(()=>a.config.multiple),l=B(()=>a.config.checkStrictly),d=B(()=>a.config.showPrefix),f=B(()=>a.checkedNodes[0]?.uid),p=B(()=>n.node.isDisabled),m=B(()=>n.node.isLeaf),h=B(()=>l.value&&!m.value||!p.value),g=B(()=>v(a.expandingNode)),_=B(()=>l.value&&a.checkedNodes.some(v)),v=e=>{let{level:t,uid:r}=n.node;return e?.pathNodes[t-1]?.uid===r},y=()=>{g.value||a.expandNode(n.node)},b=e=>{let{node:t}=n;e!==t.checked&&a.handleCheckChange(t,e)},x=()=>{a.lazyLoad(n.node,()=>{m.value||y()})},C=e=>{s.value&&(w(),!m.value&&i(`expand`,e))},w=()=>{let{node:e}=n;!h.value||e.loading||(e.loaded?y():x())},E=()=>{m.value&&!p.value&&!l.value&&!c.value?O(!0):(a.config.checkOnClickNode&&(c.value||l.value)||m.value&&a.config.checkOnClickLeaf)&&!p.value?D(!n.node.checked):s.value||w()},D=e=>{l.value?(b(e),n.node.loaded&&y()):O(e)},O=e=>{n.node.loaded?(b(e),!l.value&&y()):x()};return(t,n)=>(k(),U(`li`,{id:`${e.menuId}-${e.node.uid}`,role:`menuitem`,"aria-haspopup":!m.value,"aria-owns":m.value?void 0:e.menuId,"aria-expanded":g.value,tabindex:h.value?-1:void 0,class:T([K(o).b(),K(o).is(`selectable`,l.value),K(o).is(`active`,e.node.checked),K(o).is(`disabled`,!h.value),g.value&&`in-active-path`,_.value&&`in-checked-path`]),onMouseenter:C,onFocus:C,onClick:E},[V(` prefix `),c.value&&d.value?(k(),q(K(oi),{key:0,"model-value":e.node.checked,indeterminate:e.node.indeterminate,disabled:p.value,onClick:n[0]||=lt(()=>{},[`stop`]),"onUpdate:modelValue":D},null,8,[`model-value`,`indeterminate`,`disabled`])):l.value&&d.value?(k(),q(K(li),{key:1,"model-value":f.value,label:e.node.uid,disabled:p.value,"onUpdate:modelValue":D,onClick:n[1]||=lt(()=>{},[`stop`])},{default:S(()=>[V(`
|
||||
Add an empty element to avoid render label,
|
||||
do not use empty fragment here for https://github.com/vuejs/vue-next/pull/2485
|
||||
`),n[2]||=G(`span`,null,null,-1)]),_:1},8,[`model-value`,`label`,`disabled`])):m.value&&e.node.checked?(k(),q(K(Hn),{key:2,class:T(K(o).e(`prefix`))},{default:S(()=>[W(K(r))]),_:1},8,[`class`])):V(`v-if`,!0),V(` content `),W(K(Hc),{node:e.node},null,8,[`node`]),V(` postfix `),m.value?V(`v-if`,!0):(k(),U(ve,{key:3},[e.node.loading?(k(),q(K(Hn),{key:0,class:T([K(o).is(`loading`),K(o).e(`postfix`)])},{default:S(()=>[W(K(Fe))]),_:1},8,[`class`])):(k(),q(K(Hn),{key:1,class:T([`arrow-right`,K(o).e(`postfix`)])},{default:S(()=>[W(K(pe))]),_:1},8,[`class`]))],64))],42,Uc))}}),Gc=Se({name:`ElCascaderMenu`,__name:`menu`,props:{nodes:{type:Array,required:!0},index:{type:Number,required:!0},virtualScroll:{type:Boolean,required:!1,default:!1},itemSize:{type:Number,required:!1,default:34},height:{type:Number,required:!1,default:204}},setup(e,{expose:t}){let n=e,r=xe(),i=u(`cascader-menu`),{t:a}=on(),o=Gn(),c,l,d=Xe(Bc),f=H(),p=H(),m=B(()=>!n.nodes.length),h=B(()=>!d.initialLoaded),g=B(()=>`${o.value}-${n.index}`),v=()=>{let e;if(d.expandingNode){let{level:t,pathNodes:r}=d.expandingNode;n.index<t?e=r[n.index]?.uid:n.index===t&&d.checkedNodes.length>0&&(e=d.checkedNodes[0]?.pathNodes[n.index]?.uid)}else d.checkedNodes.length>0&&n.index<d.checkedNodes[0].pathNodes.length&&(e=d.checkedNodes[0].pathNodes[n.index]?.uid);return e===void 0?-1:n.nodes.findIndex(t=>t.uid===e)},y=e=>e?n.nodes.findIndex(t=>`${g.value}-${t.uid}`===e):-1,b=e=>{let t=dr(e,0,n.nodes.length-1);p.value?.scrollToItem(t)},C=e=>{if(!n.nodes.length)return;let t=dr(e,0,n.nodes.length-1);b(t),J(()=>{let e=r.vnode.el?.querySelector(`#${g.value}-${n.nodes[t].uid}`);e&&kn(e)})},w=e=>{c=e.target},E=e=>{if(!(!d.isHoverMenu||!c||!f.value))if(c.contains(e.target)){D();let t=r.vnode.el,{left:a}=t.getBoundingClientRect(),{offsetWidth:o,offsetHeight:s}=t,l=e.clientX-a,u=c.offsetTop,d=u+c.offsetHeight,m=n.virtualScroll?p.value?.states?.scrollOffset||0:t.querySelector(`.${i.e(`wrap`)}`)?.scrollTop||0;f.value.innerHTML=`
|
||||
<path style="pointer-events: auto;" fill="transparent" d="M${l} ${u} L${o} ${m} V${u} Z" />
|
||||
<path style="pointer-events: auto;" fill="transparent" d="M${l} ${d} L${o} ${s+m} V${d} Z" />
|
||||
`}else l||=window.setTimeout(O,d.config.hoverThreshold)},D=()=>{l&&=(clearTimeout(l),void 0)},O=()=>{f.value&&(f.value.innerHTML=``,D())};return t({getActiveNodeIndex:v,getNodeIndexById:y,scrollToItem:b,focusNodeAt:C,virtualListRef:p,get $el(){return r.vnode.el}}),(t,n)=>e.virtualScroll?(k(),U(`div`,{key:g.value,class:T(K(i).b()),onMousemove:E,onMouseleave:O},[W(K(fc),{ref_key:`virtualListRef`,ref:p,height:e.height,"item-size":e.itemSize,data:e.nodes,total:e.nodes.length,"class-name":K(i).e(`list`),"inner-element":`ul`,"inner-props":{role:`menu`,class:K(i).is(`empty`,m.value)}},{default:S(({data:e,index:t,style:n})=>[(k(),q(Wc,{key:e[t].uid,node:e[t],"menu-id":g.value,style:tt(n),onExpand:w},null,8,[`node`,`menu-id`,`style`]))]),_:1},8,[`height`,`item-size`,`data`,`total`,`class-name`,`inner-props`]),h.value?(k(),U(`div`,{key:0,class:T(K(i).e(`empty-text`))},[W(K(Hn),{size:14,class:T(K(i).is(`loading`))},{default:S(()=>[W(K(Fe))]),_:1},8,[`class`]),Pe(` `+s(K(a)(`el.cascader.loading`)),1)],2)):m.value?(k(),U(`div`,{key:1,class:T(K(i).e(`empty-text`))},[x(t.$slots,`empty`,{},()=>[Pe(s(K(a)(`el.cascader.noData`)),1)])],2)):K(d)?.isHoverMenu?(k(),U(ve,{key:2},[V(` eslint-disable vue/html-self-closing `),(k(),U(`svg`,{ref_key:`hoverZone`,ref:f,class:T(K(i).e(`hover-zone`))},null,2))],2112)):V(`v-if`,!0),V(` eslint-enable vue/html-self-closing `)],34)):(k(),q(K(kr),{key:g.value,tag:`ul`,role:`menu`,class:T(K(i).b()),"wrap-class":K(i).e(`wrap`),"view-class":[K(i).e(`list`),K(i).is(`empty`,m.value)],onMousemove:E,onMouseleave:O},{default:S(()=>[(k(!0),U(ve,null,_(e.nodes,e=>(k(),q(Wc,{key:e.uid,node:e,"menu-id":g.value,onExpand:w},null,8,[`node`,`menu-id`]))),128)),h.value?(k(),U(`div`,{key:0,class:T(K(i).e(`empty-text`))},[W(K(Hn),{size:14,class:T(K(i).is(`loading`))},{default:S(()=>[W(K(Fe))]),_:1},8,[`class`]),Pe(` `+s(K(a)(`el.cascader.loading`)),1)],2)):m.value?(k(),U(`div`,{key:1,class:T(K(i).e(`empty-text`))},[x(t.$slots,`empty`,{},()=>[Pe(s(K(a)(`el.cascader.noData`)),1)])],2)):K(d)?.isHoverMenu?(k(),U(ve,{key:2},[V(` eslint-disable vue/html-self-closing `),(k(),U(`svg`,{ref_key:`hoverZone`,ref:f,class:T(K(i).e(`hover-zone`))},null,2))],2112)):V(`v-if`,!0),V(` eslint-enable vue/html-self-closing `)]),_:3},8,[`class`,`wrap-class`,`view-class`]))}}),Kc=0,qc=e=>{let t=[e],{parent:n}=e;for(;n;)t.unshift(n),n=n.parent;return t},Jc=class e{constructor(t,n,r,i=!1){this.data=t,this.config=n,this.parent=r,this.root=i,this.uid=Kc++,this.checked=!1,this.indeterminate=!1,this.loading=!1;let{value:a,label:o,children:s}=n,c=t[s],l=qc(this);this.level=i?0:r?r.level+1:1,this.value=t[a],this.label=t[o],this.pathNodes=l,this.pathValues=l.map(e=>e.value),this.pathLabels=l.map(e=>e.label),this.childrenData=c,this.children=(c||[]).map(t=>new e(t,n,this)),this.loaded=!n.lazy||this.isLeaf||!ke(c),this.text=``}get isDisabled(){let{data:e,parent:t,config:n}=this,{disabled:r,checkStrictly:i}=n;return(qe(r)?r(e,this):!!e[r])||!i&&!!t?.isDisabled}get isLeaf(){let{data:e,config:t,childrenData:n,loaded:r}=this,{lazy:i,leaf:a}=t,o=qe(a)?a(e,this):e[a];return A(o)?i&&!r?!1:!(L(n)&&n.length):!!o}get valueByOption(){return this.config.emitPath?this.pathValues:this.value}appendChild(t){let{childrenData:n,children:r}=this,i=new e(t,this.config,this);return L(n)?n.push(t):this.childrenData=[t],r.push(i),i}calcText(e,t){let n=e?this.pathLabels.join(t):this.label;return this.text=n,n}broadcast(e){this.children.forEach(t=>{t&&(t.broadcast(e),t.onParentCheck?.(e))})}emit(){let{parent:e}=this;e&&(e.onChildCheck?.(),e.emit())}onParentCheck(e){this.isDisabled||this.setCheckState(e)}onChildCheck(){let{children:e}=this,t=e.filter(e=>!e.isDisabled),n=t.length?t.every(e=>e.checked):!1;this.setCheckState(n)}setCheckState(e){let t=this.children.length,n=this.children.reduce((e,t)=>e+(t.checked?1:t.indeterminate?.5:0),0);this.checked=this.loaded&&this.children.filter(e=>!e.isDisabled).every(e=>e.loaded&&e.checked)&&e,this.indeterminate=this.loaded&&n!==t&&n>0}doCheck(e){if(this.checked===e)return;let{checkStrictly:t,multiple:n}=this.config;t||!n?this.checked=e:(this.broadcast(e),this.setCheckState(e),this.emit())}},Yc=(e,t)=>e.reduce((e,n)=>(n.isLeaf?e.push(n):(!t&&e.push(n),e=e.concat(Yc(n.children,t))),e),[]),Xc=class{constructor(e,t){this.config=t;let n=(e||[]).map(e=>new Jc(e,this.config));this.nodes=n,this.allNodes=Yc(n,!1),this.leafNodes=Yc(n,!0)}getNodes(){return this.nodes}getFlattedNodes(e){return e?this.leafNodes:this.allNodes}appendNode(e,t){let n=t?t.appendChild(e):new Jc(e,this.config);t||this.nodes.push(n),this.appendAllNodesAndLeafNodes(n)}appendNodes(e,t){e.length>0?e.forEach(e=>this.appendNode(e,t)):t&&t.isLeaf&&this.leafNodes.push(t)}appendAllNodesAndLeafNodes(e){this.allNodes.push(e),e.isLeaf&&this.leafNodes.push(e),e.children&&e.children.forEach(e=>{this.appendAllNodesAndLeafNodes(e)})}getNodeByValue(e,t=!1){return Ee(e)?null:this.getFlattedNodes(t).find(t=>Un(t.value,e)||Un(t.pathValues,e))||null}getSameNode(e){return e&&this.
Line truncated
|
||||
`||t===`\r`)){o=e;continue}if(a.includes(t)){let n=o===-1?r:o;s={pattern:i.slice(e+1,n),start:e+1,end:n,prefix:t,prefixIndex:e,splitIndex:o,selectionEnd:r};break}}return s},eg=(e,t={debug:!1,useSelectionEnd:!1})=>{let n=e.selectionStart===null?0:e.selectionStart,r=e.selectionEnd===null?0:e.selectionEnd,i=t.useSelectionEnd?r:n,a=`direction.boxSizing.width.height.overflowX.overflowY.borderTopWidth.borderRightWidth.borderBottomWidth.borderLeftWidth.borderStyle.paddingTop.paddingRight.paddingBottom.paddingLeft.fontStyle.fontVariant.fontWeight.fontStretch.fontSize.fontSizeAdjust.lineHeight.fontFamily.textAlign.textTransform.textIndent.textDecoration.letterSpacing.wordSpacing.tabSize.MozTabSize`.split(`.`);if(t.debug){let e=document.querySelector(`#input-textarea-caret-position-mirror-div`);e?.parentNode&&e.parentNode.removeChild(e)}let o=document.createElement(`div`);o.id=`input-textarea-caret-position-mirror-div`,document.body.appendChild(o);let s=o.style,c=window.getComputedStyle(e),l=e.nodeName===`INPUT`;s.whiteSpace=l?`nowrap`:`pre-wrap`,l||(s.wordWrap=`break-word`),s.position=`absolute`,t.debug||(s.visibility=`hidden`),a.forEach(e=>{if(l&&e===`lineHeight`)if(c.boxSizing===`border-box`){let e=Number.parseInt(c.height),t=Number.parseInt(c.paddingTop)+Number.parseInt(c.paddingBottom)+Number.parseInt(c.borderTopWidth)+Number.parseInt(c.borderBottomWidth),n=t+Number.parseInt(c.lineHeight);e>n?s.lineHeight=`${e-t}px`:e===n?s.lineHeight=c.lineHeight:s.lineHeight=`0`}else s.lineHeight=c.height;else s[e]=c[e]}),wt()?e.scrollHeight>Number.parseInt(c.height)&&(s.overflowY=`scroll`):s.overflow=`hidden`,o.textContent=e.value.slice(0,Math.max(0,i)),l&&o.textContent&&(o.textContent=o.textContent.replace(/\s/g,`\xA0`));let u=document.createElement(`span`);u.textContent=e.value.slice(Math.max(0,i))||`.`,u.style.position=`relative`,u.style.left=`${-e.scrollLeft}px`,u.style.top=`${-e.scrollTop}px`,o.appendChild(u);let d={top:u.offsetTop+Number.parseInt(c.borderTopWidth),left:u.offsetLeft+Number.parseInt(c.borderLeftWidth),height:Number.parseInt(c.fontSize)*1.5};return t.debug?u.style.backgroundColor=`#aaa`:document.body.removeChild(o),d.left>=e.clientWidth&&(d.left=e.clientWidth),d},tg=R({...Ft,options:{type:h(Array),default:()=>[]},prefix:{type:h([String,Array]),default:`@`,validator:e=>D(e)?e.length===1:e.every(e=>D(e)&&e.length===1)},split:{type:String,default:` `,validator:e=>e.length===1},filterOption:{type:h([Boolean,Function]),default:()=>Qh,validator:e=>e===!1||qe(e)},placement:{type:h(String),default:`bottom`},showArrow:Boolean,offset:{type:Number,default:0},whole:Boolean,checkIsWhole:{type:h(Function)},modelValue:String,loading:Boolean,popperClass:Mr.popperClass,popperStyle:Mr.popperStyle,popperOptions:{type:h(Object),default:()=>({})},props:{type:h(Object),default:()=>rg}}),ng={[Kt]:e=>D(e),"whole-remove":(e,t)=>D(e)&&D(t),input:e=>D(e),search:(e,t)=>D(e)&&D(t),select:(e,t)=>m(e)&&D(t),focus:e=>e instanceof FocusEvent,blur:e=>e instanceof FocusEvent},rg={value:`value`,label:`label`,disabled:`disabled`},ig=R({options:{type:h(Array),default:()=>[]},loading:Boolean,disabled:Boolean,contentId:String,ariaLabel:String}),ag={select:e=>D(e.value)},og=[`id`,`aria-disabled`,`aria-selected`,`onMousemove`,`onClick`],sg=Se({name:`ElMentionDropdown`,__name:`mention-dropdown`,props:ig,emits:ag,setup(e,{expose:t,emit:n}){let r=e,i=n,a=u(`mention`),{t:o}=on(),c=H(-1),l=H(),d=H(),f=H(),p=(e,t)=>[a.be(`dropdown`,`item`),a.is(`hovering`,c.value===t),a.is(`disabled`,e.disabled||r.disabled)],m=e=>{e.disabled||r.disabled||i(`select`,e)},h=e=>{c.value=e},g=B(()=>r.disabled||r.options.every(e=>e.disabled)),v=B(()=>r.options[c.value]),y=()=>{!v.value||v.value.disabled||r.disabled||i(`select`,v.value)},b=e=>{let{options:t}=r;if(t.length===0||g.value)return;e===`next`?(c.value++,c.value===t.length&&(c.value=0)):e===`prev`&&(c.value--,c.value<0&&(c.value=t.length-1));let n=t[c.value];if(n.disabled){b(e);return}J(()=>w(n))},w=e=>{let{options:t}=r,n=t.findIndex(t=>t.value===e.value),i=d.value?.[n];if(i){let e=f.value?.querySelector?.(`.${a.be(`dropdown`,`wrap`)}`);e&&dt(e,i)}l.value?.handleScroll()};return C(()=>r.options,()=>{g.value||r.options.length===0?c.value=-1:c.value=r.options.findIndex(e=>!e.disabled)},{immediate:!0}),t({hoveringIndex:c,navigateOptions:b,selectHoverOption:y,hoverOption:v}),(t,n)=>(k(),U(`div`,{ref_key:`dropdownRef`,ref:f,class:T(K(a).b(`dropdown`))},[t.$slots.header?(k(),U(`div`,{key:0,class:T(K(a).be(`dropdown`,`header`))},[x(t.$slots,`header`)],2)):V(`v-if`,!0),ue(W(K(kr),{id:e.contentId,ref_key:`scrollbarRef`,ref:l,tag:`ul`,"wrap-class":K(a).be(`dropdown`,`wrap`),"view-class":K(a).be(`dropdown`,`list`),role:`listbox`,"aria-label":e.ariaLabel,"aria-orientation":`vertical`},{default:S(()=>[(k(!0),U(ve,null,_(e.options,(n,r)=>(k(),U(`li`,{id:`${e.contentId}-${r}`,ref_for:!0,ref_key:`optionRefs`,ref:d,key:r,class:T(p(n,r)),role:`option`,"aria-disabled":n.disabled||e.disabled||void 0,"aria-selected":c.value===r,onMousemo
Line truncated
|
||||
`;function uk(e){return!!e.field||[`seq`,`checkbox`,`radio`].indexOf(e.type||``)===-1}var dk=e=>{let t=[];return e.forEach(e=>{e.childNodes&&e.childNodes.length?(t.push(e),t.push(...dk(e.childNodes))):t.push(e)}),t},fk=e=>{let t=1,n=(e,r)=>{if(r&&(e._level=r._level+1,t<e._level&&(t=e._level)),e.childNodes&&e.childNodes.length){let t=0;e.childNodes.forEach(r=>{n(r,e),t+=r._colSpan}),e._colSpan=t}else e._colSpan=1};e.forEach(e=>{e._level=1,n(e)});let r=[];for(let e=0;e<t;e++)r.push([]);return dk(e).forEach(e=>{e._rowSpan=e.childNodes&&e.childNodes.length?1:t-e._level+1,r[e._level-1].push(e)}),r};function pk(e){return e===!0?`full`:e||`default`}function mk(e){return e===`TRUE`||e===`true`||e===!0}function hk(e,t,n){let r=e.xeGrid,i=e.xeGantt,{footerFilterMethod:a}=t;return a?n.filter((t,n)=>a({$table:e,$grid:r,$gantt:i,items:t,$rowIndex:n})):n}function gk(e,t){if(t){if(e.type===`seq`)return`\t${t}`;switch(e.cellType){case`string`:if(!isNaN(t))return`\t${t}`;break;case`number`:break;default:if(t.length>=12&&!isNaN(t))return`\t${t}`}}return t}function _k(e){return/[",\s\n]/.test(e)?`"${e.replace(/"/g,`""`)}"`:Z.eqNull(e)?``:e}function vk(e,t){return e.getElementsByTagName(t)}function yk(e){return`#${e}@${Z.uniqueId()}`}function bk(e,t){return e.replace(/#\d+@\d+/g,e=>Z.hasOwnProp(t,e)?t[e]:e)}function xk(e,t){return bk(e,t).replace(/^"+$/g,e=>`"`.repeat(Math.ceil(e.length/2)))}function Sk(e,t){let{fieldMaps:n,titleMaps:r}=e;if(!n[t]){let e=r[t];e&&e.field&&(t=e.field)}return t}function Ck(e,t,n){let r=t.split(lk),i=[],a=[];if(r.length){let t={},o=Date.now();r.forEach(r=>{if(r){let s={};r=r.replace(/("")|(\n)/g,(e,n)=>{let r=yk(o);return t[r]=n?`"`:`
|
||||
`,r}).replace(/"(.*?)"/g,(e,n)=>{let r=yk(o);return t[r]=bk(n,t),r});let c=r.split(n);a.length?(c.forEach((e,n)=>{n<a.length&&(s[a[n]]=xk(e.trim(),t))}),i.push(s)):a=c.map(n=>Sk(e,xk(n.trim(),t)))}})}return{fields:a,rows:i}}function wk(e,t){return Ck(e,t,`,`)}function Tk(e,t){return Ck(e,t,` `)}function Ek(e,t){let n=vk(new DOMParser().parseFromString(t,`text/html`),`body`),r=[],i=[];if(n.length){let t=vk(n[0],`table`);if(t.length){let n=vk(t[0],`thead`);if(n.length){Z.arrayEach(vk(n[0],`tr`),t=>{Z.arrayEach(vk(t,`th`),t=>{i.push(Sk(e,t.textContent||``))})});let a=vk(t[0],`tbody`);a.length&&Z.arrayEach(vk(a[0],`tr`),e=>{let t={};Z.arrayEach(vk(e,`td`),(e,n)=>{i[n]&&(t[i[n]]=e.textContent||``)}),r.push(t)})}}}return{fields:i,rows:r}}function Dk(e,t){let n=vk(new DOMParser().parseFromString(t,`application/xml`),`Worksheet`),r=[],i=[];if(n.length){let t=vk(n[0],`Table`);if(t.length){let n=vk(t[0],`Row`);n.length&&(Z.arrayEach(vk(n[0],`Cell`),t=>{i.push(Sk(e,t.textContent||``))}),Z.arrayEach(n,(e,t)=>{if(t){let t={},n=vk(e,`Cell`);Z.arrayEach(n,(e,n)=>{i[n]&&(t[i[n]]=e.textContent)}),r.push(t)}}))}}return{fields:i,rows:r}}function Ok(e){Z.eachTree(e,e=>{delete e._level,delete e._colSpan,delete e._rowSpan,delete e._children,delete e.childNodes},{children:`children`})}var kk=[`exportData`,`importByFile`,`importData`,`saveFile`,`readFile`,`print`,`getPrintHtml`,`openImport`,`closeImport`,`openExport`,`closeExport`,`openPrint`,`closePrint`];ak.add(`tableExportModule`,{setupTable(e){let{props:t,reactData:n,internalData:r}=e,{computeTreeOpts:i,computePrintOpts:a,computeExportOpts:o,computeImportOpts:s,computeCustomOpts:c,computeSeqOpts:l,computeRadioOpts:u,computeCheckboxOpts:d,computeColumnOpts:f,computeAggregateOpts:p}=e.getComputeMaps(),m=(t,n,r,i,a)=>{let o=l.value.seqMethod||i.seqMethod;return o?o({$table:e,row:n,rowIndex:e.getRowIndex(n),_rowIndex:e.getVTRowIndex(n),$rowIndex:r,column:i,columnIndex:e.getColumnIndex(i),_columnIndex:e.getVTColumnIndex(i),$columnIndex:a}):t};function h(t,n){let r=f.value,i=n.headerExportMethod||r.headerExportMethod;return i?i({column:n,options:t,$table:e}):(t.isTitle?e.getHeaderCellLabel(n):n.field)||``}let g=e=>Z.isBoolean(e)?e?`TRUE`:`FALSE`:e,_=e=>Kw(e)?``:`${e}`,v=(a,o,s)=>{let{isTreeAllExpanded:c,isRowGroupAllExpanded:l,mode:h}=a,{treeConfig:v}=t,{isRowGroupStatus:y}=n,{fullColumnFieldData:b}=r,x=u.value,S=d.value,C=i.value,w=f.value,T=p.value;sk||=document.createElement(`div`);let{handleGetRowId:E}=TE(e);if(y){let{mode:t,showTotal:n,totalMethod:r,countFields:i,contentMethod:c,formatValuesMethod:u,mapChildrenField:d}=T,f=[],p={},v={};return Z.eachTree(s,(s,y,C,T,D,O)=>{let k=s._row||s,A=E(k);if(v[A])return;let j=D&&D._row?D._row:D,M=j?E(j):``;if(l||!j||p[M]&&e.isRowExpandByRow(j)){let s=d&&k[d]&&k[d].length,l={_row:k,_level:O.length-1,_hasChild:s,_expand:s&&e.isRowExpandByRow(k)};o.forEach((o,s)=>{let{field:f,editRender:p,cellRender:v,aggFunc:C,rowGroupNode:E}=o,D=``,O=p||v,A=o.exportMethod||w.exportMethod;if(!A&&O&&O.name){let e=ok.get(O.name);e&&(A=e.tableExportMethod||e.exportMethod)}if(A||=w.exportMethod,A)D=A({$table:e,row:k,column:o,options:a});else switch(o.type){case`seq`:{let e=T.map((e,t)=>t%2==0?Number(e)+1:`.`).join(``);D=h===`all`?e:m(e,k,y,o,s);break}case`checkbox`:D=g(e.isCheckedByCheckboxRow(k)),l._checkboxLabel=S.labelField?Z.get(k,S.labelField):``,l._checkboxDisabled=S.checkMethod&&!S.checkMethod({$table:e,row:k});break;case`radio`:D=g(e.isCheckedByRadioRow(k)),l._radioLabel=x.labelField?Z.get(k,x.labelField):``,l._radioDisabled=x.checkMethod&&!x.checkMethod({$table:e,row:k});break;default:if(f&&k.isAggregate){let a=k,s=a.aggData,l=s?s[f]:null,p=a.groupField,m=a.groupContent,h=d&&a[d]||[],g=a.childCount,_=b[p]||{},v={$table:e,groupField:p,groupColumn:_?_.column:null,column:o,groupValue:m,childList:h,childCount:g,aggValue:null,children:h,totalValue:g};if(t===`column`?f===a.groupField:E)D=m,c&&(D=`${c(v)}`),n&&(D=ik(`vxe.table.rowGroupContentTotal`,[D,r?r(v):g,g]));else if(e.getPivotTableAggregateCellAggValue){let t={$table:e,row:k,column:o};D=e.getPivotTableAggregateCellAggValue(t)}else(C===!0||i&&i.includes(f))&&(D=l?l.value:g,v.aggValue=D,u&&(D=u(v)))}else if(a.original)D=RE(k,o);else if(D=e.getCellLabel(k,o),o.type===`html`)sk.innerHTML=D,D=sk.innerText.trim();else{let t=e.getCellElement(k,o);t&&!NT(t,`is--progress`)&&(D=t.innerText.trim())}}l[o.id]=_(D)}),v[A]=!0,M&&(p[M]=!0),f.push(Object.assign(l,k))}},{children:d}),f}if(v){let t=C.children||C.childrenField,n=[],r={},i={};return Z.eachTree(s,(s,l,u,d,f,p)=>{let v=s._row||s,y=E(v);if(i[y])return;let b=f&&f._row?f._row:f,C=b?E(b):``;if(c||!b||r[C]&&e.isTreeExpandByRow(b)){let s=v[t]&&v[t].length,c={_row:v,_level:p.length-1,_hasChild:s,_expand:s&&e.isTreeExpandByRow(v)};o.forEach((t,n)=>{let r=``,i=t.editRender||t.cellRender,o=t.exportMethod||w.exportMethod;if(!o&&i&&i.name){let e=ok.get(i.name);e&&(o=e.tableExportMethod||e.exportMethod)}if(o||=w.exportMethod,o)r=o({$table:e,row:v,column:t,options:a});els
Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{At as e,Br as t,Ct as n,Et as r,Fn as i,Jn as a,Kn as o,L as s,Lr as c,Nn as l,Pn as u,R as d,Sr as f,Tt as p,X as m,_t as h,an as g,b as _,cn as v,en as y,gn as b,hn as x,ir as S,ln as C,mn as w,on as T,pr as E,sn as D,xn as O,y as k,yn as A,zn as j}from"./useApi-CROJJdhE-mMpa5RAf.js";import{l as ee}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{at as M,f as N,u as P}from"./serverScope-O8Rw8SFk.js";import{C as F,Kt as I,R as L,h as R,it as z,u as B,ut as te,v as ne,y as re}from"./use-global-config-D-dPcPvU.js";import{r as ie,t as V}from"./select-BGsfCDCJ.js";var H=Symbol(`elPaginationKey`),U=p({disabled:Boolean,currentPage:{type:Number,default:1},prevText:{type:String},prevIcon:{type:R}}),W={click:e=>e instanceof MouseEvent},G=[`disabled`,`aria-label`,`aria-disabled`],K={key:0},q=x({name:`ElPaginationPrev`,__name:`prev`,props:U,emits:W,setup(e){let n=e,{t:r}=F(),i=g(()=>n.disabled||n.currentPage<=1);return(e,n)=>(l(),C(`button`,{type:`button`,class:`btn-prev`,disabled:i.value,"aria-label":e.prevText||E(r)(`el.pagination.prev`),"aria-disabled":i.value,onClick:n[0]||=t=>e.$emit(`click`,t)},[e.prevText?(l(),C(`span`,K,t(e.prevText),1)):(l(),D(E(B),{key:1},{default:a(()=>[(l(),D(j(e.prevIcon)))]),_:1}))],8,G))}}),J=p({disabled:Boolean,currentPage:{type:Number,default:1},pageCount:{type:Number,default:50},nextText:{type:String},nextIcon:{type:R}}),Y=[`disabled`,`aria-label`,`aria-disabled`],ae={key:0},oe=x({name:`ElPaginationNext`,__name:`next`,props:J,emits:[`click`],setup(e){let n=e,{t:r}=F(),i=g(()=>n.disabled||n.currentPage===n.pageCount||n.pageCount===0);return(e,n)=>(l(),C(`button`,{type:`button`,class:`btn-next`,disabled:i.value,"aria-label":e.nextText||E(r)(`el.pagination.next`),"aria-disabled":i.value,onClick:n[0]||=t=>e.$emit(`click`,t)},[e.nextText?(l(),C(`span`,ae,t(e.nextText),1)):(l(),D(E(B),{key:1},{default:a(()=>[(l(),D(j(e.nextIcon)))]),_:1}))],8,Y))}}),X=()=>O(H,{}),se=p({pageSize:{type:Number,required:!0},pageSizes:{type:r(Array),default:()=>N([10,20,30,40,50,100])},popperClass:{type:String},popperStyle:{type:r([String,Object])},disabled:Boolean,teleported:Boolean,size:{type:String,values:I},appendSizeTo:String}),ce=x({name:`ElPaginationSizes`,__name:`sizes`,props:se,emits:[`page-size-change`],setup(e,{emit:t}){let r=e,s=t,{t:u}=F(),d=n(`pagination`),p=X(),m=S(r.pageSize);o(()=>r.pageSizes,(e,t)=>{te(e,t)||f(e)&&s(`page-size-change`,e.includes(r.pageSize)?r.pageSize:r.pageSizes[0])}),o(()=>r.pageSize,e=>{m.value=e});let h=g(()=>r.pageSizes);function _(e){e!==m.value&&(m.value=e,p.handleSizeChange?.(Number(e)))}return(e,t)=>(l(),C(`span`,{class:c(E(d).e(`sizes`))},[w(E(ie),{"model-value":m.value,disabled:e.disabled,"popper-class":e.popperClass,"popper-style":e.popperStyle,size:e.size,teleported:e.teleported,"validate-event":!1,"append-to":e.appendSizeTo,onChange:_},{default:a(()=>[(l(!0),C(y,null,i(h.value,e=>(l(),D(E(V),{key:e,value:e,label:e+E(u)(`el.pagination.pagesize`)},null,8,[`value`,`label`]))),128))]),_:1},8,[`model-value`,`disabled`,`popper-class`,`popper-style`,`size`,`teleported`,`append-to`])],2))}}),le=p({size:{type:String,values:I}}),ue=[`disabled`],de=x({name:`ElPaginationJumper`,__name:`jumper`,props:le,setup(e){let{t:r}=F(),i=n(`pagination`),{pageCount:a,disabled:o,currentPage:s,changeEvent:u}=X(),d=S(),f=g(()=>d.value??s?.value);function p(e){d.value=e?+e:``}function m(e){e=Math.trunc(+e),u?.(e),d.value=void 0}return(e,n)=>(l(),C(`span`,{class:c(E(i).e(`jump`)),disabled:E(o)},[T(`span`,{class:c([E(i).e(`goto`)])},t(E(r)(`el.pagination.goto`)),3),w(E(P),{size:e.size,class:c([E(i).e(`editor`),E(i).is(`in-pagination`)]),min:1,max:E(a),disabled:E(o),"model-value":f.value,"validate-event":!1,"aria-label":E(r)(`el.pagination.page`),type:`number`,"onUpdate:modelValue":p,onChange:m},null,8,[`size`,`class`,`max`,`disabled`,`model-value`,`aria-label`]),T(`span`,{class:c([E(i).e(`classifier`)])},t(E(r)(`el.pagination.pageClassifier`)),3)],10,ue))}}),fe=p({total:{type:Number,default:1e3}}),pe=[`disabled`],me=x({name:`ElPaginationTotal`,__name:`total`,props:fe,setup(e){let{t:r}=F(),i=n(`pagination`),{disabled:a}=X();return(e,n)=>(l(),C(`span`,{class:c(E(i).e(`total`)),disabled:E(a)},t(E(r)(`el.pagination.total`,{total:e.total})),11,pe))}}),he=p({currentPage:{type:Number,default:1},pageCount:{type:Number,required:!0},pagerCount:{type:Number,default:7},disabled:Boolean}),Z=[`aria-current`,`aria-label`,`tabindex`],ge=[`tabindex`,`aria-label`],_e=[`aria-current`,`aria-label`,`tabindex`],ve=[`tabindex`,`aria-label`],ye=[`aria-current`,`aria-label`,`tabindex`],be=x({name:`ElPaginationPager`,__name:`pager`,props:he,emits:[M],setup(e,{emit:r}){let a=e,u=r,f=n(`pager`),p=n(`icon`),{t:h}=F(),_=S(!1),b=S(!1),x=S(!1),w=S(!1),T=S(!1),O=S(!1),k=g(()=>{let e=a.pagerCount,t=(e-1)/2,n=Number(a.currentPage),r=Number(a.pageCount),i=!1,o=!1;r>e&&(n>e-t&&(i=!0),n<r-t&&(o=!0));let s=[];if(i&&!o){let t=r-(e-2);for(let e=t;e<r;e++)s.push(e)}else if(!i&&o)for(let t=2;t<e;t++)s.push(t);else if(i&&o){lLine truncated
|
||||
@@ -1,10 +0,0 @@
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Login-hDgdqSpL.js","assets/useApi-CROJJdhE-mMpa5RAf.js","assets/runtime-dom.esm-bundler-YxjRGSuG.js","assets/serverScope-O8Rw8SFk.js","assets/use-global-config-D-dPcPvU.js","assets/form-F--u6XQJ.js","assets/omit-zqi_K1DB.js","assets/castArray-CpgoCob_.js","assets/button-CPx9BSuo.js","assets/checkbox-CdKclTX1.js","assets/css-DsD2Typt.js","assets/css-ZSOkJyjJ.css","assets/css-cyJZB4WD.css","assets/favicon-CjgOoDgN.js","assets/css-49fsIjk3.js","assets/css-BrTRgFS7.css","assets/css-DMLZMbB9.js","assets/css-CzNtyWdF.css","assets/css-DmmbJMxg.js","assets/css-BtQxgKdl.css","assets/Login-Cx6fJYVq.css","assets/DefaultLayout-rzjKdYWy.js","assets/click-outside-bcMsT2om.js","assets/numbers-cik3maFd.js","assets/tag-BSnLMVgs.js","assets/menu-BLdj5hCm.js","assets/vnode-SMLE-MKY.js","assets/collapse-transition-D5PfF1iI.js","assets/refs-Cc5FwKWV.js","assets/css-CY4c3_XL.js","assets/css-C8-vPSoj.css","assets/css-yeo4Q6aC.js","assets/CompanyDetail-x1XGuNl0.css","assets/css-BEipSTAx.js","assets/css-1VV9QMa7.css","assets/css-6qaeDme6.js","assets/css-DJFxnum_.css","assets/css-CttyGzET.js","assets/app-Bqwt3qVF.js","assets/DefaultLayout-C0yp82k_.css","assets/Dashboard-tJlcukj9.js","assets/card-Dj_UeWcA.js","assets/col-BXlaMgkQ.js","assets/directive-CY41a6pJ.js","assets/css-Cy-4mdDD.js","assets/css-Dq8WDDkr.css","assets/css-D-a1H3t1.js","assets/css-BAyktVMS.css","assets/Dashboard-BikaeE2A.css","assets/Profile-B8DTMeKY.js","assets/descriptions-Cq_aE9sg.js","assets/css-CysIl0tz.js","assets/css-BpDzfuC8.css","assets/Profile-DcQ1jZX0.css","assets/Admin-BH3hT3BL.js","assets/CrudTable-B49nrpUt.js","assets/date-picker-CM_15T0u.js","assets/debounce-DcxdqJyS.js","assets/repeat-click-BatRPHhN.js","assets/select-BGsfCDCJ.js","assets/strings-B6ImqFWg.js","assets/time-picker-DcDLR-nT.js","assets/isArrayLikeObject-Bo9Xnvp4.js","assets/radio-Cb0vAm4I.js","assets/dialog-_5VhSQg5.js","assets/use-dialog-BxrOdCc2.js","assets/input-number-CiNOxXL6.js","assets/pagination-DOGDdUWm.js","assets/switch-7puThziV.js","assets/css-w8-s2aei.js","assets/css-DExoAqKP.css","assets/css-DMOjom7l.js","assets/css-CM8IHeeM.js","assets/css-Wv38huFO.css","assets/css-DUbGnqO_.css","assets/css-Dmy6QwIc.js","assets/css-OVWuLPuT.css","assets/css-fhPIiYtD.js","assets/css-B7gvwdWB.css","assets/css-BLJI5-W_.js","assets/css-4sOBTGxz.css","assets/css-ByqxgOA-.js","assets/css-BNmWJdpO.css","assets/css-0wcCNliC.js","assets/css-hrelhGmJ.css","assets/form-B2Pzr8Vf.js","assets/CrudTable-DK-IJ6GQ.css","assets/Admin-DtD2u962.css","assets/My-DPrAT3Sr.js","assets/My-C5ItiXKZ.css","assets/Roles-CJaooumV.js","assets/Roles-t0HUgyXh.css","assets/Users-DnduOYy3.js","assets/AdminBadge-Z72F8Boy.js","assets/alert-BpFV-0dO.js","assets/AdminBadge-B-j0OYky.css","assets/Users-GCn5iXoj.css","assets/Products-Dgz6Q-xi.js","assets/Products-D5dCYkWb.css","assets/Orders-bra8jrHL.js","assets/Orders-DLa-h2zy.css","assets/Tenant-CRSIX85t.js","assets/Tenant-kI3MayTq.css","assets/Company-CxKo2eoH.js","assets/Company-IcHivBEf.css","assets/Department-BtlmnFbj.js","assets/Department-CyxqJtRs.css","assets/Workgroup-0dl3kaJX.js","assets/Workgroup-B1nl_vZW.css","assets/Role-CUf-lqkA.js","assets/Role-DKC_Ub_F.css","assets/UserDetail-DSBYMFBg.js","assets/DetailPage-m11wfvkM.js","assets/DetailPage-B9od5Isl.css","assets/InfoGrid-C1it9Z2Y.js","assets/InfoGrid-BY8rlZVK.css","assets/RoleDetail-CoZwf-El.js","assets/RoleDetail-DcAMxYp2.css","assets/RolePermissions-Ui2y81ee.js","assets/empty-CnQTxkvl.js","assets/tree-DqeBDBpX.js","assets/css-D4jab2ni2.js","assets/css-S7fQQ3B8.css","assets/css-CLuE7SsA.js","assets/css-BsdIe0y8.css","assets/RolePermissions-BGKEsQJJ.css","assets/TenantDetail-CHvvHAc4.js","assets/WorkgroupDetail-AJMWwNyx.js","assets/useResolveUUIDs-ipmPZLo4.js","assets/DepartmentDetail-TMUHEraO.js","assets/CompanyDetail-COaiszTK.js","assets/RoleDetail-C4PpwcmI.js","assets/RoleDetail-DmzzuZyT.css","assets/EmployeeDetail-Ck3_5FKo.js","assets/avatar-DXM6bmhO.js","assets/EmployeeDetail-DHUl-5tf.css","assets/Message-DDcpqM0D.js","assets/tabs-BSMusFE5.js","assets/use-ordered-children-DGQ-CQup.js","assets/css-DcINL9JV2.js","assets/css-Bn4f7rcU.css","assets/Message-DiUOBJkw.css","assets/TenantCreate-CsrbEqrJ.js","assets/TenantCreate-CUTZXCIg.css","assets/TenantReview-DQeJSqcy.js","assets/TenantReview-BK6D8djG.css","assets/PaymentConfig-BUuaxSoB.js","assets/PaymentConfig-5gOYoXK2.css","assets/EpCreate-Dd8uzb-x.js","assets/steps-C4-7Ybf-.js","assets/EpCreate-Bj7u6-ON.css","assets/Editor-5D3bQtSW.js","assets/Editor-D5L3phiY.css","assets/Manager-YB4nxbIc.js","assets/image-HD4q5QFa.js","assets/progress-CJYzD9Cp.js","assets/css-B0rEpZpL.js","assets/css-BG2Se6n6.css","assets/Manager-CMKLLDzm.css","assets/AuditLog-DSDRHrcO.js","assets/table-DPU4-geg.js","assets/AuditLog-DYDPbXyx.css","assets/Settings-az6weoSF.js","assets/Settings-BGHKexCS.css","assets/Menu-CmxVaJIX.js","assets/Menu-BU41WRra.css","assets/Database-BhusFIP8.js","assets/Database-CncfR2Ei.css","assets/DLine truncated
|
||||
import{$n as e,An as t,Br as n,Dn as r,Er as i,In as a,Jn as o,Kn as s,Ln as c,Lr as l,Mr as u,Nn as d,Nt as f,Ot as p,Pn as m,Qn as h,Sn as g,Tn as _,Wr as v,Xn as y,Yn as b,Zn as x,a as S,an as C,ar as w,bn as T,c as E,cn as D,cr as ee,d as te,er as O,f as k,g as A,hn as j,i as M,ir as N,jn as ne,kn as re,l as P,ln as ie,mn as F,n as I,nr as ae,o as L,on as R,p as oe,pn as se,pr as ce,q as le,qn as ue,r as de,s as fe,sn as z,sr as pe,t as me,tr as he,u as ge,ur as _e,vr as ve,wn as B,wr as ye,xn as be,yn as xe,zn as Se,zr as Ce}from"./useApi-CROJJdhE-mMpa5RAf.js";import{c as we,i as Te,l as Ee,t as De,u as Oe}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{ct as ke,it as Ae,m as je,n as Me,o as Ne,p as Pe,s as Fe,u as Ie,w as Le,x as Re,y as ze}from"./serverScope-O8Rw8SFk.js";import{H as Be,I as Ve,Kt as He,T as Ue,f as We,it as Ge,n as Ke,p as qe,u as Je,x as Ye}from"./use-global-config-D-dPcPvU.js";import{t as Xe}from"./button-CPx9BSuo.js";function Ze(e,t,n){return e===e&&(n!==void 0&&(e=e<=n?e:n),t!==void 0&&(e=e>=t?e:t)),e}function Qe(e,t,n){return n===void 0&&(n=t,t=void 0),n!==void 0&&(n=Ae(n),n=n===n?n:0),t!==void 0&&(t=Ae(t),t=t===t?t:0),Ze(Ae(e),t,n)}var $e=(e,n,i,a)=>{let o={offsetX:0,offsetY:0},s=N(!1),c=(t,n)=>{if(e.value){let{offsetX:r,offsetY:i}=o,s=e.value.getBoundingClientRect(),c=Math.max(s.left,0),l=Math.max(s.top,0),u=s.width,d=s.height,f=document.documentElement.clientWidth,p=document.documentElement.clientHeight,m=-c+r,h=-l+i,g=f-c-u+r,_=p-l-(d<p?d:0)+i;a?.value||(t=Qe(t,m,g),n=Qe(n,h,_)),o.offsetX=t,o.offsetY=n,e.value.style.transform=`translate(${Ue(t)}, ${Ue(n)})`}},l=e=>{let t=e.clientX,n=e.clientY,{offsetX:r,offsetY:i}=o,a=e=>{s.value||=!0,c(r+e.clientX-t,i+e.clientY-n)},l=()=>{s.value=!1,document.removeEventListener(`mousemove`,a),document.removeEventListener(`mouseup`,l)};document.addEventListener(`mousemove`,a),document.addEventListener(`mouseup`,l)},u=()=>{n.value&&e.value&&(n.value.addEventListener(`mousedown`,l),window.addEventListener(`resize`,p))},d=()=>{n.value&&e.value&&(n.value.removeEventListener(`mousedown`,l),window.removeEventListener(`resize`,p))},f=()=>{o.offsetX=0,o.offsetY=0,e.value&&(e.value.style.transform=``)},p=()=>{let{offsetX:e,offsetY:t}=o;c(e,t)};return t(()=>{ue(()=>{i.value?u():d()})}),r(()=>{d()}),{isDragging:s,resetPosition:f,updatePosition:p}},et=`_trap-focus-children`,tt=[],nt=e=>{if(tt.length===0)return;let t=Re(e),n=tt[tt.length-1][et];if(n.length>0&&t===ke.tab){if(n.length===1){e.preventDefault(),document.activeElement!==n[0]&&n[0].focus();return}let t=e.shiftKey,r=e.target===n[0],i=e.target===n[n.length-1];r&&t&&(e.preventDefault(),n[n.length-1].focus()),i&&!t&&(e.preventDefault(),n[0].focus())}},rt={beforeMount(e){e[et]=Ve(e),tt.push(e),tt.length<=1&&document.addEventListener(`keydown`,nt)},updated(e){B(()=>{e[et]=Ve(e)})},unmounted(){tt.shift(),tt.length===0&&document.removeEventListener(`keydown`,nt)}},it=e=>[``,...He].includes(e),at=j({name:`ElMessageBox`,directives:{TrapFocus:rt},components:{ElButton:Xe,ElFocusTrap:Pe,ElInput:Ie,ElOverlay:Fe,ElIcon:Je,...We},inheritAttrs:!1,props:{buttonSize:{type:String,validator:it},modal:{type:Boolean,default:!0},lockScroll:{type:Boolean,default:!0},showClose:{type:Boolean,default:!0},closeOnClickModal:{type:Boolean,default:!0},closeOnPressEscape:{type:Boolean,default:!0},closeOnHashChange:{type:Boolean,default:!0},center:Boolean,draggable:Boolean,overflow:Boolean,roundButton:Boolean,container:{type:String,default:`body`},boxType:{type:String,default:``}},emits:[`vanish`,`action`],setup(e,{emit:n}){let{locale:i,zIndex:a,ns:o,size:c}=Ke(`message-box`,C(()=>e.buttonSize)),{t:l}=i,{nextZIndex:d}=a,f=N(!1),p=ae({autofocus:!0,beforeClose:null,callback:null,cancelButtonText:``,cancelButtonClass:``,confirmButtonText:``,confirmButtonClass:``,cancelButtonType:``,confirmButtonType:`primary`,customClass:``,customStyle:{},dangerouslyUseHTMLString:!1,distinguishCancelAndClose:!1,icon:``,closeIcon:``,inputPattern:null,inputPlaceholder:``,inputType:`text`,inputValue:``,inputValidator:void 0,inputErrorMessage:``,message:``,modalFade:!0,modalClass:``,showCancelButton:!1,showConfirmButton:!0,type:``,title:void 0,showInput:!1,action:``,confirmButtonLoading:!1,cancelButtonLoading:!1,confirmButtonLoadingIcon:O(le),cancelButtonLoadingIcon:O(le),confirmButtonDisabled:!1,editorErrorMessage:``,validateError:!1,zIndex:d()}),m=C(()=>{let e=p.type;return{[o.bm(`icon`,e)]:e&&qe[e]}}),h=Ye(),g=Ye(),_=C(()=>{let e=p.type;return p.icon||e&&qe[e]||``}),v=C(()=>!!p.message),y=N(),b=N(),x=N(),S=N(),w=N(),T=C(()=>p.confirmButtonClass);s(()=>p.inputValue,async t=>{await B(),e.boxType===`prompt`&&t&&j()},{immediate:!0}),s(()=>f.value,t=>{t&&(e.boxType!==`prompt`&&(p.autofocus?x.value=w.value?.$el??y.value:x.value=y.value),p.zIndex=d()),e.boxType===`prompt`&&(t?B().then(()=>{S.value&&S.value.$el&&(p.autofocus?x.value=M()??y.value:x.value=y.value)}):(p.editorErrorMessage=``,p.validateError=!1))});let{isDragging:E}=$e(y,b,C(()=>e.draggablLine truncated
|
||||
`).forEach(function(e){i=e.indexOf(`:`),n=e.substring(0,i).trim().toLowerCase(),r=e.substring(i+1).trim();let a=q.hasOwnProp(t,n);!n||a&&q.hasOwnProp(ra,n)||(n===`set-cookie`?a?t[n].push(r):t[n]=[r]:t[n]=a?t[n]+`, `+r:r)}),t};function aa(e){let t=0,n=e.length;for(;t<n;){let n=e.charCodeAt(t);if(n!==9&&n!==32)break;t+=1}for(;n>t;){let t=e.charCodeAt(n-1);if(t!==9&&t!==32)break;--n}return t===0&&n===e.length?e:e.slice(t,n)}var oa=RegExp(`[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+`,`g`),sa=RegExp(`[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+`,`g`);function ca(e,t){return q.isArray(e)?e.map(e=>ca(e,t)):aa(String(e).replace(t,``))}var la=e=>ca(e,oa),ua=e=>ca(e,sa);function da(e){let t=Object.create(null);return q.forEach(e.toJSON(),(e,n)=>{t[n]=ua(e)}),t}var fa=Symbol(`internals`);function pa(e){return e&&String(e).trim().toLowerCase()}function ma(e){return e===!1||e==null?e:q.isArray(e)?e.map(ma):la(String(e))}function ha(e){let t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g,r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}var ga=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;function _a(e){let t=0,n=e.length;for(;t<n;){let n=e.charCodeAt(t);if(n!==9&&n!==32)break;t+=1}for(;n>t;){let t=e.charCodeAt(n-1);if(t!==9&&t!==32)break;--n}return t===0&&n===e.length?e:e.slice(t,n)}function va(e){let t=e.length-1;if(t<1||e.charCodeAt(0)!==34||e.charCodeAt(t)!==34)return e;let n=``;for(let r=1;r<t;r++){let i=e.charCodeAt(r);if(i===34||i===92&&(r+=1,r>=t))return e;n+=e[r]}return n}function ya(e){let t=Object.create(null),n=String(e),r=0,i=!1,a=!1;function o(e){let i=_a(n.slice(r,e)),a=i.indexOf(`=`);if(a<1)return;let o=_a(i.slice(0,a));if(!ga.test(o))return;let s=o.toLowerCase();if(s===`__proto__`||s===`constructor`||s===`prototype`)return;let c=_a(i.slice(a+1));t[s]=va(c)}for(let e=0;e<n.length;e++){let t=n.charCodeAt(e);i?a?a=!1:t===92?a=!0:t===34&&(i=!1):t===34?i=!0:(t===44||t===59)&&(o(e),r=e+1)}return o(n.length),t}var ba=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function xa(e,t,n,r,i){if(q.isFunction(r))return r.call(this,t,n);if(i&&(t=n),q.isString(t)){if(q.isString(r))return t.indexOf(r)!==-1;if(q.isRegExp(r))return r.test(t)}}function Sa(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,t,n)=>t.toUpperCase()+n)}function Ca(e,t){let n=q.toCamelCase(` `+t);[`get`,`set`,`has`].forEach(r=>{Object.defineProperty(e,r+n,{__proto__:null,value:function(e,n,i){return this[r].call(this,t,e,n,i)},configurable:!0})})}var J=class{constructor(e){e&&this.set(e)}set(e,t,n){let r=this;function i(e,t,n){let i=pa(t);if(!i)return;let a=q.findKey(r,i);(!a||r[a]===void 0||n===!0||n===void 0&&r[a]!==!1)&&(r[a||t]=ma(e))}let a=(e,t)=>q.forEach(e,(e,n)=>i(e,n,t));if(q.isPlainObject(e)||e instanceof this.constructor)a(e,t);else if(q.isString(e)&&(e=e.trim())&&!ba(e))a(ia(e),t);else if(q.isObject(e)&&q.isSafeIterable(e)){let n=Object.create(null),r,i;for(let t of e){if(!q.isArray(t))throw TypeError(`Object iterator must return a key-value pair`);i=t[0],q.hasOwnProp(n,i)?(r=n[i],n[i]=q.isArray(r)?[...r,t[1]]:[r,t[1]]):n[i]=t[1]}a(n,t)}else e!=null&&i(t,e,n);return this}get(e,t){if(e=pa(e),e){let n=q.findKey(this,e);if(n){let e=this[n];if(!t)return e;if(t===!0)return ha(e);if(q.isFunction(t))return t.call(this,e,n);if(q.isRegExp(t))return t.exec(e);throw TypeError(`parser must be boolean|regexp|function`)}}}has(e,t){if(e=pa(e),e){let n=q.findKey(this,e);return!!(n&&this[n]!==void 0&&(!t||xa(this,this[n],n,t)))}return!1}delete(e,t){let n=this,r=!1;function i(e){if(e=pa(e),e){let i=q.findKey(n,e);i&&(!t||xa(n,n[i],i,t))&&(delete n[i],r=!0)}}return q.isArray(e)?e.forEach(i):i(e),r}clear(e){let t=Object.keys(this),n=t.length,r=!1;for(;n--;){let i=t[n];(!e||xa(this,this[i],i,e,!0))&&(delete this[i],r=!0)}return r}normalize(e){let t=this,n={};return q.forEach(this,(r,i)=>{let a=q.findKey(n,i);if(a){t[a]=ma(r),delete t[i];return}let o=e?Sa(i):String(i).trim();o!==i&&delete t[i],t[o]=ma(r),n[o]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){let t=Object.create(null);return q.forEach(this,(n,r)=>{n!=null&&n!==!1&&(t[r]=e&&q.isArray(n)?n.join(`, `):n)}),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,t])=>e+`: `+t).join(`
|
||||
`)}getSetCookie(){let e=this.get(`set-cookie`);return q.isArray(e)?e:e==null||e===!1?[]:[e]}get[Symbol.toStringTag](){return`AxiosHeaders`}static from(e){return e instanceof this?e:new this(e)}static parseParameters(e){return ya(e)}static concat(e,...t){let n=new this(e);return t.forEach(e=>n.set(e)),n}static accessor(e){let t=(this[fa]=this[fa]={accessors:{}}).accessors,n=this.prototype;function r(e){let r=pa(e);t[r]||(Ca(n,e),t[r]=!0)}return q.isArray(e)?e.forEach(r):r(e),this}};J.accessor([`Content-Type`,`Content-Length`,`Accept`,`Accept-Encoding`,`User-Agent`,`Authorization`]),q.reduceDescriptors(J.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}}),q.freezeMethods(J);var wa=`[REDACTED ****]`;function Ta(e){if(q.hasOwnProp(e,`toJSON`))return!0;let t=Object.getPrototypeOf(e);for(;t&&t!==Object.prototype;){if(q.hasOwnProp(t,`toJSON`))return!0;t=Object.getPrototypeOf(t)}return!1}function Ea(e,t){let n=new Set(t.map(e=>String(e).toLowerCase())),r=[],i=e=>{if(typeof e!=`object`||!e||q.isBuffer(e))return e;if(r.indexOf(e)!==-1)return;e instanceof J&&(e=e.toJSON()),r.push(e);let t;if(q.isArray(e))t=[],e.forEach((e,n)=>{let r=i(e);q.isUndefined(r)||(t[n]=r)});else{if(!q.isPlainObject(e)&&Ta(e))return r.pop(),e;t=Object.create(null);for(let[r,a]of Object.entries(e)){let e=n.has(r.toLowerCase())?wa:i(a);q.isUndefined(e)||(t[r]=e)}}return r.pop(),t};return i(e)}function Da(e){try{return String(e)}catch{return``}}function Oa(e){return e.errors.map(e=>{try{return e&&e.message?Da(e.message):Da(e)}catch{return``}}).filter(Boolean).join(`; `)||e.name||`AggregateError`}var Y=class e extends Error{static from(t,n,r,i,a,o){let s=t.message;!s&&q.isArray(t.errors)&&t.errors.length&&(s=Oa(t));let c=new e(s,n||t.code,r,i,a);return Object.defineProperty(c,"cause",{__proto__:null,value:t,writable:!0,enumerable:!1,configurable:!0}),c.name=t.name,t.status!=null&&c.status==null&&(c.status=t.status),o&&Object.assign(c,o),c}constructor(e,t,n,r,i){super(e),Object.defineProperty(this,"message",{__proto__:null,value:e,enumerable:!0,writable:!0,configurable:!0}),this.name=`AxiosError`,this.isAxiosError=!0,t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),i&&(this.response=i,this.status=i.status)}toJSON(){let e=this.config,t=e&&q.hasOwnProp(e,`redact`)?e.redact:void 0,n=q.isArray(t)&&t.length>0?Ea(e,t):q.toJSONObject(e);return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:n,code:this.code,status:this.status}}};Y.ERR_BAD_OPTION_VALUE=`ERR_BAD_OPTION_VALUE`,Y.ERR_BAD_OPTION=`ERR_BAD_OPTION`,Y.ECONNABORTED=`ECONNABORTED`,Y.ETIMEDOUT=`ETIMEDOUT`,Y.ECONNREFUSED=`ECONNREFUSED`,Y.ERR_NETWORK=`ERR_NETWORK`,Y.ERR_FR_TOO_MANY_REDIRECTS=`ERR_FR_TOO_MANY_REDIRECTS`,Y.ERR_DEPRECATED=`ERR_DEPRECATED`,Y.ERR_BAD_RESPONSE=`ERR_BAD_RESPONSE`,Y.ERR_BAD_REQUEST=`ERR_BAD_REQUEST`,Y.ERR_CANCELED=`ERR_CANCELED`,Y.ERR_NOT_SUPPORT=`ERR_NOT_SUPPORT`,Y.ERR_INVALID_URL=`ERR_INVALID_URL`,Y.ERR_FORM_DATA_DEPTH_EXCEEDED=`ERR_FORM_DATA_DEPTH_EXCEEDED`;function ka(e){return q.isPlainObject(e)||q.isArray(e)}function Aa(e){return q.endsWith(e,`[]`)?e.slice(0,-2):e}function ja(e,t,n){return e?e.concat(t).map(function(e,t){return e=Aa(e),!n&&t?`[`+e+`]`:e}).join(n?`.`:``):t}function Ma(e){return q.isArray(e)&&!e.some(ka)}var Na=q.toFlatObject(q,{},null,function(e){return/^is[A-Z]/.test(e)});function Pa(e,t,n){if(!q.isObject(e))throw TypeError(`target must be an object`);t||=new FormData,n=q.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(e,t){return!q.isUndefined(t[e])});let r=n.metaTokens,i=n.visitor||m,a=n.dots,o=n.indexes,s=n.Blob||typeof Blob<`u`&&Blob,c=n.maxDepth===void 0?100:n.maxDepth,l=s&&q.isSpecCompliantForm(t),u=[];if(!q.isFunction(i))throw TypeError(`visitor must be a function`);function d(e){if(e===null)return``;if(q.isDate(e))return e.toISOString();if(q.isBoolean(e))return e.toString();if(!l&&q.isBlob(e))throw new Y(`Blob is not supported. Use a Buffer instead.`);if(q.isArrayBuffer(e)||q.isTypedArray(e)){if(l&&typeof s==`function`)return new s([e]);throw new Y(`Blob is not supported. Use a Buffer instead.`,Y.ERR_NOT_SUPPORT)}return e}function f(e){if(e>c)throw new Y(`Object is too deeply nested (`+e+` levels). Max depth: `+c,Y.ERR_FORM_DATA_DEPTH_EXCEEDED)}function p(e,t){if(c===1/0)return JSON.stringify(e);let n=[];return JSON.stringify(e,function(e,r){if(!q.isObject(r))return r;for(;n.length&&n[n.length-1]!==this;)n.pop();return n.push(r),f(t+n.length-1),r})}function m(e,n,i){let s=e;if(q.isReactNative(t)&&q.isReactNativeBlob(e))return t.append(ja(i,n,a),d(e)),!1;if(e&&!i&&typeof e==`object`){if(q.endsWith(n,`{}`))n=r?n:n.slice(0,-2),e=p(e,1);else if(q.isArray(e)&&Ma(e)||(q.isFileList(e)||q.endsWith(n,`[]`))&&(s=q.toArray(e)))return n=Aa(n),s.forEach(function(e,r){!(q.isUndefined(e)||e===null)&&t.append(o===!0?ja([n],r,a):o===null?n:n+`[]`,d(e))}),!
Line truncated
|
||||
`+e.map(ss).join(`
|
||||
`):` `+ss(e[0]):`as no adapter specified`),Y.ERR_NOT_SUPPORT)}return i}var us={getAdapter:ls,adapters:os};function ds(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new oo(null,e)}function fs(e){return ds(e),e.headers=J.from(e.headers),e.data=io.call(e,e.transformRequest),[`post`,`put`,`patch`].indexOf(e.method)!==-1&&e.headers.setContentType(`application/x-www-form-urlencoded`,!1),us.getAdapter(e.adapter||ro.adapter,e)(e).then(function(t){ds(e),e.response=t;try{t.data=io.call(e,e.transformResponse,t)}finally{delete e.response}return t.headers=J.from(t.headers),t},function(t){if(!ao(t)&&(ds(e),t&&t.response)){e.response=t.response;try{t.response.data=io.call(e,e.transformResponse,t.response)}finally{delete e.response}t.response.headers=J.from(t.response.headers)}return Promise.reject(t)})}var ps={};[`object`,`boolean`,`number`,`function`,`string`,`symbol`].forEach((e,t)=>{ps[e]=function(n){return typeof n===e||`a`+(t<1?`n `:` `)+e}});var ms={};ps.transitional=function(e,t,n){function r(e,t){return`[Axios v`+Xo+`] Transitional option '`+e+`'`+t+(n?`. `+n:``)}return(n,i,a)=>{if(e===!1)throw new Y(r(i,` has been removed`+(t?` in `+t:``)),Y.ERR_DEPRECATED);return t&&!ms[i]&&(ms[i]=!0,console.warn(r(i,` has been deprecated since v`+t+` and will be removed in the near future`))),!e||e(n,i,a)}},ps.spelling=function(e){return(t,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};function hs(e,t,n){if(typeof e!=`object`||!e)throw new Y(`options must be an object`,Y.ERR_BAD_OPTION_VALUE);let r=Object.keys(e),i=r.length;for(;i-->0;){let a=r[i],o=Object.prototype.hasOwnProperty.call(t,a)?t[a]:void 0;if(o){let t=e[a],n=t===void 0||o(t,a,e);if(n!==!0)throw new Y(`option `+a+` must be `+n,Y.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new Y(`Unknown option `+a,Y.ERR_BAD_OPTION)}}var gs={assertOptions:hs,validators:ps},Z=gs.validators,_s=class{constructor(e){this.defaults=e||{},this.interceptors={request:new Ba,response:new Ba}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t={};Error.captureStackTrace?Error.captureStackTrace(t):t=Error();let n=(()=>{if(!t.stack)return``;let e=t.stack.indexOf(`
|
||||
`);return e===-1?``:t.stack.slice(e+1)})();try{if(!e.stack)e.stack=n;else if(n){let t=n.indexOf(`
|
||||
`),r=t===-1?-1:n.indexOf(`
|
||||
`,t+1),i=r===-1?``:n.slice(r+1);String(e.stack).endsWith(i)||(e.stack+=`
|
||||
`+n)}}catch{}}throw e}}_request(e,t){typeof e==`string`?(t||={},t.url=e):t=e||{},t=ko(this.defaults,t);let{transitional:n,paramsSerializer:r,headers:i}=t;n!==void 0&&gs.assertOptions(n,{silentJSONParsing:Z.transitional(Z.boolean),forcedJSONParsing:Z.transitional(Z.boolean),clarifyTimeoutError:Z.transitional(Z.boolean),legacyInterceptorReqResOrdering:Z.transitional(Z.boolean),advertiseZstdAcceptEncoding:Z.transitional(Z.boolean),validateStatusUndefinedResolves:Z.transitional(Z.boolean)},!1),r!=null&&(q.isFunction(r)?t.paramsSerializer={serialize:r}:gs.assertOptions(r,{encode:Z.function,serialize:Z.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls===void 0?t.allowAbsoluteUrls=!0:t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls),gs.assertOptions(t,{baseUrl:Z.spelling(`baseURL`),withXsrfToken:Z.spelling(`withXSRFToken`)},!0),t.method=(t.method||this.defaults.method||`get`).toLowerCase();let a=i&&q.merge(i.common,i[t.method]);i&&q.forEach([`delete`,`get`,`head`,`post`,`put`,`patch`,`query`,`common`],e=>{delete i[e]}),t.headers=J.concat(a,i);let o=[],s=!0;this.interceptors.request.forEach(function(e){if(typeof e.runWhen==`function`&&e.runWhen(t)===!1)return;s&&=e.synchronous;let n=t.transitional||Va;n&&n.legacyInterceptorReqResOrdering?o.unshift(e.fulfilled,e.rejected):o.push(e.fulfilled,e.rejected)});let c=[];this.interceptors.response.forEach(function(e){c.push(e.fulfilled,e.rejected)});let l,u=0,d;if(!s){let e=[fs.bind(this),void 0];for(e.unshift(...o),e.push(...c),d=e.length,l=Promise.resolve(t);u<d;)l=l.then(e[u++],e[u++]);return l}d=o.length;let f=t;for(;u<d;){let e=o[u++],t=o[u++];try{f=e?e(f):f}catch(e){if(!t){l=Promise.reject(e);break}try{let n=t.call(this,e);q.isThenable(n)&&(l=Promise.resolve(n).then(()=>fs.call(this,f)))}catch(e){l=Promise.reject(e)}break}}if(!l)try{l=fs.call(this,f)}catch(e){l=Promise.reject(e)}for(u=0,d=c.length;u<d;)l=l.then(c[u++],c[u++]);return l}getUri(e){return e=ko(this.defaults,e),za(Eo(e.baseURL,e.url,e.allowAbsoluteUrls,e),e.params,e.paramsSerializer)}};q.forEach([`delete`,`get`,`head`,`options`],function(e){_s.prototype[e]=function(t,n){return this.request(ko(n||{},{method:e,url:t,data:n&&q.hasOwnProp(n,`data`)?n.data:void 0}))}}),q.forEach([`post`,`put`,`patch`,`query`],function(e){function t(t){return function(n,r,i){return this.request(ko(i||{},{method:e,headers:t?{"Content-Type":`multipart/form-data`}:{},url:n,data:r}))}}_s.prototype[e]=t(),e!==`query`&&(_s.prototype[e+`Form`]=t(!0))});var vs=class e{constructor(e){if(typeof e!=`function`)throw TypeError(`executor must be a function.`);let t;this.promise=new Promise(function(e){t=e});let n=this;this.promise.then(e=>{if(!n._listeners)return;let t=n._listeners.length;for(;t-->0;)n._listeners[t](e);n._listeners=null}),this.promise.then=e=>{let t,r=new Promise(e=>{n.subscribe(e),t=e}).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e(function(e,r,i){n.reason||(n.reason=new oo(e,r,i),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let t=this._listeners.indexOf(e);t!==-1&&this._listeners.splice(t,1)}toAbortSignal(){let e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let t;return{token:new e(function(e){t=e}),cancel:t}}};function ys(e){return function(t){return e.apply(null,t)}}function bs(e){return q.isObject(e)&&e.isAxiosError===!0}var xs={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerReturnsAnUnknownError:520,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(xs).forEach(([e,t])=>{xs[t]=e});functi
Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,At as t,Br as n,Cn as r,Ct as i,Dn as a,Er as o,Et as s,Fn as c,Ft as l,Gt as u,In as d,Jn as f,Kn as p,Ln as m,Lr as h,Mr as g,N as _,Nn as v,Nt as y,Or as ee,Pn as te,Rn as ne,Sn as re,Sr as b,Tt as ie,Vr as x,Wn as ae,Yn as S,_t as C,an as w,bt as T,cn as E,cr as oe,en as D,gn as O,hn as k,ir as A,kt as se,ln as j,mn as M,mr as ce,nr as le,on as N,pn as ue,pr as de,qn as fe,sn as P,sr as pe,ur as F,v as me,wn as I,wr as he,xn as L,zn as ge,zr as R}from"./useApi-CROJJdhE-mMpa5RAf.js";import{c as _e,u as z}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{A as ve,G as B,W as ye,Z as be,_ as xe,at as Se,ct as V,g as Ce,it as we,m as Te,rt as H,st as Ee,v as De,x as Oe}from"./serverScope-O8Rw8SFk.js";import{At as U,C as ke,Et as Ae,H as je,N as Me,St as Ne,Tt as Pe,Ut as Fe,W as Ie,_ as Le,a as Re,at as ze,dt as Be,et as Ve,g as He,h as Ue,i as We,kt as W,m as Ge,o as Ke,s as qe,u as Je,ut as G,wt as K,x as Ye,y as Xe}from"./use-global-config-D-dPcPvU.js";import{t as q}from"./castArray-CpgoCob_.js";import{b as Ze}from"./router-CMu0lceh.js";import{n as Qe}from"./strings-B6ImqFWg.js";import{a as $e,i as et,m as tt,n as nt,s as rt,t as it}from"./click-outside-bcMsT2om.js";import{t as at}from"./vnode-SMLE-MKY.js";import{n as ot,t as J}from"./tag-BSnLMVgs.js";var st=1/0,ct=17976931348623157e292;function lt(e){return e?(e=we(e),e===st||e===-st?(e<0?-1:1)*ct:e===e?e:0):e===0?e:0}function ut(e){var t=lt(e),n=t%1;return t===t?n?t-n:t:0}function dt(e,t,n,r){for(var i=e.length,a=n+(r?1:-1);r?a--:++a<i;)if(t(e[a],a,e))return a;return-1}var ft=1,Y=2;function pt(e,t,n,r){var i=n.length,a=i,o=!r;if(e==null)return!a;for(e=Object(e);i--;){var s=n[i];if(o&&s[2]?s[1]!==e[s[0]]:!(s[0]in e))return!1}for(;++i<a;){s=n[i];var c=s[0],l=e[c],u=s[1];if(o&&s[2]){if(l===void 0&&!(c in e))return!1}else{var d=new Ne;if(r)var f=r(l,u,c,e,t,d);if(!(f===void 0?Be(u,l,ft|Y,r,d):f))return!1}}return!0}function mt(e){return e===e&&!u(e)}function ht(e){for(var t=U(e),n=t.length;n--;){var r=t[n],i=e[r];t[n]=[r,i,mt(i)]}return t}function gt(e,t){return function(n){return n!=null&&n[e]===t&&(t!==void 0||e in Object(n))}}function _t(e){var t=ht(e);return t.length==1&&t[0][2]?gt(t[0][0],t[0][1]):function(n){return n===e||pt(n,e,t)}}var vt=1,yt=2;function bt(e,t){return W(e)&&mt(t)?gt(Ae(e),t):function(n){var r=K(n,e);return r===void 0&&r===t?be(n,e):Be(t,r,vt|yt)}}function xt(e){return function(t){return t?.[e]}}function St(e){return function(t){return Pe(t,e)}}function Ct(e){return W(e)?xt(Ae(e)):St(e)}function X(e){return typeof e==`function`?e:e==null?H:typeof e==`object`?Fe(e)?bt(e[0],e[1]):_t(e):Ct(e)}var wt=Math.max,Tt=Math.min;function Et(e,t,n){var r=e==null?0:e.length;if(!r)return-1;var i=r-1;return n!==void 0&&(i=ut(n),i=n<0?wt(r+i,0):Tt(i,r-1)),dt(e,X(t,3),i,!0)}function Dt(){let e=pe(),t=A(0),n=w(()=>({minWidth:`${Math.max(t.value,11)}px`}));return B(e,()=>{t.value=e.value?.getBoundingClientRect().width??0}),{calculatorRef:e,calculatorWidth:t,inputStyle:n}}var Z=Symbol(`ElSelectGroup`),Q=Symbol(`ElSelect`),$={label:`label`,value:`value`,disabled:`disabled`,options:`options`};function Ot(e){let t=A({...$,...e.props}),n={...e.props};return p(()=>e.props,e=>{G(e,n)||(t.value={...$,...e},n={...e})},{deep:!0}),{aliasProps:t,getLabel:e=>K(e,t.value.label),getValue:e=>K(e,t.value.value),getDisabled:e=>K(e,t.value.disabled),getOptions:e=>K(e,t.value.options)}}var kt=ie({name:String,id:String,modelValue:{type:s([Array,String,Number,Boolean,Object]),default:void 0},autocomplete:{type:String,default:`off`},automaticDropdown:Boolean,size:Xe,effect:{type:s(String),default:`light`},disabled:{type:Boolean,default:void 0},clearable:Boolean,filterable:Boolean,allowCreate:Boolean,loading:Boolean,popperClass:{type:String,default:``},popperStyle:{type:s([String,Object])},popperOptions:{type:s(Object),default:()=>({})},remote:Boolean,debounce:{type:Number,default:300},loadingText:String,noMatchText:String,noDataText:String,remoteMethod:{type:s(Function)},filterMethod:{type:s(Function)},multiple:Boolean,multipleLimit:{type:Number,default:0},placeholder:{type:String},defaultFirstOption:Boolean,reserveKeyword:{type:Boolean,default:!0},valueKey:{type:String,default:`value`},collapseTags:Boolean,collapseTagsTooltip:Boolean,tagTooltip:{type:s(Object),default:()=>({})},maxCollapseTags:{type:Number,default:1},teleported:rt.teleported,persistent:{type:Boolean,default:!0},clearIcon:{type:Ue,default:_},fitInputWidth:Boolean,suffixIcon:{type:Ue,default:me},tagType:{...ot.type,default:`info`},tagEffect:{...ot.effect,default:`light`},validateEvent:{type:Boolean,default:!0},remoteShowSuffix:Boolean,showArrow:{type:Boolean,default:!0},offset:{type:Number,default:12},placement:{type:s(String),values:tt,default:`bottom-start`},fallbackPlacements:{type:s(Array),default:[`bottom-start`,`top-start`,`right`,`left`]},tabindex:{type:[String,Number],default:0},appendTo:rt.appendTo,options:{type:s(Array)},props:{type:s(Object),default:()=>$},...Le,...Ce([`ariaLabel`])}Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,At as t,Br as n,Ct as r,Dt as i,Et as a,In as o,Jn as s,Kn as c,Lr as l,Mr as u,Nn as d,Tt as f,_t as p,an as m,cn as h,hn as g,ir as _,kr as v,ln as y,mn as b,mr as x,on as S,pr as C,q as w,sn as T,sr as ee,wn as te,zn as E,zr as D}from"./useApi-CROJJdhE-mMpa5RAf.js";import{l as O,u as k}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{at as A,g as j,ot as M,st as N}from"./serverScope-O8Rw8SFk.js";import{T as ne,a as re,at as ie,h as P,i as F,it as I,o as L,s as R,u as z}from"./use-global-config-D-dPcPvU.js";import{v as B}from"./router-CMu0lceh.js";var V=f({modelValue:{type:[Boolean,String,Number],default:!1},disabled:{type:Boolean,default:void 0},loading:Boolean,size:{type:String,validator:B},width:{type:[String,Number],default:``},inlinePrompt:Boolean,inactiveActionIcon:{type:P},activeActionIcon:{type:P},activeIcon:{type:P},inactiveIcon:{type:P},activeText:{type:String,default:``},inactiveText:{type:String,default:``},activeValue:{type:[Boolean,String,Number],default:!0},inactiveValue:{type:[Boolean,String,Number],default:!1},name:{type:String,default:``},validateEvent:{type:Boolean,default:!0},beforeChange:{type:a(Function)},id:String,tabindex:{type:[String,Number]},...j([`ariaLabel`])}),H={[N]:e=>i(e)||u(e)||t(e),[A]:e=>i(e)||u(e)||t(e),[M]:e=>i(e)||u(e)||t(e)},U=[`id`,`aria-checked`,`aria-disabled`,`aria-label`,`name`,`true-value`,`false-value`,`disabled`,`tabindex`],W=[`aria-hidden`],G={key:1},K={key:1},q=[`aria-hidden`],J=`ElSwitch`,Y=p(g({name:J,__name:`switch`,props:V,emits:H,setup(t,{expose:a,emit:u}){let f=t,p=u,{formItem:g}=F(),j=R(),P=r(`switch`),{inputId:B}=re(f,{formItemContext:g}),V=L(m(()=>{if(f.loading)return!0})),H=_(f.modelValue!==!1),Y=ee(),ae=m(()=>[P.b(),P.m(j.value),P.is(`disabled`,V.value),P.is(`checked`,Z.value)]),oe=m(()=>[P.e(`label`),P.em(`label`,`left`),P.is(`active`,!Z.value)]),se=m(()=>[P.e(`label`),P.em(`label`,`right`),P.is(`active`,Z.value)]),ce=m(()=>({width:ne(f.width)}));c(()=>f.modelValue,()=>{H.value=!0});let X=m(()=>H.value?f.modelValue:!1),Z=m(()=>X.value===f.activeValue);[f.activeValue,f.inactiveValue].includes(X.value)||(I(J,`model-value must be active-value or inactive-value`),p(N,f.inactiveValue),p(A,f.inactiveValue),p(M,f.inactiveValue)),c(Z,e=>{Y.value.checked=e,f.validateEvent&&g?.validate?.(`change`).catch(x)});let Q=()=>{let e=Z.value?f.inactiveValue:f.activeValue;p(N,e),p(A,e),p(M,e),te(()=>{Y.value.checked=Z.value})},$=()=>{if(V.value)return;let{beforeChange:e}=f;if(!e){Q();return}let t=e();[v(t),i(t)].includes(!0)||ie(J,"beforeChange must return type `Promise<boolean>` or `boolean`"),v(t)?t.then(e=>{e&&Q()}).catch(e=>{I(J,`some error occurred: ${e}`)}):t&&Q()};return e(()=>{Y.value.checked=Z.value}),a({focus:()=>{Y.value?.focus?.()},checked:Z}),(e,r)=>(d(),y(`div`,{class:l(ae.value),onClick:k($,[`prevent`])},[S(`input`,{id:C(B),ref_key:`input`,ref:Y,class:l(C(P).e(`input`)),type:`checkbox`,role:`switch`,"aria-checked":Z.value,"aria-disabled":C(V),"aria-label":t.ariaLabel,name:t.name,"true-value":t.activeValue,"false-value":t.inactiveValue,disabled:C(V),tabindex:t.tabindex,onChange:Q,onKeydown:O($,[`enter`])},null,42,U),!t.inlinePrompt&&(t.inactiveIcon||t.inactiveText||e.$slots.inactive)?(d(),y(`span`,{key:0,class:l(oe.value)},[o(e.$slots,`inactive`,{},()=>[t.inactiveIcon?(d(),T(C(z),{key:0},{default:s(()=>[(d(),T(E(t.inactiveIcon)))]),_:1})):h(`v-if`,!0),!t.inactiveIcon&&t.inactiveText?(d(),y(`span`,{key:1,"aria-hidden":Z.value},n(t.inactiveText),9,W)):h(`v-if`,!0)])],2)):h(`v-if`,!0),S(`span`,{class:l(C(P).e(`core`)),style:D(ce.value)},[t.inlinePrompt?(d(),y(`div`,{key:0,class:l(C(P).e(`inner`))},[Z.value?(d(),y(`div`,{key:1,class:l(C(P).e(`inner-wrapper`))},[o(e.$slots,`active`,{},()=>[t.activeIcon?(d(),T(C(z),{key:0},{default:s(()=>[(d(),T(E(t.activeIcon)))]),_:1})):h(`v-if`,!0),!t.activeIcon&&t.activeText?(d(),y(`span`,K,n(t.activeText),1)):h(`v-if`,!0)])],2)):(d(),y(`div`,{key:0,class:l(C(P).e(`inner-wrapper`))},[o(e.$slots,`inactive`,{},()=>[t.inactiveIcon?(d(),T(C(z),{key:0},{default:s(()=>[(d(),T(E(t.inactiveIcon)))]),_:1})):h(`v-if`,!0),!t.inactiveIcon&&t.inactiveText?(d(),y(`span`,G,n(t.inactiveText),1)):h(`v-if`,!0)])],2))],2)):h(`v-if`,!0),S(`div`,{class:l(C(P).e(`action`))},[t.loading?(d(),T(C(z),{key:0,class:l(C(P).is(`loading`))},{default:s(()=>[b(C(w))]),_:1},8,[`class`])):Z.value?o(e.$slots,`active-action`,{key:1},()=>[t.activeActionIcon?(d(),T(C(z),{key:0},{default:s(()=>[(d(),T(E(t.activeActionIcon)))]),_:1})):h(`v-if`,!0)]):Z.value?h(`v-if`,!0):o(e.$slots,`inactive-action`,{key:2},()=>[t.inactiveActionIcon?(d(),T(C(z),{key:0},{default:s(()=>[(d(),T(E(t.inactiveActionIcon)))]),_:1})):h(`v-if`,!0)])],2)],6),!t.inlinePrompt&&(t.activeIcon||t.activeText||e.$slots.active)?(d(),y(`span`,{key:1,class:l(se.value)},[o(e.$slots,`active`,{},()=>[t.activeIcon?(d(),T(C(z),{key:0},{default:s(()=>[(d(),T(E(t.activeIcon)))]),_:1})):h(`v-if`,!0),!t.activeIcon&&t.activeText?(d(),y(`span`,{key:1,"aria-hidden":!Z.value},n(t.activeText)Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{$n as e,$t as t,An as n,At as r,Br as i,Bt as a,Ct as o,Dn as s,Dt as c,En as l,Er as u,Fn as d,Gt as f,In as p,Jn as m,Kn as h,Ln as g,Lr as _,Lt as v,Mn as y,Mr as b,Nn as x,Nt as S,Ot as C,Pn as ee,Sn as w,Sr as T,Wn as te,Wt as E,Yn as D,_t as O,an as k,b as ne,bt as A,cn as re,en as j,gn as M,hn as N,ir as P,jn as F,jt as I,ln as L,mn as R,nr as ie,on as z,pn as ae,pr as B,q as V,qn as oe,sn as H,ur as se,v as ce,vr as U,wn as W,wr as G,x as le,xn as K,yn as q,zr as ue}from"./useApi-CROJJdhE-mMpa5RAf.js";import{c as de,i as fe}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{G as pe,H as me,M as he,ct as J,et as ge,m as _e,x as ve}from"./serverScope-O8Rw8SFk.js";import{At as ye,C as be,D as xe,Ft as Se,H as Ce,Ht as we,It as Te,Mt as Ee,O as De,Rt as Y,St as Oe,Ut as ke,Vt as Ae,Wt as je,at as Me,it as Ne,r as Pe,s as Fe,st as Ie,u as Le,w as Re,wt as ze,y as Be}from"./use-global-config-D-dPcPvU.js";import{u as Ve}from"./select-BGsfCDCJ.js";import{a as He,c as Ue,i as We,o as Ge,r as Ke,s as qe}from"./omit-zqi_K1DB.js";import{n as Je,t as Ye}from"./isArrayLikeObject-Bo9Xnvp4.js";import{t as Xe}from"./castArray-CpgoCob_.js";import{t as Ze}from"./debounce-DcxdqJyS.js";import{t as Qe}from"./numbers-cik3maFd.js";import{a as $e,n as et,s as tt}from"./click-outside-bcMsT2om.js";import{r as nt,t as rt}from"./checkbox-CdKclTX1.js";function it(e,t,n){if(!f(n))return!1;var r=typeof t;return(r==`number`?Y(n)&&we(t,n.length):r==`string`&&t in n)?Ae(n[t],e):!1}function at(e){return Je(function(t,n){var r=-1,i=n.length,a=i>1?n[i-1]:void 0,o=i>2?n[2]:void 0;for(a=e.length>3&&typeof a==`function`?(i--,a):void 0,o&&it(n[0],n[1],o)&&(a=i<3?void 0:a,i=1),t=Object(t);++r<i;){var s=n[r];s&&e(t,s,r,a)}return t})}function ot(e){return function(t,n,r){for(var i=-1,a=Object(t),o=r(t),s=o.length;s--;){var c=o[e?s:++i];if(n(a[c],c,a)===!1)break}return t}}var st=ot();function ct(e,t){return e&&st(e,t,ye)}function lt(e,t){return function(n,r){if(n==null)return n;if(!Y(n))return e(n,r);for(var i=n.length,a=t?i:-1,o=Object(n);(t?a--:++a<i)&&r(o[a],a,o)!==!1;);return n}}var ut=lt(ct);function dt(e,t,n){(n!==void 0&&!Ae(e[t],n)||n===void 0&&!(t in e))&&a(e,t,n)}function ft(e,t){if((t!==`constructor`||typeof e[t]!=`function`)&&t!=`__proto__`)return e[t]}function pt(e){return qe(e,Ge(e))}function mt(e,t,n,r,i,a,o){var s=ft(e,n),c=ft(t,n),l=o.get(c);if(l){dt(e,n,l);return}var u=a?a(s,c,n+``,e,t,o):void 0,d=u===void 0;if(d){var p=ke(c),m=!p&&Se(c),h=!p&&!m&&Ee(c);u=c,p||m||h?ke(s)?u=s:Ye(s)?u=Ue(s):m?(d=!1,u=He(c,!0)):h?(d=!1,u=We(c,!0)):u=[]:v(c)||Te(c)?(u=s,Te(s)?u=pt(s):(!f(s)||E(s))&&(u=Ke(c))):d=!1}d&&(o.set(c,u),i(u,c,r,a,o),o.delete(c)),dt(e,n,u)}function ht(e,t,n,r,i){e!==t&&st(t,function(a,o){if(i||=new Oe,f(a))mt(e,t,o,n,ht,r,i);else{var s=r?r(ft(e,o),a,o+``,e,t,i):void 0;s===void 0&&(s=a),dt(e,o,s)}},Ge)}function gt(e,t){var n=-1,r=Y(e)?Array(e.length):[];return ut(e,function(e,i,a){r[++n]=t(e,i,a)}),r}function _t(e,t){return(ke(e)?je:gt)(e,Ve(t,3))}function vt(e,t){return ge(_t(e,t),1)}function yt(e){return e===null}var bt=at(function(e,t,n){ht(e,t,n)}),xt=!1,St,Ct,wt,Tt,Et,Dt,Ot,kt,At,jt,Mt,Nt,Pt,Ft,It;function X(){if(!xt){xt=!0;var e=navigator.userAgent,t=/(?:MSIE.(\d+\.\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\d+\.\d+))|(?:Opera(?:.+Version.|.)(\d+\.\d+))|(?:AppleWebKit.(\d+(?:\.\d+)?))|(?:Trident\/\d+\.\d+.*rv:(\d+\.\d+))/.exec(e),n=/(Mac OS X)|(Windows)|(Linux)/.exec(e);if(Nt=/\b(iPhone|iP[ao]d)/.exec(e),Pt=/\b(iP[ao]d)/.exec(e),jt=/Android/i.exec(e),Ft=/FBAN\/\w+;/i.exec(e),It=/Mobile/i.exec(e),Mt=!!/Win64/.exec(e),t){St=t[1]?parseFloat(t[1]):t[5]?parseFloat(t[5]):NaN,St&&document&&document.documentMode&&(St=document.documentMode);var r=/(?:Trident\/(\d+.\d+))/.exec(e);Dt=r?parseFloat(r[1])+4:St,Ct=t[2]?parseFloat(t[2]):NaN,wt=t[3]?parseFloat(t[3]):NaN,Tt=t[4]?parseFloat(t[4]):NaN,Tt?(t=/(?:Chrome\/(\d+\.\d+))/.exec(e),Et=t&&t[1]?parseFloat(t[1]):NaN):Et=NaN}else St=Ct=wt=Et=Tt=NaN;if(n){if(n[1]){var i=/(?:Mac OS X (\d+(?:[._]\d+)?))/.exec(e);Ot=!i||parseFloat(i[1].replace(`_`,`.`))}else Ot=!1;kt=!!n[2],At=!!n[3]}else Ot=kt=At=!1}}var Lt={ie:function(){return X()||St},ieCompatibilityMode:function(){return X()||Dt>St},ie64:function(){return Lt.ie()&&Mt},firefox:function(){return X()||Ct},opera:function(){return X()||wt},webkit:function(){return X()||Tt},safari:function(){return Lt.webkit()},chrome:function(){return X()||Et},windows:function(){return X()||kt},osx:function(){return X()||Ot},linux:function(){return X()||At},iphone:function(){return X()||Nt},mobile:function(){return X()||Nt||Pt||jt||It},nativeApp:function(){return X()||Ft},android:function(){return X()||jt},ipad:function(){return X()||Pt}},Rt=Lt,zt=!!(typeof window<`u`&&window.document&&window.document.createElement),Bt={canUseDOM:zt,canUseWorkers:typeof Worker<`u`,canUseEventListeners:zt&&!!(window.addEventListener||window.attachEvent),canUseViewport:zt&&!!window.screen,isInWorker:!zt},Vt;Bt.canUseDOM&&(Vt=document.implementation&&document.implLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{An as e,At as t,Ct as n,Dn as r,Et as i,I as a,In as o,Kn as s,Lr as c,Mn as l,Mr as u,Nn as d,Nt as f,On as p,Pn as m,Q as h,Tt as g,Wn as _,Yn as v,_t as y,an as b,b as x,bt as S,cn as C,fr as w,gn as T,hn as E,ir as D,ln as O,mn as k,nr as A,pr as j,sr as ee,wn as M,xn as N,y as te,zr as ne}from"./useApi-CROJJdhE-mMpa5RAf.js";import{c as re}from"./runtime-dom.esm-bundler-YxjRGSuG.js";import{G as P,M as F,P as ie,V as ae,ct as I,f as L,j as R,q as oe,st as z,x as B,z as se}from"./serverScope-O8Rw8SFk.js";import{at as V,u as H}from"./use-global-config-D-dPcPvU.js";import{t as ce}from"./omit-zqi_K1DB.js";import{b as le}from"./router-CMu0lceh.js";import{n as U,t as W}from"./numbers-cik3maFd.js";import{t as G}from"./strings-B6ImqFWg.js";import{t as ue}from"./use-ordered-children-DGQ-CQup.js";var de=({atEndEdge:e,atStartEdge:t,layout:n},r)=>{let i,a=0,o=n=>n<0&&t.value||n>0&&e.value;return{hasReachedEdge:o,onWheel:e=>{R(i);let{deltaX:t,deltaY:s}=e;e.shiftKey&&s!==0&&(t=s,s=0);let c=n.value===`horizontal`?t:s;o(c)||(a+=c,!ie()&&c!==0&&e.preventDefault(),i=F(()=>{r(a),a=0}))}}},K=e=>{let t=0,n=e;for(;n;)t+=n.offsetTop,n=n.offsetParent;return t},fe=(e,t)=>Math.abs(K(e)-K(t)),q=e=>{let t,n;return e.type===`touchend`?(n=e.changedTouches[0].clientY,t=e.changedTouches[0].clientX):e.type.startsWith(`touch`)?(n=e.touches[0].clientY,t=e.touches[0].clientX):(n=e.clientY,t=e.clientX),{clientX:t,clientY:n}},J=Symbol(`tabsRootContextKey`),Y=g({tabs:{type:i(Array),default:()=>L([])},tabRefs:{type:i(Object),default:()=>L({})}}),X=`ElTabBar`,pe=E({name:X,__name:`tab-bar`,props:Y,setup(e,{expose:t}){let i=e,a=N(J);a||V(X,`<el-tabs><el-tab-bar /></el-tabs>`);let o=n(`tabs`),l=D(),u=D(),p=b(()=>f(a.props.defaultValue)||!!u.value?.transform),m=()=>{let e=0,t=0,n=[`top`,`bottom`].includes(a.props.tabPosition)?`width`:`height`,r=n===`width`?`x`:`y`,o=r===`x`?`left`:`top`;return i.tabs.every(r=>{if(f(r.paneName))return!1;let a=i.tabRefs[r.paneName];if(!a)return!1;if(!r.active)return!0;e=a[`offset${G(o)}`],t=a[`client${G(n)}`];let s=window.getComputedStyle(a);return n===`width`&&(t-=Number.parseFloat(s.paddingLeft)+Number.parseFloat(s.paddingRight),e+=Number.parseFloat(s.paddingLeft)),!1}),{[n]:`${t}px`,transform:`translate${G(r)}(${e}px)`}},h=()=>u.value=m(),g=[],_=()=>{g.forEach(e=>e.stop()),g.length=0,Object.values(i.tabRefs).forEach(e=>{g.push(P(e,h))})};s(()=>i.tabs,async()=>{await M(),h(),_()},{immediate:!0});let v=P(l,()=>h());return r(()=>{g.forEach(e=>e.stop()),g.length=0,v.stop()}),t({ref:l,update:h}),(e,t)=>p.value?(d(),O(`div`,{key:0,ref_key:`barRef`,ref:l,class:c([j(o).e(`active-bar`),j(o).is(j(a).props.tabPosition)]),style:ne(u.value)},null,6)):C(`v-if`,!0)}}),me=5,he=({scrollable:e,navOffset:t,navSize:n,navContainerSize:r,isHorizontal:i})=>{let a=D(!1),o=b(()=>Math.max(n.value-r.value,0)),s,c,l=n=>{if(!e.value||n.touches.length!==1)return;let{clientX:r,clientY:i}=q(n);s={startX:r,startY:i,startOffset:t.value},c=void 0},u=n=>{if(!s||!e.value)return;if(n.touches.length!==1){d();return}let{clientX:r,clientY:l}=q(n),u=s.startX-r,f=s.startY-l,p=i.value?u:f,m=i.value?f:u,h=Math.abs(p),g=Math.abs(m);if(U(c)){if(Math.max(h,g)<=me)return;c=h>g}if(!c)return;let _=le(s.startOffset+p,0,o.value);o.value<=0||_===t.value||!n.cancelable||(n.preventDefault(),a.value=!0,t.value=_)},d=()=>{s=void 0,c=void 0,a.value=!1};return{isTouchScrolling:a,handleTouchStart:l,handleTouchMove:u,handleTouchEnd:d}},Z=g({panes:{type:i(Array),default:()=>L([])},currentName:{type:[String,Number],default:``},editable:Boolean,type:{type:String,values:[`card`,`border-card`,``],default:``},stretch:Boolean,tabindex:{type:[String,Number],default:void 0}}),Q={tabClick:(e,t,n)=>n instanceof Event,tabRemove:(e,t)=>t instanceof Event},ge=`ElTabNav`,_e=E({name:ge,props:Z,emits:Q,setup(t,{expose:r,emit:i}){let o=N(J);o||V(ge,`<el-tabs><tab-nav /></el-tabs>`);let c=n(`tabs`),u=se(),d=oe(),f=D(),p=D(),m=D(),h=D({}),g=D(),_=D(!1),v=D(0),y=D(!1),S=D(!0),C=D(!1),T=ee(),E=b(()=>[`top`,`bottom`].includes(o.props.tabPosition)),O=b(()=>E.value?`width`:`height`),A=b(()=>{let e=O.value===`width`?`X`:`Y`;return{transition:C.value||U.value?`none`:void 0,transform:`translate${e}(-${v.value}px)`}}),{width:j,height:ne}=ae(f),{width:re,height:ie}=ae(p,{width:0,height:0},{box:`border-box`}),L=b(()=>E.value?j.value:ne.value),R=b(()=>E.value?re.value:ie.value),{onWheel:z}=de({atStartEdge:b(()=>v.value<=0),atEndEdge:b(()=>R.value-v.value<=L.value),layout:b(()=>E.value?`horizontal`:`vertical`)},e=>{v.value=le(v.value+e,0,R.value-L.value)}),ce=e=>{C.value=!0,z(e),F(()=>{C.value=!1})},{isTouchScrolling:U,handleTouchStart:G,handleTouchMove:ue,handleTouchEnd:K}=he({scrollable:_,navOffset:v,navSize:R,navContainerSize:L,isHorizontal:E}),fe=()=>{if(!f.value)return;let e=f.value.getBoundingClientRect()[O.value],t=v.value;t&&(v.value=t>e?t-e:0)},q=()=>{if(!f.value||!p.value)return;let e=p.value.getBoundingClientRect()[O.value],t=f.value.getBoundingClientRect()[O.value],n=v.value;W(e-n,t)&&(vLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{Br as e,Cn as t,Ct as n,Et as r,Gr as i,Lr as a,Nn as o,Pn as s,Sr as c,Tt as l,_t as u,an as d,cn as f,hn as p,ir as m,ln as ee,mn as h,on as g,pr as _,wn as te,xn as ne}from"./useApi-CROJJdhE-mMpa5RAf.js";import{ct as re,et as v,st as y,x as ie}from"./serverScope-O8Rw8SFk.js";import{_ as b,a as x,c as ae,d as S,f as C,g as oe,i as w,l as se,m as T,o as E,s as ce,u as D}from"./date-picker-CM_15T0u.js";import{C as le,_t as O,ft as k,mt as A,pt as j}from"./use-global-config-D-dPcPvU.js";import{d as M}from"./select-BGsfCDCJ.js";import{n as N,t as P}from"./isArrayLikeObject-Bo9Xnvp4.js";function F(){}function I(e){return e!==e}function L(e,t,n){for(var r=n-1,i=e.length;++r<i;)if(e[r]===t)return r;return-1}function R(e,t,n){return t===t?L(e,t,n):M(e,I,n)}function z(e,t){return!!(e!=null&&e.length)&&R(e,t,0)>-1}function B(e,t,n){for(var r=-1,i=e==null?0:e.length;++r<i;)if(n(t,e[r]))return!0;return!1}var V=O&&1/k(new O([,-0]))[1]==1/0?function(e){return new O(e)}:F,H=200;function U(e,t,n){var r=-1,i=z,a=e.length,o=!0,s=[],c=s;if(n)o=!1,i=B;else if(a>=H){var l=t?null:V(e);if(l)return k(l);o=!1,i=j,c=new A}else c=t?[]:s;outer:for(;++r<a;){var u=e[r],d=t?t(u):u;if(u=n||u!==0?u:0,o&&d===d){for(var f=c.length;f--;)if(c[f]===d)continue outer;t&&c.push(d),s.push(u)}else i(c,d,n)||(c!==s&&c.push(d),s.push(u))}return s}var W=N(function(e){return U(v(e,1,P,!0))}),G=l({...C,parsedValue:{type:r(Array)}}),K=i(T(),1),ue=[`disabled`],q=p({__name:`panel-time-range`,props:G,emits:[`pick`,`select-range`,`set-picker-option`],setup(t,{emit:r}){let i=t,s=r,l=(e,t)=>{let n=[];for(let r=e;r<=t;r++)n.push(r);return n},{t:u,lang:p}=le(),v=n(`time`),y=n(`picker`),b=ne(oe),{arrowControl:x,disabledHours:S,disabledMinutes:C,disabledSeconds:w,defaultValue:T}=b.props,D=d(()=>[v.be(`range-picker`,`body`),v.be(`panel`,`content`),v.is(`arrow`,x),N.value?`has-seconds`:``]),O=d(()=>[v.be(`range-picker`,`body`),v.be(`panel`,`content`),v.is(`arrow`,x),N.value?`has-seconds`:``]),k=d(()=>i.parsedValue[0]),A=d(()=>i.parsedValue[1]),j=ae(i,{modelValue:d(()=>b.props.modelValue),valueOnClear:d(()=>b?.emptyValues?b.emptyValues.valueOnClear.value:null)}),M=()=>{let e=j.value;s(`pick`,e,!1),te(()=>{j.value=e})},N=d(()=>i.format.includes(`ss`)),P=d(()=>i.format.includes(`A`)?`A`:i.format.includes(`a`)?`a`:``),F=(e=!1)=>{s(`pick`,[k.value,A.value],e)},I=e=>{z(e.millisecond(0),A.value)},L=e=>{z(k.value,e.millisecond(0))},R=e=>{let t=e.map(e=>(0,K.default)(e).locale(p.value)),n=Q(t);return t[0].isSame(n[0])&&t[1].isSame(n[1])},z=(e,t)=>{i.visible&&s(`pick`,[e,t],!0)},B=d(()=>k.value>A.value),V=m([0,2]),H=(e,t)=>{s(`select-range`,e,t,`min`),V.value=[e,t]},U=d(()=>N.value?11:8),G=(e,t)=>{s(`select-range`,e,t,`max`);let n=_(U);V.value=[e+n,t+n]},q=e=>{let t=N.value?[0,3,6,11,14,17]:[0,3,8,11],n=[`hours`,`minutes`].concat(N.value?[`seconds`]:[]),r=(t.indexOf(V.value[0])+e+t.length)%t.length,i=t.length/2;r<i?$.start_emitSelectRange(n[r]):$.end_emitSelectRange(n[r-i])},J=e=>{let t=ie(e),{left:n,right:r,up:i,down:a}=re;if([n,r].includes(t)){q(t===n?-1:1),e.preventDefault();return}if([i,a].includes(t)){let n=t===i?-1:1;$[`${V.value[0]<U.value?`start`:`end`}_scrollDown`](n),e.preventDefault();return}},Y=(e,t)=>{let n=S?S(e):[],r=e===`start`,i=(t||(r?A.value:k.value)).hour();return W(n,r?l(i+1,23):l(0,i-1))},X=(e,t,n)=>{let r=C?C(e,t):[],i=t===`start`,a=n||(i?A.value:k.value);if(e!==a.hour())return r;let o=a.minute();return W(r,i?l(o+1,59):l(0,o-1))},Z=(e,t,n,r)=>{let i=w?w(e,t,n):[],a=n===`start`,o=r||(a?A.value:k.value),s=o.hour(),c=o.minute();if(e!==s||t!==c)return i;let u=o.second();return W(i,a?l(u+1,59):l(0,u-1))},Q=([e,t])=>[me(e,`start`,!0,t),me(t,`end`,!1,e)],{getAvailableHours:de,getAvailableMinutes:fe,getAvailableSeconds:pe}=ce(Y,X,Z),{timePickerOptions:$,getAvailableTime:me,onSetOption:he}=se({getAvailableHours:de,getAvailableMinutes:fe,getAvailableSeconds:pe});return s(`set-picker-option`,[`parseUserInput`,e=>e?c(e)?e.map(e=>(0,K.default)(e,i.format).locale(p.value)):(0,K.default)(e,i.format).locale(p.value):null]),s(`set-picker-option`,[`isValidValue`,R]),s(`set-picker-option`,[`handleKeydownInput`,J]),s(`set-picker-option`,[`getDefaultValue`,()=>{if(c(T))return T.map(e=>(0,K.default)(e).locale(p.value));let e=(0,K.default)(T).locale(p.value);return[e,e.add(60,`m`)]}]),s(`set-picker-option`,[`getRangeAvailableTime`,Q]),s(`set-picker-option`,[`handleCancel`,M]),(t,n)=>t.actualVisible?(o(),ee(`div`,{key:0,class:a([_(v).b(`range-picker`),_(y).b(`panel`)])},[g(`div`,{class:a(_(v).be(`range-picker`,`content`))},[g(`div`,{class:a(_(v).be(`range-picker`,`cell`))},[g(`div`,{class:a(_(v).be(`range-picker`,`header`))},e(_(u)(`el.datepicker.startTime`)),3),g(`div`,{class:a(D.value)},[h(E,{ref:`minSpinner`,role:`start`,"show-seconds":N.value,"am-pm-mode":P.value,"arrow-control":_(x),"spinner-date":k.value,"disabled-hours":Y,"disabled-minutes":X,"disabled-seconds":Z,onChange:I,onSetOption:_(he),onSelectRange:H},null,8,[`show-seconds`,`am-pm-mode`,`arrow-control`,`Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
import{ir as e}from"./useApi-CROJJdhE-mMpa5RAf.js";import{t}from"./form-B2Pzr8Vf.js";var n={Company:`CompanyName`,Department:`DeptName`,Workgroup:`WorkgroupName`,UserRole:`RoleName`,Role:`RoleName`,User:`UserName`},r={Company:`CompanyUUID`,Department:`DeptUUID`,Workgroup:`WorkgroupUUID`,UserRole:`UserRoleUUID`,Role:`RoleUUID`,User:`UserUUID`},i=new Map;function a(e){return(e||``).slice(0,8)+`...`}function o(){let o=e(!1);async function s(e){o.value=!0;try{let o={};for(let[s,{table:c,uuids:l}]of Object.entries(e)){o[s]={};let e=n[c]||`${c}Name`,u=r[c]||`${c}UUID`;i.has(c)||i.set(c,new Map);let d=i.get(c),f=l.filter(e=>!d.has(e));for(let n of f)try{let r=await t.list(c,{[u]:n,pageSize:1}),i=(Array.isArray(r)?r:r.list||[])[0]?.[e];d.set(n,i?String(i):a(n))}catch{d.set(n,a(n))}for(let e of l)o[s][e]=d.get(e)||a(e)}return o}finally{o.value=!1}}function c(e,t){return i.get(e)?.get(t)}return{loading:o,resolveUUIDs:s,getCachedLabel:c}}export{o as t};
|
||||
@@ -5,7 +5,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>GERP 管理系统</title>
|
||||
<script type="module" crossorigin src="/assets/index-CjWCN1N9.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-DwuP2m3e.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/useApi-CROJJdhE-mMpa5RAf.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/runtime-dom.esm-bundler-YxjRGSuG.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/use-global-config-D-dPcPvU.js">
|
||||
@@ -20,14 +20,14 @@
|
||||
<link rel="modulepreload" crossorigin href="/assets/vnode-SMLE-MKY.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/descriptions-Cq_aE9sg.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/castArray-CpgoCob_.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/router-CMu0lceh.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/router-lhgEEoBs.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/strings-B6ImqFWg.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/tag-BSnLMVgs.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/select-BGsfCDCJ.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/select-C6bKVB-D.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/isArrayLikeObject-Bo9Xnvp4.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/time-picker-DcDLR-nT.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/time-picker-TCWcdl6M.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/checkbox-CdKclTX1.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/table-DPU4-geg.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/table-BMMHIZYf.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/form-F--u6XQJ.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/image-HD4q5QFa.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/skeleton-DGDficlh.js">
|
||||
@@ -37,20 +37,20 @@
|
||||
<link rel="modulepreload" crossorigin href="/assets/card-Dj_UeWcA.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/use-dialog-BxrOdCc2.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/drawer-Cu-arLgK.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/tabs-BSMusFE5.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/tabs-CprxXUdp.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/radio-Cb0vAm4I.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/col-BXlaMgkQ.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/collapse-transition-D5PfF1iI.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/refs-Cc5FwKWV.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/dialog-_5VhSQg5.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/dialog-HOUKmN79.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/menu-BLdj5hCm.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/empty-CnQTxkvl.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/input-number-CiNOxXL6.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pagination-DOGDdUWm.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pagination-DjMzc_Tw.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/progress-CJYzD9Cp.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/result-gkzjWpF7.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/steps-C4-7Ybf-.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/switch-7puThziV.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/switch-BF4Q1eKX.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/tree-DqeBDBpX.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/directive-CY41a6pJ.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CHOuvNKI.css">
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
git init
|
||||
git add .
|
||||
git commit -m "XXX"
|
||||
git remote add origin https://github.com/XXX
|
||||
git push -u origin master
|
||||
|
||||
git branch -m main master
|
||||
|
||||
git remote remove origin
|
||||
git remote add origin [新的仓库地址]
|
||||
|
||||
git pull --rebase origin master # (或 main)
|
||||
git push -u origin master # (或 main)
|
||||
@@ -40,7 +40,6 @@ const MenuData1 = {
|
||||
title: "相关页面",
|
||||
items: [
|
||||
{ name: "工作室 API", description: "竭尽全力为您提供我们最好的应用程序编程接口", link: "https://api.gvsds.com", target: "_blank" },
|
||||
{ name: "历史页面托管", description: "为您托管曾经发生过的一切", link: "https://history.gvsds.com", target: "_blank" },
|
||||
{ name: "南京大屠杀", description: "谨以此页,悼念所有南京大屠杀死难者,缅怀为民族解放献身的先烈。历史不容篡改,真相不容否认。", link: "https://nanjingmassacre.gvsds.com", target: "_blank" }
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,708 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>【GDrive - 云存储】当数据获得自由,创新便无所限制</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdn.gvsds.com/jquery/3.7.1/jquery-3.7.1.min.js"></script>
|
||||
<link href="https://cdn.gvsds.com/font-awesome/css/all.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.gvsds.com/chart.js/dist/chart.umd.js"></script>
|
||||
<link href="https://cdn.gvsds.com/toast/style.css" rel="stylesheet">
|
||||
<script src="https://cdn.gvsds.com/toast/script.js"></script>
|
||||
<script src="/lib/js/tailwindcss.config.js"></script>
|
||||
<!--link href="/lib/css/tailwindcss.tool.css" rel="stylesheet"-->
|
||||
<style type="text/tailwindcss">
|
||||
@layer utilities {
|
||||
.content-auto {
|
||||
content-visibility: auto;
|
||||
}
|
||||
.scrollbar-hide {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
.scrollbar-hide::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.transition-height {
|
||||
transition: max-height 0.3s ease-in-out;
|
||||
}
|
||||
.file-item-hover {
|
||||
@apply hover:bg-gray-100 dark:hover:bg-dark-100 transition-all duration-200;
|
||||
}
|
||||
.btn-primary {
|
||||
@apply bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-all duration-200 shadow-md hover:shadow-lg;
|
||||
}
|
||||
.btn-secondary {
|
||||
@apply bg-white dark:bg-dark-200 text-gray-700 dark:text-gray-200 border border-gray-300 dark:border-dark-100 px-4 py-2 rounded-lg hover:bg-gray-50 dark:hover:bg-dark-100 transition-all duration-200;
|
||||
}
|
||||
.page {
|
||||
@apply transition-all duration-300 ease-in-out transform;
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
.page.active {
|
||||
@apply opacity-100 translate-y-0;
|
||||
}
|
||||
|
||||
/* 模态框动画 */
|
||||
.modal-enter {
|
||||
@apply opacity-0 scale-95;
|
||||
}
|
||||
|
||||
.modal-enter-active {
|
||||
@apply opacity-100 scale-100 transition-all duration-300 ease-out;
|
||||
}
|
||||
|
||||
.modal-exit {
|
||||
@apply opacity-100 scale-100;
|
||||
}
|
||||
|
||||
.modal-exit-active {
|
||||
@apply opacity-0 scale-95 transition-all duration-300 ease-in;
|
||||
}
|
||||
|
||||
/* 侧边栏动画 */
|
||||
.sidebar-enter {
|
||||
@apply -translate-x-full;
|
||||
}
|
||||
|
||||
.sidebar-enter-active {
|
||||
@apply translate-x-0 transition-transform duration-300 ease-out;
|
||||
}
|
||||
|
||||
.sidebar-exit {
|
||||
@apply translate-x-0;
|
||||
}
|
||||
|
||||
.sidebar-exit-active {
|
||||
@apply -translate-x-full transition-transform duration-300 ease-in;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<link href="/lib/css/gdrive.css" rel="stylesheet">
|
||||
</head>
|
||||
<body class="font-inter bg-gray-50 dark:bg-dark-300 text-gray-800 dark:text-gray-200 min-h-screen flex flex-col transition-colors duration-300">
|
||||
<!-- 顶部导航栏 -->
|
||||
<header class="bg-white dark:bg-dark-200 shadow-sm fixed w-full z-50 transition-all duration-300">
|
||||
<div class="container mx-auto px-4 flex items-center justify-between h-16">
|
||||
<!-- Logo和标题 -->
|
||||
<div class="flex items-center space-x-2">
|
||||
<button id="sidebar-toggle" class="lg:hidden text-gray-500 dark:text-gray-400 hover:text-primary dark:hover:text-primary p-2 rounded-lg transition-colors">
|
||||
<i class="fa fa-bars text-xl"></i>
|
||||
</button>
|
||||
<div class="flex items-center">
|
||||
<div class="w-8 h-8 rounded-lg bg-primary flex items-center justify-center text-white">
|
||||
<i class="fa fa-cloud"></i>
|
||||
</div>
|
||||
<h1 class="ml-2 text-xl font-bold text-gray-800 dark:text-white">GDrive</h1>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 搜索栏
|
||||
<div class="hidden md:flex flex-1 max-w-xl mx-8">
|
||||
<div class="relative w-full">
|
||||
<input type="text" placeholder="搜索文件..." class="w-full py-2 pl-10 pr-4 rounded-lg bg-gray-100 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200">
|
||||
<i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
||||
</div>
|
||||
</div-->
|
||||
<!-- 右侧操作区 -->
|
||||
<div class="flex items-center space-x-1">
|
||||
<!-- 主题切换 -->
|
||||
<button id="theme-toggle" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-moon dark:hidden text-gray-500"></i>
|
||||
<i class="fa fa-sun hidden dark:block text-gray-400"></i>
|
||||
</button>
|
||||
<!-- 通知
|
||||
<button class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors relative">
|
||||
<i class="fa fa-bell text-gray-500 dark:text-gray-400"></i>
|
||||
<span class="absolute top-1 right-1 w-2 h-2 bg-primary rounded-full"></span>
|
||||
</button -->
|
||||
<!-- 用户菜单 -->
|
||||
<div class="relative">
|
||||
<button id="user-menu-button" class="flex items-center space-x-2 p-1 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<img id="user-avatar" src="https://ugm.gvsds.com/GetCookiesUserHeadPng.api" alt="UserHeadPng" class="w-8 h-8 rounded-full object-cover border-2 border-primary">
|
||||
<span id="user-menu-name" class="hidden md:inline font-medium">UserName</span>
|
||||
<i class="fa fa-caret-down text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<div id="user-menu" class="absolute right-0 mt-2 w-48 bg-white dark:bg-dark-200 rounded-lg shadow-lg py-2 z-50 hidden transition-all duration-200 transform origin-top-right scale-95 opacity-0">
|
||||
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-user mr-2 text-gray-500 dark:text-gray-400"></i>个人资料
|
||||
</a>
|
||||
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-cog mr-2 text-gray-500 dark:text-gray-400"></i>设置
|
||||
</a>
|
||||
<div class="border-t border-gray-100 dark:border-dark-100 my-1"></div>
|
||||
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors text-danger">
|
||||
<i class="fa fa-sign-out mr-2"></i>退出登录
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- 主内容区 -->
|
||||
<div class="flex pt-16 h-[calc(100vh-4rem)]">
|
||||
<aside id="sidebar" class="bg-white dark:bg-dark-200 shadow-sm w-64 fixed h-full left-0 top-16 transform -translate-x-full lg:translate-x-0 transition-transform duration-300 z-40 overflow-y-auto scrollbar-hide">
|
||||
<nav class="p-4 h-full flex flex-col">
|
||||
<div class="mb-6">
|
||||
<h2 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">主导航</h2>
|
||||
<ul class="space-y-1">
|
||||
<li>
|
||||
<a href="#dashboard" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg bg-primary/10 text-primary font-medium">
|
||||
<i class="fa fa-tachometer w-5 text-center"></i>
|
||||
<span>仪表盘</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#files" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-folder w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>我的文件</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#shared" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-share-alt w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>共享文件</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#settings" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-folder w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>设置</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mb-16 mt-auto p-4 bg-gray-50 dark:bg-dark-100 rounded-xl">
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<h3 class="font-medium">存储空间</h3>
|
||||
<span class="text-sm text-gray-500 dark:text-gray-400" id="sidebar-storage-usage">...GB/...GB</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 dark:bg-dark-300 rounded-full h-2 mb-1">
|
||||
<div class="bg-primary h-2 rounded-full" id="sidebar-storage-bar" style="width: 0%"></div>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs text-gray-500 dark:text-gray-400">
|
||||
<span>已使用 <span id="sidebar-storage-span-bar">...%</span></span>
|
||||
<!--a href="#" class="text-primary hover:underline">升级空间</a-->
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</aside>
|
||||
<!-- 遮罩层 -->
|
||||
<div id="sidebar-backdrop" class="fixed inset-0 bg-black/50 z-30 lg:hidden hidden transition-opacity duration-300"></div>
|
||||
<!-- 主内容 -->
|
||||
<main class="flex-1 lg:ml-64 p-4 md:p-6 overflow-y-auto scrollbar-hide" style="height: calc(100vh - 64px);">
|
||||
<!-- 页面切换容器 -->
|
||||
<div id="page-container">
|
||||
<!-- 仪表盘页面 -->
|
||||
<div id="dashboard-page" class="page active">
|
||||
<div class="mb-6">
|
||||
<h1 class="text-2xl md:text-3xl font-bold mb-2">仪表盘</h1>
|
||||
<p class="text-gray-500 dark:text-gray-400">欢迎回来,<span id="dashboard-user-name">UserName</span>!这是您的存储概览</p>
|
||||
</div>
|
||||
<!-- 统计卡片 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-5 hover:shadow-md transition-shadow">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="font-medium text-gray-500 dark:text-gray-400">总空间</h3>
|
||||
<div class="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary">
|
||||
<i class="fa fa-file"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-3xl font-bold" id="dashboard-storage-total">... GB</p>
|
||||
<p class="text-sm text-success mt-1">
|
||||
内部储存
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-5 hover:shadow-md transition-shadow">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="font-medium text-gray-500 dark:text-gray-400">已使用空间</h3>
|
||||
<div class="w-10 h-10 rounded-full bg-warning/10 flex items-center justify-center text-warning">
|
||||
<i class="fa fa-hdd"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-3xl font-bold" id="dashboard-storage-usage">... GB</p>
|
||||
<p class="text-sm text-warning mt-1">
|
||||
<span id="dashboard-storage-percentage">...%</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-5 hover:shadow-md transition-shadow">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="font-medium text-gray-500 dark:text-gray-400">共享文件</h3>
|
||||
<div class="w-10 h-10 rounded-full bg-success/10 flex items-center justify-center text-success">
|
||||
<i class="fa fa-share-alt"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-3xl font-bold">42</p>
|
||||
<p class="text-sm text-success mt-1">
|
||||
<i class="fa fa-arrow-up"></i> 24% 较上月
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-5 hover:shadow-md transition-shadow">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="font-medium text-gray-500 dark:text-gray-400">回收站</h3>
|
||||
<div class="w-10 h-10 rounded-full bg-danger/10 flex items-center justify-center text-danger">
|
||||
<i class="fa fa-trash"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-3xl font-bold">18</p>
|
||||
<p class="text-sm text-danger mt-1">
|
||||
<i class="fa fa-arrow-up"></i> 5% 较上月
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图表区域 -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
|
||||
<!-- 存储使用趋势 -->
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-5 lg:col-span-2">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="font-semibold">存储使用趋势</h3>
|
||||
<div class="flex space-x-2">
|
||||
<button class="px-3 py-1 text-sm rounded-md bg-primary/10 text-primary">月</button>
|
||||
<button class="px-3 py-1 text-sm rounded-md hover:bg-gray-100 dark:hover:bg-dark-100">季</button>
|
||||
<button class="px-3 py-1 text-sm rounded-md hover:bg-gray-100 dark:hover:bg-dark-100">年</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-64">
|
||||
<canvas id="storageChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 文件类型分布 -->
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-5">
|
||||
<h3 class="font-semibold mb-6">文件类型分布</h3>
|
||||
<div class="h-64">
|
||||
<canvas id="fileTypeChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 文件页面 -->
|
||||
<div id="files-page" class="page hidden">
|
||||
<div class="mb-6">
|
||||
<h1 class="text-2xl md:text-3xl font-bold mb-2">我的文件</h1>
|
||||
<p class="text-gray-500 dark:text-gray-400">管理您的所有文件和文件夹</p>
|
||||
</div>
|
||||
<button id="navigate-up" class="btn-secondary hidden">
|
||||
<i class="fa fa-arrow-up mr-2"></i>返回上一级
|
||||
</button>
|
||||
|
||||
<!-- 文件操作工具栏 -->
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-4 mb-6">
|
||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-2">
|
||||
<button class="btn-primary">
|
||||
<i class="fa fa-upload mr-2"></i>上传
|
||||
</button>
|
||||
<button class="btn-secondary">
|
||||
<i class="fa fa-folder mr-2"></i>新建文件夹
|
||||
</button>
|
||||
<button class="btn-secondary">
|
||||
<i class="fa fa-refresh mr-2"></i>刷新
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索文件..." class="py-2 pl-8 pr-4 rounded-lg bg-gray-100 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200">
|
||||
<i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-1">
|
||||
<button class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="列表视图">
|
||||
<i class="fa fa-list text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-2 rounded-lg bg-primary/10 text-primary transition-colors" title="网格视图">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 文件路径导航 -->
|
||||
<div id="breadcrumb-container" class="flex items-center mb-4 text-sm"></div>
|
||||
<!--div class="flex items-center mb-4 text-sm">
|
||||
<a href="#" class="text-primary hover:underline">主目录</a>
|
||||
<i class="fa fa-angle-right mx-2 text-gray-400"></i>
|
||||
<a href="#" class="text-primary hover:underline">文档</a>
|
||||
<i class="fa fa-angle-right mx-2 text-gray-400"></i>
|
||||
<span class="text-gray-500 dark:text-gray-400">项目</span>
|
||||
</div-->
|
||||
<!-- 文件网格 -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 mb-6" id="file-list-container"></div>
|
||||
<!-- 分页
|
||||
<div class="flex justify-between items-center bg-white dark:bg-dark-200 rounded-xl shadow-sm p-4">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">显示 1-8 项,共 24 项</p>
|
||||
<div class="flex items-center space-x-1">
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg bg-primary text-white">1</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">2</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">3</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div-->
|
||||
</div>
|
||||
<!-- 共享文件页面 -->
|
||||
<div id="shared-page" class="page hidden">
|
||||
<div class="mb-6">
|
||||
<h1 class="text-2xl md:text-3xl font-bold mb-2">共享文件</h1>
|
||||
<p class="text-gray-500 dark:text-gray-400">查看和管理与您共享的文件和文件夹</p>
|
||||
</div>
|
||||
<!-- 共享文件列表 -->
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm overflow-hidden">
|
||||
<div class="p-4 border-b border-gray-200 dark:border-dark-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="font-semibold">与我共享</h3>
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索共享文件..." class="py-2 pl-8 pr-4 rounded-lg bg-gray-100 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200">
|
||||
<i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="bg-gray-50 dark:bg-dark-100">
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">名称</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">共享者</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">权限</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">大小</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">修改日期</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-dark-100">
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-folder text-primary mr-3"></i>
|
||||
<span class="font-medium">设计资源</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<img src="https://picsum.photos/200/200?random=3" alt="用户头像" class="w-6 h-6 rounded-full mr-2">
|
||||
<span>李四</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full bg-primary/10 text-primary">可编辑</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">42.5 MB</td>
|
||||
<td class="px-4 py-3">2023-05-18</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-1">
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="打开">
|
||||
<i class="fa fa-folder-open text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="更多">
|
||||
<i class="fa fa-ellipsis-v text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-file-pdf text-danger mr-3"></i>
|
||||
<span class="font-medium">市场分析.pdf</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<img src="https://picsum.photos/200/200?random=4" alt="用户头像" class="w-6 h-6 rounded-full mr-2">
|
||||
<span>王五</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full bg-secondary/10 text-secondary">只读</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">3.8 MB</td>
|
||||
<td class="px-4 py-3">2023-05-15</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-1">
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="打开">
|
||||
<i class="fa fa-folder-open text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="更多">
|
||||
<i class="fa fa-ellipsis-v text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-file-excel text-success mr-3"></i>
|
||||
<span class="font-medium">销售数据.xlsx</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<img src="https://picsum.photos/200/200?random=5" alt="用户头像" class="w-6 h-6 rounded-full mr-2">
|
||||
<span>赵六</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full bg-primary/10 text-primary">可编辑</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">5.2 MB</td>
|
||||
<td class="px-4 py-3">2023-05-12</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-1">
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="打开">
|
||||
<i class="fa fa-folder-open text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="更多">
|
||||
<i class="fa fa-ellipsis-v text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-folder text-primary mr-3"></i>
|
||||
<span class="font-medium">项目文档</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<img src="https://picsum.photos/200/200?random=6" alt="用户头像" class="w-6 h-6 rounded-full mr-2">
|
||||
<span>孙七</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full bg-primary/10 text-primary">可编辑</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">12.8 MB</td>
|
||||
<td class="px-4 py-3">2023-05-10</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-1">
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="打开">
|
||||
<i class="fa fa-folder-open text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="更多">
|
||||
<i class="fa fa-ellipsis-v text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="p-4 border-t border-gray-200 dark:border-dark-100 flex justify-between items-center">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">显示 1-4 项,共 12 项</p>
|
||||
<div class="flex items-center space-x-1">
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg bg-primary text-white">1</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">2</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">3</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 设置页面 -->
|
||||
<div id="settings-page" class="page hidden">
|
||||
<div class="mb-6">
|
||||
<h1 class="text-2xl md:text-3xl font-bold mb-2">设置</h1>
|
||||
<p class="text-gray-500 dark:text-gray-400">管理您的账户和偏好设置</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<!-- 设置侧边栏 -->
|
||||
<div class="lg:col-span-1">
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm overflow-hidden">
|
||||
<nav class="p-4">
|
||||
<ul class="space-y-1">
|
||||
<li>
|
||||
<a href="#account-settings" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg bg-primary/10 text-primary font-medium">
|
||||
<i class="fa fa-user w-5 text-center"></i>
|
||||
<span>账户设置</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#preferences" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-sliders w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>偏好设置</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#security" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-shield w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>安全设置</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#notifications" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-bell w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>通知设置</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#storage" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-hdd w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>存储设置</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 设置内容 -->
|
||||
<div class="lg:col-span-2">
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-6">
|
||||
<h3 class="text-xl font-semibold mb-6">账户设置</h3>
|
||||
<form id="account-settings-form">
|
||||
<div class="space-y-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label for="first-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">名字</label>
|
||||
<input type="text" id="first-name" class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-dark-100 bg-gray-50 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200" value="张">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="last-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">姓氏</label>
|
||||
<input type="text" id="last-name" class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-dark-100 bg-gray-50 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200" value="三">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">邮箱地址</label>
|
||||
<input type="email" id="email" class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-dark-100 bg-gray-50 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200" value="zhangsan@example.com">
|
||||
</div>
|
||||
<div>
|
||||
<label for="phone" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">手机号码</label>
|
||||
<input type="tel" id="phone" class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-dark-100 bg-gray-50 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200" value="13800138000">
|
||||
</div>
|
||||
<div>
|
||||
<label for="bio" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">个人简介</label>
|
||||
<textarea id="bio" rows="3" class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-dark-100 bg-gray-50 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200">热爱技术,致力于提供优质的云存储服务体验。</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">头像</label>
|
||||
<!--div class="flex items-center space-x-4">
|
||||
<img src="https://ugm.gvsds.com/GetCookiesUserHeadPng.api" alt="用户头像" class="w-16 h-16 rounded-full object-cover border-2 border-primary">
|
||||
<div>
|
||||
<button type="button" class="btn-secondary mb-2">
|
||||
<i class="fa fa-upload mr-2"></i>上传新头像
|
||||
</button>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">支持 JPG, PNG 格式,最大 5MB</p>
|
||||
</div>
|
||||
</div-->
|
||||
</div>
|
||||
|
||||
<div class="pt-4 border-t border-gray-200 dark:border-dark-100">
|
||||
<div class="flex justify-end">
|
||||
<button type="button" class="btn-secondary mr-3">
|
||||
取消
|
||||
</button>
|
||||
<button type="submit" class="btn-primary">
|
||||
保存更改
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<!-- 上传文件模态框 -->
|
||||
<div id="upload-modal" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-lg w-full max-w-md p-6 transform transition-all duration-300 scale-95 opacity-0" id="upload-modal-content">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h3 class="text-xl font-semibold">上传文件</h3>
|
||||
<button id="close-upload-modal" class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200">
|
||||
<i class="fa fa-times text-xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<div class="border-2 border-dashed border-gray-300 dark:border-dark-100 rounded-xl p-8 text-center hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors cursor-pointer" id="drop-area">
|
||||
<i class="fa fa-cloud-upload text-4xl text-gray-400 mb-4"></i>
|
||||
<p class="text-gray-500 dark:text-gray-400 mb-2">拖放文件到此处上传</p>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">或</p>
|
||||
<button class="mt-4 btn-primary">
|
||||
<i class="fa fa-folder-open mr-2"></i>选择文件
|
||||
</button>
|
||||
<input type="file" multiple class="hidden" id="file-input">
|
||||
</div>
|
||||
</div>
|
||||
<div id="upload-progress-container" class="hidden">
|
||||
<h4 class="font-medium mb-2">上传进度</h4>
|
||||
<div id="upload-progress" class="w-full bg-gray-200 dark:bg-dark-300 rounded-full h-2 mb-2">
|
||||
<div class="bg-primary h-2 rounded-full" style="width: 0%"></div>
|
||||
</div>
|
||||
<p id="upload-status" class="text-sm text-gray-500 dark:text-gray-400">正在上传...</p>
|
||||
</div>
|
||||
<div class="flex justify-end space-x-3">
|
||||
<button id="cancel-upload" class="btn-secondary">
|
||||
取消
|
||||
</button>
|
||||
<button id="start-upload" class="btn-primary">
|
||||
开始上传
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 新建文件夹模态框 -->
|
||||
<div id="new-folder-modal" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-lg w-full max-w-md p-6 transform transition-all duration-300 scale-95 opacity-0" id="new-folder-modal-content">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h3 class="text-xl font-semibold">新建文件夹</h3>
|
||||
<button id="close-new-folder-modal" class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200">
|
||||
<i class="fa fa-times text-xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label for="folder-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">文件夹名称</label>
|
||||
<input type="text" id="folder-name" class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-dark-100 bg-gray-50 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200" placeholder="输入文件夹名称">
|
||||
</div>
|
||||
<div class="flex justify-end space-x-3">
|
||||
<button id="cancel-new-folder" class="btn-secondary">
|
||||
取消
|
||||
</button>
|
||||
<button id="create-folder" class="btn-primary">
|
||||
创建文件夹
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作成功提示 --
|
||||
<div id="success-toast" class="fixed bottom-4 right-4 bg-success text-white px-4 py-3 rounded-lg shadow-lg z-50 flex items-center space-x-3 transform translate-y-20 opacity-0 transition-all duration-300">
|
||||
<i class="fa fa-check-circle text-xl"></i>
|
||||
<span id="success-message">操作成功!</span>
|
||||
</div>
|
||||
<-- 操作失败提示 --
|
||||
<div id="error-toast" class="fixed bottom-4 right-4 bg-danger text-white px-4 py-3 rounded-lg shadow-lg z-50 flex items-center space-x-3 transform translate-y-20 opacity-0 transition-all duration-300">
|
||||
<i class="fa fa-exclamation-circle text-xl"></i>
|
||||
<span id="error-message">操作失败!</span>
|
||||
</div-->
|
||||
<!-- JavaScript API -->
|
||||
<script src="/lib/js/gdrive.js"></script>
|
||||
<script src="/lib/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,42 +0,0 @@
|
||||
.loading-overlay {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
backdrop-filter: blur(5px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 100;
|
||||
border-radius: 8px;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.loading-spinner {
|
||||
border: 4px solid rgba(0, 0, 0, 0.1);
|
||||
border-left-color: #0051ff;
|
||||
border-radius: 50%;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
.loading-overlay.show {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.loading-overlay.hide {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
}
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
#breadcrumb-container a {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
@layer utilities {
|
||||
.content-auto {
|
||||
content-visibility: auto;
|
||||
}
|
||||
.scrollbar-hide {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
.scrollbar-hide::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.transition-height {
|
||||
transition: max-height 0.3s ease-in-out;
|
||||
}
|
||||
.file-item-hover {
|
||||
@apply hover:bg-gray-100 dark:hover:bg-dark-100 transition-all duration-200;
|
||||
}
|
||||
.btn-primary {
|
||||
@apply bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-all duration-200 shadow-md hover:shadow-lg;
|
||||
}
|
||||
.btn-secondary {
|
||||
@apply bg-white dark:bg-dark-200 text-gray-700 dark:text-gray-200 border border-gray-300 dark:border-dark-100 px-4 py-2 rounded-lg hover:bg-gray-50 dark:hover:bg-dark-100 transition-all duration-200;
|
||||
}
|
||||
.page {
|
||||
@apply transition-all duration-300 ease-in-out transform;
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
.page.active {
|
||||
@apply opacity-100 translate-y-0;
|
||||
}
|
||||
|
||||
/* 模态框动画 */
|
||||
.modal-enter {
|
||||
@apply opacity-0 scale-95;
|
||||
}
|
||||
|
||||
.modal-enter-active {
|
||||
@apply opacity-100 scale-100 transition-all duration-300 ease-out;
|
||||
}
|
||||
|
||||
.modal-exit {
|
||||
@apply opacity-100 scale-100;
|
||||
}
|
||||
|
||||
.modal-exit-active {
|
||||
@apply opacity-0 scale-95 transition-all duration-300 ease-in;
|
||||
}
|
||||
|
||||
/* 侧边栏动画 */
|
||||
.sidebar-enter {
|
||||
@apply -translate-x-full;
|
||||
}
|
||||
|
||||
.sidebar-enter-active {
|
||||
@apply translate-x-0 transition-transform duration-300 ease-out;
|
||||
}
|
||||
|
||||
.sidebar-exit {
|
||||
@apply translate-x-0;
|
||||
}
|
||||
|
||||
.sidebar-exit-active {
|
||||
@apply -translate-x-full transition-transform duration-300 ease-in;
|
||||
}
|
||||
}
|
||||
@@ -1,521 +0,0 @@
|
||||
// 初始化GDrive API
|
||||
const GDrive = (function() {
|
||||
// 内部状态变量
|
||||
const state = {
|
||||
storage: {
|
||||
used: 520,
|
||||
total: 521,
|
||||
percentage: 99
|
||||
},
|
||||
user: {
|
||||
UserName: null,
|
||||
UserVersion: null,
|
||||
UserVDiskTotal: null
|
||||
}
|
||||
};
|
||||
// 存储相关API
|
||||
const storage = {
|
||||
// 获取存储使用情况
|
||||
getUsage: () => {
|
||||
return {
|
||||
...state.storage
|
||||
};
|
||||
},
|
||||
// 更新存储使用情况
|
||||
updateUsage: (used, total) => {
|
||||
state.storage = {
|
||||
used: used,
|
||||
total: total,
|
||||
percentage: Math.round((used / total) * 100)
|
||||
};
|
||||
// 更新侧边栏存储信息
|
||||
document.getElementById('sidebar-storage-usage')
|
||||
.textContent = `${state.storage.used}GB/${state.storage.total}GB`;
|
||||
document.getElementById('sidebar-storage-bar')
|
||||
.style.width = `${state.storage.percentage}%`;
|
||||
document.getElementById('sidebar-storage-span-bar')
|
||||
.textContent = `${state.storage.percentage}%`;
|
||||
// 更新仪表盘存储信息
|
||||
document.getElementById('dashboard-storage-usage')
|
||||
.textContent = `${state.storage.used} GB`;
|
||||
document.getElementById('dashboard-storage-percentage')
|
||||
.textContent = `${state.storage.percentage}%`;
|
||||
document.getElementById('dashboard-storage-total')
|
||||
.textContent = `${state.storage.total} GB`;
|
||||
return {
|
||||
...state.storage
|
||||
};
|
||||
}
|
||||
};
|
||||
// 用户相关API
|
||||
const user = {
|
||||
// 获取当前用户信息
|
||||
getInfo: () => {
|
||||
return {
|
||||
...state.user
|
||||
};
|
||||
},
|
||||
// 更新用户信息
|
||||
updateInfo: (data) => {
|
||||
// 合并数据
|
||||
state.user = {
|
||||
...state.user,
|
||||
...data
|
||||
};
|
||||
// 更新UI
|
||||
document.getElementById('user-menu-name') .textContent = state.user.UserName;
|
||||
document.getElementById('dashboard-user-name') .textContent = state.user.UserName;
|
||||
// document.querySelector('.user-menu-version') .textContent = state.user.UserVersion;
|
||||
return {
|
||||
...state.user
|
||||
};
|
||||
}
|
||||
};
|
||||
// 文件相关API
|
||||
const files = {
|
||||
// 获取文件夹列表
|
||||
getList: (FileUUID="0", FileTypeParent=0) => {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('FileUUID', FileUUID);
|
||||
formData.append('FileTypeParent', FileTypeParent);
|
||||
return fetch("/API/GetFileList.api", {method: "POST", body: formData}).then(res => res.json()).then(res => {
|
||||
if (res.code) {
|
||||
notifications.error('错误', '获取文件列表失败!');
|
||||
return;
|
||||
}
|
||||
files.currentUUID = res.FileUUID;
|
||||
return res.FileList;
|
||||
})
|
||||
} catch (error) {
|
||||
notifications.error('错误', '获取文件列表失败,json解析错误');
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
// 删除文件/文件夹
|
||||
delete: (id) => {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('FileUUID', id);
|
||||
return fetch("/API/DeleteFile.api", {method: "POST", body: formData}).then(res => res.json()).then(res => {
|
||||
return res;
|
||||
})
|
||||
} catch (error) {
|
||||
notifications.error('错误', '删除文件失败,json解析错误');
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
createFolder: (FileName) => {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('FileParentUUID', files.currentUUID);
|
||||
formData.append('FileName', FileName);
|
||||
return fetch("/API/CreateFolder.api", {method: "POST", body: formData}).then(res => res.json()).then(res => {
|
||||
if (res.code) {
|
||||
notifications.error('错误', `创建文件夹失败,错误原因:${res.msg}`);
|
||||
} else {
|
||||
notifications.success('成功', '创建文件夹成功');
|
||||
}
|
||||
return res;
|
||||
})
|
||||
} catch (error) {
|
||||
notifications.error('错误', '创建文件夹失败,json解析错误');
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
// 恢复文件/文件夹
|
||||
restore: (id, isFolder = false) => {
|
||||
// 实际应通过API恢复
|
||||
console.log(`恢复${isFolder ? '文件夹' : '文件'} ID: ${id}`);
|
||||
return true;
|
||||
},
|
||||
currentPath: '/',
|
||||
currentUUID: '0',
|
||||
// 导航到文件夹
|
||||
navigateToFolder: (folderId) => {
|
||||
// 更新当前路径
|
||||
files.currentUUID = folderId;
|
||||
const loading = GDrive.files.loading();
|
||||
// 获取文件夹内容
|
||||
files.getList(files.currentUUID).then(folderContents => {
|
||||
if (folderContents) {
|
||||
// 更新UI
|
||||
files.updateFileListUI(folderContents);
|
||||
// 更新面包屑导航
|
||||
files.updateBreadcrumb();
|
||||
GDrive.files.close(loading);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 返回上一级
|
||||
navigateUp: () => {
|
||||
if (files.currentPath !== '/') {
|
||||
const loading = GDrive.files.loading();
|
||||
// 获取上一级内容
|
||||
files.getList(files.currentUUID, 1).then(folderContents => {
|
||||
if (folderContents) {
|
||||
// 更新UI
|
||||
files.updateFileListUI(folderContents);
|
||||
// 更新面包屑导航
|
||||
files.updateBreadcrumb();
|
||||
GDrive.files.close(loading);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
loading: () => {
|
||||
const container = document.getElementById('file-list-container');
|
||||
const overlay = document.createElement('div');
|
||||
overlay.classList.add('loading-overlay');
|
||||
const spinner = document.createElement('div');
|
||||
spinner.classList.add('loading-spinner');
|
||||
overlay.appendChild(spinner);
|
||||
container.appendChild(overlay);
|
||||
setTimeout(() => {
|
||||
overlay.classList.add('show');
|
||||
}, 0);
|
||||
return overlay;
|
||||
},
|
||||
close: (overlay) => {
|
||||
if (overlay && overlay.parentNode) {
|
||||
overlay.classList.remove('show');
|
||||
overlay.classList.add('hide');
|
||||
setTimeout(() => {
|
||||
if (overlay.parentNode) {
|
||||
overlay.parentNode.removeChild(overlay);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
getFileExtension: (filename) => {
|
||||
if (!filename) {return ''}
|
||||
const parts = filename.split('.');
|
||||
return (parts.length > 1 ? parts.pop() : '').toLowerCase();
|
||||
},
|
||||
updateBreadcrumb: () => {
|
||||
const breadcrumbContainer = document.getElementById('breadcrumb-container');
|
||||
const pathParts = GDrive.files.currentPath.split('/').filter(part => part !== '');
|
||||
let breadcrumbHTML = '<div class="flex items-center space-x-2 text-sm">';
|
||||
breadcrumbHTML += '<a class="text-primary hover:underline" data-path="/" data-folder-id="0">根目录</a>';
|
||||
let currentPath = '';
|
||||
pathParts.forEach((part, index) => {
|
||||
currentPath += `${part}/`;
|
||||
const isLast = index === pathParts.length - 1;
|
||||
breadcrumbHTML += `
|
||||
<span class="text-gray-500 dark:text-gray-400">/</span>
|
||||
${isLast
|
||||
? `<span class="text-gray-700 dark:text-gray-300">${part}</span>`
|
||||
: `<a class="text-primary hover:underline" data-path="${currentPath}" data-folder-id="${currentUUID}">${part}</a>`
|
||||
}
|
||||
`;
|
||||
});
|
||||
breadcrumbHTML += '</div>';
|
||||
breadcrumbContainer.innerHTML = breadcrumbHTML;
|
||||
// 为面包屑链接添加点击事件
|
||||
document.querySelectorAll('#breadcrumb-container a[data-path]')
|
||||
.forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
// GDrive.files.currentPath = link.getAttribute('data-path');
|
||||
//files.getList(GDrive.files.currentPath).then(folderContents => {
|
||||
// if (folderContents) {
|
||||
// files.updateFileListUI(folderContents);
|
||||
// files.updateBreadcrumb();
|
||||
// }
|
||||
//});
|
||||
files.navigateToFolder(link.getAttribute('data-folder-id'));
|
||||
});
|
||||
});
|
||||
},
|
||||
// 更新文件列表UI的函数
|
||||
updateFileListUI: (items) => {
|
||||
const container = document.getElementById('file-list-container');
|
||||
container.innerHTML = '';
|
||||
|
||||
items.forEach(item => {
|
||||
const itemElement = document.createElement('div');
|
||||
itemElement.className = 'bg-white dark:bg-dark-200 rounded-xl shadow-sm p-4 file-item-hover cursor-pointer';
|
||||
|
||||
if (!item.FileType) {
|
||||
// Folder item
|
||||
itemElement.innerHTML = `
|
||||
<div class="folder-item bg-white dark:bg-dark-200 rounded-xl shadow-sm overflow-hidden file-item-hover" data-folder-id="${item.FileUUID}">
|
||||
<div class="h-36 bg-primary/10 flex items-center justify-center">
|
||||
<i class="fa fa-folder text-6xl text-primary"></i>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<h3 class="font-medium truncate">${item.FileName}</h3>
|
||||
<div class="flex space-x-1">
|
||||
<button class="share-btn p-1 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="分享" data-id="${item.FileUUID}">
|
||||
<i class="fa fa-share-alt text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="download-btn p-1 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载" data-id="${item.FileUUID}">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="delete-btn p-1 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="删除" data-id="${item.FileUUID}">
|
||||
<i class="fa fa-trash text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">${item.Files}个文件</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-2">修改于 ${item.FileLastChangeTime}</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
// File item
|
||||
let ico = `<div class="flex flex-col items-center"><i class="fa fa-file text-6xl"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-danger/10 px-2 py-1 rounded">FILE</span></div>`;
|
||||
if (files.getFileExtension(item.FileName) === 'pdf') {
|
||||
ico=`
|
||||
<div class="flex flex-col items-center"><i class="fa fa-file-pdf text-6xl text-danger"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-danger/10 text-danger px-2 py-1 rounded">PDF</span></div>`;
|
||||
} else if (files.getFileExtension(item.FileName) === 'xlsx') {
|
||||
ico=`
|
||||
<div class="flex flex-col items-center"><i class="fa fa-file-excel text-6xl text-success"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-success/10 text-success px-2 py-1 rounded">XLSX</span></div>`;
|
||||
} else if (files.getFileExtension(item.FileName) === 'pptx') {
|
||||
ico=`
|
||||
<div class="flex flex-col items-center"><i class="fa fa-file-powerpoint text-6xl text-warning"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-warning/10 text-warning px-2 py-1 rounded">PPTX</span></div>`;
|
||||
} else if (files.getFileExtension(item.FileName) === 'xls') {
|
||||
ico=`
|
||||
<div class="flex flex-col items-center"><i class="fa fa-file-excel text-6xl text-success"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-success/10 text-success px-2 py-1 rounded">XLS</span></div>`;
|
||||
} else if (files.getFileExtension(item.FileName) === 'ppt') {
|
||||
ico=`
|
||||
<div class="flex flex-col items-center"><i class="fa fa-file-powerpoint text-6xl text-warning"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-warning/10 text-warning px-2 py-1 rounded">PPT</span></div>`;
|
||||
} else if (files.getFileExtension(item.FileName) === 'doc') {
|
||||
ico=`
|
||||
<div class="flex flex-col items-center"><i class="fa fa-file-word text-6xl text-primary"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-primary/10 text-primary px-2 py-1 rounded">DOC</span></div>`;
|
||||
} else if (files.getFileExtension(item.FileName) === 'docx') {
|
||||
ico=`
|
||||
<div class="flex flex-col items-center"><i class="fa fa-file-word text-6xl text-primary"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-primary/10 text-primary px-2 py-1 rounded">DOCX</span></div>`;
|
||||
} else if (files.getFileExtension(item.FileName) === 'zip') {
|
||||
ico=`
|
||||
<div class="flex flex-col items-center"><i class="fa fa-file-zip text-6xl text-secondary"></i>
|
||||
<span class="mt-2 text-xs font-medium bg-secondary/10 text-secondary px-2 py-1 rounded">ZIP</span></div>`
|
||||
} else if (files.getFileExtension(item.FileName).match(/(jpg|jpeg|png|gif|bmp|webp)$/i)) {
|
||||
ico=`
|
||||
<img src="/API/PreviewImage.api?FileUUID=${item.FileUUID}" alt="产品截图" class="w-full h-full object-cover">`;
|
||||
}
|
||||
itemElement.innerHTML = `
|
||||
<div class="file-item bg-white dark:bg-dark-200 rounded-xl shadow-sm overflow-hidden file-item-hover" data-file-id="${item.FileUUID}">
|
||||
<div class="h-36 bg-gray-100 dark:bg-dark-100 flex items-center justify-center">
|
||||
${ico}
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<h3 class="font-medium truncate">${item.FileName}</h3>
|
||||
<div class="flex space-x-1">
|
||||
<button class="share-btn p-1 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="分享" data-id="${item.FileUUID}">
|
||||
<i class="fa fa-share-alt text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="download-btn p-1 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载" data-id="${item.FileUUID}">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="delete-btn p-1 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="删除" data-id="${item.FileUUID}">
|
||||
<i class="fa fa-trash text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">${(item.FileSize/(1024*1024)).toFixed(2)}MB</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-2">修改于 ${item.FileLastChangeTime}</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
container.appendChild(itemElement);
|
||||
});
|
||||
|
||||
// Add event listeners after all items are rendered
|
||||
document.querySelectorAll('.share-btn').forEach(btn => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const fileId = btn.getAttribute('data-id');
|
||||
// Call your share function here
|
||||
console.log('Share file/folder with ID:', fileId);
|
||||
// Example: files.shareFile(fileId);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.download-btn').forEach(btn => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const fileId = btn.getAttribute('data-id');
|
||||
// Call your download function here
|
||||
console.log('Download file/folder with ID:', fileId);
|
||||
// Example: files.downloadFile(fileId);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.delete-btn').forEach(btn => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const fileId = btn.getAttribute('data-id');
|
||||
const loading = GDrive.files.loading();
|
||||
GDrive.files.delete(fileId).then(res => {
|
||||
if (res.code) {
|
||||
notifications.error('错误', `删除文件失败,错误原因:${res.msg}`);
|
||||
} else {
|
||||
notifications.success('成功', '删除文件成功');
|
||||
}
|
||||
GDrive.files.refreshFileList();
|
||||
GDrive.files.close(loading);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
// Add click handler for folder/file items if needed
|
||||
document.querySelectorAll('.folder-item, .file-item').forEach(item => {
|
||||
item.addEventListener('click', () => {
|
||||
const id = item.getAttribute('data-folder-id') || item.getAttribute('data-file-id');
|
||||
if (item.classList.contains('folder-item')) {
|
||||
// Handle folder click (e.g., navigate into folder)
|
||||
console.log('Open folder with ID:', id);
|
||||
// Example: files.openFolder(id);
|
||||
} else {
|
||||
// Handle file click (e.g., preview file)
|
||||
console.log('Open file with ID:', id);
|
||||
// Example: files.previewFile(id);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
refreshFileList: () => {
|
||||
const initialFiles = GDrive.files.getList();
|
||||
const loading = GDrive.files.loading();
|
||||
initialFiles.then(folderContents => {
|
||||
if (folderContents) {
|
||||
GDrive.files.updateFileListUI(folderContents);
|
||||
GDrive.files.updateBreadcrumb();
|
||||
GDrive.files.close(loading);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
// 共享相关API
|
||||
const sharing = {
|
||||
// 获取共享列表
|
||||
getSharedWithMe: () => {
|
||||
// 这里返回模拟数据,实际应通过API获取
|
||||
return [{
|
||||
id: 1,
|
||||
name: "设计资源",
|
||||
type: "folder",
|
||||
owner: {
|
||||
name: "李四",
|
||||
avatar: "https://picsum.photos/200/200?random=3"
|
||||
},
|
||||
permission: "edit",
|
||||
size: 42.5, // MB
|
||||
modified: "2023-05-18"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "市场分析.pdf",
|
||||
type: "file",
|
||||
owner: {
|
||||
name: "王五",
|
||||
avatar: "https://picsum.photos/200/200?random=4"
|
||||
},
|
||||
permission: "view",
|
||||
size: 3.8, // MB
|
||||
modified: "2023-05-15"
|
||||
}
|
||||
];
|
||||
},
|
||||
// 共享文件/文件夹
|
||||
share: (id, users, permission) => {
|
||||
// 实际应通过API共享
|
||||
console.log(`共享${id}给用户:`, users);
|
||||
console.log(`权限: ${permission}`);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 主题相关API
|
||||
const theme = {
|
||||
// 切换主题
|
||||
toggle: () => {
|
||||
if (document.documentElement.classList.contains('dark')) {
|
||||
document.documentElement.classList.remove('dark');
|
||||
localStorage.theme = 'light';
|
||||
return 'light';
|
||||
} else {
|
||||
document.documentElement.classList.add('dark');
|
||||
localStorage.theme = 'dark';
|
||||
return 'dark';
|
||||
}
|
||||
},
|
||||
// 设置主题
|
||||
set: (theme) => {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
localStorage.theme = 'dark';
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
localStorage.theme = 'light';
|
||||
}
|
||||
return theme;
|
||||
},
|
||||
// 获取当前主题
|
||||
get: () => {
|
||||
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)')
|
||||
.matches)) {
|
||||
return 'dark';
|
||||
} else {
|
||||
return 'light';
|
||||
}
|
||||
}
|
||||
};
|
||||
/* 通知相关API
|
||||
const notifications = {
|
||||
// 显示成功通知
|
||||
success: (message) => {
|
||||
const toast = document.getElementById('success-toast');
|
||||
const toastMessage = document.getElementById('success-message');
|
||||
|
||||
toastMessage.textContent = message || "操作成功!";
|
||||
toast.classList.remove('translate-y-20', 'opacity-0');
|
||||
toast.classList.add('translate-y-0', 'opacity-100');
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('translate-y-0', 'opacity-100');
|
||||
toast.classList.add('translate-y-20', 'opacity-0');
|
||||
}, 3000);
|
||||
},
|
||||
|
||||
// 显示错误通知
|
||||
error: (message) => {
|
||||
const toast = document.getElementById('error-toast');
|
||||
const toastMessage = document.getElementById('error-message');
|
||||
|
||||
toastMessage.textContent = message || "操作失败!";
|
||||
toast.classList.remove('translate-y-20', 'opacity-0');
|
||||
toast.classList.add('translate-y-0', 'opacity-100');
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('translate-y-0', 'opacity-100');
|
||||
toast.classList.add('translate-y-20', 'opacity-0');
|
||||
}, 3000);
|
||||
}
|
||||
};*/
|
||||
const notifications = Toast;
|
||||
|
||||
// 返回API对象
|
||||
return {
|
||||
storage,
|
||||
user,
|
||||
files,
|
||||
sharing,
|
||||
theme,
|
||||
notifications
|
||||
};
|
||||
})();
|
||||
// 注册到window对象
|
||||
window.GDrive = GDrive;
|
||||
@@ -1,445 +0,0 @@
|
||||
// DOM 加载完成后初始化
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// 初始化主题
|
||||
if (GDrive.theme.get() === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
// 主题切换按钮
|
||||
document.getElementById('theme-toggle')
|
||||
.addEventListener('click', () => {
|
||||
GDrive.theme.toggle();
|
||||
});
|
||||
// 用户菜单
|
||||
document.getElementById('user-menu-button')
|
||||
.addEventListener('click', () => {
|
||||
const menu = document.getElementById('user-menu');
|
||||
menu.classList.toggle('hidden');
|
||||
menu.classList.toggle('scale-95');
|
||||
menu.classList.toggle('scale-100');
|
||||
menu.classList.toggle('opacity-0');
|
||||
menu.classList.toggle('opacity-100');
|
||||
});
|
||||
// 点击其他区域关闭用户菜单
|
||||
document.addEventListener('click', (e) => {
|
||||
const userMenuButton = document.getElementById('user-menu-button');
|
||||
const userMenu = document.getElementById('user-menu');
|
||||
|
||||
if (!userMenuButton.contains(e.target) && !userMenu.contains(e.target)) {
|
||||
userMenu.classList.add('hidden', 'scale-95', 'opacity-0');
|
||||
userMenu.classList.remove('scale-100', 'opacity-100');
|
||||
}
|
||||
});
|
||||
// 侧边栏切换
|
||||
document.getElementById('sidebar-toggle')
|
||||
.addEventListener('click', () => {
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const backdrop = document.getElementById('sidebar-backdrop');
|
||||
|
||||
sidebar.classList.toggle('-translate-x-full');
|
||||
backdrop.classList.toggle('hidden');
|
||||
});
|
||||
// 点击遮罩层关闭侧边栏
|
||||
document.getElementById('sidebar-backdrop')
|
||||
.addEventListener('click', () => {
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const backdrop = document.getElementById('sidebar-backdrop');
|
||||
|
||||
sidebar.classList.add('-translate-x-full');
|
||||
backdrop.classList.add('hidden');
|
||||
});
|
||||
// 页面切换
|
||||
document.querySelectorAll('nav a[href^="#"]')
|
||||
.forEach(anchor => {
|
||||
anchor.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
const targetId = this.getAttribute('href')
|
||||
.substring(1);
|
||||
const currentPage = document.querySelector('.page.active');
|
||||
const targetPage = document.getElementById(`${targetId}-page`);
|
||||
if (!targetPage || targetPage === currentPage) return;
|
||||
currentPage.classList.add('hidden');
|
||||
currentPage.classList.remove('active');
|
||||
targetPage.classList.remove('hidden');
|
||||
setTimeout(() => {
|
||||
targetPage.classList.add('active');
|
||||
}, 10);
|
||||
document.querySelectorAll('nav a')
|
||||
.forEach(link => {
|
||||
link.classList.remove('bg-primary/10', 'text-primary');
|
||||
link.classList.add('hover:bg-gray-100', 'dark:hover:bg-dark-100');
|
||||
});
|
||||
this.classList.add('bg-primary/10', 'text-primary');
|
||||
this.classList.remove('hover:bg-gray-100', 'dark:hover:bg-dark-100');
|
||||
if (window.innerWidth < 1024) {
|
||||
document.getElementById('sidebar')
|
||||
.classList.add('-translate-x-full');
|
||||
document.getElementById('sidebar-backdrop')
|
||||
.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
// 上传文件模态框
|
||||
document.querySelector('.btn-primary:has(.fa-upload)')
|
||||
.addEventListener('click', () => {
|
||||
const modal = document.getElementById('upload-modal');
|
||||
const modalContent = document.getElementById('upload-modal-content');
|
||||
modal.classList.remove('hidden');
|
||||
setTimeout(() => {
|
||||
modalContent.classList.remove('scale-95', 'opacity-0');
|
||||
modalContent.classList.add('scale-100', 'opacity-100');
|
||||
}, 10);
|
||||
});
|
||||
// 关闭上传模态框
|
||||
document.getElementById('close-upload-modal')
|
||||
.addEventListener('click', () => {
|
||||
const modal = document.getElementById('upload-modal');
|
||||
const modalContent = document.getElementById('upload-modal-content');
|
||||
modalContent.classList.remove('scale-100', 'opacity-100');
|
||||
modalContent.classList.add('scale-95', 'opacity-0');
|
||||
setTimeout(() => {
|
||||
modal.classList.add('hidden');
|
||||
}, 300);
|
||||
});
|
||||
// 取消上传
|
||||
document.getElementById('cancel-upload')
|
||||
.addEventListener('click', () => {
|
||||
const modal = document.getElementById('upload-modal');
|
||||
const modalContent = document.getElementById('upload-modal-content');
|
||||
modalContent.classList.remove('scale-100', 'opacity-100');
|
||||
modalContent.classList.add('scale-95', 'opacity-0');
|
||||
setTimeout(() => {
|
||||
modal.classList.add('hidden');
|
||||
}, 300);
|
||||
});
|
||||
// 选择文件按钮
|
||||
document.getElementById('drop-area')
|
||||
.addEventListener('click', () => {
|
||||
document.getElementById('file-input')
|
||||
.click();
|
||||
});
|
||||
// 文件选择
|
||||
document.getElementById('file-input')
|
||||
.addEventListener('change', (e) => {
|
||||
const files = e.target.files;
|
||||
if (files.length > 0) {
|
||||
document.getElementById('upload-progress-container')
|
||||
.classList.remove('hidden');
|
||||
document.getElementById('upload-status')
|
||||
.textContent = `已选择 ${files.length} 个文件`;
|
||||
}
|
||||
});
|
||||
// 开始上传
|
||||
document.getElementById('start-upload').addEventListener('click', async () => {
|
||||
const files = document.getElementById('file-input').files;
|
||||
if (files.length === 0) return;
|
||||
const uploadStatus = document.getElementById('upload-status');
|
||||
const progressBar = document.querySelector('#upload-progress div');
|
||||
const uploadProgressContainer = document.getElementById('upload-progress-container');
|
||||
uploadStatus.textContent = '正在上传...';
|
||||
uploadProgressContainer.classList.remove('hidden');
|
||||
try {
|
||||
let totalUploaded = 0;
|
||||
const totalSize = Array.from(files).reduce((sum, file) => sum + file.size, 0);
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
uploadStatus.textContent = `正在上传文件 ${i + 1}/${files.length}...`;
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append('FileParentUUID', GDrive.files.currentUUID);
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
// 添加进度节流控制
|
||||
let lastUpdateTime = 0;
|
||||
let lastLoaded = 0;
|
||||
await new Promise((resolve, reject) => {
|
||||
xhr.upload.onprogress = (event) => {
|
||||
if (event.lengthComputable) {
|
||||
const now = Date.now();
|
||||
// 每500毫秒(0.5秒)更新一次
|
||||
if (now - lastUpdateTime >= 500) {
|
||||
const currentFileProgress = event.loaded / event.total;
|
||||
var overallProgress = (totalUploaded + event.loaded) / totalSize;
|
||||
// 计算瞬时速度 (KB/s)
|
||||
const deltaLoaded = event.loaded - lastLoaded;
|
||||
const deltaTime = (now - lastUpdateTime) / 1000; // 秒
|
||||
const speed = deltaLoaded / deltaTime / 1024; // KB/s
|
||||
if (overallProgress > 1){
|
||||
overallProgress=1;
|
||||
}
|
||||
progressBar.style.width = `${overallProgress * 100}%`;
|
||||
console.log(`进度: ${(overallProgress * 100).toFixed(1)}% 速度: ${speed.toFixed(2)}KB/s`);
|
||||
// 更新最后记录值
|
||||
lastUpdateTime = now;
|
||||
lastLoaded = event.loaded;
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.onload = () => {
|
||||
// 强制触发最终进度更新(100%)
|
||||
progressBar.style.width = `${((totalUploaded + file.size) / totalSize) * 100}%`;
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
try {
|
||||
const response = JSON.parse(xhr.response);
|
||||
if (!response.code) {
|
||||
totalUploaded += file.size;
|
||||
resolve(xhr.response);
|
||||
GDrive.notifications.success("恭喜", `文件上传成功,文件名:${file.name}`);
|
||||
GDrive.files.refreshFileList();
|
||||
} else {
|
||||
GDrive.notifications.error("错误", `文件上传失败,文件名:${file.name},错误原因:${response.msg}`);
|
||||
}
|
||||
} catch {
|
||||
GDrive.notifications.error("错误", `文件上传失败: JSON格式化失败`)
|
||||
}
|
||||
} else {
|
||||
reject(new Error(`上传失败: ${xhr.statusText}`));
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = () => reject(new Error('上传过程中发生错误'));
|
||||
xhr.open('POST', '/API/UpdateFile.api', true);
|
||||
xhr.send(formData);
|
||||
});
|
||||
}
|
||||
// 上传完成
|
||||
uploadStatus.textContent = '上传完成!';
|
||||
// 动画效果和通知
|
||||
setTimeout(() => {
|
||||
const modal = document.getElementById('upload-modal');
|
||||
const modalContent = document.getElementById('upload-modal-content');
|
||||
modalContent.classList.remove('scale-100', 'opacity-100');
|
||||
modalContent.classList.add('scale-95', 'opacity-0');
|
||||
setTimeout(() => {
|
||||
modal.classList.add('hidden');
|
||||
uploadProgressContainer.classList.add('hidden');
|
||||
document.getElementById('file-input').value = '';
|
||||
progressBar.style.width = '0%';
|
||||
}, 300);
|
||||
}, 1000);
|
||||
} catch (error) {
|
||||
console.error('上传错误:', error);
|
||||
uploadStatus.textContent = '上传失败';
|
||||
GDrive.notifications.error('错误', '文件上传失败!');
|
||||
}
|
||||
});
|
||||
// 刷新
|
||||
document.querySelector('.btn-secondary:has(.fa-refresh)')
|
||||
.addEventListener('click', () => {
|
||||
GDrive.files.refreshFileList();
|
||||
});
|
||||
// 新建文件夹模态框
|
||||
document.querySelector('.btn-secondary:has(.fa-folder)')
|
||||
.addEventListener('click', () => {
|
||||
const modal = document.getElementById('new-folder-modal');
|
||||
const modalContent = document.getElementById('new-folder-modal-content');
|
||||
modal.classList.remove('hidden');
|
||||
setTimeout(() => {
|
||||
modalContent.classList.remove('scale-95', 'opacity-0');
|
||||
modalContent.classList.add('scale-100', 'opacity-100');
|
||||
}, 10);
|
||||
});
|
||||
// 关闭新建文件夹模态框
|
||||
document.getElementById('close-new-folder-modal')
|
||||
.addEventListener('click', () => {
|
||||
const modal = document.getElementById('new-folder-modal');
|
||||
const modalContent = document.getElementById('new-folder-modal-content');
|
||||
modalContent.classList.remove('scale-100', 'opacity-100');
|
||||
modalContent.classList.add('scale-95', 'opacity-0');
|
||||
setTimeout(() => {
|
||||
modal.classList.add('hidden');
|
||||
}, 300);
|
||||
});
|
||||
// 取消新建文件夹
|
||||
document.getElementById('cancel-new-folder')
|
||||
.addEventListener('click', () => {
|
||||
const modal = document.getElementById('new-folder-modal');
|
||||
const modalContent = document.getElementById('new-folder-modal-content');
|
||||
modalContent.classList.remove('scale-100', 'opacity-100');
|
||||
modalContent.classList.add('scale-95', 'opacity-0');
|
||||
setTimeout(() => {
|
||||
modal.classList.add('hidden');
|
||||
}, 300);
|
||||
});
|
||||
// 创建文件夹
|
||||
document.getElementById('create-folder')
|
||||
.addEventListener('click', () => {
|
||||
const folderName = document.getElementById('folder-name')
|
||||
.value.trim();
|
||||
if (folderName) {
|
||||
GDrive.files.createFolder(folderName).then(res => {
|
||||
// 关闭模态框
|
||||
const modal = document.getElementById('new-folder-modal');
|
||||
const modalContent = document.getElementById('new-folder-modal-content');
|
||||
modalContent.classList.remove('scale-100', 'opacity-100');
|
||||
modalContent.classList.add('scale-95', 'opacity-0');
|
||||
setTimeout(() => {
|
||||
modal.classList.add('hidden');
|
||||
document.getElementById('folder-name').value = '';
|
||||
if (res.code) {
|
||||
GDrive.notifications.error('错误', `创建文件夹失败,错误原因:${res.msg}`);
|
||||
} else {
|
||||
GDrive.notifications.success('成功', '创建文件夹成功');
|
||||
GDrive.files.up
|
||||
}
|
||||
}, 300);
|
||||
});
|
||||
// 模拟创建文件夹
|
||||
// const newFolder = GDrive.files.createFolder(folderName);
|
||||
} else {
|
||||
// 显示错误通知
|
||||
GDrive.notifications.error('错误', '请输入文件夹名称!');
|
||||
}
|
||||
});
|
||||
// 账户设置表单提交
|
||||
document.getElementById('account-settings-form')
|
||||
.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// 获取表单数据
|
||||
const firstName = document.getElementById('first-name')
|
||||
.value;
|
||||
const lastName = document.getElementById('last-name')
|
||||
.value;
|
||||
const email = document.getElementById('email')
|
||||
.value;
|
||||
const phone = document.getElementById('phone')
|
||||
.value;
|
||||
const bio = document.getElementById('bio')
|
||||
.value;
|
||||
|
||||
// 更新用户信息
|
||||
GDrive.user.updateInfo({
|
||||
name: `${firstName}${lastName}`,
|
||||
email,
|
||||
phone,
|
||||
bio
|
||||
});
|
||||
|
||||
// 显示成功通知
|
||||
GDrive.notifications.success('恭喜', '账户信息更新成功!');
|
||||
});
|
||||
|
||||
|
||||
// 文件夹点击事件委托
|
||||
document.getElementById('file-list-container')
|
||||
.addEventListener('click', (e) => {
|
||||
const folderItem = e.target.closest('.folder-item');
|
||||
if (folderItem) {
|
||||
const folderId = folderItem.getAttribute('data-folder-id');
|
||||
GDrive.files.navigateToFolder(folderId);
|
||||
}
|
||||
});
|
||||
|
||||
// 返回上一级按钮
|
||||
document.getElementById('navigate-up')
|
||||
.addEventListener('click', () => {
|
||||
GDrive.files.navigateUp();
|
||||
});
|
||||
|
||||
try {
|
||||
fetch("/API/info.api", {method: "GET"}).then(res => res.json()).then(res => {
|
||||
if (res.code) {
|
||||
GDrive.notifications.error('错误', '获取用户信息失败!E: 0');
|
||||
return;
|
||||
}
|
||||
GDrive.user.updateInfo(res)
|
||||
})
|
||||
} catch {
|
||||
GDrive.notifications.error('错误', '获取用户信息失败!E: 1');
|
||||
}
|
||||
|
||||
try {
|
||||
fetch("/API/GetVDiskTheStorageSpaceSize.api", {method: "GET"}).then(res => res.json()).then(res => {
|
||||
if (res.code) {
|
||||
GDrive.notifications.error('错误', '获取用户VDISK信息失败!E: 0');
|
||||
return;
|
||||
}
|
||||
GDrive.storage.updateUsage((res.UserVDiskUsed / (1024*1024*1024)).toFixed(2), (res.UserVDiskTotal / (1024*1024*1024)).toFixed(2))
|
||||
})
|
||||
} catch {
|
||||
GDrive.notifications.error('错误', '获取用户VDISK信息失败!E: 1');
|
||||
}
|
||||
|
||||
// 初始化文件列表
|
||||
GDrive.files.refreshFileList();
|
||||
|
||||
// 初始化图表
|
||||
initCharts();
|
||||
});
|
||||
|
||||
// 初始化图表
|
||||
function initCharts() {
|
||||
// 存储使用趋势图表
|
||||
const storageCtx = document.getElementById('storageChart')
|
||||
.getContext('2d');
|
||||
new Chart(storageCtx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['1月', '2月', '3月', '4月', '5月', '6月'],
|
||||
datasets: [{
|
||||
label: '已使用空间 (GB)',
|
||||
data: [1.2, 1.5, 1.8, 2.0, 2.2, 2.4],
|
||||
borderColor: '#165DFF',
|
||||
backgroundColor: 'rgba(22, 93, 255, 0.1)',
|
||||
tension: 0.3,
|
||||
fill: true
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
grid: {
|
||||
color: 'rgba(0, 0, 0, 0.05)'
|
||||
}
|
||||
},
|
||||
x: {
|
||||
grid: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// 文件类型分布图表
|
||||
const fileTypeCtx = document.getElementById('fileTypeChart')
|
||||
.getContext('2d');
|
||||
new Chart(fileTypeCtx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: ['图片', '文档', '视频', '其他'],
|
||||
datasets: [{
|
||||
data: [40000, 30000, 20000, 114514],
|
||||
backgroundColor: [
|
||||
'#165DFF',
|
||||
'#36D399',
|
||||
'#FBBD23',
|
||||
'#6B7280'
|
||||
],
|
||||
borderWidth: 0
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
padding: 20,
|
||||
usePointStyle: true,
|
||||
pointStyle: 'circle'
|
||||
}
|
||||
}
|
||||
},
|
||||
cutout: '70%'
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
tailwind.config = {
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#165DFF',
|
||||
secondary: '#6B7280',
|
||||
success: '#36D399',
|
||||
warning: '#FBBD23',
|
||||
danger: '#F87272',
|
||||
dark: {
|
||||
100: '#374151',
|
||||
200: '#1F2937',
|
||||
300: '#111827',
|
||||
400: '#030712'
|
||||
}
|
||||
},
|
||||
fontFamily: {
|
||||
inter: ['Inter', 'sans-serif'],
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,455 +0,0 @@
|
||||
<!-- 共享文件页面 -->
|
||||
<div id="shared-page" class="page hidden">
|
||||
<div class="mb-6">
|
||||
<h1 class="text-2xl md:text-3xl font-bold mb-2">共享文件</h1>
|
||||
<p class="text-gray-500 dark:text-gray-400">查看和管理与您共享的文件和文件夹</p>
|
||||
</div>
|
||||
|
||||
<!-- 共享文件列表 -->
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm overflow-hidden">
|
||||
<div class="p-4 border-b border-gray-200 dark:border-dark-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="font-semibold">与我共享</h3>
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索共享文件..." class="py-2 pl-8 pr-4 rounded-lg bg-gray-100 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200">
|
||||
<i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="bg-gray-50 dark:bg-dark-100">
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">名称</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">共享者</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">权限</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">大小</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">修改日期</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-dark-100">
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-folder text-primary mr-3"></i>
|
||||
<span class="font-medium">设计资源</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<img src="https://picsum.photos/200/200?random=3" alt="用户头像" class="w-6 h-6 rounded-full mr-2">
|
||||
<span>李四</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full bg-primary/10 text-primary">可编辑</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">42.5 MB</td>
|
||||
<td class="px-4 py-3">2023-05-18</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-1">
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="打开">
|
||||
<i class="fa fa-folder-open text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="更多">
|
||||
<i class="fa fa-ellipsis-v text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-file-pdf text-danger mr-3"></i>
|
||||
<span class="font-medium">市场分析.pdf</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<img src="https://picsum.photos/200/200?random=4" alt="用户头像" class="w-6 h-6 rounded-full mr-2">
|
||||
<span>王五</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full bg-secondary/10 text-secondary">只读</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">3.8 MB</td>
|
||||
<td class="px-4 py-3">2023-05-15</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-1">
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="打开">
|
||||
<i class="fa fa-folder-open text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="更多">
|
||||
<i class="fa fa-ellipsis-v text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-file-excel text-success mr-3"></i>
|
||||
<span class="font-medium">销售数据.xlsx</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<img src="https://picsum.photos/200/200?random=5" alt="用户头像" class="w-6 h-6 rounded-full mr-2">
|
||||
<span>赵六</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full bg-primary/10 text-primary">可编辑</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">5.2 MB</td>
|
||||
<td class="px-4 py-3">2023-05-12</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-1">
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="打开">
|
||||
<i class="fa fa-folder-open text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="更多">
|
||||
<i class="fa fa-ellipsis-v text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-folder text-primary mr-3"></i>
|
||||
<span class="font-medium">项目文档</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<img src="https://picsum.photos/200/200?random=6" alt="用户头像" class="w-6 h-6 rounded-full mr-2">
|
||||
<span>孙七</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full bg-primary/10 text-primary">可编辑</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">12.8 MB</td>
|
||||
<td class="px-4 py-3">2023-05-10</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-1">
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="打开">
|
||||
<i class="fa fa-folder-open text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="下载">
|
||||
<i class="fa fa-download text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
<button class="p-1.5 rounded-full hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors" title="更多">
|
||||
<i class="fa fa-ellipsis-v text-gray-500 dark:text-gray-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="p-4 border-t border-gray-200 dark:border-dark-100 flex justify-between items-center">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">显示 1-4 项,共 12 项</p>
|
||||
<div class="flex items-center space-x-1">
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg bg-primary text-white">1</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">2</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">3</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 回收站页面 -->
|
||||
<div id="trash-page" class="page hidden">
|
||||
<div class="mb-6">
|
||||
<h1 class="text-2xl md:text-3xl font-bold mb-2">回收站</h1>
|
||||
<p class="text-gray-500 dark:text-gray-400">管理已删除的文件和文件夹</p>
|
||||
</div>
|
||||
|
||||
<!-- 回收站操作 -->
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-4 mb-6">
|
||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-2">
|
||||
<button class="btn-primary">
|
||||
<i class="fa fa-refresh mr-2"></i>刷新
|
||||
</button>
|
||||
<button class="btn-secondary">
|
||||
<i class="fa fa-trash mr-2"></i>清空回收站
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索回收站文件..." class="py-2 pl-8 pr-4 rounded-lg bg-gray-100 dark:bg-dark-100 focus:outline-none focus:ring-2 focus:ring-primary/50 transition-all duration-200">
|
||||
<i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 回收站文件列表 -->
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="bg-gray-50 dark:bg-dark-100">
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">名称</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">大小</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">删除日期</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">原位置</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-dark-100">
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-file-pdf text-danger mr-3"></i>
|
||||
<span class="font-medium">旧版项目计划.pdf</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">2.5 MB</td>
|
||||
<td class="px-4 py-3">2023-05-18</td>
|
||||
<td class="px-4 py-3">文档/项目</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-2">
|
||||
<button class="btn-secondary text-sm px-3 py-1">
|
||||
<i class="fa fa-undo mr-1"></i>恢复
|
||||
</button>
|
||||
<button class="btn-secondary text-sm px-3 py-1 text-danger">
|
||||
<i class="fa fa-trash mr-1"></i>删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-folder text-primary mr-3"></i>
|
||||
<span class="font-medium">临时文件</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">18.7 MB</td>
|
||||
<td class="px-4 py-3">2023-05-15</td>
|
||||
<td class="px-4 py-3">主目录</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-2">
|
||||
<button class="btn-secondary text-sm px-3 py-1">
|
||||
<i class="fa fa-undo mr-1"></i>恢复
|
||||
</button>
|
||||
<button class="btn-secondary text-sm px-3 py-1 text-danger">
|
||||
<i class="fa fa-trash mr-1"></i>删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-file-image text-warning mr-3"></i>
|
||||
<span class="font-medium">旧版Logo设计.png</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">4.2 MB</td>
|
||||
<td class="px-4 py-3">2023-05-12</td>
|
||||
<td class="px-4 py-3">图片/设计</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-2">
|
||||
<button class="btn-secondary text-sm px-3 py-1">
|
||||
<i class="fa fa-undo mr-1"></i>恢复
|
||||
</button>
|
||||
<button class="btn-secondary text-sm px-3 py-1 text-danger">
|
||||
<i class="fa fa-trash mr-1"></i>删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50 dark:hover:bg-dark-100 transition-colors">
|
||||
<td class="px-4 py-3">
|
||||
<div class="flex items-center">
|
||||
<i class="fa fa-file-zip text-secondary mr-3"></i>
|
||||
<span class="font-medium">备份文件.zip</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3">12.5 MB</td>
|
||||
<td class="px-4 py-3">2023-05-10</td>
|
||||
<td class="px-4 py-3">文档/备份</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<div class="flex justify-end space-x-2">
|
||||
<button class="btn-secondary text-sm px-3 py-1">
|
||||
<i class="fa fa-undo mr-1"></i>恢复
|
||||
</button>
|
||||
<button class="btn-secondary text-sm px-3 py-1 text-danger">
|
||||
<i class="fa fa-trash mr-1"></i>删除
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="p-4 border-t border-gray-200 dark:border-dark-100 flex justify-between items-center">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">显示 1-4 项,共 18 项</p>
|
||||
<div class="flex items-center space-x-1">
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg bg-primary text-white">1</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">2</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">3</button>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded-lg border border-gray-300 dark:border-dark-100 hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- 存储 --
|
||||
<div class="mb-6">
|
||||
<h2 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3">存储</h2>
|
||||
<ul class="space-y-1">
|
||||
<li>
|
||||
<a href="#images" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-image w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>图片</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#videos" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-film w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>视频</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#documents" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-file-text w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>文档</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#music" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-music w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>音乐</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!--li>
|
||||
<a href="#shared" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-share-alt w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>共享文件</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#trash" class="flex items-center space-x-3 px-3 py-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-dark-100 transition-colors">
|
||||
<i class="fa fa-trash w-5 text-center text-gray-500 dark:text-gray-400"></i>
|
||||
<span>回收站</span>
|
||||
</a>
|
||||
</li-->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- 最近活动 -->
|
||||
<div class="bg-white dark:bg-dark-200 rounded-xl shadow-sm p-5 mb-6">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="font-semibold">最近活动</h3>
|
||||
<a href="#" class="text-primary hover:underline text-sm">查看全部</a>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-start space-x-4">
|
||||
<div class="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary flex-shrink-0">
|
||||
<i class="fa fa-upload"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="font-medium">上传了文档</p>
|
||||
<span class="text-sm text-gray-500 dark:text-gray-400">10分钟前</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">project_report.pdf</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4">
|
||||
<div class="w-10 h-10 rounded-full bg-success/10 flex items-center justify-center text-success flex-shrink-0">
|
||||
<i class="fa fa-share-alt"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="font-medium">共享了文件夹</p>
|
||||
<span class="text-sm text-gray-500 dark:text-gray-400">1小时前</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">Design Resources</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4">
|
||||
<div class="w-10 h-10 rounded-full bg-warning/10 flex items-center justify-center text-warning flex-shrink-0">
|
||||
<i class="fa fa-download"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="font-medium">下载了文件</p>
|
||||
<span class="text-sm text-gray-500 dark:text-gray-400">3小时前</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">marketing_plan.xlsx</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4">
|
||||
<div class="w-10 h-10 rounded-full bg-danger/10 flex items-center justify-center text-danger flex-shrink-0">
|
||||
<i class="fa fa-trash"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="font-medium">删除了文件</p>
|
||||
<span class="text-sm text-gray-500 dark:text-gray-400">昨天</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">old_designs.zip</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,521 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>银河锋锐历史网页托管 - history.gvsds.com</title>
|
||||
<link href="https://cdn.gvsds.com/font-awesome/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.gvsds.com/font-awesome/css/font-awesome.min.css" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #1a237e;
|
||||
--secondary-color: #c62828;
|
||||
--accent-color: #d4af37;
|
||||
--dark-bg: #0a0f1e;
|
||||
--darker-bg: #050812;
|
||||
--light-text: #f5f5f5;
|
||||
--medium-text: #b0bec5;
|
||||
--border-color: #37474f;
|
||||
--transition: all 0.4s ease;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: var(--light-text);
|
||||
background-color: var(--dark-bg);
|
||||
background-image: url('/page.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 英雄区域 - 全屏设计 */
|
||||
.hero {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.9));
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
max-width: 900px;
|
||||
padding: 0 20px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--light-text);
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
|
||||
letter-spacing: 1px;
|
||||
animation: fadeInUp 1s ease-out;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.5rem;
|
||||
color: var(--medium-text);
|
||||
margin-bottom: 2rem;
|
||||
animation: fadeInUp 1s ease-out 0.3s both;
|
||||
}
|
||||
|
||||
.hero-btn {
|
||||
display: inline-block;
|
||||
background-color: var(--secondary-color);
|
||||
color: white;
|
||||
padding: 12px 30px;
|
||||
font-size: 1rem;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
transition: var(--transition);
|
||||
animation: fadeInUp 1s ease-out 0.6s both;
|
||||
}
|
||||
|
||||
.hero-btn:hover {
|
||||
background-color: #9a0000;
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 5px 15px rgba(198, 40, 40, 0.3);
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
.section {
|
||||
padding: 8rem 2rem;
|
||||
position: relative;
|
||||
background: rgba(10, 15, 30, 0.7);
|
||||
}
|
||||
|
||||
.section-dark {
|
||||
background-color: rgba(5, 8, 18, 0.7);
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.section-light {
|
||||
background-color: rgba(10, 15, 30, 0.7);
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--light-text);
|
||||
margin-bottom: 2rem;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section-title::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 80px;
|
||||
height: 3px;
|
||||
background-color: var(--secondary-color);
|
||||
margin: 0.5rem auto 0;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: 1.2rem;
|
||||
color: var(--medium-text);
|
||||
text-align: center;
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
.content-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 3rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.content-card {
|
||||
background-color: rgba(10, 15, 30, 0.5);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
padding: 2rem;
|
||||
transition: var(--transition);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 5px;
|
||||
height: 100%;
|
||||
background-color: var(--secondary-color);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.content-card:hover {
|
||||
transform: translateY(-10px);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
font-size: 2rem;
|
||||
color: var(--accent-color);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--light-text);
|
||||
}
|
||||
|
||||
.card-text {
|
||||
color: var(--medium-text);
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.card-hover-text {
|
||||
color: var(--light-text);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.5s ease;
|
||||
}
|
||||
|
||||
.content-card:hover .card-hover-text {
|
||||
max-height: 300px;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
/* 提交区域 */
|
||||
.submission-area {
|
||||
background: linear-gradient(rgba(10, 15, 30, 0.8), rgba(10, 15, 30, 0.8)),
|
||||
url('https://picsum.photos/id/1015/1920/1080') no-repeat center center/cover;
|
||||
background-attachment: fixed;
|
||||
padding: 10rem 2rem;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.submission-content {
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.submission-title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--light-text);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.submission-text {
|
||||
font-size: 1.1rem;
|
||||
color: var(--medium-text);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.email-link {
|
||||
color: var(--secondary-color);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: var(--transition);
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.email-link:hover {
|
||||
color: var(--accent-color);
|
||||
transform: translateX(5px);
|
||||
}
|
||||
|
||||
.email-link::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background-color: var(--accent-color);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.email-link:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 历史意义部分 */
|
||||
.history-significance {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.significance-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 2rem 0;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.significance-icon {
|
||||
font-size: 3rem;
|
||||
color: var(--accent-color);
|
||||
margin-bottom: 1rem;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.significance-item:hover .significance-icon {
|
||||
transform: rotate(10deg) scale(1.1);
|
||||
}
|
||||
|
||||
.significance-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--light-text);
|
||||
}
|
||||
|
||||
.significance-text {
|
||||
color: var(--medium-text);
|
||||
}
|
||||
|
||||
/* 页脚(简化版,仅包含必要信息) */
|
||||
.simplified-footer {
|
||||
background-color: var(--darker-bg);
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
color: var(--medium-text);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* 动画 */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.hero-title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.submission-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 5rem 1.5rem;
|
||||
}
|
||||
|
||||
.submission-area {
|
||||
padding: 7rem 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.hero-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.submission-title {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 4rem 1rem;
|
||||
}
|
||||
|
||||
.submission-area {
|
||||
padding: 6rem 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 英雄区域 - 全屏 -->
|
||||
<section class="hero">
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title">银河锋锐历史网页托管</h1>
|
||||
<p class="hero-subtitle">保存时光印记,传承历史记忆<br>聚焦近现代中国红色历史,兼收世界各角落的历史碎片</p>
|
||||
<a href="#about" class="hero-btn">了解更多 <i class="fas fa-arrow-down ml-2"></i></a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 关于托管服务 -->
|
||||
<section id="about" class="section section-light">
|
||||
<div class="container">
|
||||
<h2 class="section-title">关于历史网页托管</h2>
|
||||
<p class="section-subtitle">这里是历史记忆的数字档案馆,是时光碎片的汇聚之地</p>
|
||||
|
||||
<div class="content-grid">
|
||||
<div class="content-card">
|
||||
<div class="card-icon">
|
||||
<i class="fas fa-book-open"></i>
|
||||
</div>
|
||||
<h3 class="card-title">红色历史聚焦</h3>
|
||||
<p class="card-text">重点托管近现代中国红色历史相关网页</p>
|
||||
<div class="card-hover-text">
|
||||
包含革命战争时期的文献资料、根据地建设史料、重要会议记录、先烈手稿与影像等。我们致力于构建数字化的红色记忆库,让井冈山精神、长征精神、延安精神等通过网页载体永续传承。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="card-icon">
|
||||
<i class="fas fa-globe"></i>
|
||||
</div>
|
||||
<h3 class="card-title">世界历史碎片</h3>
|
||||
<p class="card-text">接收来自世界各地、各时期的历史网页托管</p>
|
||||
<div class="card-hover-text">
|
||||
从两河流域的楔形文字泥板数字化档案,到二战时期欧洲抵抗运动的秘密通讯记录;从日本明治维新的政论报纸扫描件,到非洲独立运动的珍贵影像网页——任何地域的历史切片都能在此找到寄存之处。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="card-icon">
|
||||
<i class="fas fa-archive"></i>
|
||||
</div>
|
||||
<h3 class="card-title">数字存档技术</h3>
|
||||
<p class="card-text">提供专业的网页存档技术,确保历史内容保存</p>
|
||||
<div class="card-hover-text">
|
||||
采用Memento协议进行网页捕获,保留JavaScript、CSS等动态元素,同时生成WARC格式存档。针对历史网页特有的字体、格式问题,开发了兼容1990年代至今的浏览器渲染引擎模拟系统,确保内容原貌呈现。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="card-icon">
|
||||
<i class="fas fa-heart"></i>
|
||||
</div>
|
||||
<h3 class="card-title">非系统梳理模式</h3>
|
||||
<p class="card-text">平台不做系统历史梳理,内容呈现更具随机性</p>
|
||||
<div class="card-hover-text">
|
||||
区别于传统档案馆的线性叙事,我们保留历史的碎片化特质:可能上一页是1950年代上海纺织厂的工资单扫描件,下一页就是1980年代深圳蛇口工业区的招商广告。这种「无序性」恰是历史原生状态的数字镜像。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 历史意义 -->
|
||||
<section class="section section-dark">
|
||||
<div class="container">
|
||||
<h2 class="section-title">历史的意义</h2>
|
||||
<p class="section-subtitle">每一段历史都值得被铭记,每一个印记都值得被保存</p>
|
||||
|
||||
<div class="history-significance">
|
||||
<div class="significance-item">
|
||||
<div class="significance-icon">
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
</div>
|
||||
<h3 class="significance-title">传承记忆</h3>
|
||||
<p class="significance-text">将散落的历史记忆汇聚,让过去的声音在数字时代继续回响</p>
|
||||
</div>
|
||||
|
||||
<div class="significance-item">
|
||||
<div class="significance-icon">
|
||||
<i class="fas fa-link"></i>
|
||||
</div>
|
||||
<h3 class="significance-title">连接过去与现在</h3>
|
||||
<p class="significance-text">历史不是割裂的片段,而是连接过去与现在的桥梁</p>
|
||||
</div>
|
||||
|
||||
<div class="significance-item">
|
||||
<div class="significance-icon">
|
||||
<i class="fas fa-users"></i>
|
||||
</div>
|
||||
<h3 class="significance-title">集体记忆</h3>
|
||||
<p class="significance-text">无论是个人回忆还是群体历史,都是构成集体记忆的重要部分</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 提交托管区域 -->
|
||||
<section class="submission-area">
|
||||
<div class="submission-content">
|
||||
<h2 class="submission-title">提交历史网页托管</h2>
|
||||
<p class="submission-text">如果您有需要托管的历史网页或相关内容,请通过以下方式联系我们:</p>
|
||||
<p class="submission-text">邮箱:<a href="mailto:support@gvsds.com" class="email-link">support@gvsds.com</a></p>
|
||||
<p class="submission-text">请在邮件中说明您的来意、托管内容的简要介绍以及相关文件或链接。</p>
|
||||
<p class="submission-text">我们将尽快与您联系,评估并处理您的托管请求。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 简化页脚 -->
|
||||
<div class="simplified-footer">
|
||||
<p class="footer-text">银河锋锐软件开发工作室 | history.gvsds.com | 历史网页托管平台</p>
|
||||
<p class="footer-text mt-1">保存历史记忆,传承文化根脉 | 2025</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 平滑滚动效果
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
document.querySelector(this.getAttribute('href')).scrollIntoView({
|
||||
behavior: 'smooth'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 滚动时添加动画效果
|
||||
window.addEventListener('scroll', function() {
|
||||
const elements = document.querySelectorAll('.content-card, .significance-item');
|
||||
elements.forEach(element => {
|
||||
const elementPosition = element.getBoundingClientRect().top;
|
||||
const screenPosition = window.innerHeight / 1.3;
|
||||
|
||||
if (elementPosition < screenPosition) {
|
||||
element.style.opacity = '1';
|
||||
element.style.transform = 'translateY(0)';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.
|
||||
|
Before Width: | Height: | Size: 570 KiB After Width: | Height: | Size: 570 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |