Skip to content

Commit 9df1e28

Browse files
committed
feat: 显示字数、文件大小、最后更新日期
1 parent 8c6bbb5 commit 9df1e28

File tree

7 files changed

+57
-12
lines changed

7 files changed

+57
-12
lines changed

backend/src/cgi.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ async function main() {
7676
if (type) {
7777
console.log(`Content-Type: ${type}`);
7878
console.log(`Content-Length: ${body.size}`);
79+
console.log(`Last-Modified: ${body.time}`);
7980
console.log("");
8081
body.stream.pipe(process.stdout);
8182
} else {

backend/src/koa.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ app.use(async (ctx) => {
2222
if (type) {
2323
ctx.set("Content-Type", type);
2424
ctx.set("Content-Length", body.size);
25+
ctx.set("Last-Modified", body.time);
2526
ctx.body = body.stream;
2627
} else {
2728
ctx.set("Content-Type", "application/json; charset=utf-8");

backend/src/router/read.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ module.exports = async function read({ query }) {
2424
console.log(
2525
`Expires: ${new Date(Date.now() + maxAge * 1000).toUTCString()}`
2626
);
27-
console.log(`Last-Modified: ${stat.mtime.toUTCString()}`);
2827
console.log(`ETag: "${stat.size}-${stat.mtime.getTime()}"`);
2928
}
3029

@@ -33,6 +32,7 @@ module.exports = async function read({ query }) {
3332
msg: "操作成功",
3433
data: {
3534
size: stat.size,
35+
time: stat.mtime.toUTCString(),
3636
filename: path.split("/").pop(),
3737
stream: fs.createReadStream(path),
3838
},

backend/src/router/save.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ module.exports = async function read({ body }) {
3030

3131
fs.writeFileSync(path, iconv.encode(value, encode));
3232

33-
return { code: 200, msg: "操作成功", data: null };
33+
const stat = fs.statSync(path);
34+
35+
return {
36+
code: 200,
37+
msg: "操作成功",
38+
data: { size: stat.size, time: stat.mtime.toUTCString() },
39+
};
3440
} catch (err) {
3541
if (err.code === "EACCES") {
3642
return { code: 401, msg: "权限不足,无法写入文件", data: body };

frontend/src/components/MonacoEditor.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@
1414
</div>
1515

1616
<div class="footer">
17-
<div class="developed">Developed by Flex_7746</div>
17+
<div class="info" v-if="code.date">修改时间:{{ code.date.format('YYYY/MM/DD HH:mm:ss') }}</div>
18+
<div class="info" v-if="code.byte !== undefined">文件大小:{{ getSize(code.byte) }}</div>
1819

1920
<div style="flex: 1"></div>
2021

22+
<div class="info">{{ code.value.length }} 个字符</div>
23+
2124
<el-switch
2225
v-if="code.lang === 'markdown'"
2326
v-model="mdView"
@@ -70,6 +73,7 @@ import MdView from '@/components/MdView.vue'
7073
import { useUserStore } from '@/store/user'
7174
7275
import { LANG_OPTIONS, ENCODING_OPTIONS } from '@/utils/option'
76+
import { getSize } from '@/utils/file'
7377
7478
import useCode from '../hooks/useCode'
7579
import useEditor from '../hooks/useEditor'
@@ -81,7 +85,7 @@ const user = useUserStore()
8185
8286
const mdView = ref(user.cfg.fileMdView)
8387
84-
const showMdView = computed(() => code.lang === 'markdown' && mdView)
88+
const showMdView = computed(() => code.lang === 'markdown' && mdView.value)
8589
8690
defineExpose({
8791
save: () => save(),
@@ -130,15 +134,15 @@ onMounted(() => {
130134
border-top: solid 1px var(--el-border-color);
131135
display: flex;
132136
align-items: center;
133-
gap: 4px;
137+
gap: 8px;
134138
padding: 0 4px;
135139
background-color: var(--el-bg-color);
136140
137141
> * {
138142
margin: 0;
139143
}
140144
141-
> .developed {
145+
> .info {
142146
font-size: 12px;
143147
line-height: 32px;
144148
color: var(--el-text-color-placeholder);

frontend/src/hooks/useCode.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { reactive } from 'vue'
2-
import { ElMessage, ElMessageBox } from 'element-plus'
2+
import { dayjs, ElMessage, ElMessageBox } from 'element-plus'
33
import axios from 'axios'
44

55
import { HOST } from '@/utils/env'
@@ -21,6 +21,8 @@ interface CodeModel {
2121
value: string
2222
lang: string
2323
encode: string
24+
byte?: number
25+
date?: dayjs.Dayjs
2426
}
2527

2628
export default function useCode(option: OptionModel) {
@@ -42,7 +44,7 @@ export default function useCode(option: OptionModel) {
4244
return ''
4345
}
4446

45-
const { data } = await axios.get(HOST, {
47+
const { data, headers } = await axios.get(HOST, {
4648
params: { _api: 'read', path },
4749
responseType: 'blob',
4850
})
@@ -53,10 +55,11 @@ export default function useCode(option: OptionModel) {
5355
return
5456
}
5557

56-
code.blob = data
58+
code.byte = headers['content-length'] ? Number(headers['content-length']) : undefined
59+
code.date = headers['last-modified'] ? dayjs(headers['last-modified']) : undefined
5760

61+
code.blob = data
5862
code.path = path
59-
6063
code.org = code.value = await data.text()
6164

6265
const filename = path.split('/').pop() || ''
@@ -91,7 +94,11 @@ export default function useCode(option: OptionModel) {
9194

9295
const upload = async (force?: 1) => {
9396
try {
94-
const { data: value }: any = await axios.post(
97+
const { data: value } = await axios.post<{
98+
code: number
99+
msg: string
100+
data: { size: number; time: string }
101+
}>(
95102
HOST,
96103
{
97104
encode: code.encode,
@@ -105,6 +112,9 @@ export default function useCode(option: OptionModel) {
105112
if (value.code === 200) {
106113
ElMessage({ type: 'success', message: '操作成功' })
107114

115+
code.byte = value.data.size
116+
code.date = dayjs(value.data.time)
117+
108118
code.org = code.value
109119

110120
option.onSave()

frontend/src/utils/file.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { HOST } from '@/utils/env'
22

3-
export const getFileName = (v: string) => (v.split('/').pop() || '').toLocaleLowerCase()
3+
export const getFileName = (v: string) => v.split('/').pop() || ''
44

55
export const getFileSuffix = (v: string) => (v.split('.').pop() || '').toLocaleLowerCase()
66

@@ -12,6 +12,29 @@ export const getFullPath = (path: string) => {
1212
return `${HOST}?_api=read&path=${encodeURIComponent(path)}`
1313
}
1414

15+
export const getSize = (byte: number) => {
16+
if (byte < 1024) {
17+
return `${byte} B`
18+
}
19+
20+
const KB = byte / 1024
21+
if (KB < 1024) {
22+
return `${Number(KB.toFixed(2))} KB`
23+
}
24+
25+
const MB = KB / 1024
26+
if (MB < 1024) {
27+
return `${Number(MB.toFixed(2))} MB`
28+
}
29+
30+
const TB = MB / 1024
31+
if (TB < 1024) {
32+
return `${Number(TB.toFixed(2))} TB`
33+
}
34+
35+
return ''
36+
}
37+
1538
export async function isBinaryContent(blob: Blob) {
1639
const slice = blob.slice(0, 1024)
1740
const arrayBuffer = await slice.arrayBuffer()

0 commit comments

Comments
 (0)