Compare commits
18 Commits
91c7a7c562
...
main
Author | SHA1 | Date | |
---|---|---|---|
d514e82e9b | |||
0c602a8ccd | |||
559af65260 | |||
7e5eaa82e3 | |||
b1c336e43c | |||
1f2c23c157 | |||
b88b78a946 | |||
d0faf8b8b2 | |||
d663087c41 | |||
6d01222ce4 | |||
d2965c64e1 | |||
232c7da723 | |||
446210ea4c | |||
cf301559de | |||
78d13ece36 | |||
57ade9911d | |||
330f8d3b8c | |||
4616650184 |
@@ -18,7 +18,6 @@ class Inventory(db.Model):
|
||||
tag = db.Column(db.Text)
|
||||
amount = db.Column(db.Integer)
|
||||
checked = db.Column(db.Boolean, default=False)
|
||||
name = db.Column(db.Text)
|
||||
# mtime = db.Column(db.Date)
|
||||
|
||||
|
||||
|
@@ -1,14 +1,17 @@
|
||||
body {
|
||||
background-color: azure;
|
||||
}
|
||||
main {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
font-size: 25px;
|
||||
font-size: 18px;
|
||||
}
|
||||
input {
|
||||
width: 4ch;
|
||||
text-align: center;
|
||||
}
|
||||
hr {
|
||||
width: 450px;
|
||||
width: 350px;
|
||||
height: 3px;
|
||||
}
|
||||
.grail{
|
||||
@@ -20,7 +23,7 @@ hr {
|
||||
align-items: center;
|
||||
}
|
||||
.handler {
|
||||
width: 450px;
|
||||
width: 350px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: space-between;
|
||||
@@ -29,8 +32,8 @@ hr {
|
||||
align-items: center;
|
||||
}
|
||||
button, input {
|
||||
font-size: 25px;
|
||||
font-size: 18px;
|
||||
}
|
||||
form {
|
||||
width:450px;
|
||||
width:350px;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 894 B |
@@ -16,8 +16,8 @@ function checknext() {
|
||||
var id = parseInt(idelement.innerText, 10); // 第二个参数10表示解析的基数,这里是十进制
|
||||
var tagelement = document.getElementById("inventory-tag");
|
||||
var tag = tagelement.innerText;
|
||||
var name = "A"
|
||||
var msg = document.getElementById("flash-msg");
|
||||
var location = document.getElementById("inventory-location");
|
||||
// var params = new URLSearchParams({
|
||||
// checked: 1,
|
||||
// id: id,
|
||||
@@ -29,7 +29,7 @@ function checknext() {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({id: id, amount: amount.value, name: name})
|
||||
body: JSON.stringify({id: id, amount: amount.value})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
@@ -38,35 +38,14 @@ function checknext() {
|
||||
tagelement.innerText = data.tag;
|
||||
idelement.innerText = data.id;
|
||||
msg.innerText = data.checkedone + " 盘点数 " + data.checkedamount;
|
||||
location.innerText = data.location;
|
||||
|
||||
})
|
||||
.catch(error => console.error('Error:', error));
|
||||
|
||||
}
|
||||
function apiAuth() {
|
||||
if (!window.h5sdk) {
|
||||
alert("请在飞书客户端中打开");
|
||||
return;
|
||||
}
|
||||
|
||||
window.h5sdk.ready(() => {
|
||||
tt.requestAccess({
|
||||
appID: "your_app_id",
|
||||
scopeList: [],
|
||||
success(res) {
|
||||
// 将 code 发送到服务端
|
||||
fetch(`/callback?code=${res.code}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("用户信息:", data);
|
||||
// 在页面上展示用户姓名
|
||||
document.getElementById("username").innerText = data.name;
|
||||
});
|
||||
},
|
||||
fail(err) {
|
||||
console.error("获取授权码失败:", err);
|
||||
}
|
||||
});
|
||||
});
|
||||
function backtoroot(msg="已完成,返回") {
|
||||
alert(msg);
|
||||
location.href="/";
|
||||
}
|
||||
apiAuth();
|
16
inventory_check/templates/after.html
Normal file
16
inventory_check/templates/after.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>盘库助手</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/script.js') }}"></script>
|
||||
<script>
|
||||
backtoroot( "{{ msg }}" );
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -16,14 +16,13 @@
|
||||
{% block content %}{% endblock %}
|
||||
<footer>
|
||||
{% block footer %}
|
||||
<small> © 2025 <a href="http://yum2.cc" title="Written by luff">luff</a> /
|
||||
<small> 2025 © SDHLMH
|
||||
</small>
|
||||
<!-- <p><a id="bottom" href="#" title="Go Top">↑</a></p> -->
|
||||
{% endblock %}
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/script.js') }}"></script>
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
@@ -7,7 +7,7 @@
|
||||
<div>
|
||||
<div class="handler">
|
||||
<a href="/"><button type="button">返回</button></a>
|
||||
<div></div><div><p id="inventory-id" hidden>{{ inventory.id }}</p></div>
|
||||
<div id="inventory-location"></div><div><p id="inventory-id" hidden>{{ inventory.id }}</p></div>
|
||||
</div>
|
||||
<h1 id="inventory-tag">{{ inventory.tag }}</h1>
|
||||
<hr>
|
||||
|
@@ -5,9 +5,6 @@
|
||||
<form method=get action="/upload">
|
||||
<input style="width:150px;" type=submit value=上传XLSX>
|
||||
</form>
|
||||
<form method=get action="/list">
|
||||
<input style="width:150px;" type=submit value=显示列表>
|
||||
</form>
|
||||
<form method=get action="/check">
|
||||
<input style="width:150px;" type=submit value=继续盘点>
|
||||
</form>
|
||||
|
@@ -1,62 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div id="flash-msg">
|
||||
开始盘点>>>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<div class="handler">
|
||||
<a href="/"><button type="button">返回</button></a>
|
||||
<div></div><div><p id="inventory-id" hidden>0</p></div>
|
||||
</div>
|
||||
<div class="handler">
|
||||
<button onclick="previousPage()" type="button">上页</button>
|
||||
<div></div>
|
||||
<button onclick="nextPage()" type="button">下页</button>
|
||||
</div>
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<th>标签</th>
|
||||
<th>数量</th>
|
||||
<th>已盘</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="tag1">一月</td>
|
||||
<td id="amount1">¥3400</td>
|
||||
<td id="checked1">¥3400</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="tag2">一月</td>
|
||||
<td id="amount2">¥3400</td>
|
||||
<td id="checked2">¥3400</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="tag3">一月</td>
|
||||
<td id="amount3">¥3400</td>
|
||||
<td id="checked3">¥3400</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="tag4">一月</td>
|
||||
<td id="amount4">¥3400</td>
|
||||
<td id="checked4">¥3400</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="tag5">一月</td>
|
||||
<td id="amount5">¥3400</td>
|
||||
<td id="checked5">¥3400</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="tag6">一月</td>
|
||||
<td id="amount6">¥3400</td>
|
||||
<td id="checked6">¥3400</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="handler">
|
||||
<button onclick="previousPage()" type="button">上页</button>
|
||||
<div></div>
|
||||
<button onclick="nextPage()" type="button">下页</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@@ -3,11 +3,13 @@
|
||||
|
||||
{% block content %}
|
||||
<h1>上传Excel XLSX文件</h1>
|
||||
<form method=get action="/">
|
||||
<input style="width:150px;" type=submit value=返回>
|
||||
</form>
|
||||
<div class="handler">
|
||||
<a href="/"><button type="button">返回</button></a>
|
||||
<div></div><div></div>
|
||||
</div>
|
||||
<hr>
|
||||
<form method=post enctype=multipart/form-data action="/import">
|
||||
<div><input style="width:300px;" type=file name=选择></div>
|
||||
<div><input style="width:300px;" type=file name=file></div>
|
||||
<div class="handler"><div></div><input style="width:100px;"type=submit value=上传></div>
|
||||
</form>
|
||||
<div>
|
||||
|
@@ -5,8 +5,9 @@
|
||||
:copyright: © 2025 luffmims <luffmims@hotmaill.com>
|
||||
:license: MIT, see LICENSE for more details.
|
||||
"""
|
||||
import time
|
||||
from flask import jsonify, redirect, request, url_for, render_template, send_file
|
||||
from flask import make_response, session
|
||||
from flask import make_response
|
||||
from io import BytesIO
|
||||
from openpyxl import Workbook
|
||||
from inventory_check import app, db
|
||||
@@ -17,16 +18,11 @@ from werkzeug.exceptions import BadRequest
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
@app.route('/list')
|
||||
def list():
|
||||
return render_template('list.html')
|
||||
|
||||
@app.route('/check', methods=['GET'])
|
||||
def check():
|
||||
inventory = Inventory.query.filter_by(checked=False).first()
|
||||
print(inventory)
|
||||
if not inventory:
|
||||
return "All checked"
|
||||
return render_template('after.html',msg="未导入或已盘完")
|
||||
return render_template('check.html',inventory=inventory)
|
||||
|
||||
@app.route('/get_inventory', methods=['POST'])
|
||||
@@ -36,7 +32,6 @@ def update_inventory():
|
||||
data = request.get_json()
|
||||
inventory_id = data['id']
|
||||
amount = data['amount']
|
||||
name = data['name']
|
||||
|
||||
if not inventory_id or not amount:
|
||||
raise BadRequest('Missing inventory id or amount')
|
||||
@@ -47,7 +42,6 @@ def update_inventory():
|
||||
raise BadRequest('Inventory not found')
|
||||
checkedone = inventory.tag
|
||||
inventory.amount = amount
|
||||
inventory.name = name
|
||||
inventory.checked = True
|
||||
|
||||
# 提交更改
|
||||
@@ -63,6 +57,7 @@ def update_inventory():
|
||||
return jsonify({
|
||||
'id': inventory.id,
|
||||
'tag': inventory.tag,
|
||||
'location': inventory.location,
|
||||
'amount': inventory.amount,
|
||||
'checkedone': checkedone,
|
||||
'checkedamount': amount
|
||||
@@ -94,7 +89,7 @@ def import_file():
|
||||
file_path = 'data.xlsx'
|
||||
file.save(file_path)
|
||||
import_from_xlsx(file_path)
|
||||
return '文件导入成功! <a href="/">返回</a>'
|
||||
return render_template('after.html',msg="成功")
|
||||
|
||||
return redirect(url_for('upload_form'))
|
||||
|
||||
@@ -102,6 +97,7 @@ def import_file():
|
||||
|
||||
@app.route('/download-xlsx')
|
||||
def download_xlsx():
|
||||
filename = "PD-" + time.strftime("%Y%m%d", time.localtime()) + ".xlsx"
|
||||
# 创建一个 Excel 工作簿
|
||||
inventorys = Inventory.query.all() # 查询所有数据, and sort data by sort
|
||||
# 创建一个工作簿
|
||||
@@ -111,65 +107,16 @@ def download_xlsx():
|
||||
# 设置工作表名称
|
||||
ws.title = "Inventory"
|
||||
# 设置工作表列名
|
||||
ws.append(["sort", "location", "tag", "amount", "checked", "name"])
|
||||
ws.append(["序号", "位置", "标签", "数量", "已确认"])
|
||||
# 写入数据
|
||||
for inventory in inventorys:
|
||||
ws.append([inventory.sort, inventory.location, inventory.tag, inventory.amount, inventory.checked, inventory.name])
|
||||
ws.append([inventory.sort, inventory.location, inventory.tag, inventory.amount, inventory.checked])
|
||||
|
||||
output = BytesIO()
|
||||
wb.save(output)
|
||||
output.seek(0) # 移动到字节流的开头
|
||||
|
||||
# 设置响应头,提供下载功能
|
||||
response = make_response(send_file(output, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', as_attachment=True, download_name='example.xlsx'))
|
||||
response.headers["Content-Disposition"] = "attachment; filename=example.xlsx"
|
||||
response = make_response(send_file(output, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', as_attachment=True, download_name=filename))
|
||||
response.headers["Content-Disposition"] = "attachment; filename=" + filename
|
||||
return response
|
||||
|
||||
# 应用凭证信息
|
||||
APP_ID = "cli_a70da4f71bf1d00c"
|
||||
APP_SECRET = "4zV9xcunWUE8E4kKS4hw5e3m6pgjoduz"
|
||||
|
||||
# 获取 app_access_token
|
||||
def get_app_access_token():
|
||||
url = "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal/"
|
||||
payload = {
|
||||
"app_id": APP_ID,
|
||||
"app_secret": APP_SECRET
|
||||
}
|
||||
response = request.post(url, json=payload)
|
||||
return response.json().get("app_access_token")
|
||||
|
||||
# 获取 user_access_token
|
||||
def get_user_access_token(app_access_token, code):
|
||||
url = "https://open.feishu.cn/open-apis/authen/v1/access_token"
|
||||
headers = {"Authorization": f"Bearer {app_access_token}"}
|
||||
payload = {"grant_type": "authorization_code", "code": code}
|
||||
response = request.post(url, headers=headers, json=payload)
|
||||
return response.json().get("data", {}).get("access_token")
|
||||
|
||||
# 获取用户信息
|
||||
def get_user_info(user_access_token):
|
||||
url = "https://open.feishu.cn/open-apis/authen/v1/user_info"
|
||||
headers = {"Authorization": f"Bearer {user_access_token}"}
|
||||
response = request.get(url, headers=headers)
|
||||
return response.json().get("data")
|
||||
|
||||
@app.route("/callback", methods=["GET"])
|
||||
def callback():
|
||||
code = request.args.get("code")
|
||||
if not code:
|
||||
return jsonify({"error": "Missing code parameter"}), 400
|
||||
|
||||
# 获取 app_access_token
|
||||
app_access_token = get_app_access_token()
|
||||
|
||||
# 获取 user_access_token
|
||||
user_access_token = get_user_access_token(app_access_token, code)
|
||||
|
||||
# 获取用户信息
|
||||
user_info = get_user_info(user_access_token)
|
||||
|
||||
# 存储用户信息到 session
|
||||
session["user_info"] = user_info
|
||||
|
||||
return jsonify(user_info)
|
BIN
sheet.xlsx
Normal file
BIN
sheet.xlsx
Normal file
Binary file not shown.
BIN
游芯盘点表.xlsx
BIN
游芯盘点表.xlsx
Binary file not shown.
Reference in New Issue
Block a user