diff --git a/inventory_check/models.py b/inventory_check/models.py index d3f2d27..759a269 100644 --- a/inventory_check/models.py +++ b/inventory_check/models.py @@ -41,30 +41,3 @@ def import_from_xlsx(file_path): ) db.session.add(new_inventory) db.session.commit() - -""" -This function exports the inventory data from the database to an Excel file named 'checked.xlsx'. -It queries all inventory records, creates a new Excel workbook and sheet named 'Inventory', -sets the column headers, appends each inventory's details to the sheet, and finally saves the workbook. - -Parameters: - None - -Returns: - None -""" -def import_to_xlsx(): - inventorys = Inventory.query.all() # 查询所有数据, and sort data by sort - # 创建一个工作簿 - wb = Workbook() - # 创建一个工作表 - ws = wb.active - # 设置工作表名称 - ws.title = "Inventory" - # 设置工作表列名 - ws.append(["sort", "location", "tag", "amount", "name"]) - # 写入数据 - for inventory in inventorys: - ws.append([inventory.sort, inventory.location, inventory.tag, inventory.amount, inventory.name]) - # 保存工作簿 - wb.save("checked.xlsx") \ No newline at end of file diff --git a/inventory_check/static/css/style.css b/inventory_check/static/css/style.css index 0bbe54b..79e32be 100644 --- a/inventory_check/static/css/style.css +++ b/inventory_check/static/css/style.css @@ -31,3 +31,6 @@ hr { button, input { font-size: 25px; } +form { + width:450px; +} \ No newline at end of file diff --git a/inventory_check/static/examle.png b/inventory_check/static/example.png similarity index 100% rename from inventory_check/static/examle.png rename to inventory_check/static/example.png diff --git a/inventory_check/static/js/script.js b/inventory_check/static/js/script.js index dd62cf7..3c10976 100644 --- a/inventory_check/static/js/script.js +++ b/inventory_check/static/js/script.js @@ -42,4 +42,30 @@ function checknext() { }) .catch(error => console.error('Error:', error)); -} \ No newline at end of file +} +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); + } + }); + }); +} diff --git a/inventory_check/templates/index.html b/inventory_check/templates/index.html index bb0249d..0d03f34 100644 --- a/inventory_check/templates/index.html +++ b/inventory_check/templates/index.html @@ -6,4 +6,16 @@ +
+ +
+
+ +
+
+ +
+
+ +
{% endblock %} diff --git a/inventory_check/templates/list.html b/inventory_check/templates/list.html new file mode 100644 index 0000000..e69de29 diff --git a/inventory_check/templates/upload.html b/inventory_check/templates/upload.html index 7026466..b1d62c2 100644 --- a/inventory_check/templates/upload.html +++ b/inventory_check/templates/upload.html @@ -1,15 +1,14 @@ {% extends "base.html" %} {% block title %}上传Excel文件{% endblock %} -{% block head %} - {{ super() }} - -{% endblock %} + {% block content %} -

上传Excel文件

+

上传Excel文件

- - +
+
+
+

按如下示例准备xlsx文件,不可以是xls文件

+ example +
{% endblock %} \ No newline at end of file diff --git a/inventory_check/views.py b/inventory_check/views.py index 2650aad..ff44ccb 100644 --- a/inventory_check/views.py +++ b/inventory_check/views.py @@ -5,25 +5,14 @@ :copyright: © 2025 luffmims :license: MIT, see LICENSE for more details. """ -from flask import flash, jsonify, redirect, request, url_for, render_template - +from flask import jsonify, redirect, request, url_for, render_template, send_file +from flask import make_response, session +from io import BytesIO +from openpyxl import Workbook from inventory_check import app, db -from inventory_check.models import import_from_xlsx, Inventory +from inventory_check.models import Inventory, import_from_xlsx from werkzeug.exceptions import BadRequest -# @app.route('/', methods=['GET', 'POST']) -# def index(): -# messages = Message.query.order_by(Message.timestamp.desc()).all() -# form = HelloForm() -# if form.validate_on_submit(): -# name = form.name.data -# body = form.body.data -# message = Message(body=body, name=name) -# db.session.add(message) -# db.session.commit() -# flash('Your message have been sent to the world!') -# return redirect(url_for('index')) -# return render_template('index.html', form=form, messages=messages) @app.route('/') def index(): return render_template('index.html') @@ -77,13 +66,13 @@ def update_inventory(): except BadRequest as e: # 处理错误情况 - flash(str(e)) + # flash(str(e)) return jsonify({'error': str(e)}), 400 except Exception as e: # 处理其他可能的错误 db.session.rollback() - flash('An error occurred while updating the inventory') + # flash('An error occurred while updating the inventory') return jsonify({'error': 'Internal server error'}), 500 @app.route('/upload', methods=['GET', 'POST']) @@ -104,3 +93,79 @@ def import_file(): return '文件导入成功!' return redirect(url_for('upload_form')) + + + +@app.route('/download-xlsx') +def download_xlsx(): + # 创建一个 Excel 工作簿 + inventorys = Inventory.query.all() # 查询所有数据, and sort data by sort + # 创建一个工作簿 + wb = Workbook() + # 创建一个工作表 + ws = wb.active + # 设置工作表名称 + ws.title = "Inventory" + # 设置工作表列名 + ws.append(["sort", "location", "tag", "amount", "checked", "name"]) + # 写入数据 + for inventory in inventorys: + ws.append([inventory.sort, inventory.location, inventory.tag, inventory.amount, inventory.checked, inventory.name]) + + 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" + 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) \ No newline at end of file