Skip to content

Commit

Permalink
保存排班表截图
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhaoZuohong committed Oct 12, 2023
1 parent 5b4678f commit 0c392e7
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 93 deletions.
44 changes: 39 additions & 5 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@

import pathlib

import tkinter
from tkinter import messagebox


mimetypes.add_type("text/html", ".html")
mimetypes.add_type("text/css", ".css")
mimetypes.add_type("application/javascript", ".js")
Expand Down Expand Up @@ -104,7 +108,7 @@ def operator_list():

@app.route("/shop")
def shop_list():
return shop_items
return shop_items


def read_log(conn):
Expand Down Expand Up @@ -225,6 +229,35 @@ def open_folder_dialog():
return ""


@app.route("/dialog/save/img", methods=["POST"])
@require_token
def save_file_dialog():
img = request.files["img"]
if not img:
return "图片未上传"
window = webview.active_window()
folder_path = window.create_file_dialog(
dialog_type=webview.SAVE_DIALOG,
save_filename="plan.png",
file_types=("PNG图片 (*.png)",),
)
if not folder_path:
return "保存已取消"
img_path = folder_path[0]
if os.path.exists(img_path):
root = tkinter.Tk()
root.withdraw()
replace = messagebox.askyesno(
"arknights-mower",
f"同名文件{img_path}已存在,是否覆盖?",
)
root.destroy()
if not replace:
return f"保存已取消"
img.save(img_path)
return f"图片已导出至{img_path}"


@app.route("/check-maa")
@require_token
def get_maa_adb_version():
Expand Down Expand Up @@ -282,14 +315,15 @@ def test_email():
return "邮件发送失败!\n" + str(e)
return "邮件发送成功!"


@app.route("/test-serverJang-push")
@require_token
def test_serverJang_push():
try:
response = requests.get(f"https://sctapi.ftqq.com/{conf['sendKey']}.send", params={
"title": "arknights-mower推送测试",
"desp": "arknights-mower推送测试"
})
response = requests.get(
f"https://sctapi.ftqq.com/{conf['sendKey']}.send",
params={"title": "arknights-mower推送测试", "desp": "arknights-mower推送测试"},
)

