├── src ├── scss │ ├── _mixin.scss │ ├── fonts │ │ ├── Galvji.ttf │ │ ├── Galvji-Bold.ttf │ │ ├── ImpactPureNumber.ttf │ │ └── JetBrainsMono-Regular.ttf │ ├── _plugin.scss │ ├── _font.scss │ ├── _dark.scss │ ├── _gutter.scss │ ├── _menu-section.scss │ ├── _gradient.scss │ ├── _normalize.scss │ ├── _form.scss │ ├── _statistics.scss │ ├── _reset.scss │ ├── diary.scss │ └── _utility.scss ├── assets │ ├── images │ │ ├── favicon.png │ │ └── appicon_apple.png │ └── icons │ │ ├── logo │ │ ├── logo_black.png │ │ ├── logo_rounded.svg │ │ ├── logo.svg │ │ ├── logo_close.svg │ │ ├── logo_avatar.svg │ │ ├── logo_server_error.svg │ │ ├── logo_black.svg │ │ ├── logo_register.svg │ │ ├── logo_title.svg │ │ └── logo_title_saved.svg │ │ ├── tab │ │ ├── add.svg │ │ ├── add_black.svg │ │ ├── done.svg │ │ ├── close.svg │ │ ├── done_black.svg │ │ ├── close_black.svg │ │ ├── eye_close.svg │ │ ├── eye_close_black.svg │ │ ├── menu.svg │ │ ├── statistics.svg │ │ ├── about.svg │ │ ├── card.svg │ │ ├── done_saved.svg │ │ ├── menu_black.svg │ │ ├── search.svg │ │ ├── done_changed.svg │ │ ├── statistics_black.svg │ │ ├── about_black.svg │ │ ├── card_black.svg │ │ ├── eye_open.svg │ │ ├── back.svg │ │ ├── search_black.svg │ │ ├── eye_open_black.svg │ │ ├── back_black.svg │ │ ├── list_simple.svg │ │ ├── list_simple_black.svg │ │ ├── category.svg │ │ ├── category_black.svg │ │ ├── list_detail.svg │ │ ├── bill_simple.svg │ │ ├── list_detail_black.svg │ │ ├── bill_simple_black.svg │ │ ├── recover.svg │ │ ├── recover_black.svg │ │ ├── edit.svg │ │ ├── edit_black.svg │ │ ├── key.svg │ │ ├── key_black.svg │ │ ├── calendar.svg │ │ ├── calendar_black.svg │ │ ├── share.svg │ │ ├── share_black.svg │ │ ├── waterfall.svg │ │ ├── changelog.svg │ │ ├── waterfall_black.svg │ │ ├── changelog_black.svg │ │ ├── invitation.svg │ │ ├── invitation_black.svg │ │ ├── others.svg │ │ ├── others_black.svg │ │ ├── bill.svg │ │ ├── bill_black.svg │ │ ├── folder.svg │ │ ├── todo.svg │ │ ├── todo_black.svg │ │ └── folder_black.svg │ │ ├── bank │ │ ├── 工商银行.svg │ │ ├── 交通银行.svg │ │ ├── 建设银行.svg │ │ ├── 招商银行.svg │ │ ├── 银行.svg │ │ ├── 民生银行.svg │ │ ├── 浦发银行.svg │ │ ├── 中国银行.svg │ │ ├── 农业银行.svg │ │ ├── 中信银行.svg │ │ └── 广发银行.svg │ │ ├── icons │ │ ├── content_white.svg │ │ ├── content_md.svg │ │ ├── content_md_white.svg │ │ ├── content.svg │ │ └── clipboard.svg │ │ └── weather │ │ ├── overcast_white.svg │ │ ├── overcast.svg │ │ ├── overcast_active.svg │ │ ├── snow.svg │ │ ├── snow_white.svg │ │ ├── thunderstorm.svg │ │ ├── thunderstorm_white.svg │ │ ├── cloudy_white.svg │ │ ├── thunderstorm_active.svg │ │ ├── rain_white.svg │ │ ├── cloudy_active.svg │ │ ├── snow_active.svg │ │ ├── rain.svg │ │ ├── cloudy.svg │ │ ├── rain_active.svg │ │ ├── tornado.svg │ │ ├── tornado_white.svg │ │ ├── tornado_active.svg │ │ ├── sandstorm.svg │ │ ├── sandstorm_active.svg │ │ ├── sandstorm_white.svg │ │ ├── fog.svg │ │ ├── fog_active.svg │ │ ├── fog_white.svg │ │ ├── sunny_active.svg │ │ ├── sprinkle.svg │ │ ├── sprinkle_white.svg │ │ └── sprinkle_active.svg ├── listStyle.ts ├── entity │ ├── Category.ts │ ├── Response.ts │ ├── Todo.ts │ ├── StatisticCategory.ts │ ├── Authorization.ts │ ├── StatisticYear.ts │ ├── StatisticUser.ts │ ├── User.ts │ ├── LunarDate.ts │ └── Weather.ts ├── api │ ├── bankCardApi.ts │ ├── fileApi.ts │ ├── invitationApi.ts │ ├── billApi.ts │ ├── statisticApi.ts │ ├── fileManagerApi.ts │ └── userApi.ts ├── view │ ├── Invitation │ │ └── InvitationEntity.ts │ ├── BankCard │ │ └── BankCard.ts │ ├── Bill │ │ ├── BorrowInfo │ │ │ └── Borrow.ts │ │ ├── Bill.ts │ │ ├── BillMonthSummary.vue │ │ └── BillYearSelector.vue │ ├── FileManager │ │ ├── File.ts │ │ └── file-list-item.scss │ ├── ChangeProfile │ │ └── change-profile.scss │ ├── Calendar │ │ ├── VCalendar.ts │ │ ├── _calendar.scss │ │ └── CalendarListHeader.vue │ ├── Menu │ │ ├── ChangeLog │ │ │ └── ChangeLog.vue │ │ ├── YearSelector │ │ │ └── YearSelector.vue │ │ └── MenuCategorySelector │ │ │ ├── MenuCategoryIndicatorInlineVertical.vue │ │ │ ├── MenuCategoryIndicator.vue │ │ │ └── MenuCategoryIndicatorInline.vue │ ├── Login&Register │ │ ├── RegisterTip.vue │ │ └── FetchPassword.vue │ ├── Statistics │ │ ├── BillMonthSum │ │ │ └── StatisticBillMonthSum.vue │ │ ├── BillDaySum │ │ │ └── StatisticBillDaySum.vue │ │ ├── chartOption.ts │ │ ├── StatisticPanel.vue │ │ ├── Diary │ │ │ └── StatisticInfo.vue │ │ └── Weather │ │ │ └── StatisticWeather.vue │ ├── Edit │ │ ├── WeatherSelector │ │ │ ├── WeatherSelector.vue │ │ │ └── weather-selector.scss │ │ └── CategorySelector │ │ │ └── EditorCategorySelector.vue │ ├── Detail │ │ └── DateItem.vue │ └── DiaryList │ │ └── ListHeader.vue ├── framework │ ├── CalendarFramework.vue │ ├── pageHeader │ │ ├── PageHeader.vue │ │ └── page-header.scss │ ├── MenuPanelContainer.vue │ ├── IndexFramework.vue │ └── WaterfallFramework.vue ├── components │ ├── Modal.vue │ ├── ButtonNormal.vue │ ├── Button.vue │ ├── ButtonSmall.vue │ ├── ServerError.vue │ └── NotFound_404.vue └── main.ts ├── public ├── favicon.png ├── appicon-apple.png └── logo.svg ├── design_files ├── 银行图标.ai └── 标题日记-页面.ai ├── data_grip ├── 查询所有统计数量为 0 的用户.sql ├── 演示数据 - 删除操作.sql ├── 查询所有统计数量为 0 的用户和关联的日记.sql ├── 查询所有统计数量为 0 的用户和关联的邀请码.sql └── 生成演示数据.sql ├── custom.d.ts ├── .gitignore ├── config └── project_config.json ├── tsconfig.node.json ├── deploy.sh ├── .github └── FUNDING.yml ├── scripts └── update-date.js ├── tsconfig.json ├── README_screenshot.md ├── README.md └── package.json /src/scss/_mixin.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/public/favicon.png -------------------------------------------------------------------------------- /design_files/银行图标.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/design_files/银行图标.ai -------------------------------------------------------------------------------- /design_files/标题日记-页面.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/design_files/标题日记-页面.ai -------------------------------------------------------------------------------- /public/appicon-apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/public/appicon-apple.png -------------------------------------------------------------------------------- /src/scss/fonts/Galvji.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/src/scss/fonts/Galvji.ttf -------------------------------------------------------------------------------- /src/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/src/assets/images/favicon.png -------------------------------------------------------------------------------- /src/scss/fonts/Galvji-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/src/scss/fonts/Galvji-Bold.ttf -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/src/assets/icons/logo/logo_black.png -------------------------------------------------------------------------------- /src/assets/images/appicon_apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/src/assets/images/appicon_apple.png -------------------------------------------------------------------------------- /src/listStyle.ts: -------------------------------------------------------------------------------- 1 | // 列表的三种样式 2 | export enum EnumListStyle { 3 | 'list', // 普通列表 4 | 'detail', // 详情列表 5 | } -------------------------------------------------------------------------------- /src/scss/fonts/ImpactPureNumber.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/src/scss/fonts/ImpactPureNumber.ttf -------------------------------------------------------------------------------- /src/entity/Category.ts: -------------------------------------------------------------------------------- 1 | export interface CategoryEntity { 2 | name: string, 3 | name_en: string, 4 | color: string, 5 | } -------------------------------------------------------------------------------- /src/scss/fonts/JetBrainsMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyleBing/diary/HEAD/src/scss/fonts/JetBrainsMono-Regular.ttf -------------------------------------------------------------------------------- /src/entity/Response.ts: -------------------------------------------------------------------------------- 1 | export interface ResponseEntity { 2 | success: boolean, 3 | data: any[]|any, 4 | message: string 5 | } -------------------------------------------------------------------------------- /src/entity/Todo.ts: -------------------------------------------------------------------------------- 1 | export interface TodoEntity { 2 | id: number, 3 | isDone: boolean, 4 | content: string, 5 | note?: string 6 | } -------------------------------------------------------------------------------- /src/scss/_plugin.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "utility"; 3 | @import "gradient"; 4 | 5 | @import "animate"; 6 | @import "font"; 7 | @import "toast"; 8 | -------------------------------------------------------------------------------- /src/api/bankCardApi.ts: -------------------------------------------------------------------------------- 1 | import request from '../request.ts' 2 | 3 | export default { 4 | getBankCard() { return request('get' , null, null,'bank-card')} , 5 | } 6 | -------------------------------------------------------------------------------- /src/api/fileApi.ts: -------------------------------------------------------------------------------- 1 | import request from "../request.ts"; 2 | 3 | export default { 4 | getUploadToken(params: {bucket: string}) {return request('get', params, null, '/image-qiniu/')}, 5 | } 6 | -------------------------------------------------------------------------------- /src/view/Invitation/InvitationEntity.ts: -------------------------------------------------------------------------------- 1 | export interface InvitationEntity { 2 | id: string, 3 | date_create: string | Date, 4 | date_register: string | Date, 5 | binding_uid: number, 6 | is_shared: 0|1 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/view/BankCard/BankCard.ts: -------------------------------------------------------------------------------- 1 | export interface BankCardEntity{ 2 | cardNo: string, 3 | cardName: string, 4 | cardType: string, 5 | extraInfos: any[], 6 | '开户行'?: string, 7 | note?: string 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/view/Bill/BorrowInfo/Borrow.ts: -------------------------------------------------------------------------------- 1 | export interface EntityBorrow{ 2 | dateLoan: string, // 借还日期 3 | lender: string, // 贷款人 4 | usage: string, // 用途 5 | dateDue: string, // 还款日期 6 | total: number // 总额 7 | type: '借入'|'借出' 8 | } -------------------------------------------------------------------------------- /src/entity/StatisticCategory.ts: -------------------------------------------------------------------------------- 1 | export interface StatisticCategoryEntity{ 2 | nickname: string 3 | uid: number 4 | email: string 5 | phone: string 6 | avatar: string 7 | token: string 8 | group_id: number 9 | city: string 10 | geolocation: string 11 | } -------------------------------------------------------------------------------- /src/entity/Authorization.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface AuthorizationEntity{ 3 | nickname: string 4 | uid: number 5 | email: string 6 | phone: string 7 | avatar: string 8 | token: string 9 | group_id: number 10 | city: string 11 | geolocation: string 12 | } 13 | -------------------------------------------------------------------------------- /src/view/FileManager/File.ts: -------------------------------------------------------------------------------- 1 | export interface EntityFile { 2 | id: number, 3 | name_original: string, 4 | path: string, 5 | description: string, 6 | date_create: string, 7 | date_time: string, 8 | type: string, 9 | uid: number, 10 | size: number 11 | } 12 | 13 | -------------------------------------------------------------------------------- /data_grip/查询所有统计数量为 0 的用户.sql: -------------------------------------------------------------------------------- 1 | select * 2 | from users 3 | where users.count_diary < 5 4 | and users.count_qr = 0 5 | and users.count_words = 0 6 | and users.count_dict = 0 7 | and users.count_map_route = 0 8 | and users.count_map_pointer = 0 9 | and users.sync_count = 0 10 | and uid > 10 -------------------------------------------------------------------------------- /src/entity/StatisticYear.ts: -------------------------------------------------------------------------------- 1 | export interface StatisticYearEntity{ 2 | year: number, 3 | count: number, 4 | months: StatisticMonthEntity[] 5 | } 6 | export interface StatisticMonthEntity{ 7 | id: string, // 202501 8 | month: number, 9 | count: number 10 | } 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/entity/StatisticUser.ts: -------------------------------------------------------------------------------- 1 | export interface StatisticUserEntity{ 2 | uid: number, 3 | last_visit_time: string, 4 | nickname: string, 5 | register_time: string, 6 | count_diary: number, 7 | count_dict: number, 8 | count_map_route: number, 9 | sync_count: number 10 | } 11 | -------------------------------------------------------------------------------- /custom.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.svg?url" { 2 | const content: any; 3 | export default content; 4 | } 5 | 6 | declare module "*.md" { 7 | const content: string; 8 | export default content; 9 | } 10 | 11 | declare module "marked" { 12 | export function parse(text: string): string; 13 | } 14 | -------------------------------------------------------------------------------- /data_grip/演示数据 - 删除操作.sql: -------------------------------------------------------------------------------- 1 | delete 2 | from diary.diaries 3 | 4 | where uid = 10 5 | and ( 6 | title REGEXP '闲鱼|龚|林晴|点点|爸|姑|姨|邴|工资|闫|密码|王奇|金|酒店|宾馆|华山|泰物|她|癫痫|贷|哥|志辉|仁远|姣|延璐|肛|杀|5530|韩' 7 | or content REGEXP '闲鱼|龚|林晴|点点|爸|姑|姨|邴|工资|闫|密码|王奇|金|酒店|宾馆|华山|泰物|她|癫痫|贷|哥|志辉|仁远|姣|延璐|肛|杀|5530|韩' 8 | ) 9 | and date 10 | between '2024-01-01 00:00:00' and '2025-03-14 11:26:06' 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json 4 | /dist 5 | /diary 6 | 7 | # local env files 8 | .env.local 9 | .env.*.local 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | 25 | 26 | 27 | archive 28 | dev-dist 29 | -------------------------------------------------------------------------------- /data_grip/查询所有统计数量为 0 的用户和关联的日记.sql: -------------------------------------------------------------------------------- 1 | delete diaries 2 | from diaries join users on users.uid = diaries.uid 3 | where users.count_diary < 5 4 | and users.count_qr = 0 5 | and users.count_words = 0 6 | and users.count_dict = 0 7 | and users.count_map_route = 0 8 | and users.count_map_pointer = 0 9 | and users.sync_count = 0 10 | and users.uid > 10 11 | and users.last_visit_time < '2024-01-01 00:00:00' 12 | 13 | ; -------------------------------------------------------------------------------- /data_grip/查询所有统计数量为 0 的用户和关联的邀请码.sql: -------------------------------------------------------------------------------- 1 | delete invitations 2 | from invitations join users on users.uid = invitations.binding_uid 3 | where users.count_diary < 5 4 | and users.count_qr = 0 5 | and users.count_words = 0 6 | and users.count_dict = 0 7 | and users.count_map_route = 0 8 | and users.count_map_pointer = 0 9 | and users.sync_count = 0 10 | and users.uid > 10 11 | and users.last_visit_time < '2024-01-01 00:00:00' 12 | 13 | ; -------------------------------------------------------------------------------- /config/project_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "admin_email": "xxx@163.com", 3 | "is_show_demo_account": true, 4 | 5 | "demo_account": "test@163.com", 6 | "demo_account_password": "test", 7 | 8 | "qiniu_img_base_url": "", 9 | "qiniu_bucket_name": "", 10 | "qiniu_style_suffix": "", 11 | 12 | "hefeng_weather_api_key": "", 13 | "hefeng_weather_api_host": "", 14 | 15 | "register_tip": "

