Init
This commit is contained in:
+156
@@ -0,0 +1,156 @@
|
|||||||
|
media/
|
||||||
|
logs/
|
||||||
|
.idea
|
||||||
|
static/
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Python template
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
*.env
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test.pdf / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# Project
|
||||||
|
.vscode
|
||||||
|
.DS_Store
|
||||||
|
for_test.py
|
||||||
|
.html
|
||||||
|
/evaluate/temp.py
|
||||||
|
/evaluation/back.json
|
||||||
|
.env*
|
||||||
|
.backup/
|
||||||
|
/cloc-1.64.exe
|
||||||
|
*.db
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
FROM python:3.9.5
|
||||||
|
LABEL author="Lan"
|
||||||
|
LABEL email="vast@tom.com"
|
||||||
|
LABEL version="1.0"
|
||||||
|
|
||||||
|
|
||||||
|
COPY . /app
|
||||||
|
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||||
|
RUN echo 'Asia/Shanghai' >/etc/timezone
|
||||||
|
WORKDIR /app
|
||||||
|
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
|
||||||
|
EXPOSE 123456
|
||||||
|
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "12345"]
|
||||||
BIN
Binary file not shown.
+23
@@ -0,0 +1,23 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
from sqlalchemy import create_engine, DateTime
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy import Boolean, Column, Integer, String
|
||||||
|
|
||||||
|
engine = create_engine('sqlite:///database.db', connect_args={"check_same_thread": False})
|
||||||
|
Base = declarative_base()
|
||||||
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||||
|
|
||||||
|
|
||||||
|
class Codes(Base):
|
||||||
|
__tablename__ = 'codes'
|
||||||
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
|
code = Column(String(10), unique=True, index=True)
|
||||||
|
key = Column(String(30), unique=True, index=True)
|
||||||
|
name = Column(String(500))
|
||||||
|
size = Column(Integer)
|
||||||
|
type = Column(String(20))
|
||||||
|
text = Column(String(500))
|
||||||
|
used = Column(Boolean, default=False)
|
||||||
|
use_time = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now)
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from fastapi import FastAPI, Depends, UploadFile, Form, File
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from starlette.requests import Request
|
||||||
|
from starlette.responses import HTMLResponse
|
||||||
|
import random
|
||||||
|
|
||||||
|
from starlette.staticfiles import StaticFiles
|
||||||
|
|
||||||
|
import database
|
||||||
|
from database import engine, SessionLocal, Base
|
||||||
|
|
||||||
|
Base.metadata.create_all(bind=engine)
|
||||||
|
app = FastAPI()
|
||||||
|
if not os.path.exists('./static'):
|
||||||
|
os.makedirs('./static')
|
||||||
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
|
# 过期时间
|
||||||
|
exp_hour = 24
|
||||||
|
# 允许错误次数
|
||||||
|
error_count = 5
|
||||||
|
# 禁止分钟数
|
||||||
|
error_minute = 60
|
||||||
|
|
||||||
|
error_ip_count = {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_db():
|
||||||
|
db = SessionLocal()
|
||||||
|
try:
|
||||||
|
yield db
|
||||||
|
finally:
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
|
def get_code(db: Session = Depends(get_db)):
|
||||||
|
code = random.randint(10000, 99999)
|
||||||
|
while db.query(database.Codes).filter(database.Codes.code == code).first():
|
||||||
|
code = random.randint(10000, 99999)
|
||||||
|
return str(code)
|
||||||
|
|
||||||
|
|
||||||
|
def get_file_name(key, ext, file):
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
path = f'./static/upload/{now.year}/{now.month}/{now.day}/'
|
||||||
|
name = f'{key}.{ext}'
|
||||||
|
if not os.path.exists(path):
|
||||||
|
os.makedirs(path)
|
||||||
|
file = file.file.read()
|
||||||
|
with open(f'{os.path.join(path, name)}', 'wb') as f:
|
||||||
|
f.write(file)
|
||||||
|
return key, len(file), path[1:] + name
|
||||||
|
|
||||||
|
|
||||||
|
@app.get('/')
|
||||||
|
async def index():
|
||||||
|
with open('templates/index.html', 'r') as f:
|
||||||
|
return HTMLResponse(f.read())
|
||||||
|
|
||||||
|
|
||||||
|
@app.post('/')
|
||||||
|
async def index(request: Request, code: str, db: Session = Depends(get_db)):
|
||||||
|
info = db.query(database.Codes).filter(database.Codes.code == code).first()
|
||||||
|
error = error_ip_count.get(request.client.host, {'count': 0, 'time': datetime.datetime.now()})
|
||||||
|
if error['count'] > error_count:
|
||||||
|
if datetime.datetime.now() - error['time'] < datetime.timedelta(minutes=error_minute):
|
||||||
|
return {'code': 404, 'msg': '请求过于频繁,请稍后再试'}
|
||||||
|
else:
|
||||||
|
error['count'] = 0
|
||||||
|
else:
|
||||||
|
if not info:
|
||||||
|
error['count'] += 1
|
||||||
|
error_ip_count[request.client.host] = error
|
||||||
|
return {'code': 404, 'msg': f'取件码错误,错误5次将被禁止10分钟'}
|
||||||
|
else:
|
||||||
|
return {'code': 200, 'msg': '取件成功,请点击库查看', 'data': info}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get('/share')
|
||||||
|
async def share():
|
||||||
|
with open('templates/upload.html', 'r') as f:
|
||||||
|
return HTMLResponse(f.read())
|
||||||
|
|
||||||
|
|
||||||
|
@app.post('/share')
|
||||||
|
async def share(text: str = Form(default=None), file: UploadFile = File(default=None), db: Session = Depends(get_db)):
|
||||||
|
cutoff_time = datetime.datetime.now() - datetime.timedelta(hours=exp_hour)
|
||||||
|
db.query(database.Codes).filter(database.Codes.use_time < cutoff_time).delete()
|
||||||
|
db.commit()
|
||||||
|
code = get_code(db)
|
||||||
|
if text:
|
||||||
|
info = database.Codes(
|
||||||
|
code=code,
|
||||||
|
text=text,
|
||||||
|
type='text/plain',
|
||||||
|
key=uuid.uuid4().hex,
|
||||||
|
size=len(text),
|
||||||
|
used=True,
|
||||||
|
name='分享文本'
|
||||||
|
)
|
||||||
|
db.add(info)
|
||||||
|
db.commit()
|
||||||
|
return {'code': 200, 'msg': '上传成功,请点击文件库查看',
|
||||||
|
'data': {'code': code, 'name': '分享文本', 'text': text}}
|
||||||
|
elif file:
|
||||||
|
key, size, full_path = get_file_name(uuid.uuid4().hex, file.filename.split('.')[-1], file)
|
||||||
|
info = database.Codes(
|
||||||
|
code=code,
|
||||||
|
text=full_path,
|
||||||
|
type=file.content_type,
|
||||||
|
key=key,
|
||||||
|
size=size,
|
||||||
|
used=True,
|
||||||
|
name=file.filename
|
||||||
|
)
|
||||||
|
db.add(info)
|
||||||
|
db.commit()
|
||||||
|
return {'code': 200, 'msg': '上传成功,请点击文件库查看',
|
||||||
|
'data': {'code': code, 'name': file.filename, 'text': full_path}}
|
||||||
|
else:
|
||||||
|
return {'code': 422, 'msg': '参数错误', 'data': []}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# 口令传送箱
|
||||||
|
|
||||||
|
## 主要特色
|
||||||
|
|
||||||
|
- [x] 拖拽,复制粘贴上传
|
||||||
|
- [x] 文件口令传输
|
||||||
|
- [x] 分享文件:多种上传方式供你选择
|
||||||
|
- [x] 分享文本:直接复制粘贴直接上传
|
||||||
|
- [x] 防爆破:错误五次拉黑十分钟
|
||||||
|
- [x] 完全匿名:不记录任何信息
|
||||||
|
- [x] 无需注册:无需注册,无需登录
|
||||||
|
- [x] Sqlite3数据库:无需安装数据库
|
||||||
|
|
||||||
|
## 部署方式
|
||||||
|
|
||||||
|
### 服务端部署
|
||||||
|
|
||||||
|
1. 安装Python3
|
||||||
|
2. 拉取代码,解压缩
|
||||||
|
3. 安装依赖包:`pip install -r requirements.txt`
|
||||||
|
4. 运行` uvicorn main:app --host 0.0.0.0 --port 12345`
|
||||||
|
5. 然后你自己看怎么进程守护吧
|
||||||
|
|
||||||
|
### 宝塔部署
|
||||||
|
|
||||||
|
1. 安装宝塔Python Manager
|
||||||
|
2. 然后你自己看着填吧
|
||||||
|
|
||||||
|
### Docker部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build --file Dockerfile --tag filecodebox .
|
||||||
|
docker run -d -p 12345:12345 --name filecodebox filecodebox
|
||||||
|
```
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
anyio==3.6.2
|
||||||
|
click==8.1.3
|
||||||
|
fastapi==0.88.0
|
||||||
|
h11==0.14.0
|
||||||
|
httptools==0.5.0
|
||||||
|
idna==3.4
|
||||||
|
pydantic==1.10.2
|
||||||
|
python-dotenv==0.21.0
|
||||||
|
python-multipart==0.0.5
|
||||||
|
PyYAML==6.0
|
||||||
|
six==1.16.0
|
||||||
|
sniffio==1.3.0
|
||||||
|
SQLAlchemy==1.4.44
|
||||||
|
starlette==0.22.0
|
||||||
|
typing_extensions==4.4.0
|
||||||
|
uvicorn==0.20.0
|
||||||
|
uvloop==0.17.0
|
||||||
|
watchfiles==0.18.1
|
||||||
|
websockets==10.4
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||||||
|
<!-- 引入组件库 -->
|
||||||
|
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||||||
|
<title>取件箱-口令传送箱</title>
|
||||||
|
<style>
|
||||||
|
.qu .el-button {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
margin: 0.2rem;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qu .el-input__inner {
|
||||||
|
height: 100px;
|
||||||
|
margin: 1rem 0;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app" style="text-align: center;">
|
||||||
|
<el-row v-if="tool==0" class="qu" style="width:400px;margin: auto">
|
||||||
|
<el-card style="padding-bottom: 1rem">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-input autofocus @input="inputing" clearable v-model:value="code" maxlength="5"
|
||||||
|
:disabled="inout_disable"
|
||||||
|
placeholder="请输入取件码"></el-input>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('1')">1</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('2')">2</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('3')">3</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('4')">4</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('5')">5</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('6')">6</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('7')">7</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('8')">8</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('9')">9</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="tool=1">寄</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="inputNumber('0')">0</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span=8>
|
||||||
|
<el-button @click="quDrawer=true">取</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-card>
|
||||||
|
</el-row>
|
||||||
|
<el-row v-else style="width:400px;margin: auto">
|
||||||
|
<el-col :span="24" style="margin: 1rem 0">
|
||||||
|
<el-card>
|
||||||
|
<el-upload
|
||||||
|
drag
|
||||||
|
action="/share"
|
||||||
|
multiple
|
||||||
|
:on-success="successUpload"
|
||||||
|
>
|
||||||
|
<i class="el-icon-upload"></i>
|
||||||
|
<div class="el-upload__text">将文件拖、粘贴到此处,或<em>点击上传</em>,24h后删除</div>
|
||||||
|
<div class="el-upload__tip" slot="tip">
|
||||||
|
<el-button @click="tool=0">去取件</el-button>
|
||||||
|
<el-button @click="cunDrawer=true">文件箱</el-button>
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<div style="text-align: center; margin-top: 1rem;color: #606266">
|
||||||
|
<span> By: <a style="text-decoration: none;color: #606266" target="_blank"
|
||||||
|
href="https://github.com/vastsa/FileShare">Lan</a></span>
|
||||||
|
</div>
|
||||||
|
<el-drawer
|
||||||
|
title="文件库"
|
||||||
|
:visible.sync="quDrawer"
|
||||||
|
:direction="direction"
|
||||||
|
size="50%"
|
||||||
|
>
|
||||||
|
<el-card v-for="(file,index) in files" :key="index" class="box-card">
|
||||||
|
<div style="cursor: pointer;text-align: left">
|
||||||
|
<div>取件码:${ file.code }</div>
|
||||||
|
<div>文件名:${ file.name }</div>
|
||||||
|
<div v-if="file.name==='分享文本'">
|
||||||
|
<span>内 容:${ file.text }</span>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<span>链 接:</span>
|
||||||
|
<a :href="file.text" target="_blank"
|
||||||
|
style="color: #1E9FFF;text-underline: none"
|
||||||
|
type="primary">点击下载</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<el-empty v-if="files.length===0" description="请输入取件码,收取文件"></el-empty>
|
||||||
|
</el-drawer>
|
||||||
|
<el-drawer
|
||||||
|
title="文件库"
|
||||||
|
:visible.sync="cunDrawer"
|
||||||
|
direction="btt"
|
||||||
|
size="50%">
|
||||||
|
<el-card>
|
||||||
|
<el-empty v-if="files.length===0" description="请上传文件"></el-empty>
|
||||||
|
<el-card style="margin-top: 0.2rem" v-for="file in files" :key="file.code">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" style="line-height: 45px">
|
||||||
|
${ file.name }
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
取件码:<h1 style="margin: 0;display: inline">${ file.code }</h1>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</el-card>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<!-- import Vue before Element -->
|
||||||
|
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
|
||||||
|
<!-- import JavaScript -->
|
||||||
|
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||||||
|
<script src="//unpkg.com/axios/dist/axios.min.js"></script>
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
delimiters: ['${', '}'],
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
code: '',
|
||||||
|
inout_disable: false,
|
||||||
|
files: [],
|
||||||
|
quDrawer: false,
|
||||||
|
cunDrawer: false,
|
||||||
|
direction: 'btt',
|
||||||
|
tool: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
this.code = window.location.search.substring('code=='.length)
|
||||||
|
if (this.code) {
|
||||||
|
this.get_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
document.addEventListener('paste', function (event) {
|
||||||
|
if (that.tool === 1) {
|
||||||
|
const items = event.clipboardData && event.clipboardData.items;
|
||||||
|
if (items && items.length) {
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
if (items[i].kind === 'string') {
|
||||||
|
if (items[i].type.match(/^text\/plain/)) {
|
||||||
|
const FileData = new FormData();
|
||||||
|
that.$message('剪切板文字正在上传,请稍等');
|
||||||
|
items[i].getAsString(function (str) {
|
||||||
|
FileData.append('text', str);
|
||||||
|
axios.post('/share', FileData)
|
||||||
|
.then(function (response) {
|
||||||
|
that.$message({'message': response.data.msg, 'type': 'success'});
|
||||||
|
that.files.push(response.data.data)
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
that.$message({'message': error.data.msg, 'type': 'error'});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const file = items[i].getAsFile();
|
||||||
|
that.$message('剪切板文件正在上传,请稍等');
|
||||||
|
const FileData = new FormData();
|
||||||
|
FileData.append('file', file || '');
|
||||||
|
axios.post('/share', FileData).then(async res => {
|
||||||
|
that.files.push(res.data.data);
|
||||||
|
that.$message({'message': res.data.msg, 'type': 'success'});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
inputing: function (value) {
|
||||||
|
if (value.length === 5) {
|
||||||
|
this.inout_disable = true;
|
||||||
|
this.get_file();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get_file: function () {
|
||||||
|
const that = this;
|
||||||
|
axios.post('?code=' + this.code).then(function (response) {
|
||||||
|
if (response.data.code === 404) {
|
||||||
|
that.$message({
|
||||||
|
message: response.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
that.files.push(response.data.data);
|
||||||
|
that.$message({
|
||||||
|
message: response.data.msg,
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.code = '';
|
||||||
|
that.inout_disable = false
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
inputNumber: function (number) {
|
||||||
|
if (number === 'C') {
|
||||||
|
this.code = '';
|
||||||
|
} else if (number === 'X') {
|
||||||
|
this.code = this.code.substring(0, this.code.length - 1);
|
||||||
|
} else {
|
||||||
|
if (this.code.length < 5) {
|
||||||
|
this.code += number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.code.length === 5) {
|
||||||
|
this.inout_disable = true
|
||||||
|
this.get_file()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
successUpload(response, file, fileList) {
|
||||||
|
this.files.push(response.data[0])
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||||||
|
<!-- 引入组件库 -->
|
||||||
|
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||||||
|
<title>寄件箱-口令传送箱</title>
|
||||||
|
<style>
|
||||||
|
.el-upload-dragger {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app" style="text-align: center;height: 100vh">
|
||||||
|
<el-row style="width:400px;margin: auto">
|
||||||
|
<el-col :span="24" style="margin: 1rem 0">
|
||||||
|
<el-card>
|
||||||
|
<el-upload
|
||||||
|
drag
|
||||||
|
action=""
|
||||||
|
multiple
|
||||||
|
:on-success="successUpload"
|
||||||
|
>
|
||||||
|
<i class="el-icon-upload"></i>
|
||||||
|
<div class="el-upload__text">将文件拖、粘贴到此处,或<em>点击上传</em>,24h后删除</div>
|
||||||
|
<div class="el-upload__tip" slot="tip">
|
||||||
|
<a href="/">
|
||||||
|
<el-button>去取件</el-button>
|
||||||
|
</a>
|
||||||
|
<el-button @click="drawer=true">文件箱</el-button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-drawer
|
||||||
|
title="文件库"
|
||||||
|
:visible.sync="drawer"
|
||||||
|
direction="btt"
|
||||||
|
size="50%">
|
||||||
|
<el-card>
|
||||||
|
<el-empty v-if="files.length===0" description="请上传文件"></el-empty>
|
||||||
|
<el-card style="margin-top: 0.2rem" v-for="file in files" :key="file.code">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24" style="line-height: 45px">
|
||||||
|
${ file.name }
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
取件码:<h1 style="margin: 0;display: inline">${ file.code }</h1>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</el-card>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<!-- import Vue before Element -->
|
||||||
|
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
|
||||||
|
<!-- import JavaScript -->
|
||||||
|
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||||||
|
<script src="//unpkg.com/axios/dist/axios.min.js"></script>
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
delimiters: ['${', '}'],
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
files: [],
|
||||||
|
drawer: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
const that = this
|
||||||
|
document.addEventListener('paste', function () {
|
||||||
|
const items = event.clipboardData && event.clipboardData.items;
|
||||||
|
if (items && items.length) {
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
if (items[i].kind === 'string') {
|
||||||
|
if (items[i].type.match(/^text\/plain/)) {
|
||||||
|
const FileData = new FormData();
|
||||||
|
that.$message('剪切板文字正在上传,请稍等');
|
||||||
|
items[i].getAsString(function (str) {
|
||||||
|
FileData.append('text', str);
|
||||||
|
axios.post('', FileData)
|
||||||
|
.then(function (response) {
|
||||||
|
that.$message({'message': response.data.msg, 'type': 'success'});
|
||||||
|
that.files.push(response.data.data)
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
that.$message({'message': error.data.msg, 'type': 'error'});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const file = items[i].getAsFile();
|
||||||
|
that.$message('剪切板文件正在上传,请稍等');
|
||||||
|
const FileData = new FormData();
|
||||||
|
FileData.append('file', file || '');
|
||||||
|
axios.post('', FileData).then(async res => {
|
||||||
|
that.files.push(res.data.data);
|
||||||
|
that.$message({'message': res.data.msg, 'type': 'success'});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
successUpload(response, file, fileList) {
|
||||||
|
this.files.push(response.data[0])
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user