v0.7.2 顶栏精简:移除常驻打卡与周记提示按钮,周记提醒改为周五至周日 toast 一次性提示
This commit is contained in:
+2
-2
@@ -1,2 +1,2 @@
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./web-9h8A4HQx.js","./index-pe6VFzmc.js","./index-BiI44Vix.css"])))=>i.map(i=>d[i]);
|
||||
import{r as s,_ as i}from"./index-pe6VFzmc.js";var t;(function(e){e.Documents="DOCUMENTS",e.Data="DATA",e.Library="LIBRARY",e.Cache="CACHE",e.External="EXTERNAL",e.ExternalStorage="EXTERNAL_STORAGE"})(t||(t={}));var a;(function(e){e.UTF8="utf8",e.ASCII="ascii",e.UTF16="utf16"})(a||(a={}));const E=s("Filesystem",{web:()=>i(()=>import("./web-9h8A4HQx.js"),__vite__mapDeps([0,1,2]),import.meta.url).then(e=>new e.FilesystemWeb)});export{t as Directory,a as Encoding,E as Filesystem};
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./web-Deo5OtIz.js","./index-ynPmf8i8.js","./index-COwenkhO.css"])))=>i.map(i=>d[i]);
|
||||
import{r as s,_ as i}from"./index-ynPmf8i8.js";var t;(function(e){e.Documents="DOCUMENTS",e.Data="DATA",e.Library="LIBRARY",e.Cache="CACHE",e.External="EXTERNAL",e.ExternalStorage="EXTERNAL_STORAGE"})(t||(t={}));var a;(function(e){e.UTF8="utf8",e.ASCII="ascii",e.UTF16="utf16"})(a||(a={}));const E=s("Filesystem",{web:()=>i(()=>import("./web-Deo5OtIz.js"),__vite__mapDeps([0,1,2]),import.meta.url).then(e=>new e.FilesystemWeb)});export{t as Directory,a as Encoding,E as Filesystem};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
-27
File diff suppressed because one or more lines are too long
+27
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -8,8 +8,8 @@
|
||||
<link rel="icon" href="./icons/icon.svg" type="image/svg+xml" />
|
||||
<link rel="apple-touch-icon" href="./icons/icon-192.png" />
|
||||
<title>实习工作日志</title>
|
||||
<script type="module" crossorigin src="./assets/index-pe6VFzmc.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-BiI44Vix.css">
|
||||
<script type="module" crossorigin src="./assets/index-ynPmf8i8.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-COwenkhO.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "intern-log",
|
||||
"private": true,
|
||||
"version": "0.7.1",
|
||||
"version": "0.7.2",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
+19
-98
@@ -15,11 +15,11 @@ import UserAdminView from './views/UserAdminView.vue'
|
||||
import LoginView from './views/LoginView.vue'
|
||||
import { getSession, logoutUser, openUserDatabase, type Session } from './db/auth'
|
||||
import { autoSyncNow, enableRealtimeSync, ensureCloudBinding, stopRealtime } from './sync/engine'
|
||||
import { clockIn, getAttendance, getWorkRule, getWeeklyNote, searchLogItems, searchMemos, smartClockOut, type WorkRule } from './db/repo'
|
||||
import { addDays, hhmm, todayStr, weekStart } from './lib/date'
|
||||
import { getWorkRule, getWeeklyNote, searchLogItems, searchMemos } from './db/repo'
|
||||
import { todayStr, weekStart } from './lib/date'
|
||||
import { showToast, useToasts } from './lib/toast'
|
||||
import { attendanceChanged, focusDate, focusMemo, notifyAttendanceChanged } from './lib/bus'
|
||||
import { categoryLabel, type Attendance, type LogItem, type Memo } from './db/schema'
|
||||
import { focusDate, focusMemo } from './lib/bus'
|
||||
import { categoryLabel, type LogItem, type Memo } from './db/schema'
|
||||
|
||||
const toasts = useToasts()
|
||||
|
||||
@@ -30,8 +30,7 @@ async function onLogin(s: Session) {
|
||||
openUserDatabase(s.userId)
|
||||
location.hash = '#/calendar'
|
||||
route.value = 'calendar'
|
||||
await refreshClock()
|
||||
await refreshTip()
|
||||
await checkWeeklyReminder()
|
||||
startSyncTimer()
|
||||
try {
|
||||
await ensureCloudBinding()
|
||||
@@ -161,72 +160,24 @@ function pickLog(item: LogItem & { date: string }) { openLog(item); mobileSearch
|
||||
function pickMemo(m: Memo) { openMemo(m); mobileSearch.value = false }
|
||||
|
||||
|
||||
// ---- 工具栏打卡 ----
|
||||
const today = ref(todayStr())
|
||||
const att = ref<Attendance | undefined>(undefined)
|
||||
const yesterdayPending = ref(false)
|
||||
|
||||
async function refreshClock() {
|
||||
att.value = await getAttendance(today.value)
|
||||
yesterdayPending.value = false
|
||||
const now = new Date()
|
||||
if (now.getHours() < 4) {
|
||||
const yRec = await getAttendance(addDays(today.value, -1))
|
||||
yesterdayPending.value = !!(yRec && yRec.clock_in_at && !yRec.clock_out_at)
|
||||
}
|
||||
}
|
||||
|
||||
const hasActiveSession = computed(() => {
|
||||
const a = att.value
|
||||
if (a && a.clock_in_at && !a.clock_out_at) return true
|
||||
return yesterdayPending.value && !(a && a.clock_in_at)
|
||||
})
|
||||
const clockDone = computed(() => {
|
||||
const a = att.value
|
||||
return !!(a && a.clock_in_at && a.clock_out_at)
|
||||
})
|
||||
const clockLabel = computed(() => {
|
||||
const a = att.value
|
||||
if (hasActiveSession.value) return '下班打卡'
|
||||
if (clockDone.value) return '已打卡 ' + hhmm(a?.clock_in_at) + ' - ' + hhmm(a?.clock_out_at)
|
||||
return '上班打卡'
|
||||
})
|
||||
|
||||
async function doClock() {
|
||||
if (hasActiveSession.value) {
|
||||
try { await smartClockOut() } catch { /* 没有进行中的打卡 */ }
|
||||
} else {
|
||||
await clockIn(today.value)
|
||||
}
|
||||
await refreshClock()
|
||||
notifyAttendanceChanged()
|
||||
}
|
||||
|
||||
// 任何视图发生的考勤变更(含今日面板、日历抽屉)都实时同步到顶栏
|
||||
watch(attendanceChanged, () => {
|
||||
if (session.value) refreshClock()
|
||||
})
|
||||
|
||||
// ---- 周记提醒 ----
|
||||
const weekTip = ref(false)
|
||||
async function refreshTip() {
|
||||
const rule: WorkRule = await getWorkRule()
|
||||
if (rule.remind_weekly === 'off') { weekTip.value = false; return }
|
||||
const wd = new Date().getDay()
|
||||
if (wd === 5 || wd === 6 || wd === 0) {
|
||||
const note = await getWeeklyNote(weekStart(today.value))
|
||||
weekTip.value = !note || (!note.highlights && !note.challenges && !note.plan_next)
|
||||
} else {
|
||||
weekTip.value = false
|
||||
}
|
||||
// ---- 周记提醒:周五至周日打开应用时 toast 提示一次,不占用常驻界面 ----
|
||||
async function checkWeeklyReminder() {
|
||||
try {
|
||||
const rule = await getWorkRule()
|
||||
if (rule.remind_weekly === 'off') return
|
||||
const wd = new Date().getDay()
|
||||
if (wd !== 5 && wd !== 6 && wd !== 0) return
|
||||
const note = await getWeeklyNote(weekStart(todayStr()))
|
||||
if (note && (note.highlights || note.challenges || note.plan_next)) return
|
||||
showToast('本周周记还没写,可在「总结」页填写')
|
||||
} catch { /* 提醒检查失败不影响使用 */ }
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
window.addEventListener('keydown', onGlobalKey)
|
||||
if (session.value) {
|
||||
openUserDatabase(session.value.userId)
|
||||
await refreshClock()
|
||||
await refreshTip()
|
||||
await checkWeeklyReminder()
|
||||
startSyncTimer()
|
||||
}
|
||||
})
|
||||
@@ -287,17 +238,7 @@ onMounted(async () => {
|
||||
<div v-else class="gs-empty muted">无匹配结果</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="flex1"></span>
|
||||
<div class="topbar-actions">
|
||||
<button v-if="weekTip" class="week-tip" @click="nav('report')">
|
||||
<span class="dot" style="background: var(--warn)"></span>
|
||||
填写本周周记
|
||||
</button>
|
||||
<button class="btn btn-primary" :disabled="clockDone" @click="doClock">
|
||||
<Icon :name="clockDone ? 'check-circle' : 'clock'" :size="14" />
|
||||
<span class="num">{{ clockLabel }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
<main class="content">
|
||||
<div class="content-inner">
|
||||
@@ -507,8 +448,6 @@ onMounted(async () => {
|
||||
}
|
||||
.title { font-size: 15px; font-weight: 600; white-space: nowrap; }
|
||||
|
||||
.topbar-actions { display: flex; align-items: center; gap: 8px; }
|
||||
|
||||
.gsearch { position: relative; width: 320px; max-width: 38vw; }
|
||||
.gs-icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--text-3); }
|
||||
.gs-input {
|
||||
@@ -554,21 +493,6 @@ onMounted(async () => {
|
||||
.gs-date { font-size: 12px; flex: none; }
|
||||
.gs-empty { padding: 10px; font-size: 12px; text-align: center; }
|
||||
|
||||
.week-tip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
border: 1px solid var(--warn);
|
||||
color: var(--warn);
|
||||
background: var(--bg-page);
|
||||
border-radius: 999px;
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.week-tip:hover { background: #FDF4EC; }
|
||||
|
||||
.content { flex: 1; overflow: auto; }
|
||||
.content-inner { max-width: 1280px; margin: 0 auto; padding: 20px 24px 48px; }
|
||||
@@ -752,10 +676,7 @@ onMounted(async () => {
|
||||
.gsearch { display: none; }
|
||||
.gsearch .gs-panel { display: none; }
|
||||
.mob-search-btn { display: flex; }
|
||||
.topbar-actions { margin-left: auto; gap: 6px; }
|
||||
.week-tip { height: 28px; max-width: 118px; padding: 0 8px; white-space: nowrap; overflow: hidden; }
|
||||
.topbar-actions .btn { padding: 0 12px; height: 34px; }
|
||||
.topbar-actions .btn .num { font-size: 12px; }
|
||||
.mob-search-btn { margin-left: auto; }
|
||||
|
||||
.tabbar { display: flex; }
|
||||
.tab-btn { height: 56px; font-size: 11px; }
|
||||
|
||||
Reference in New Issue
Block a user