长期未使用的用户将定期进行清理,大概一年清一次。

" 16 | } 17 | -------------------------------------------------------------------------------- /src/assets/icons/tab/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / add 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/api/invitationApi.ts: -------------------------------------------------------------------------------- 1 | import request from '../request.ts' 2 | 3 | export default { 4 | list() { return request('get' , null, null, 'invitation/list')} , 5 | generate() { return request('post' , null, null, 'invitation/generate')} , 6 | delete(params: {diaryId: number}){ return request('delete', params, null, 'invitation/delete')}, 7 | markAsShared(requestData: {id: number}){ return request('post', null, requestData, 'invitation/mark-shared')}, 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true, 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["src/*"], 11 | "@/view/*": ["src/view/*"], 12 | "@/api/*": ["src/api/*"] 13 | } 14 | }, 15 | "include": [ 16 | "vite.config.ts", 17 | "./**/*.ts", 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /src/assets/icons/tab/add_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / add_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/entity/User.ts: -------------------------------------------------------------------------------- 1 | export interface UserEntity { 2 | name: string, 3 | name_en: string, 4 | color: string, 5 | } 6 | 7 | export interface UserRegisterEntity { 8 | nickname: string, 9 | invitationCode: string, 10 | email: string, 11 | password: string, 12 | } 13 | 14 | export interface UserProfileEntity{ 15 | nickname: string, 16 | phone: string, 17 | avatar: string, 18 | city: string, 19 | geolocation: string, 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/assets/icons/tab/done.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / done 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/tab/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / close 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/api/billApi.ts: -------------------------------------------------------------------------------- 1 | import request from '../request.ts' 2 | 3 | export default { 4 | sorted(params: {years: string, keyword: string}) { return request('get' , params, null, 'bill/sorted')} , 5 | keys() { return request('get' , null, null, 'bill/keys')} , 6 | 7 | getBorrowList(): Promise<{success: boolean, data: string}> { 8 | return request('get', null, null,'bill/borrow')}, 9 | 10 | // allInOne(params) { return request('get' , params, null, 'bill')} , 11 | } 12 | -------------------------------------------------------------------------------- /src/assets/icons/tab/done_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / done_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/scss/_font.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "ImpactDiary"; 3 | src: url(@/scss/fonts/ImpactPureNumber.ttf); 4 | } 5 | 6 | @font-face { 7 | font-family: "JetBrainsMonoDiary"; 8 | src: url(@/scss/fonts/JetBrainsMono-Regular.ttf); 9 | } 10 | 11 | @font-face { 12 | font-family: "Galvji"; 13 | src: url(@/scss/fonts/Galvji.ttf); 14 | font-weight: normal; 15 | } 16 | @font-face { 17 | font-family: "Galvji"; 18 | src: url(@/scss/fonts/Galvji-Bold.ttf); 19 | font-weight: bold; 20 | } 21 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd /var/www/html 3 | 4 | # 尝试列出匹配的文件,并将错误信息重定向到 /dev/null 5 | file_list=$(ls diary-*.zip 2>/dev/null) 6 | 7 | # 判断获取到的文件名列表是否为空 8 | if [ -n "$file_list" ]; then 9 | echo "存在匹配 diary-*.zip 的文件,开始解压..." 10 | 11 | # 清空 ./diary 目录 12 | rm -Rf ./diary/* 13 | 14 | # 遍历匹配到的文件并解压 15 | for file in $file_list; do 16 | unzip -o "$file" -d ./diary 17 | done 18 | echo "解压完成。" 19 | rm -f "${file}" 20 | else 21 | echo "不存在匹配 diary-*.zip 的文件。" 22 | fi 23 | -------------------------------------------------------------------------------- /src/assets/icons/tab/close_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / close_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/entity/LunarDate.ts: -------------------------------------------------------------------------------- 1 | export interface LunarDateEntity{ 2 | Animal: string, 3 | IDayCn: string, 4 | IMonthCn: string, 5 | Term: null, 6 | astro: string, 7 | cDay: number, 8 | cMonth: number, 9 | cYear: number, 10 | gzDay: string, 11 | gzMonth: string, 12 | gzYear: string, 13 | isLeap: false, 14 | isTerm: false, 15 | isToday: false, 16 | lDay: number, 17 | lMonth: number, 18 | lYear: number, 19 | nWeek: number, 20 | ncWeek: string 21 | } 22 | -------------------------------------------------------------------------------- /src/assets/icons/tab/eye_close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / eye_close 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/api/statisticApi.ts: -------------------------------------------------------------------------------- 1 | import request from '../request.ts' 2 | export default { 3 | category(){ return request('get', null, null,'statistic/category')}, 4 | year() { return request('get', null, null,'statistic/year')} , 5 | users() { return request('get', null, null,'statistic/users')} , 6 | weather() { return request('get', null, null,'statistic/weather')} , 7 | daySum() { return request('get', null , null,'bill/day-sum')} , 8 | monthSum() { return request('get', null, null,'bill/month-sum')} , 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/icons/tab/eye_close_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / eye_close_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/framework/CalendarFramework.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /src/assets/icons/tab/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / menu 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/api/fileManagerApi.ts: -------------------------------------------------------------------------------- 1 | import request from "../request.ts"; 2 | 3 | export default { 4 | list(params: {pageNo: number, pageSize: number}) {return request('get', params, null, '/file-manager/list')}, 5 | upload(requestData: FormData) {return request('post', null, requestData, '/file-manager/upload')}, 6 | modifyFileName(requestData: {fileId: number, description: string}) {return request('post', null, requestData, '/file-manager/modify')}, 7 | delete(requestData: {fileId: number}) {return request('delete', null, requestData, '/file-manager/delete')}, 8 | } 9 | -------------------------------------------------------------------------------- /src/assets/icons/tab/statistics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ statistics 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/tab/about.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ about 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/card.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/card 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/done_saved.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / done_saved 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/menu_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / menu_black 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / search 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/done_changed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / done_changed 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/statistics_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ statistics_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/tab/about_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ about_black 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/card_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ card_black 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/eye_open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / eye_open 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/scss/_dark.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * 样式 - 暗黑模式 3 | */ 4 | 5 | 6 | @media (prefers-color-scheme: dark) { 7 | 8 | // SCROLL 9 | ::-webkit-scrollbar { 10 | background-color: $dark-bg-dark; 11 | } 12 | ::-webkit-scrollbar-track { 13 | background-color: rgba(0, 0, 0, 0); 14 | } 15 | ::-webkit-scrollbar-thumb { 16 | background-color: $dark-scroll-thumb; 17 | } 18 | 19 | body{ 20 | background-color: $dark-bg-nav !important; 21 | .diary-list-container{ 22 | border-right-color: $dark-border !important; 23 | background-color: $dark-bg; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/assets/icons/bank/工商银行.svg: -------------------------------------------------------------------------------- 1 | 工商银行 -------------------------------------------------------------------------------- /src/assets/icons/tab/back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / back 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/view/ChangeProfile/change-profile.scss: -------------------------------------------------------------------------------- 1 | @import "../../scss/plugin"; 2 | 3 | .avatar{ 4 | flex-shrink: 0; 5 | box-sizing: content-box; 6 | @extend .btn-like; 7 | @include transition(all 0.3s); 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | border: 2.5px solid $color-main; 12 | img{ 13 | width: 100%; 14 | } 15 | &:hover{ 16 | border-color: $color-main; 17 | @include transition(all 0.3s); 18 | @include box-shadow(0 0 25px transparentize($color-main, 0.3)) 19 | } 20 | } 21 | 22 | input[type=file]{ 23 | display: none; 24 | } 25 | -------------------------------------------------------------------------------- /src/assets/icons/tab/search_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / search_black 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/eye_open_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / eye_open_black 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/back_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / back_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/icons/content_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | content_white 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/list_simple.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ list_simple 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/view/Calendar/VCalendar.ts: -------------------------------------------------------------------------------- 1 | export interface CalendarAttribute { 2 | key: number, 3 | bar: { 4 | style: { 5 | backgroundColor: string 6 | } 7 | }, 8 | highlight: { 9 | fillMode: 'solid' | 'light' | 'outline', 10 | color: string, 11 | }, 12 | color: string, 13 | dates: Date, 14 | popover: { 15 | label: string, 16 | visibility: 'click' | 'hover', 17 | hideIndicator: boolean, // 隐藏弹窗中不同条目的类别标识,在条目前面的标识 18 | } 19 | } 20 | 21 | 22 | export interface CalendarEntity { 23 | name: string, 24 | color: string, 25 | dates: Array<[Array]> 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/assets/icons/tab/list_simple_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ list_simple_black 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/icons/weather/overcast_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / overcast_white 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/tab/category.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ category 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/entity/Weather.ts: -------------------------------------------------------------------------------- 1 | export const WeatherArray = [ 2 | {value : 'sunny' , label : '晴'} , 3 | {value : 'cloudy' , label : '多云'} , 4 | {value : 'overcast' , label : '阴'} , 5 | {value : 'sprinkle' , label : '小雨'} , 6 | {value : 'rain' , label : '雨'} , 7 | {value : 'thunderstorm' , label : '暴雨'} , 8 | {value : 'snow' , label : '雪'} , 9 | {value : 'fog' , label : '雾'} , 10 | {value : 'tornado' , label : '龙卷风'} , 11 | {value : 'smog' , label : '雾霾'} , 12 | {value : 'sandstorm' , label : '沙尘暴'} , 13 | ] 14 | 15 | export const WeatherMap: Map = new Map(WeatherArray.map(item => [item.value, item.label])) 16 | 17 | -------------------------------------------------------------------------------- /src/assets/icons/bank/交通银行.svg: -------------------------------------------------------------------------------- 1 | 交通银行 -------------------------------------------------------------------------------- /src/assets/icons/tab/category_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ category_black 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/scss/_gutter.scss: -------------------------------------------------------------------------------- 1 | $timer: 5px; 2 | // common 3 | @for $item from 0 through 8 { 4 | .mt-#{$item}{margin-top : $timer * $item !important;} 5 | .mb-#{$item}{margin-bottom : $timer * $item !important;} 6 | .ml-#{$item}{margin-left : $timer * $item !important;} 7 | .mr-#{$item}{margin-right : $timer * $item !important;} 8 | .m-#{$item} {margin : $timer * $item !important;} 9 | 10 | .pt-#{$item}{padding-top : $timer * $item !important;} 11 | .pb-#{$item}{padding-bottom : $timer * $item !important;} 12 | .pl-#{$item}{padding-left : $timer * $item !important;} 13 | .pr-#{$item}{padding-right : $timer * $item !important;} 14 | .p-#{$item} {padding : $timer * $item !important;} 15 | } 16 | -------------------------------------------------------------------------------- /src/assets/icons/bank/建设银行.svg: -------------------------------------------------------------------------------- 1 | 建设银行 -------------------------------------------------------------------------------- /src/view/Menu/ChangeLog/ChangeLog.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 19 | 20 | 26 | -------------------------------------------------------------------------------- /src/components/Modal.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 39 | -------------------------------------------------------------------------------- /src/assets/icons/tab/list_detail.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ list_detail 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/framework/pageHeader/PageHeader.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 24 | 25 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/assets/icons/tab/bill_simple.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ bill_simple 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/tab/list_detail_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ list_detail_black 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/tab/bill_simple_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ bill_simple_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/tab/recover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / recover 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/ButtonNormal.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 37 | -------------------------------------------------------------------------------- /src/assets/icons/tab/recover_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / recover_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/weather/overcast.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | weather / overcast 5 | Created with Sketch. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data_grip/生成演示数据.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO diary.diaries (date, title, content, temperature, temperature_outside, weather, category, date_create, 2 | date_modify, uid, is_public, is_markdown) 3 | select date, 4 | title, 5 | content, 6 | temperature, 7 | temperature_outside, 8 | weather, 9 | category, 10 | date_create, 11 | date_modify, 12 | 10, 13 | is_public, 14 | is_markdown 15 | from diary.diaries 16 | where uid = 3 17 | and category = 'memo' 18 | and title not REGEXP '闲鱼|龚|林晴|点点|爸|姑|姨|邴|工资|闫|密码|王奇|金|酒店|宾馆|华山|泰物|她|癫痫|贷|哥|志辉|仁远|姣|延璐|肛|杀|5530|韩' 19 | and content not REGEXP '闲鱼|龚|林晴|点点|爸|姑|姨|邴|工资|闫|密码|王奇|金|酒店|宾馆|华山|泰物|她|癫痫|贷|哥|志辉|仁远|姣|延璐|肛|杀|5530|韩' 20 | and date 21 | between '2024-01-01 00:00:00' and '2025-03-14 11:26:06' 22 | -------------------------------------------------------------------------------- /src/assets/icons/tab/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / edit 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/bank/招商银行.svg: -------------------------------------------------------------------------------- 1 | 招商银行 -------------------------------------------------------------------------------- /src/assets/icons/icons/content_md.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | content_md 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/edit_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / edit_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/weather/overcast_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | weather / overcast_active 5 | Created with Sketch. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/icons/weather/snow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / snow 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/framework/pageHeader/page-header.scss: -------------------------------------------------------------------------------- 1 | @import "../../scss/plugin"; 2 | 3 | .page-header{ 4 | z-index: $z-header; 5 | position: sticky; 6 | top: 0; 7 | height: $height-navbar; 8 | background-color: $bg-main; 9 | display: flex; 10 | color: white; 11 | padding-right: 10px; 12 | justify-content: space-between; 13 | align-items: center; 14 | .page-title{ 15 | flex-shrink: 0; 16 | font-size: $fz-title; 17 | font-weight: bold; 18 | text-align: left; 19 | } 20 | .page-subtitle{ 21 | margin-left: 10px; 22 | color: transparentize(white, 0.6); 23 | flex-grow: 1; 24 | font-size: $fz-main; 25 | text-align: left; 26 | } 27 | .page-back-btn{ 28 | } 29 | } 30 | 31 | @media (prefers-color-scheme: dark) { 32 | // Page Header 33 | .page-header{ 34 | background-color: $dark-bg-nav; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/assets/icons/bank/银行.svg: -------------------------------------------------------------------------------- 1 | 银行 -------------------------------------------------------------------------------- /src/assets/icons/icons/content_md_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | content_md_white 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/weather/snow_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / snow_white 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_rounded.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo-login 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [KyleBing] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: ['kylebing.cn'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /src/api/userApi.ts: -------------------------------------------------------------------------------- 1 | import request from '../request.ts' 2 | import {UserProfileEntity, UserRegisterEntity} from "../entity/User.ts"; 3 | 4 | export default { 5 | login(requestData: {email: string, password: string}) { return request('post', {}, requestData, 'user/login')} , 6 | register(requestData: UserRegisterEntity) { return request('post', {}, requestData, 'user/register')} , 7 | changePassword(requestData: {password: string}){ return request('put' , {}, requestData, 'user/change-password')}, 8 | setProfile(requestData: UserProfileEntity) { return request('put' , {}, requestData, 'user/set-profile')}, 9 | // 注销账户 10 | destroyAccount() { return request('delete' , {}, null, 'user/destroy-account')}, 11 | 12 | // 获取头像 13 | getAvatar(params: {email: string}) { return request('get', params, null, 'user/avatar')} , 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/assets/icons/weather/thunderstorm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / thunderstorm 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/weather/thunderstorm_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / thunderstorm_white 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/weather/cloudy_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / cloudy_white 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/weather/thunderstorm_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / thunderstorm_active 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | web / logo 4 | 8 | -------------------------------------------------------------------------------- /src/scss/_menu-section.scss: -------------------------------------------------------------------------------- 1 | // Menu Section 2 | .menu-section{ 3 | padding: 0 0 30px; 4 | border-bottom: -1px solid $color-border-menu; 5 | .menu-section-title{ 6 | font-size: $fz-title; 7 | font-weight: bold; 8 | color: white; 9 | margin-bottom: 5px; 10 | } 11 | .menu-section-subtitle{ 12 | font-size: $fz-small; 13 | color: $text-menu-second; 14 | margin-bottom: 15px; 15 | } 16 | .menu-section-content{ 17 | .btn-list{ 18 | display: flex; 19 | justify-content: flex-start; 20 | flex-flow: row wrap; 21 | .btn{ 22 | margin-bottom: 10px; 23 | width: 48%; 24 | margin-right: 4%; 25 | &:nth-child(2n){ 26 | margin-right: 0; 27 | } 28 | } 29 | } 30 | } 31 | } 32 | 33 | .desc{ 34 | font-size: $fz-small; 35 | color: $text-menu-second; 36 | } 37 | 38 | @media (max-width: $grid-separate-width-sm) { 39 | .menu-section {} 40 | } 41 | -------------------------------------------------------------------------------- /src/scss/_gradient.scss: -------------------------------------------------------------------------------- 1 | 2 | $gradient-violet: #8876fe; 3 | $gradient-plum: #8d1287; 4 | $gradient-indigo: #622aff; 5 | $gradient-azure: #027fff; 6 | $gradient-tomato: #f63e54; 7 | $gradient-persimmon: #e94b1b; 8 | $gradient-pumpkin: #e2620c; 9 | $gradient-orange: #e66702; 10 | $gradient-green: #0c9d46; 11 | $gradient-sea-green: #099b9d; 12 | $gradient-teal: #049cb7; 13 | $gradient-aqua: #039e8f; 14 | $gradient-sapphire: #3d44c3; 15 | $gradient-ultramarine: #0d1387; 16 | $gradient-magenta: #dd04d1; 17 | $gradient-tangelo: #ff3e17; 18 | $gradient-cobalt: #5451fb; 19 | 20 | 21 | $gradient-linear-blue: linear-gradient(135deg,#1c7df3,#1abcfa); 22 | $gradient-linear-green: linear-gradient(135deg, $gradient-teal,#3dd9bd); 23 | $gradient-linear-purple: linear-gradient(135deg,#0D1387,#867AF6); 24 | $gradient-linear-red: linear-gradient(135deg,$gradient-tomato,$gradient-tangelo); 25 | $gradient-linear-orange: linear-gradient(135deg,$gradient-tomato,$gradient-orange); 26 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo / logo 4 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/weather/rain_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / rain_white 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scripts/update-date.js: -------------------------------------------------------------------------------- 1 | import { readFileSync, writeFileSync } from 'fs'; 2 | import { fileURLToPath } from 'url'; 3 | import { dirname, join } from 'path'; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | // Get current date in YYYY.MM.DD format 9 | const now = new Date(); 10 | const year = now.getFullYear(); 11 | const month = String(now.getMonth() + 1).padStart(2, '0'); 12 | const day = String(now.getDate()).padStart(2, '0'); 13 | const dateModify = `${year}.${month}.${day}`; 14 | 15 | // Read package.json 16 | const packagePath = join(__dirname, '..', 'package.json'); 17 | const packageJson = JSON.parse(readFileSync(packagePath, 'utf8')); 18 | 19 | // Update dateModify 20 | packageJson.dateModify = dateModify; 21 | 22 | // Write back to package.json 23 | writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8'); 24 | 25 | console.log(`✓ Updated dateModify to: ${dateModify}`); 26 | 27 | -------------------------------------------------------------------------------- /src/assets/icons/bank/民生银行.svg: -------------------------------------------------------------------------------- 1 | 民生银行 -------------------------------------------------------------------------------- /src/assets/icons/weather/cloudy_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | weather / cloudy_active 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo / logo_close 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["src/*"], 6 | "@/view/*": ["src/view/*"], 7 | "@/api/*": ["src/api/*"] 8 | }, 9 | 10 | "target": "ES2020", 11 | "useDefineForClassFields": true, 12 | "module": "ESNext", 13 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 14 | "skipLibCheck": true, 15 | 16 | /* Bundler mode */ 17 | "moduleResolution": "bundler", 18 | "allowImportingTsExtensions": true, 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "noEmit": true, 22 | 23 | /* Linting */ 24 | "strict": true, 25 | "noUnusedLocals": true, 26 | "noUnusedParameters": true, 27 | "noFallthroughCasesInSwitch": true, 28 | "allowSyntheticDefaultImports": true 29 | }, 30 | "files": ["custom.d.ts"], 31 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], 32 | "references": [{ "path": "./tsconfig.node.json" }] 33 | } 34 | -------------------------------------------------------------------------------- /src/assets/icons/weather/snow_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / snow_active 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/icons/bank/浦发银行.svg: -------------------------------------------------------------------------------- 1 | 浦发银行 -------------------------------------------------------------------------------- /src/assets/icons/icons/content.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | content 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/icons/tab/key.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ key 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/tab/key_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ key_black 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/scss/_normalize.scss: -------------------------------------------------------------------------------- 1 | .bold{ 2 | font-weight: bold; 3 | } 4 | .number{ 5 | font-family: 'JetBrainsMonoDiary' !important; 6 | } 7 | .text-green{color: $gradient-aqua;} 8 | .text-orange{color: $gradient-pumpkin;} 9 | .text-black{color: #000;} 10 | .text-gray{color: $gray;} 11 | .text-income{color: #9e8600} 12 | .text-expense{color: #01a67a} 13 | .text-invalid{color: #999} 14 | 15 | 16 | .text-left{text-align: left !important;} 17 | .text-right{text-align: right !important;} 18 | .text-center{text-align: center !important;} 19 | 20 | 21 | .float-left {float: left !important;} 22 | .float-right {float: right !important;} 23 | .hidden {display: none !important;} 24 | .show {display: block !important;} 25 | 26 | 27 | .flex-start{ 28 | justify-content: flex-start !important; 29 | } 30 | .flex-end{ 31 | justify-content: flex-end !important; 32 | } 33 | .flex-center{ 34 | justify-content: center !important; 35 | } 36 | 37 | 38 | .link { 39 | @extend .btn-like; 40 | &:hover { 41 | text-decoration: underline; 42 | } 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/assets/icons/weather/rain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | weather / rain 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/bank/中国银行.svg: -------------------------------------------------------------------------------- 1 | 中国银行 -------------------------------------------------------------------------------- /src/assets/icons/tab/calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ calendar 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/framework/MenuPanelContainer.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 43 | -------------------------------------------------------------------------------- /src/assets/icons/weather/cloudy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | weather / cloudy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/tab/calendar_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ calendar_black 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/icons/tab/share.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / share 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/icons/weather/rain_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | weather / rain_active 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/tab/share_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / share_black 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_avatar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo-avatar 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/tab/waterfall.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ waterfall 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_server_error.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo / logo_server_error 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/tab/changelog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/changelog 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/icons/tab/waterfall_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ waterfall_black 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/tab/changelog_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ changelog_black 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/icons/bank/农业银行.svg: -------------------------------------------------------------------------------- 1 | 农业银行 -------------------------------------------------------------------------------- /src/assets/icons/tab/invitation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ invitation 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | // main.ts 2 | import {createApp} from 'vue' 3 | 4 | // APP 5 | import App from './App.vue' 6 | const app = createApp(App) 7 | 8 | // PINIA 9 | import {createPinia} from "pinia" 10 | const pinia = createPinia() 11 | app.use(pinia) 12 | 13 | // ROUTER 14 | import {router} from "./router" 15 | app.use(router) 16 | 17 | 18 | // TOOLTIP 19 | import FloatingVue from 'floating-vue' 20 | let tooltipOptions = { 21 | // tooltip for bill 22 | arrowOverflow: true, 23 | themes: { 24 | 'tooltip-bill': { // 这是主题名,对应 bill 页面中 v-tooltip 的 theme 25 | placement: 'right', 26 | triggers: ['hover', 'focus', 'touch'], 27 | } 28 | } 29 | } 30 | app.use(FloatingVue, tooltipOptions) 31 | import 'floating-vue/dist/style.css' 32 | 33 | // 使移动端支持 :hover 样式 34 | document.addEventListener("touchstart", function () { 35 | }, false) 36 | 37 | // MOMENT 38 | import Moment from "moment" 39 | Moment.locale('zh', { 40 | week: { 41 | dow: 1 // 全局配置 moment,设置星期的第一天为 星期一 42 | } 43 | }) 44 | 45 | // Date Picker 46 | import Datepicker from '@vuepic/vue-datepicker'; 47 | import '@vuepic/vue-datepicker/dist/main.css'; 48 | app.component('Datepicker', Datepicker); 49 | 50 | app.mount('#app') 51 | -------------------------------------------------------------------------------- /src/assets/icons/tab/invitation_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ invitation_black 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/view/Login&Register/RegisterTip.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 19 | 20 | 54 | -------------------------------------------------------------------------------- /src/assets/icons/bank/中信银行.svg: -------------------------------------------------------------------------------- 1 | 中信银行 -------------------------------------------------------------------------------- /src/assets/icons/bank/广发银行.svg: -------------------------------------------------------------------------------- 1 | 广发银行 -------------------------------------------------------------------------------- /README_screenshot.md: -------------------------------------------------------------------------------- 1 | project_logo 2 | 3 | # 标题日记 4 | 5 | login 6 | list-diary 7 | detail 8 | todo-list 9 | diary-filter 10 | bill 11 | bill-filter 12 | function 13 | statistic 14 | -------------------------------------------------------------------------------- /src/assets/icons/weather/tornado.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / tornado 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/view/Statistics/BillMonthSum/StatisticBillMonthSum.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 41 | 42 | 44 | -------------------------------------------------------------------------------- /src/assets/icons/weather/tornado_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / tornado_white 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/icons/weather/tornado_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / tornado_active 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/view/Statistics/BillDaySum/StatisticBillDaySum.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 41 | 42 | 44 | -------------------------------------------------------------------------------- /src/view/Statistics/chartOption.ts: -------------------------------------------------------------------------------- 1 | /* 通用 echart 配置 */ 2 | 3 | const COLOR = { 4 | main : '#00deff', 5 | label : '#aaa', 6 | title : '#fff', 7 | white : '#fff', 8 | line : 'rgba(0,0,0,0.2)', 9 | green : '#2bb06a', 10 | cyan : '#5AC8FA', 11 | blue : '#007AFF', 12 | purple : '#5856D6', 13 | magenta: '#FF2D70', 14 | red : '#FF3B30', 15 | orange : '#FF9500', 16 | yellow : '#FFCC00', 17 | gray : '#8E8E93', 18 | primary: '#409EFF' 19 | } 20 | const COLOR_ARRAY = [ 21 | '#FF9500', 22 | '#007AFF', 23 | '#4CD964', 24 | '#5AC8FA', 25 | '#5856D6', 26 | '#FF2D70', 27 | '#FF3B30', 28 | '#FFCC00', 29 | '#8E8E93', 30 | ] 31 | 32 | const LEGEND = { // 图例样式 33 | textStyle: { 34 | color: '#fff' 35 | }, 36 | type: 'scroll', 37 | orient: 'vertical', 38 | top: 0, 39 | right: 0, 40 | data: [] 41 | } 42 | const TOOLTIP = { 43 | trigger: 'axis', 44 | } 45 | const GRID = { // 图表边界 46 | top: 20, 47 | bottom: 20, 48 | left: 40, 49 | right: 20, 50 | borderColor: COLOR.green 51 | } 52 | 53 | export default { 54 | COLOR, 55 | LEGEND, 56 | GRID, 57 | TOOLTIP, 58 | COLOR_ARRAY, 59 | COLOR_OPTION: [COLOR.main, COLOR.green], 60 | COLOR_BAR: [COLOR.green, COLOR.purple], 61 | } 62 | -------------------------------------------------------------------------------- /src/view/Calendar/_calendar.scss: -------------------------------------------------------------------------------- 1 | @import "../../scss/plugin"; 2 | 3 | // 日历容器 4 | .calendar-container{ 5 | flex-shrink: 0; 6 | display: flex; 7 | justify-content: flex-start; 8 | overflow-y: auto; 9 | } 10 | 11 | // 日历本体 12 | .calendar{ 13 | padding: 20px; 14 | overflow-y: auto; 15 | 16 | } 17 | 18 | // 日历操作面板 19 | .calendar-operation-panel{ 20 | flex-grow: 1; 21 | } 22 | 23 | // 日历日记列表弹窗 24 | .popover-list{ 25 | padding: 5px; 26 | font-size: $fz-small; 27 | 28 | .popover-list-item{ 29 | padding: 1px 0; 30 | display: flex; 31 | justify-content: flex-start; 32 | align-items: center; 33 | .indicator{ 34 | margin-right: 5px; 35 | display: block; 36 | @include border-radius(10px); 37 | width: 12px; 38 | height: 4px; 39 | } 40 | } 41 | } 42 | 43 | // 日历日记列表 44 | .calendar-diary-list{ 45 | background-color: $bg-light; 46 | border-left: 1px solid $color-border; 47 | border-right: 1px solid $color-border; 48 | padding: 20px; 49 | width: 500px; 50 | overflow-y: auto; 51 | } 52 | 53 | @media (prefers-color-scheme: dark) { 54 | .calendar-diary-list{ 55 | background-color: $dark-bg; 56 | border-left-color: $dark-border; 57 | border-right-color: $dark-border; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/components/Button.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | 54 | -------------------------------------------------------------------------------- /src/view/Edit/WeatherSelector/WeatherSelector.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 41 | 42 | 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | project_logo 2 | 3 | # 标题日记 4 | 5 | 一个纯文本 web 日记应用,专注记录生活琐事。 6 | [http://kylebing.cn/diary](http://kylebing.cn/diary) 7 | 8 | 9 | 10 | ## 一、界面 11 | 12 | ![main_view](https://github.com/user-attachments/assets/4c3efa8f-322c-41ae-bb0d-0b20c6143bea) 13 | 14 | 15 | ## 二、用法 16 | 17 | **标题**:20 字以内,概括 18 | **内容**:事件详情 19 | 20 | 记录一天中你感觉值得记录的事,生活、学习、工作、运动 等等方面。 21 | 记下此刻,记下你怕忘的内容,日后好查找。 22 | 23 | ## 三、前端、后台 24 | 25 | - 前端:[https://github.com/KyleBing/diary-vue](https://github.com/KyleBing/diary-vue) `vue3`、`ts`、`vite` 26 | - 后台:[https://github.com/KyleBing/portal](https://github.com/KyleBing/portal) `nodejs` 27 | 28 | --- 29 | 30 | ## → [日记详细使用说明](https://kylebing.github.io/readme/diary/%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D.html) 31 | ## → [部署自己的日记系统](https://kylebing.github.io/readme/diary/%E9%83%A8%E7%BD%B2%E8%AF%B4%E6%98%8E.html) 32 | ## → [其它截图](./README_screenshot.md) 33 | ## → [版本更新记录](https://github.com/KyleBing/diary/discussions/3) 34 | 35 | 36 | --- 37 | 38 | 感谢 [JetBrains](https://www.jetbrains.com/?from=diary-vue@KyleBing) 提供的工具支持 39 | 40 | JetBrains 41 | -------------------------------------------------------------------------------- /src/view/Statistics/StatisticPanel.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | 20 | 64 | 65 | -------------------------------------------------------------------------------- /src/view/Statistics/Diary/StatisticInfo.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 38 | 39 | 41 | -------------------------------------------------------------------------------- /src/assets/icons/icons/clipboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icons / clipboard 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/components/ButtonSmall.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 47 | -------------------------------------------------------------------------------- /src/view/Detail/DateItem.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | 26 | 65 | -------------------------------------------------------------------------------- /src/components/ServerError.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 21 | 22 | 54 | -------------------------------------------------------------------------------- /src/scss/_form.scss: -------------------------------------------------------------------------------- 1 | input[type=checkbox], 2 | input[type=radio] 3 | { 4 | display: none; 5 | } 6 | 7 | $height-radio: 16px; 8 | $radio-gap: 3px; 9 | $radio-length-timer: 2.5; 10 | 11 | input[type=checkbox] + label.switch 12 | { 13 | position: relative; 14 | display: block; 15 | @include border-radius($height-radio * 1.5); 16 | background-color: $color-border; 17 | @include box-shadow(inset 0 1px 2px rgba(0,0,0,0.1)); 18 | height: $height-radio + $radio-gap * 2; 19 | width: $height-radio * $radio-length-timer; 20 | @include transition(all 0.3s); 21 | &:before{ 22 | content: ''; 23 | display: block; 24 | position: absolute; 25 | top: $radio-gap; 26 | left: $radio-gap; 27 | width: $height-radio; 28 | height: $height-radio; 29 | @include border-radius($height-radio); 30 | background-color: white; 31 | @include box-shadow(1px 2px 3px rgba(0,0,0,0.2)); 32 | @include transition(all 0.3s); 33 | } 34 | } 35 | 36 | input[type=checkbox]:checked + label.switch 37 | { 38 | background-color: $green; 39 | @include box-shadow(inset 0 1px 2px rgba(0,0,0,0.1)); 40 | @include transition(all 0.3s); 41 | &:before{ 42 | content: ''; 43 | display: block; 44 | position: absolute; 45 | left: $height-radio * $radio-length-timer - $radio-gap - $height-radio; 46 | right: 0; 47 | width: $height-radio; 48 | height: $height-radio; 49 | @include border-radius($height-radio); 50 | @include transition(all 0.3s); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/assets/icons/weather/sandstorm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / sandstorm 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/tab/others.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ others 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo / logo-black 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/icons/tab/others_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ others_black 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/view/Login&Register/FetchPassword.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 24 | 39 | -------------------------------------------------------------------------------- /src/view/Statistics/Weather/StatisticWeather.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /src/components/NotFound_404.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | 19 | 59 | -------------------------------------------------------------------------------- /src/view/Bill/Bill.ts: -------------------------------------------------------------------------------- 1 | export const MonthNameMap: Map = new Map([ 2 | ['01', '一月'], 3 | ['02', '二月'], 4 | ['03', '三月'], 5 | ['04', '四月'], 6 | ['05', '五月'], 7 | ['06', '六月'], 8 | ['07', '七月'], 9 | ['08', '八月'], 10 | ['09', '九月'], 11 | ['10', '十月'], 12 | ['11', '十一月'], 13 | ['12', '十二月'], 14 | ]) 15 | 16 | // 月份账单 17 | export interface EntityBillMonth { 18 | id: number, 19 | days: Array, 20 | food: EntityBillFood, 21 | month: string, 22 | month_id: string, 23 | sum: number, 24 | sumIncome: number, 25 | sumOutput: number, 26 | incomeTop5: Array, 27 | outcomeTop5: Array, 28 | } 29 | 30 | // 日账单 31 | export interface EntityBillDay { 32 | id: number, 33 | date: string, 34 | sum: number, 35 | sumIncome: number, 36 | sumOutput: number, 37 | items: Array 38 | } 39 | 40 | // 吃饭账单 41 | export interface EntityBillFood { 42 | breakfast: number, // 早 43 | launch: number, // 午 44 | dinner: number, // 晚 45 | supermarket: number, // 超市 46 | fruit: number, // 水果 47 | sum: number // 合计 48 | } 49 | 50 | export interface EntityBillItem{ 51 | item: string, 52 | price: number 53 | } 54 | 55 | // income top5 & outcome top5 item 56 | export interface EntityBillTop5Item extends EntityBillItem{ 57 | isFiltered?: boolean 58 | } 59 | 60 | 61 | export interface BillKey { 62 | key: string, // 账单条目 63 | count: number, // 数量 64 | sort?: number, // 排序 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/assets/icons/weather/sandstorm_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / sandstorm_active 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/weather/sandstorm_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / sandstorm_white 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/view/Edit/CategorySelector/EditorCategorySelector.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 50 | 51 | 54 | -------------------------------------------------------------------------------- /src/assets/icons/tab/bill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ bill 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "diary", 3 | "nameZh": "标题日记", 4 | "type": "module", 5 | "description": "一句话概括你的一天", 6 | "version": "9.3.2", 7 | "dateModify": "2025.12.06", 8 | "dateInit": "2018.08.14", 9 | "admin_email": "kylebing@163.com", 10 | "author": { 11 | "email": "kylebing@163.com", 12 | "homePage": "http://kylebing.cn", 13 | "name": "KyleBing", 14 | "nameZh": "邴新科" 15 | }, 16 | "private": true, 17 | "scripts": { 18 | "dev": "vite", 19 | "update-date": "node scripts/update-date.js", 20 | "build": "node scripts/update-date.js && vite build", 21 | "preview": "vite preview" 22 | }, 23 | "dependencies": { 24 | "@popperjs/core": "^2.11.8", 25 | "@vuepic/vue-datepicker": "^3.3.1", 26 | "axios": "1.8.2", 27 | "clipboard": "^2.0.11", 28 | "core-js": "^3.26.1", 29 | "echarts": "^5.4.3", 30 | "floating-vue": "^2.0.0-beta.20", 31 | "js-base64": "^3.7.5", 32 | "js-calendar-converter": "^0.0.6", 33 | "js-yaml": "^4.1.0", 34 | "marked": "^4.2.4", 35 | "moment": "^2.29.4", 36 | "pinia": "^2.1.7", 37 | "qiniu-js": "^3.4.1", 38 | "register-service-worker": "^1.7.2", 39 | "v-calendar": "^3.1.2", 40 | "vue": "^3.4.3", 41 | "vue-router": "^4.2.5", 42 | "vuedraggable": "^4.1.0" 43 | }, 44 | "devDependencies": { 45 | "@types/js-yaml": "^4.0.9", 46 | "@vitejs/plugin-vue": "^4.2.3", 47 | "sass": "^1.69.6", 48 | "sass-loader": "^13.3.2", 49 | "typescript": "^5.0.2", 50 | "vite": "6.3.4", 51 | "vite-plugin-pwa": "^0.17.4", 52 | "vite-plugin-zip-pack": "^1.0.7", 53 | "vite-svg-loader": "^5.1.0", 54 | "vue-tsc": "^1.8.5" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/assets/icons/tab/bill_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ bill_black 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/weather/fog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / fog 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/scss/_statistics.scss: -------------------------------------------------------------------------------- 1 | .statistic-container{ 2 | width: 100%; 3 | background-color: white; 4 | box-sizing: border-box; 5 | } 6 | 7 | .statistic-content{ 8 | overflow-y: auto; 9 | overflow-x: hidden; 10 | } 11 | 12 | .statistic-diary{ 13 | display: flex; 14 | flex-flow: row nowrap; 15 | justify-content: space-between; 16 | align-items: flex-start; 17 | } 18 | 19 | .statistic-user{ 20 | } 21 | 22 | 23 | @media (min-width: $grid-separate-width-max) { 24 | .statistic-content{ 25 | padding: 20px; 26 | } 27 | } 28 | 29 | @media (min-width: $grid-separate-width-big) and (max-width: $grid-separate-width-max) { 30 | .statistic-content{ 31 | padding: 20px; 32 | } 33 | } 34 | 35 | @media (min-width: $grid-separate-width-md) and (max-width: $grid-separate-width-big) { 36 | .statistic-content{ 37 | padding: 20px; 38 | } 39 | } 40 | 41 | @media (min-width: $grid-separate-width-sm) and (max-width: $grid-separate-width-md) { 42 | .statistic-content{ 43 | padding: 30px; 44 | } 45 | } 46 | 47 | @media (max-width: $grid-separate-width-sm) { 48 | .statistic-content{ 49 | padding: 5px; 50 | .statistic-diary, .statistic-user{ 51 | flex-flow: column nowrap; 52 | } 53 | .statistic-info, .statistic-charts{ 54 | width: 100%; 55 | flex-flow: column nowrap; 56 | } 57 | } 58 | .statistic-user{ 59 | flex-flow: column nowrap; 60 | } 61 | } 62 | 63 | 64 | // DARK 65 | @media (prefers-color-scheme: dark) { 66 | .statistic-container{ 67 | color: $dark-text; 68 | background-color: $dark-bg-dark !important; 69 | } 70 | .statistic-header{ 71 | background-color: $dark-bg-nav !important; 72 | } 73 | } 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/assets/icons/weather/fog_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / fog_active 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/weather/fog_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / fog_white 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/view/Edit/WeatherSelector/weather-selector.scss: -------------------------------------------------------------------------------- 1 | @import "../../../scss/plugin"; 2 | 3 | $height-weather: 30px; 4 | 5 | .weather-selector{ 6 | border: 1px solid $color-border; 7 | @include border-radius($radius-mobile); 8 | display: flex; 9 | justify-content: flex-start; 10 | flex-flow: row wrap; 11 | padding: 20px; 12 | background-color: white; 13 | .weather{ 14 | @include border-radius(50px); 15 | @extend .unselectable; 16 | padding: 7px; 17 | display: block; 18 | font-weight: bold; 19 | cursor: pointer; 20 | flex-shrink: 0; 21 | &:hover{ 22 | background-color: $bg-light; 23 | } 24 | img{ 25 | @extend .unselectable; 26 | margin: 0 auto; 27 | height: $height-weather; 28 | width: $height-weather; 29 | display: block; 30 | } 31 | } 32 | } 33 | 34 | 35 | 36 | // MAX 37 | @media (min-width: $grid-separate-width-big){ 38 | .weather-selector { 39 | @include border-radius($radius-pc); 40 | .weather{ 41 | } 42 | } 43 | } 44 | 45 | // md 46 | @media (min-width: $grid-separate-width-md) and (max-width: $grid-separate-width-big) { 47 | .weather-selector { 48 | @include border-radius($radius-pc); 49 | .weather{ 50 | } 51 | } 52 | } 53 | 54 | // sm 55 | @media (max-width: $grid-separate-width-md) { 56 | .weather-selector { 57 | @include border-radius($radius-pc); 58 | } 59 | } 60 | 61 | 62 | // DARK 63 | @media (prefers-color-scheme: dark) { 64 | .weather-selector{ 65 | border-color: $dark-border; 66 | background-color: $dark-bg-dark; 67 | border-bottom-color: $dark-border; 68 | .weather:hover{ 69 | background-color: $dark-bg; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/scss/_reset.scss: -------------------------------------------------------------------------------- 1 | @import "plugin"; 2 | 3 | * { 4 | padding: 0; 5 | margin: 0; 6 | border: 0; 7 | font-family: inherit; 8 | -webkit-box-sizing: border-box; 9 | -moz-box-sizing: border-box; 10 | box-sizing: border-box; 11 | font-size: inherit; 12 | } 13 | 14 | body { 15 | font-family: "SF UI Display", "PingFang SC", "Microsoft Yahei UI", "Microsoft Yahei", "Helvetica", sans-serif;; 16 | width: 100%; 17 | margin: 0 auto; 18 | } 19 | 20 | a { 21 | text-decoration: none; 22 | } 23 | 24 | table { 25 | border-collapse: collapse; 26 | } 27 | 28 | input, 29 | textarea { 30 | -webkit-appearance: none !important; 31 | } 32 | 33 | code, 34 | kbd, 35 | pre, 36 | samp, 37 | tt { 38 | font-family: "JetBrainsMonoDiary", "SF UI Display", "PingFang SC", "Microsoft Yahei UI", "Microsoft Yahei", "Helvetica", sans-serif; 39 | } 40 | 41 | :focus, 42 | :active { 43 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 44 | outline: none; 45 | } 46 | 47 | .clearfix::after { 48 | content: ''; 49 | display: block; 50 | visibility: hidden; 51 | clear: both; 52 | } 53 | 54 | ::-webkit-scrollbar { 55 | z-index: 50; 56 | width: 2px; 57 | height: 10px; 58 | } 59 | 60 | ::-webkit-scrollbar-track { 61 | background-color: rgba(0, 0, 0, 0); 62 | } 63 | 64 | ::-webkit-scrollbar-thumb { 65 | -webkit-border-radius: 50px; 66 | -moz-border-radius: 50px; 67 | border-radius: 50px; 68 | background-color: $color-border-highlight; 69 | transition: all .2s; 70 | cursor: pointer; 71 | } 72 | 73 | 74 | ::-webkit-scrollbar-button { 75 | display: none; 76 | } 77 | 78 | ::-webkit-scrollbar-corner { 79 | display: none; 80 | } 81 | -------------------------------------------------------------------------------- /src/assets/icons/tab/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ folder 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/framework/IndexFramework.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 51 | 52 | 57 | -------------------------------------------------------------------------------- /src/view/Menu/YearSelector/YearSelector.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 39 | 40 | 43 | -------------------------------------------------------------------------------- /src/view/Menu/MenuCategorySelector/MenuCategoryIndicatorInlineVertical.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | 28 | 58 | -------------------------------------------------------------------------------- /src/view/Bill/BillMonthSummary.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 30 | 31 | 61 | -------------------------------------------------------------------------------- /src/scss/diary.scss: -------------------------------------------------------------------------------- 1 | @import "reset"; 2 | @import "plugin"; 3 | @import "normalize"; 4 | 5 | @import "login-register"; // menu 6 | @import "menu"; // menu 7 | @import "menu-section"; // menu 8 | @import "gutter"; // 间隔 9 | @import "markdown"; // markdown 10 | @import "form"; // 组件 11 | @import "statistics"; // 统计数据 12 | 13 | // FRAME 14 | body{ 15 | position: relative; 16 | background-color: $bg-main; 17 | } 18 | 19 | .diary { 20 | padding-top: $height-navbar; 21 | .diary-list-container { 22 | overflow-y: auto; 23 | width: 100%; 24 | background-color: $bg-light; 25 | } 26 | .diary-container {} 27 | } 28 | 29 | .diary-list-group-container{ 30 | padding-bottom: 100px; 31 | } 32 | 33 | // PC & IPAD 34 | @media (min-width: $grid-separate-width-md) { 35 | .diary { 36 | display: flex; 37 | .diary-list-container { 38 | border-right: 1px solid $color-border; 39 | overflow-y: auto; 40 | width: $menu-panel-big; 41 | flex-shrink: 0; 42 | background-color: $bg-light; 43 | } 44 | .diary-container { 45 | display: block; 46 | overflow-y: auto; 47 | flex-grow: 1; 48 | } 49 | } 50 | } 51 | 52 | // IPAD 53 | @media (min-width: $grid-separate-width-md) and (max-width: $grid-separate-width-big) { 54 | .diary { 55 | padding-top: $height-navbar; 56 | display: flex; 57 | .diary-list-container { 58 | border-right: 1px solid $color-border; 59 | width: 400px; 60 | } 61 | .diary-container { 62 | display: block; 63 | } 64 | } 65 | } 66 | 67 | // MOBILE 68 | @media (max-width: $grid-separate-width-md) { 69 | .diary { 70 | .diary-list-container { 71 | width: 100%; 72 | } 73 | .diary-container { 74 | display: none; 75 | } 76 | } 77 | } 78 | 79 | // VCalendar 80 | .vc-container { 81 | width: auto !important; 82 | } 83 | 84 | @import "dark"; 85 | -------------------------------------------------------------------------------- /src/view/FileManager/file-list-item.scss: -------------------------------------------------------------------------------- 1 | .file-list-item{ 2 | margin-left: 20px; 3 | margin-bottom: 20px; 4 | padding: 12px 20px; 5 | background-color: $bg-light; 6 | @include border-radius($radius-pc); 7 | display: flex; 8 | align-items: center; 9 | font-size: $fz-small; 10 | } 11 | 12 | .id{ 13 | flex-shrink: 0; 14 | font-size: $fz-title; 15 | @include border-radius(100px); 16 | text-align: center; 17 | height: 40px; 18 | width: 40px; 19 | line-height: 40px; 20 | } 21 | 22 | .file-meta{ 23 | width: 80px; 24 | display: flex; 25 | flex-shrink: 0; 26 | justify-content: center; 27 | align-items: center; 28 | flex-flow: row wrap; 29 | } 30 | 31 | 32 | .file-info{ 33 | min-width: 150px; 34 | color: $text-label; 35 | margin-left: 10px; 36 | .name{ 37 | white-space: nowrap; 38 | text-overflow: ellipsis; 39 | overflow: hidden; 40 | line-height: 1.5; 41 | color: $text-title; 42 | font-size: $fz-main; 43 | font-weight: bold; 44 | } 45 | .size{ 46 | font-family: "JetBrainsMonoDiary", "SF UI Display", "PingFang SC", "Microsoft Yahei UI", "Microsoft Yahei", "Helvetica", sans-serif; 47 | color: $text-subtitle; 48 | } 49 | .description{ 50 | white-space: nowrap; 51 | text-overflow: ellipsis; 52 | overflow: hidden; 53 | color: $text-subtitle; 54 | } 55 | .file-type{ 56 | color: $blue; 57 | &.image{ 58 | color: $magenta; 59 | } 60 | } 61 | .date{} 62 | .path{} 63 | .owner{} 64 | } 65 | 66 | 67 | // MOBILE 68 | @media (max-width: $grid-separate-width-sm) { 69 | .file-list-item{ 70 | margin-left: 0; 71 | width: 100%; 72 | line-height: 1.2; 73 | margin-bottom: 10px; 74 | } 75 | } 76 | 77 | // DARK 78 | @media (prefers-color-scheme: dark) { 79 | .file-list-item{ 80 | background: linear-gradient(white, darken(white, 20%)); 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /src/assets/icons/tab/todo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab / todo 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/weather/sunny_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / sunny_active 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/icons/tab/todo_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ todo_black 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_register.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo-register 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_title.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo / logo_title 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/view/Menu/MenuCategorySelector/MenuCategoryIndicator.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | 28 | 59 | -------------------------------------------------------------------------------- /src/assets/icons/weather/sprinkle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / sprinkle 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/weather/sprinkle_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / sprinkle_white 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/view/Menu/MenuCategorySelector/MenuCategoryIndicatorInline.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | 28 | 63 | -------------------------------------------------------------------------------- /src/assets/icons/weather/sprinkle_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | weather / sprinkle_active 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/view/Bill/BillYearSelector.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 40 | 41 | 72 | -------------------------------------------------------------------------------- /src/view/DiaryList/ListHeader.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 25 | 26 | 81 | -------------------------------------------------------------------------------- /src/framework/WaterfallFramework.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 63 | 64 | 69 | -------------------------------------------------------------------------------- /src/assets/icons/tab/folder_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tab/ folder_black 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/icons/logo/logo_title_saved.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | logo / logo_title_saved 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/scss/_utility.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | // box-shadow 4 | @mixin box-shadow($value ...){ 5 | -webkit-box-shadow: $value; 6 | -moz-box-shadow: $value; 7 | box-shadow: $value; 8 | } 9 | 10 | // border-radius 11 | @mixin border-radius($corner: $radius-mobile){ 12 | -webkit-border-radius: $corner; 13 | -moz-border-radius: $corner; 14 | border-radius: $corner; 15 | } 16 | 17 | 18 | 19 | @mixin clearfix(){ 20 | &:after{ 21 | content: ''; 22 | display: block; 23 | clear: both; 24 | visibility: hidden; 25 | } 26 | } 27 | 28 | @mixin transform($value){ 29 | -webkit-transform: $value; 30 | -moz-transform: $value; 31 | -ms-transform: $value; 32 | -o-transform: $value; 33 | transform: $value; 34 | } 35 | 36 | @mixin animation($value){ 37 | -webkit-animation: $value; 38 | -o-animation: $value; 39 | animation: $value; 40 | } 41 | 42 | @mixin transition($value){ 43 | -webkit-transition: $value; 44 | -moz-transition: $value; 45 | -ms-transition: $value; 46 | -o-transition: $value; 47 | transition: $value; 48 | } 49 | 50 | @mixin linear-gradient($direct, $colors){ 51 | background: linear-gradient($direct, $colors); 52 | background: -webkit-linear-gradient($direct, $colors); 53 | background: -moz-linear-gradient($direct, $colors); 54 | } 55 | 56 | @mixin backdrop-filter($value){ 57 | backdrop-filter: $value ; 58 | -webkit-backdrop-filter: $value; 59 | } 60 | 61 | // 1像素 62 | @mixin divider-1px(){ 63 | content:''; 64 | height: 1px; 65 | display: block; 66 | width: 100%; 67 | position: absolute; 68 | background-color: $color-border; 69 | @include transform(scaleY(.5)) 70 | } 71 | 72 | 73 | 74 | 75 | .unselectable{ 76 | -webkit-user-select: none; 77 | -moz-user-select: none; 78 | -ms-user-select: none; 79 | user-select: none; 80 | } 81 | 82 | .btn-like{ 83 | white-space: nowrap; 84 | @extend .unselectable; 85 | cursor: pointer; 86 | &:active{ 87 | transform: translateY(2px); 88 | } 89 | } 90 | 91 | 92 | 93 | @media (max-width: $grid-separate-width-sm) { 94 | .hide-in-mobile{ 95 | display: none; 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /src/view/Calendar/CalendarListHeader.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 24 | 25 | 79 | --------------------------------------------------------------------------------