if response.status_code == 200 and response.json().get("code") == 0:
return "发送成功"
Expand Down
1 change: 1 addition & 0 deletions ui/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ declare module '@vue/runtime-core' {
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
NLog: typeof import('naive-ui')['NLog']
NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NModal: typeof import('naive-ui')['NModal']
NRadio: typeof import('naive-ui')['NRadio']
NRadioButton: typeof import('naive-ui')['NRadioButton']
Expand Down
11 changes: 11 additions & 0 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"chartjs-adapter-luxon": "^1.3.1",
"chartjs-adapter-moment": "^1.0.1",
"chartjs-plugin-datalabels": "^2.2.0",
"file-saver": "^2.0.5",
"highlight.js": "^11.8.0",
"html-to-image": "^1.11.11",
"katex": "^0.16.8",
Expand Down
162 changes: 82 additions & 80 deletions ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,86 +8,88 @@
>
<n-global-style />
<n-dialog-provider>
<n-layout :has-sider="!mobile" class="outer-layout">
<n-layout-sider
v-if="!mobile"
bordered
collapse-mode="width"
:collapsed-width="50"
:width="210"
show-trigger
>
<n-menu
:indent="24"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
<n-layout-content class="layout-content-container">
<router-view v-if="loaded" />
</n-layout-content>
<n-layout-footer v-if="mobile">
<n-tabs type="line" justify-content="space-evenly" size="small">
<n-tab name="主页" @click="$router.push('/')">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="BookOutline" />
日志
</div>
</n-tab>
<n-tab name="设置" @click="$router.push('/settings')">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="Settings" />
设置
</div>
</n-tab>
<n-tab name="排班" @click="$router.push('/plan-editor')">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="Home" />
排班
</div>
</n-tab>
<n-tab name="报表" @click="showModal = true">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="StatsChart" />
报表
</div>
<n-modal v-model:show="showModal">
<n-card
style="width: 300px"
title="基建报表"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<div>
<n-button @click=";(showModal = false), $router.push('/record/line')">
心情曲线
</n-button>
</div>
<div>
<n-button @click=";(showModal = false), $router.push('/record/pie')">
心情饼图
</n-button>
</div>
<div>
<n-button @click=";(showModal = false), $router.push('/record/depot')">
仓库
</n-button>
</div>
</n-card>
</n-modal>
</n-tab>
<n-tab name="帮助" @click="$router.push('/doc')">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="HelpCircle" />
帮助
</div>
</n-tab>
</n-tabs>
</n-layout-footer>
</n-layout>
<n-message-provider>
<n-layout :has-sider="!mobile" class="outer-layout">
<n-layout-sider
v-if="!mobile"
bordered
collapse-mode="width"
:collapsed-width="50"
:width="210"
show-trigger
>
<n-menu
:indent="24"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
<n-layout-content class="layout-content-container">
<router-view v-if="loaded" />
</n-layout-content>
<n-layout-footer v-if="mobile">
<n-tabs type="line" justify-content="space-evenly" size="small">
<n-tab name="主页" @click="$router.push('/')">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="BookOutline" />
日志
</div>
</n-tab>
<n-tab name="设置" @click="$router.push('/settings')">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="Settings" />
设置
</div>
</n-tab>
<n-tab name="排班" @click="$router.push('/plan-editor')">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="Home" />
排班
</div>
</n-tab>
<n-tab name="报表" @click="showModal = true">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="StatsChart" />
报表
</div>
<n-modal v-model:show="showModal">
<n-card
style="width: 300px"
title="基建报表"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<div>
<n-button @click=";(showModal = false), $router.push('/record/line')">
心情曲线
</n-button>
</div>
<div>
<n-button @click=";(showModal = false), $router.push('/record/pie')">
心情饼图
</n-button>
</div>
<div>
<n-button @click=";(showModal = false), $router.push('/record/depot')">
仓库
</n-button>
</div>
</n-card>
</n-modal>
</n-tab>
<n-tab name="帮助" @click="$router.push('/doc')">
<div style="display: flex; flex-direction: column; align-items: center">
<n-icon size="20" style="margin-bottom: -1px" :component="HelpCircle" />
帮助
</div>
</n-tab>
</n-tabs>
</n-layout-footer>
</n-layout>
</n-message-provider>
</n-dialog-provider>
</n-config-provider>
</template>
Expand Down
4 changes: 2 additions & 2 deletions ui/src/components/PlanEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ defineExpose({
</script>

<template>
<div class="plan-container">
<div class="outer" ref="outer">
<div class="plan-container" ref="outer">
<div class="outer">
<!---->
<div class="left_box">
<div class="left_contain" v-for="row in 3">
Expand Down
37 changes: 35 additions & 2 deletions ui/src/pages/Plan.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const {
} = storeToRefs(plan_store)
const { load_plan } = plan_store
import { inject } from 'vue'
import { inject, ref } from 'vue'
const axios = inject('axios')
import { file_dialog } from '@/utils/dialog'
Expand All @@ -32,6 +32,35 @@ async function open_plan_file() {
await load_plan()
}
}
import { toBlob } from 'html-to-image'
import { useMessage } from 'naive-ui'
const plan_editor = ref(null)
const generating_image = ref(false)
const message = useMessage()
const loading = ref(null)
async function save() {
generating_image.value = true
loading.value = message.loading('正在生成图片……', { duration: 0 })
if (
/webkit/i.test(navigator.userAgent) &&
/gecko/i.test(navigator.userAgent) &&
/safari/i.test(navigator.userAgent)
) {
await toBlob(plan_editor.value.outer)
}
const blob = await toBlob(plan_editor.value.outer, { pixelRatio: 3, backgroundColor: 'white' })
loading.value.destroy()
generating_image.value = false
const form_data = new FormData()
form_data.append('img', blob)
const resp = await axios.post(`${import.meta.env.VITE_HTTP_URL}/dialog/save/img`, form_data)
message.info(resp.data)
}
</script>
<template>
Expand All @@ -45,10 +74,14 @@ async function open_plan_file() {
<td>
<n-button @click="open_plan_file">...</n-button>
</td>
<td>
<n-button v-if="generating_image" disabled>正在生成</n-button>
<n-button @click="save" v-else>导出图片</n-button>
</td>
</tr>
</table>
</div>
<plan-editor />
<plan-editor ref="plan_editor" />
<div class="home-container external-container no-grow">
<n-divider />
</div>
Expand Down
6 changes: 2 additions & 4 deletions ui/src/utils/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import axios from 'axios'

export async function file_dialog() {
const response = await axios.get(`${import.meta.env.VITE_HTTP_URL}/dialog/file`)
const file_path = response.data
return file_path
return response.data
}

export async function folder_dialog() {
const response = await axios.get(`${import.meta.env.VITE_HTTP_URL}/dialog/folder`)
const folder_path = response.data
return folder_path
return response.data
}

0 comments on commit 0c392e7

Please sign in to comment.