feat:重构模块

This commit is contained in:
2025-10-08 22:06:39 +08:00
parent f60d78fe8b
commit 2e81e57774
222 changed files with 2267 additions and 3059 deletions

View File

@@ -8,17 +8,18 @@ server {
server_name _;
#location /admin-service/ {
#proxy_pass http://admin-service:8080/;
#}
location /sweet-hut/ {
alias /usr/share/nginx/html/;
try_files $uri $uri/ /sweet-hut/index.html;
}
location /home-service/ {
proxy_pass http://home-service:8081/;
location /home-api/ {
proxy_pass http://host.docker.internal:8081/;
}
#location /blog-service/ {
#proxy_pass http://blog-service:8082/;
#}
location /blog-api/ {
proxy_pass http://host.docker.internal:8082/;
}
location / {
try_files $uri $uri/ =404;

View File

@@ -4,7 +4,7 @@
</template>
<script setup lang="ts">
import AppLoading from '@/components/AppLoading.vue'
import AppLoading from '@/components/Common/AppLoading.vue'
import { useAppStore } from '@/store/app.ts'
import { useRouter } from 'vue-router'

View File

@@ -1,29 +0,0 @@
import { cloudService } from './index'
import { IAccount } from '@/types/auth.ts'
export const queryAccountApi = (): Promise<IAccount[]> =>
cloudService({
url: '/admin-service/account',
method: 'get'
})
export const registerAccountApi = (account: IAccount): Promise<boolean> =>
cloudService({
url: '/admin-service/account',
method: 'post',
data: account
})
export const deleteAccountApi = (id: number): Promise<boolean> =>
cloudService({
url: `/admin-service/account/${id}`,
method: 'delete'
})
export const updateAccountPasswordApi = (id: number,
oldPassword: string, newPassword: string): Promise<boolean> =>
cloudService({
url: `/admin-service/account/password/${id}`,
method: 'put',
params: { oldPassword, newPassword }
})

View File

@@ -4,33 +4,33 @@ import { IStatsChart } from 'vue3-common/types'
export const addAnniversaryApi = (anniversary: IAnniversary): Promise<boolean> =>
cloudService({
url: '/home-service/anniversary',
url: '/home-api/anniversary',
method: 'post',
data: anniversary
})
export const updateAnniversaryApi = (id: number, anniversary: IAnniversary): Promise<boolean> =>
cloudService({
url: `/home-service/anniversary/${id}`,
url: `/home-api/anniversary/${id}`,
method: 'put',
data: anniversary
})
export const deleteAnniversaryApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/anniversary/${id}`,
url: `/home-api/anniversary/${id}`,
method: 'delete'
})
export const queryAnniversaryApi = (category: string): Promise<IAnniversary[]> =>
cloudService({
url: '/home-service/anniversary',
url: '/home-api/anniversary',
method: 'get',
params: { category }
})
export const queryAnniversaryCategoryApi = (): Promise<IStatsChart[]> =>
cloudService({
url: '/home-service/anniversary/category',
url: '/home-api/anniversary/category',
method: 'get'
})

View File

@@ -3,33 +3,33 @@ import { IAssetRecord } from '@/types/asset'
export const addAssetApi = (asset: IAssetRecord): Promise<boolean> =>
cloudService({
url: '/home-service/asset',
url: '/home-api/asset',
method: 'post',
data: asset
})
export const updateAssetApi = (id: number, asset: IAssetRecord): Promise<boolean> =>
cloudService({
url: `/home-service/asset/${id}`,
url: `/home-api/asset/${id}`,
method: 'put',
data: asset
})
export const deleteAssetApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/asset/${id}`,
url: `/home-api/asset/${id}`,
method: 'delete'
})
export const queryAssetApi = (category: string): Promise<IAssetRecord[]> =>
cloudService({
url: '/home-service/asset',
url: '/home-api/asset',
method: 'get',
params: { category }
})
export const queryAssetCategoryApi = (): Promise<string[]> =>
cloudService({
url: '/home-service/asset/category',
url: '/home-api/asset/category',
method: 'get'
})

View File

@@ -4,106 +4,106 @@ import {
IBillCategory,
IBillPay,
IBillQuery,
IBillRecord,
IBillRecord
} from '@/types/bill'
import { IStatsChart } from 'vue3-common/dist/types'
export const addBillRecordApi = (billRecord: IBillRecord): Promise<boolean> =>
cloudService({
url: '/home-service/bill',
url: '/home-api/bill',
method: 'post',
data: billRecord
})
export const updateBillRecordApi = (id: number, billRecord: IBillRecord): Promise<boolean> =>
cloudService({
url: `/home-service/bill/${id}`,
url: `/home-api/bill/${id}`,
method: 'put',
data: billRecord
})
export const deleteBillRecordApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/bill/${id}`,
url: `/home-api/bill/${id}`,
method: 'DELETE'
})
export const queryBillRecordApi = (id: number): Promise<IBillRecord> =>
cloudService({
url: `/home-service/bill/${id}`,
url: `/home-api/bill/${id}`,
method: 'get'
})
export const queryBillSummaryApi = (query: IBillQuery): Promise<IBillRecord[]> =>
cloudService({
url: '/home-service/bill/summary',
url: '/home-api/bill/summary',
method: 'get',
params: query
})
export const queryBillStatsApi = (type: string, query: IBillQuery): Promise<IStatsChart[]> =>
cloudService({
url: `/home-service/bill/stats/${type}`,
url: `/home-api/bill/stats/${type}`,
method: 'get',
params: query
})
export const queryBillPayApi = (): Promise<IBillPay[]> =>
cloudService({
url: '/home-service/bill/pay',
url: '/home-api/bill/pay',
method: 'get'
})
export const queryBillBookApi = (): Promise<IBillBook[]> =>
cloudService({
url: '/home-service/bill/book',
url: '/home-api/bill/book',
method: 'get'
})
export const queryBillCategoryApi = (): Promise<IBillCategory[]> =>
cloudService({
url: '/home-service/bill/category',
url: '/home-api/bill/category',
method: 'get'
})
export const addBillPayApi = (billPay: IBillPay): Promise<boolean> =>
cloudService({
url: '/home-service/bill-manage/pay',
url: '/home-api/bill-manage/pay',
method: 'post',
data: billPay
})
export const updateBillPayApi = (id: number, billPay: IBillPay): Promise<boolean> =>
cloudService({
url: `/home-service/bill-manage/pay/${id}`,
url: `/home-api/bill-manage/pay/${id}`,
method: 'put',
data: billPay
})
export const addBillBookApi = (billBook: IBillBook): Promise<boolean> =>
cloudService({
url: '/home-service/bill-manage/book',
url: '/home-api/bill-manage/book',
method: 'post',
data: billBook
})
export const updateBillBookApi = (id: number, billBook: IBillBook): Promise<boolean> =>
cloudService({
url: `/home-service/bill-manage/book/${id}`,
url: `/home-api/bill-manage/book/${id}`,
method: 'put',
data: billBook
})
export const addBillCategoryApi = (billCategory: IBillCategory): Promise<boolean> =>
cloudService({
url: '/home-service/bill-manage/category',
url: '/home-api/bill-manage/category',
method: 'post',
data: billCategory
})
export const updateBillCategoryApi = (id: number, billCategory: IBillCategory): Promise<boolean> =>
cloudService({
url: `/home-service/bill-manage/category/${id}`,
url: `/home-api/bill-manage/category/${id}`,
method: 'put',
data: billCategory
})

View File

@@ -1,19 +1,19 @@
import { cloudService } from './index'
import { IBlog, IBlogCategory, IBlogComment, IBlogStats, IBlogVisit, INewBlog, IQueryBlog } from '@/types/blog'
import { IBlog, IBlogCategory, IBlogComment, IBlogStats, INewBlog, IQueryBlog } from '@/types/blog'
import qs from 'qs'
import { IPageRecord } from '@/types'
export const queryBlogApi = (currentPage: number, pageSize: number): Promise<any> =>
export const queryBlogApi = (currentPage: number, pageSize: number): Promise<IPageRecord<IBlog>> =>
cloudService({
url: '/blog-service/blog/page',
url: '/blog-api/blog/page',
method: 'get',
params: { currentPage, pageSize }
})
export const queryBlogByConditionApi = (query: IQueryBlog): Promise<IBlog[]> =>
cloudService({
url: '/blog-service/blog/condition',
url: '/blog-api/blog/condition',
method: 'get',
params: query,
paramsSerializer: (params) => {
@@ -23,85 +23,57 @@ export const queryBlogByConditionApi = (query: IQueryBlog): Promise<IBlog[]> =>
export const queryBlogByIdApi = (id: number): Promise<IBlog> =>
cloudService({
url: `/blog-service/blog/content/${id}`,
url: `/blog-api/blog/content/${id}`,
method: 'get'
})
export const queryBlogCategoryApi = (): Promise<IBlogCategory[]> =>
cloudService({
url: '/blog-service/blog/category',
url: '/blog-api/blog/category',
method: 'get'
})
export const queryBlogStatsApi = (): Promise<IBlogStats> =>
cloudService({
url: '/blog-service/blog/stats',
url: '/blog-api/blog/stats',
method: 'get'
})
export const queryLatestBlogApi = (): Promise<IBlog[]> =>
cloudService({
url: '/blog-service/blog/latest',
url: '/blog-api/blog/latest',
method: 'get'
})
export const queryBlogCommentApi = (blogId: number): Promise<IBlogComment[]> =>
cloudService({
url: `/blog-service/blog/comment/${blogId}`,
url: `/blog-api/blog/comment/${blogId}`,
method: 'get'
})
export const addBlogCommentApi = (blogComment: IBlogComment): Promise<boolean> =>
cloudService({
url: '/blog-service/blog/comment',
url: '/blog-api/blog/comment',
method: 'put',
data: blogComment
})
export const queryAdminBlogApi = (currentPage: number,
pageSize: number): Promise<IPageRecord<IBlog>> =>
cloudService({
url: '/admin-service/blog-manage/page',
method: 'get',
params: { currentPage, pageSize }
})
export const queryAdminBlogByIdApi = (id: number): Promise<IBlog> =>
cloudService({
url: `/admin-service/blog-manage/content/${id}`,
method: 'get'
})
export const queryAdminBlogCategoryApi = (): Promise<IBlogCategory[]> =>
cloudService({
url: '/admin-service/blog-manage/category',
method: 'get'
})
export const addBlogApi = (blog: INewBlog): Promise<boolean> =>
cloudService({
url: '/admin-service/blog-manage',
url: '/admin-api/blog-manage',
method: 'post',
data: blog
})
export const updateBlogApi = (id: number, blog: INewBlog): Promise<boolean> =>
cloudService({
url: `/admin-service/blog-manage/${id}`,
url: `/admin-api/blog-manage/${id}`,
method: 'put',
data: blog
})
export const deleteBlogApi = (id: number): Promise<boolean> =>
cloudService({
url: `/admin-service/blog-manage/${id}`,
url: `/admin-api/blog-manage/${id}`,
method: 'DELETE'
})
export const queryBlogVisitApi = (currentPage: number,
pageSize: number): Promise<IPageRecord<IBlogVisit>> =>
cloudService({
url: '/admin-service/blog-manage/visit',
method: 'get',
params: { currentPage, pageSize }
})

View File

@@ -3,47 +3,47 @@ import { IBudgetInfo } from '@/types/budget'
export const addBudgetApi = (budget: IBudgetInfo): Promise<any> =>
cloudService({
url: '/home-service/budget',
url: '/home-api/budget',
method: 'post',
data: budget
})
export const updateBudgetApi = (id: number, budget: IBudgetInfo): Promise<any> =>
cloudService({
url: `/home-service/budget/${id}`,
url: `/home-api/budget/${id}`,
method: 'put',
data: budget
})
export const deleteBudgetApi = (id: number): Promise<any> =>
cloudService({
url: `/home-service/budget/${id}`,
url: `/home-api/budget/${id}`,
method: 'DELETE'
})
export const queryBudgetApi = (category: string): Promise<any> =>
cloudService({
url: '/home-service/budget',
url: '/home-api/budget',
method: 'get',
params: { category }
})
export const queryBudgetCategory = (): Promise<any> =>
cloudService({
url: '/home-service/budget/category',
url: '/home-api/budget/category',
method: 'get'
})
export const queryBudgetRankStats = (category: string): Promise<any> =>
cloudService({
url: '/home-service/budget/stats/rank',
url: '/home-api/budget/stats/rank',
method: 'get',
params: { category }
})
export const queryBudgetProjectStats = (category: string): Promise<any> =>
cloudService({
url: '/home-service/budget/stats/project',
url: '/home-api/budget/stats/project',
method: 'get',
params: { category }
})

View File

@@ -3,7 +3,7 @@ import { IFileInfo } from '@/types/file'
export const uploadFileApi = (form: FormData, path: string, md5: string): Promise<any> =>
cloudService({
url: '/home-service/file',
url: '/home-api/file',
headers: {
'Content-Type': 'multipart/form-data'
},
@@ -12,38 +12,9 @@ export const uploadFileApi = (form: FormData, path: string, md5: string): Promis
data: form
})
/**
* 上传图片到Hello图床
* @param form 表单
* @param token token
*/
export const uploadHelloImageApi = (form: FormData, token: string): Promise<any> =>
cloudService({
url: '/hello-service/upload',
headers: {
Authorization: token,
'Content-Type': 'multipart/form-data'
},
method: 'post',
data: form
})
/**
* 获取Hello图床相册
* @param token token
*/
export const getHelloAlbumsApi = (token: string): Promise<any> =>
cloudService({
url: '/hello-service/albums',
headers: {
Authorization: token
},
method: 'get'
})
export const getFolderInfoApi = (folderName: string): Promise<IFileInfo[]> =>
cloudService({
url: '/home-service/file/catalog',
url: '/home-api/file/catalog',
method: 'get',
params: { folderName }
})

View File

@@ -3,79 +3,79 @@ import { IFoodQuery, IFoodRecipe, IFoodRecord, IFoodStats } from '@/types/food'
export const addFoodRecipeApi = (foodRecipe: IFoodRecipe): Promise<boolean> =>
cloudService({
url: '/home-service/food/recipe',
url: '/home-api/food/recipe',
method: 'post',
data: foodRecipe
})
export const updateFoodRecipeApi = (id: number, foodRecipe: IFoodRecipe): Promise<boolean> =>
cloudService({
url: `/home-service/food/recipe/${id}`,
url: `/home-api/food/recipe/${id}`,
method: 'put',
data: foodRecipe
})
export const deleteFoodRecipeApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/food/recipe/${id}`,
url: `/home-api/food/recipe/${id}`,
method: 'DELETE'
})
export const queryFoodRecipeByIdApi = (id: number): Promise<any> =>
cloudService({
url: `/home-service/food/recipe/${id}`,
url: `/home-api/food/recipe/${id}`,
method: 'get'
})
export const queryFoodRecipeApi = (currentPage: number, pageSize: number,
query: IFoodQuery): Promise<any> =>
cloudService({
url: '/home-service/food/recipe/page',
url: '/home-api/food/recipe/page',
method: 'get',
params: { currentPage, pageSize, ...query }
})
export const queryFoodNameListApi = (): Promise<string[]> =>
cloudService({
url: '/home-service/food/recipe/name',
url: '/home-api/food/recipe/name',
method: 'get'
})
export const addFoodRecordApi = (foodRecord: IFoodRecord): Promise<boolean> =>
cloudService({
url: '/home-service/food/record',
url: '/home-api/food/record',
method: 'post',
data: foodRecord
})
export const updateFoodRecordApi = (id: number, foodRecord: IFoodRecord): Promise<boolean> =>
cloudService({
url: `/home-service/food/record/${id}`,
url: `/home-api/food/record/${id}`,
method: 'put',
data: foodRecord
})
export const deleteFoodRecordApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/food/record/${id}`,
url: `/home-api/food/record/${id}`,
method: 'DELETE'
})
export const queryFoodRecordApi = (startDate: string, endDate: string): Promise<IFoodRecord[]> =>
cloudService({
url: '/home-service/food/record',
url: '/home-api/food/record',
method: 'get',
params: { startDate, endDate }
})
export const queryFoodCategoryApi = (): Promise<string[]> =>
cloudService({
url: '/home-service/food/category',
url: '/home-api/food/category',
method: 'get'
})
export const queryFoodStatsApi = (): Promise<IFoodStats> =>
cloudService({
url: '/home-service/food/stats',
url: '/home-api/food/stats',
method: 'get'
})

View File

@@ -4,33 +4,33 @@ import { IJournal, IJournalQuery } from '@/types/journal.ts'
export const addJournalApi = (journal: IJournal): Promise<boolean> =>
cloudService({
url: '/home-service/journal',
url: '/home-api/journal',
method: 'post',
data: journal
})
export const updateJournalApi = (id: number, journal: IJournal): Promise<boolean> =>
cloudService({
url: `/home-service/journal/${id}`,
url: `/home-api/journal/${id}`,
method: 'put',
data: journal
})
export const deleteJournalApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/journal/${id}`,
url: `/home-api/journal/${id}`,
method: 'delete'
})
export const queryJournalApi = (query: IJournalQuery): Promise<IJournal[]> =>
cloudService({
url: '/home-service/journal',
url: '/home-api/journal',
method: 'get',
params: { ...query }
})
export const queryJournalCategoryApi = (): Promise<IStatsChart[]> =>
cloudService({
url: '/home-service/journal/category',
url: '/home-api/journal/category',
method: 'get'
})

View File

@@ -3,27 +3,27 @@ import { IKpi, IKpiQuery } from '@/types/kpi'
export const addKpiApi = (kpi: IKpi): Promise<boolean> =>
cloudService({
url: '/home-service/kpi',
url: '/home-api/kpi',
method: 'post',
data: kpi
})
export const updateKpiApi = (id: number, kpi: IKpi): Promise<boolean> =>
cloudService({
url: `/home-service/kpi/${id}`,
url: `/home-api/kpi/${id}`,
method: 'put',
data: kpi
})
export const deleteKpiApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/kpi/${id}`,
url: `/home-api/kpi/${id}`,
method: 'delete'
})
export const queryKpiApi = (query: IKpiQuery): Promise<IKpi[]> =>
cloudService({
url: '/home-service/kpi',
url: '/home-api/kpi',
method: 'get',
params: { ...query }
})

View File

@@ -3,33 +3,33 @@ import { ILedgerRecord } from '@/types/ledger'
export const addLedgerApi = (ledger: ILedgerRecord): Promise<boolean> =>
cloudService({
url: '/home-service/ledger',
url: '/home-api/ledger',
method: 'post',
data: ledger
})
export const updateLedgerApi = (id: number, ledger: ILedgerRecord): Promise<boolean> =>
cloudService({
url: `/home-service/ledger/${id}`,
url: `/home-api/ledger/${id}`,
method: 'put',
data: ledger
})
export const deleteLedgerApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/ledger/${id}`,
url: `/home-api/ledger/${id}`,
method: 'delete'
})
export const queryLedgerApi = (book: string): Promise<ILedgerRecord[]> =>
cloudService({
url: '/home-service/ledger',
url: '/home-api/ledger',
method: 'get',
params: { book }
})
export const queryLedgerBookApi = (): Promise<string[]> =>
cloudService({
url: '/home-service/ledger/book',
url: '/home-api/ledger/book',
method: 'get'
})

View File

@@ -3,33 +3,33 @@ import { IPassword, IQueryPassword } from '@/types/password'
export const addPasswordApi = (password: IPassword): Promise<boolean> =>
cloudService({
url: '/home-service/password',
url: '/home-api/password',
method: 'post',
data: password
})
export const updatePasswordApi = (id: number, password: IPassword): Promise<boolean> =>
cloudService({
url: `/home-service/password/${id}`,
url: `/home-api/password/${id}`,
method: 'put',
data: password
})
export const deletePasswordApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/password/${id}`,
url: `/home-api/password/${id}`,
method: 'delete'
})
export const queryPasswordApi = (query: IQueryPassword): Promise<IPassword[]> =>
cloudService({
url: '/home-service/password',
url: '/home-api/password',
method: 'get',
params: query
})
export const queryPasswordCategoryApi = (): Promise<string[]> =>
cloudService({
url: '/home-service/password/category',
url: '/home-api/password/category',
method: 'get'
})

View File

@@ -4,34 +4,34 @@ import { IPeriodDay, IPeriodSetting } from '@/types/period.ts'
export const updatePeriodDayApi = (id: number, periodDay: IPeriodDay): Promise<boolean> =>
cloudService({
url: `/home-service/period/day/${id}`,
url: `/home-api/period/day/${id}`,
method: 'put',
data: periodDay
})
export const queryPeriodDayApi = (month: string): Promise<IPeriodDay[]> =>
cloudService({
url: '/home-service/period/day',
url: '/home-api/period/day',
method: 'get',
params: { month }
})
export const getMenstruateFirstDateApi = (month: string): Promise<string> =>
cloudService({
url: '/home-service/period/menstruate',
url: '/home-api/period/menstruate',
method: 'get',
params: { month }
})
export const updatePeriodSettingApi = (id: number, setting: IPeriodSetting): Promise<boolean> =>
cloudService({
url: `/home-service/period/setting/${id}`,
url: `/home-api/period/setting/${id}`,
method: 'put',
data: setting
})
export const queryPeriodSettingApi = (): Promise<IPeriodSetting> =>
cloudService({
url: '/home-service/period/setting',
url: '/home-api/period/setting',
method: 'get'
})

View File

@@ -3,40 +3,40 @@ import { IPlanInfo, IPlanQuery } from '@/types/plan.ts'
export const addPlanApi = (plan: IPlanInfo): Promise<any> =>
cloudService({
url: '/home-service/plan',
url: '/home-api/plan',
method: 'post',
data: plan
})
export const updatePlanApi = (id: number, plan: IPlanInfo): Promise<any> =>
cloudService({
url: `/home-service/plan/${id}`,
url: `/home-api/plan/${id}`,
method: 'put',
data: plan
})
export const setPlanStatusApi = (id: number, status: boolean): Promise<any> =>
cloudService({
url: `/home-service/plan/${id}/status`,
url: `/home-api/plan/${id}/status`,
method: 'put',
params: { status }
})
export const deletePlanApi = (id: number): Promise<any> =>
cloudService({
url: `/home-service/plan/${id}`,
url: `/home-api/plan/${id}`,
method: 'delete'
})
export const queryPlanApi = (query: IPlanQuery): Promise<any> =>
cloudService({
url: '/home-service/plan',
url: '/home-api/plan',
method: 'get',
params: query
})
export const queryPlanStatsApi = (): Promise<any> =>
cloudService({
url: '/home-service/plan/stats',
url: '/home-api/plan/stats',
method: 'get'
})

View File

@@ -3,39 +3,39 @@ import { IProduct, IQueryProduct } from '@/types/product.ts'
export const addProductApi = (product: IProduct): Promise<boolean> =>
cloudService({
url: '/home-service/product',
url: '/home-api/product',
method: 'post',
data: product
})
export const updateProductApi = (id: number, product: IProduct): Promise<boolean> =>
cloudService({
url: `/home-service/product/${id}`,
url: `/home-api/product/${id}`,
method: 'put',
data: product
})
export const deleteProductApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/product/${id}`,
url: `/home-api/product/${id}`,
method: 'delete'
})
export const queryProductApi = (id: number): Promise<IProduct> =>
cloudService({
url: `/home-service/product/${id}`,
url: `/home-api/product/${id}`,
method: 'get'
})
export const queryProductListApi = (query: IQueryProduct): Promise<IProduct[]> =>
cloudService({
url: '/home-service/product',
url: '/home-api/product',
method: 'get',
params: query
})
export const queryProductCategoryApi = (): Promise<string[]> =>
cloudService({
url: '/home-service/product/category',
url: '/home-api/product/category',
method: 'get'
})

View File

@@ -3,6 +3,6 @@ import { IQuartzInfo } from '@/types/quartz'
export const queryQuartzApi = (): Promise<IQuartzInfo[]> =>
cloudService({
url: '/home-service/quartz',
url: '/home-api/quartz',
method: 'get'
})

View File

@@ -3,14 +3,14 @@ import { ISession } from '@/types/auth'
export const loginHomeApi = (name: string, password: string): Promise<ISession> =>
cloudService({
url: '/home-service/session',
url: '/home-api/session',
method: 'post',
params: { name, password }
})
export const loginAdminApi = (name: string, password: string): Promise<ISession> =>
cloudService({
url: '/admin-service/session',
url: '/admin-api/session',
method: 'post',
params: { name, password }
})

View File

@@ -3,80 +3,80 @@ import { ITravelQuery, ITravelRecord, ITravelSpot, ITravelStats } from '@/types/
export const addTravelSpotApi = (travelSpot: ITravelSpot): Promise<boolean> =>
cloudService({
url: '/home-service/travel/spot',
url: '/home-api/travel/spot',
method: 'post',
data: travelSpot
})
export const updateTravelSpotApi = (id: number, travelSpot: ITravelSpot): Promise<boolean> =>
cloudService({
url: `/home-service/travel/spot/${id}`,
url: `/home-api/travel/spot/${id}`,
method: 'put',
data: travelSpot
})
export const deleteTravelSpotApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/travel/spot/${id}`,
url: `/home-api/travel/spot/${id}`,
method: 'DELETE'
})
export const queryTravelSpotApi = (id: number): Promise<ITravelSpot> =>
cloudService({
url: `/home-service/travel/spot/${id}`,
url: `/home-api/travel/spot/${id}`,
method: 'get'
})
export const queryTravelSpotListApi = (currentPage: number, pageSize: number,
query: ITravelQuery): Promise<any> =>
cloudService({
url: '/home-service/travel/spot/page',
url: '/home-api/travel/spot/page',
method: 'get',
params: { currentPage, pageSize, ...query }
})
export const queryTravelSpotNameListApi = (): Promise<string[]> =>
cloudService({
url: '/home-service/travel/spot/name',
url: '/home-api/travel/spot/name',
method: 'get'
})
export const addTravelRecordApi = (travelRecord: ITravelRecord): Promise<boolean> =>
cloudService({
url: '/home-service/travel/record',
url: '/home-api/travel/record',
method: 'post',
data: travelRecord
})
export const updateTravelRecordApi = (id: number, travelRecord: ITravelRecord): Promise<boolean> =>
cloudService({
url: `/home-service/travel/record/${id}`,
url: `/home-api/travel/record/${id}`,
method: 'put',
data: travelRecord
})
export const deleteTravelRecordApi = (id: number): Promise<boolean> =>
cloudService({
url: `/home-service/travel/record/${id}`,
url: `/home-api/travel/record/${id}`,
method: 'DELETE'
})
export const queryTravelRecordApi = (startDate: string, endDate: string):
Promise<ITravelRecord[]> =>
cloudService({
url: '/home-service/travel/record',
url: '/home-api/travel/record',
method: 'get',
params: { startDate, endDate }
})
export const queryTravelCategoryApi = (): Promise<string[]> =>
cloudService({
url: '/home-service/travel/category',
url: '/home-api/travel/category',
method: 'get'
})
export const queryTravelStatsApi = (): Promise<ITravelStats> =>
cloudService({
url: '/home-service/travel/stats',
url: '/home-api/travel/stats',
method: 'get'
})

View File

@@ -1,31 +0,0 @@
import { cloudService } from './index'
export const getAllTravelRecord = (): any =>
cloudService({
url: '/travelRecord/getAllTravelRecord',
method: 'get'
})
export const getAllTravelRecordByPage = (currentPage: number, pageSize: number): any =>
cloudService({
url: '/travelRecord/getAllTravelRecordByPage',
method: 'get',
params: { currentPage, pageSize }
})
export const addTravelRecord = (travelJournal): any =>
cloudService({
url: '/travelRecord/addTravelRecord',
method: 'post',
data: travelJournal
})
export const addTravelRecordImage = (imageList, date, place): any =>
cloudService({
url: '/travelRecord/addTravelRecordImage',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
params: { date, place },
data: imageList
})

View File

@@ -3,13 +3,13 @@ import { IUser } from '@/types/auth.ts'
export const queryUserApi = (id: number): Promise<IUser> =>
cloudService({
url: `/home-service/user/${id}`,
url: `/home-api/user/${id}`,
method: 'get'
})
export const updateUserApi = (id: number, user: IUser): Promise<boolean> =>
cloudService({
url: `/home-service/user/${id}`,
url: `/home-api/user/${id}`,
method: 'put',
data: user
})

Binary file not shown.

Binary file not shown.

View File

@@ -29,7 +29,7 @@ import { defineProps, PropType } from 'vue'
import { useRouter } from 'vue-router'
import { useAnniversaryStore } from '@/store/anniversary.ts'
import { IAnniversary } from '@/types/anniversary.ts'
import { getAnniversaryRemainDays } from '@/utils/home/anniversaryUtil'
import { getAnniversaryRemainDays } from '@/utils/home/anniversaryUtil.ts'
const router = useRouter()
const anniversaryStore = useAnniversaryStore()
@@ -47,7 +47,7 @@ const selectDateCardClick = async () => {
if (props.dateItem?.category !== '节假日') {
anniversaryStore.currentAnniversary = props.dateItem as IAnniversary
const { id } = anniversaryStore.currentAnniversary
await router.push({ name: 'MobileHomeAnniversaryDetailId', params: { id } })
await router.push({ name: 'AnniversaryDetailId', params: { id } })
}
}
</script>

View File

@@ -9,8 +9,8 @@
<script setup lang="ts">
import { defineProps, PropType } from 'vue'
import { IAnniversaryCategory } from '@/types/anniversary'
import { useAnniversaryStore } from '@/store/anniversary'
import { IAnniversaryCategory } from '@/types/anniversary.ts'
import { useAnniversaryStore } from '@/store/anniversary.ts'
import { useRouter } from 'vue-router'
const props = defineProps({
@@ -29,7 +29,7 @@ const anniversaryStore = useAnniversaryStore()
const selectCategoryClick = () => {
anniversaryStore.queryInfo.category = props.categoryItem?.name as string
router.push({ name: 'MobileHomeAnniversaryList' })
router.push({ name: 'AnniversaryList' })
}
</script>

View File

@@ -33,11 +33,9 @@
<script setup lang="ts">
import { SvgIcon } from 'vue3-common'
import { defineProps, PropType } from 'vue'
import { IAsset, IAssetItem } from '@/types/asset'
import { IAsset, IAssetItem } from '@/types/asset.ts'
import { formatAmount } from 'vue3-common/utils/numberUtil'
import { isMobile } from 'vue3-common/utils/layoutUtil'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { useAssetStore } from '@/store/asset'
import { useAssetStore } from '@/store/asset.ts'
import { useRouter } from 'vue-router'
const props = defineProps({
@@ -62,15 +60,7 @@ const editClick = async (asset: IAssetItem) => {
assetStore.assetApiType = 'UPDATE'
assetStore.currentAssetRecord = assetStore.assetRecordList.find((item) => item.id === asset.id)
if (isMobile()) {
await router.push({ name: 'MobileHomeAssetDetailId', params: { id: asset.id } })
} else {
assetStore.assetDialog = {
title: '编辑资产',
visible: true,
data: deepCopyObject(assetStore.currentAssetRecord)
}
}
await router.push({ name: 'AssetDetailId', params: { id: asset.id } })
}
</script>

View File

@@ -62,13 +62,13 @@
<script lang="ts" setup>
import { nextTick, onMounted, reactive, ref } from 'vue'
import { useBillStore } from '@/store/bill'
import { useBillStore } from '@/store/bill.ts'
import { ElMessage, FormRules } from 'element-plus'
import { IBillBook } from '@/types/bill'
import { billBookRules } from '@/utils/element/elRules'
import { IBillBook } from '@/types/bill.ts'
import { billBookRules } from '@/utils/element/elRules.ts'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import type { IDialog, IHandleApi } from 'vue3-common/types'
import { addBillBookApi, updateBillBookApi } from '@/apis/bill'
import { addBillBookApi, updateBillBookApi } from '@/apis/bill.ts'
import { tableCellStyle, tableHeaderStyle, tableRowStyle } from 'vue3-common/utils/elUtil'
const formRef = ref()

View File

@@ -12,13 +12,13 @@
</template>
<script setup lang="ts">
import BillDailyItem from '@/components/Home/Bill/BillDailyItem.vue'
import BillDailyItem from '@/components/Bill/BillDailyItem.vue'
import { reactive, watch, ref, onMounted } from 'vue'
import { useBillStore } from '@/store/bill.ts'
import { formatDate } from 'vue3-common/utils/dateUtil'
import { CalendarDay, Page } from 'v-calendar/dist/types/src/utils/page'
import { getCalendarDateList } from '@/utils/home/billUtil.ts'
import { useAppStore } from '@/store/app'
import { useAppStore } from '@/store/app.ts'
const calendarRef = ref()
const billStore = useBillStore()

View File

@@ -96,11 +96,11 @@
<script lang="ts" setup>
import { nextTick, onMounted, reactive, ref } from 'vue'
import { useBillStore } from '@/store/bill'
import { IBillBook, IBillCategory } from '@/types/bill'
import { useBillStore } from '@/store/bill.ts'
import { IBillBook, IBillCategory } from '@/types/bill.ts'
import { ElMessage, FormRules } from 'element-plus'
import { billCategoryRules } from '@/utils/element/elRules'
import { addBillCategoryApi, updateBillCategoryApi } from '@/apis/bill'
import { billCategoryRules } from '@/utils/element/elRules.ts'
import { addBillCategoryApi, updateBillCategoryApi } from '@/apis/bill.ts'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { tableHeaderStyle, tableRowStyle, tableCellStyle } from 'vue3-common/utils/elUtil'
import type { IDialog, IHandleApi } from 'vue3-common/types'

View File

@@ -38,11 +38,11 @@
</template>
<script setup lang="ts">
import BillRank from '@/components/Home/Bill/BillRank.vue'
import BillRank from '@/components/Bill/BillRank.vue'
import { onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
import { lineChartOptions, barChartOptions, pieChartOptions } from 'vue3-common/utils/eChartsUtil'
import { useBillStore } from '@/store/bill'
import { useBillStore } from '@/store/bill.ts'
import { useAppStore } from '@/store/app.ts'
import type { IStatsChart } from 'vue3-common/types'
import { isMobile } from 'vue3-common/utils/layoutUtil'

View File

@@ -36,8 +36,8 @@
</template>
<script setup lang="ts">
import DailySummary from '@/components/Home/DailySummary.vue'
import DailyCard from '@/components/Home/DailyCard.vue'
import DailySummary from '@/components/DailySummary.vue'
import DailyCard from '@/components/DailyCard.vue'
import { defineProps, onMounted, reactive, watch } from 'vue'
import { useBillStore } from '@/store/bill.ts'
import { useRouter } from 'vue-router'
@@ -104,7 +104,7 @@ const selectBillRecordClick = async (billRecord: IBillRecord) => {
if (isMobile()) {
await router.push({
name: 'MobileHomeBillDetailId',
name: 'BillDetailId',
params: { id: billStore.currentBillRecord.id }
})
} else {

View File

@@ -16,7 +16,7 @@
</template>
<script setup lang="ts">
import BillDailyItem from '@/components/Home/Bill/BillDailyItem.vue'
import BillDailyItem from '@/components/Bill/BillDailyItem.vue'
import { reactive, watch } from 'vue'
import { useBillStore } from '@/store/bill.ts'

View File

@@ -118,12 +118,12 @@
<script lang="ts" setup>
import { UploadImage, AmountInput } from 'vue3-common'
import { useBillStore } from '@/store/bill'
import { useBillStore } from '@/store/bill.ts'
import { Location, Document } from '@element-plus/icons-vue'
import { FormRules } from 'element-plus'
import { billRecordRules } from '@/utils/element/elRules'
import { billRecordRules } from '@/utils/element/elRules.ts'
import { nextTick, reactive, ref } from 'vue'
import { IBillCategory } from '@/types/bill'
import { IBillCategory } from '@/types/bill.ts'
import { commonElMessageBox } from 'vue3-common/utils/elUtil'
import { fileServiceUrl, serviceFileRootPath } from '@/utils'

View File

@@ -62,12 +62,12 @@
<script lang="ts" setup>
import { nextTick, onMounted, reactive, ref } from 'vue'
import { useBillStore } from '@/store/bill'
import { useBillStore } from '@/store/bill.ts'
import { ElMessage, FormRules } from 'element-plus'
import { IBillPay } from '@/types/bill'
import { billPayRules } from '@/utils/element/elRules'
import { IBillPay } from '@/types/bill.ts'
import { billPayRules } from '@/utils/element/elRules.ts'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { addBillPayApi, updateBillPayApi } from '@/apis/bill'
import { addBillPayApi, updateBillPayApi } from '@/apis/bill.ts'
import { tableCellStyle, tableHeaderStyle, tableRowStyle } from 'vue3-common/utils/elUtil'
import type { IDialog, IHandleApi } from 'vue3-common/types'

View File

@@ -8,7 +8,7 @@
</template>
<script setup lang="ts">
import { useBillStore } from '@/store/bill'
import { useBillStore } from '@/store/bill.ts'
import { getBillSortByAmount } from '@/utils/home/billUtil.ts'
import { computed } from 'vue'

View File

@@ -19,11 +19,11 @@
</template>
<script setup lang="ts">
import StatsCard from '@/components/Home/StatsCard.vue'
import { useBillStore } from '@/store/bill'
import StatsCard from '@/components/StatsCard.vue'
import { useBillStore } from '@/store/bill.ts'
import { ref, watch } from 'vue'
import { getBillSummaryStats } from '@/utils/home/billUtil'
import { IBillSummaryStats } from '@/types/bill'
import { getBillSummaryStats } from '@/utils/home/billUtil.ts'
import { IBillSummaryStats } from '@/types/bill.ts'
import { formatAmount } from 'vue3-common/utils/numberUtil'
const billStore = useBillStore()

View File

@@ -0,0 +1,62 @@
<template>
<div class="blog-archive blog-section card-item">
<h4 class="module-title">文章归档</h4>
<el-date-picker
v-model="currentYear"
type="year" placeholder="请选择年份"
style="width: 100px"
@change="changeDateEvent"
/>
<span class="total">共计{{ blogStore.blogList.length }}篇文章</span>
<el-timeline class="time-line">
<el-timeline-item v-for="(value, index) in blogStore.blogList" :key="index">
<div class="item">
<span class="date">{{ value.createTime }}</span>
<span class="title" @click="viewBlogClick(index)">{{ value.title }}</span>
</div>
</el-timeline-item>
</el-timeline>
</div>
</template>
<script setup lang="ts">
import { useBlogStore } from '@/store/blog.ts'
import { useRouter } from 'vue-router'
import { onMounted, ref } from 'vue'
const blogStore = useBlogStore()
const router = useRouter()
const currentYear = ref(new Date())
onMounted(() => {
blogStore.queryBlogByCondition({
year: (new Date()).getFullYear()
})
})
/**
* 选择年份事件
* @param value 年份
*/
const changeDateEvent = async (value: Date) => {
await blogStore.queryBlogByCondition({
year: value.getFullYear()
})
}
/**
* 点击查看博客按钮
* @param index 索引
*/
const viewBlogClick = async (index: number) => {
const blogId = blogStore.blogList[index].id
await router.push({ name: 'DetailId', params: { id: blogId } })
}
</script>
<style scoped lang="scss">
@use "@/styles/blog/blog.archive.module";
</style>

View File

@@ -0,0 +1,40 @@
<template>
<div class="blog-category blog-section card-item">
<h4 class="module-title">文章分类</h4>
<span class="total">目前共计{{ blogStore.blogCategoryList.length }}个分类</span>
<div class="category-list">
<div v-for="(item, index) in blogStore.blogCategoryList"
:key="index" class="item" @click="viewBlogCategoryClick(item.name)">
<span class="label">{{ item.name }}</span>
<span class="value">{{ `(${item.count})` }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useBlogStore } from '@/store/blog.ts'
import { useRouter } from 'vue-router'
import { onMounted } from 'vue'
const blogStore = useBlogStore()
const router = useRouter()
onMounted(() => {
blogStore.queryBlogCategory()
})
/**
* 点击查看博客分类信息
* @param name 类别名称
*/
const viewBlogCategoryClick = async (name: string) => {
await router.push({ name: 'CategoryName', params: { name } })
}
</script>
<style scoped lang="scss">
@use "@/styles/blog/blog.category.module";
</style>

View File

@@ -0,0 +1,41 @@
<template>
<div class="blog-category-detail blog-section card-item">
<span class="name">{{ route.params?.name }}</span>
<div class="category-detail-list">
<div v-for="(item, index) in blogStore.blogList"
:key="index" class="item" @click="viewBlogClick(index)">
<span class="number">{{ index+1 }}</span>
<span class="date">{{ item?.createTime }}</span>
<span class="title">{{ item.title }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useBlogStore } from '@/store/blog.ts'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
import { onMounted } from 'vue'
const blogStore = useBlogStore()
const router = useRouter()
const route = useRoute()
onMounted(async () => {
const categoryName = route.params.name as string
await blogStore.queryBlogByCondition({
category: categoryName
})
})
const viewBlogClick = async (index: number) => {
const blogId = blogStore.blogList[index].id
await router.push({ name: 'DetailId', params: { id: blogId } })
}
</script>
<style scoped lang="scss">
@use "@/styles/blog/blog.category.detail.module";
</style>

View File

@@ -0,0 +1,30 @@
<template>
<div class="blog-comment card-item">
<div class="comment-total">
<span> {{ blogStore.blogNestedCommentList.length }} 条评论</span>
</div>
<div class="comment-list">
<blog-comment-item v-for="(item, index) in blogStore.blogNestedCommentList" :key="index"
:comment="item.comment" :replyList="item.replies"/>
</div>
</div>
</template>
<script setup lang="ts">
import BlogCommentItem from '@/components/Comment/BlogCommentItem.vue'
import { useBlogStore } from '@/store/blog.ts'
const blogStore = useBlogStore()
</script>
<style lang="scss">
.blog-comment {
width: 100%;
padding: 10px;
display: flex;
flex-direction: column;
gap: 10px;
}
</style>

View File

@@ -0,0 +1,121 @@
<template>
<div class="blog-comment-edit card-item">
<div class="comment-title">
<el-input v-model="blogComment.name"
:maxlength="10" show-word-limit
placeholder="请输入昵称"/>
<el-input v-model="blogComment.website"
:maxlength="50" show-word-limit
placeholder="请输入个人博客网站"/>
</div>
<el-input v-model="blogComment.content"
placeholder="有什么想和我说的呢" :maxlength="500"
:rows="7" show-word-limit type="textarea"
/>
<div class="comment-button">
<el-popover ref="emojiPopoverRef" placement="top" :width="300" trigger="hover">
<template #default>
<div class="emoji-panel">
<EmojiPicker :native="true" @select="onSelectEmoji" />
</div>
</template>
<template #reference>
<el-button circle>
<i class="fa-regular fa-face-smile"></i>
</el-button>
</template>
</el-popover>
<el-button type="primary"
:disabled="blogComment.content.length === 0"
@click="sendCommentClick"
class="send-button">发送</el-button>
</div>
</div>
</template>
<script setup lang="ts">
import EmojiPicker from 'vue3-emoji-picker'
import 'vue3-emoji-picker/css'
import { defineProps, ref, onMounted } from 'vue'
import { useBlogStore } from '@/store/blog.ts'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { IBlogComment } from '@/types/blog.ts'
const blogStore = useBlogStore()
const emojiPopoverRef = ref()
const props = defineProps({
parentId: {
required: true,
type: Number,
default: 0
}
})
const blogComment = ref<IBlogComment>({
id: 0,
blogId: 0,
name: '',
website: '',
content: '',
ipAddress: '',
userAgent: '',
parentId: 0,
isApproved: true,
createTime: ''
})
onMounted(() => {
blogComment.value = deepCopyObject(blogStore.getEmptyBlogComment())
})
const onSelectEmoji = (emoji) => {
if (blogComment.value.content.length <= 498) {
blogComment.value.content += emoji.i
}
emojiPopoverRef.value.hide()
}
const sendCommentClick = async () => {
blogComment.value.parentId = props.parentId
blogComment.value.blogId = blogStore.currentBlogId
if (!blogComment.value.name) {
blogComment.value.name = 'Anonymous'
}
await blogStore.addBlogComment(blogComment.value)
blogComment.value = deepCopyObject(blogStore.getEmptyBlogComment())
blogStore.isShowBlogCommentEdit = false
}
</script>
<style lang="scss">
.blog-comment-edit {
width: 100%;
padding: 10px;
display: flex;
flex-direction: column;
gap: 10px;
.comment-title {
display: flex;
justify-content: space-between;
gap: 10px;
}
.comment-button {
width: 100%;
display: flex;
.send-button {
margin-left: auto;
}
}
}
</style>

View File

@@ -0,0 +1,127 @@
<template>
<div class="blog-comment-card">
<el-avatar :src="`https://api.dicebear.com/6.x/adventurer/svg?seed=${props.comment.name}`"
:size="50" alt="未加载"/>
<div class="blog-comment-content">
<div class="basic-info">
<span>{{ props.comment.name }}</span>
<span class="content">{{ getBrowser(props.comment.userAgent) }}</span>
<span class="content">{{ getOsInfo(props.comment.userAgent) }}</span>
</div>
<div class="sub-info">
<span class="content">{{ props.comment.createTime }}</span>
<el-button v-if="!blogComment.isShowEdit"
type="primary" text @click="replyClick">回复</el-button>
<el-button v-else type="primary"
text @click="cancelClick">取消</el-button>
</div>
<p>{{ props.comment.content }}</p>
<blog-comment-edit v-if="blogComment.isShowEdit"
:parent-id="props.comment.id"/>
<div class="reply-list">
<div class="blog-comment-card" v-for="(item, index) in props.replyList" :key="index">
<el-avatar :src="`https://api.dicebear.com/6.x/adventurer/svg?seed=${item.name}`"
:size="50" alt="未加载"/>
<div class="blog-comment-content">
<div class="basic-info">
<span>{{ item.name }}</span>
<span class="content">{{ getBrowser(props.comment.userAgent) }}</span>
<span class="content">{{ getOsInfo(props.comment.userAgent) }}</span>
</div>
<div class="sub-info">
<span class="content">{{ item.createTime }}</span>
</div>
<p>{{ item.content }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import BlogCommentEdit from '@/components/Comment/BlogCommentEdit.vue'
import 'vue3-emoji-picker/css'
import { defineProps, PropType, reactive } from 'vue'
import { IBlogComment } from '@/types/blog.ts'
import { useBlogStore } from '@/store/blog.ts'
import { UAParser } from 'ua-parser-js'
const blogStore = useBlogStore()
const props = defineProps({
comment: {
required: true,
type: Object as PropType<IBlogComment>
},
replyList: {
required: true,
type: Object as PropType<IBlogComment[]>
}
})
const blogComment = reactive({
isShowEdit: false
})
const replyClick = () => {
blogStore.currentBlogComment = blogStore.getEmptyBlogComment()
blogComment.isShowEdit = true
}
const cancelClick = () => {
blogComment.isShowEdit = false
}
const getOsInfo = (userAgent: string) => {
const uaParse = new UAParser(userAgent)
return `${uaParse.getOS().name} ${uaParse.getOS().version}`
}
const getBrowser = (userAgent: string) => {
const uaParse = new UAParser(userAgent)
return `${uaParse.getBrowser().name} ${uaParse.getBrowser().version}`
}
</script>
<style lang="scss">
.blog-comment-card {
width: 100%;
padding: 10px;
display: grid;
grid-template-columns: 60px 1fr;
gap: 5px;
.blog-comment-content {
display: flex;
flex-direction: column;
gap: 5px;
.basic-info {
display: flex;
align-items: center;
gap: 10px;
font-size: small;
}
.sub-info {
display: flex;
justify-content: space-between;
align-items: center;
}
.content {
font-size: small;
color: #666666;
}
}
}
</style>

View File

@@ -0,0 +1,67 @@
<template>
<div class="blog-detail blog-section card-item" id="blog-section">
<div class="blog-title">
<span class="title">{{ blogStore.currentBlog.title }}</span>
<blog-label :basic-blog="getBasicBlog(blogStore.currentBlog)"/>
</div>
<div class="blog-md card-item">
<MdPreview editorId="blog-id"
v-model="blogStore.currentBlog.content"
:theme="appStore.isDark ? 'dark' : 'light'"/>
</div>
<div class="blog-copyright">
<span>
<strong>本文作者: </strong> Cxx
</span>
<span>
<strong>本文链接: </strong>
<a href="https://www.microsoft.com/">{{ currentUrl.href }}</a>
</span>
<span>
<strong>版权声明: </strong>
本博客所有文章除特别声明外均采用
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">©BY-NC-SA</a>
许可协议转载请注明出处
</span>
</div>
<div class="blog-ending">
<span>-------------本文结束感谢您的阅读给个五星好评吧~~-------------</span>
</div>
<blog-comment-edit :parent-id="0"/>
<blog-comment />
</div>
</template>
<script setup lang="ts">
import BlogLabel from '@/components/Content/BlogLabel.vue'
import BlogCommentEdit from '@/components/Comment/BlogCommentEdit.vue'
import BlogComment from '@/components/Comment/BlogComment.vue'
import { MdPreview } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import { useBlogStore } from '@/store/blog.ts'
import { useAppStore } from '@/store/app.ts'
import { getBasicBlog } from '@/utils/blog/blogUtil.ts'
import { useRoute } from 'vue-router'
import { onMounted } from 'vue'
const blogStore = useBlogStore()
const appStore = useAppStore()
const route = useRoute()
const currentUrl = new URL(window.location.href)
onMounted(async () => {
const blogId = route.params.id as number
blogStore.currentBlogId = blogId
await blogStore.queryBlogById(blogId)
})
</script>
<style scoped lang="scss">
@use "@/styles/blog/blog.detail.module";
</style>

View File

@@ -0,0 +1,92 @@
<template>
<div class="label-list">
<div class="container">
<div class="top-value item" v-if="props.basicBlog?.topValue > 1">
<i class="fa-solid fa-thumbtack"></i>
</div>
<div v-if="props.basicBlog?.topValue > 1" class="item">|</div>
<div class="great item" v-if="props.basicBlog?.isGreat">
<i class="fa-regular fa-newspaper"></i>
</div>
<div v-if="props.basicBlog?.isGreat" class="item">|</div>
<div class="item">
<i class="fa-regular fa-calendar"></i>
<span class="date">{{ formatDate(props.basicBlog.createTime) }}</span>
</div>
<div class="item">|</div>
<div class="item">
<i class="fa-regular fa-calendar-check"></i>
<span class="date">{{ formatDate(props.basicBlog.createTime) }}</span>
</div>
<div class="item">|</div>
<div class="item">
<i class="fa-regular fa-folder"></i>
<span class="category" @click="viewBlogCategoryClick">
{{ props.basicBlog.category }}
</span>
</div>
<div class="item">|</div>
<div class="item">
<i class="fa-solid fa-eye"></i>
<span>{{ props.basicBlog.visitCount }} </span>
</div>
</div>
<div class="container">
<div class="item">
<i class="fa-regular fa-file-word"></i>
<span>{{ props.basicBlog.wordCount }} </span>
</div>
<div class="item">|</div>
<div class="item">
<i class="fa-regular fa-clock"></i>
<span>{{ props.basicBlog.readDuration.toFixed(0) }} 分钟</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { defineProps, PropType } from 'vue'
import { IBasicBlog } from '@/types/blog.ts'
import { useBlogStore } from '@/store/blog.ts'
import { useRouter } from 'vue-router'
import { formatDate } from 'vue3-common/utils/dateUtil'
const blogStore = useBlogStore()
const router = useRouter()
const props = defineProps({
basicBlog: {
required: true,
type: Object as PropType<IBasicBlog>
}
})
/**
* 点击查看博客分类按钮
*/
const viewBlogCategoryClick = async () => {
const category = props.basicBlog?.category as string
await blogStore.queryBlogByCondition({
category
})
await router.push({ name: 'CategoriesBlog', params: { name: category } })
}
</script>
<style scoped lang="scss">
@use "@/styles/blog/blog.label.module";
</style>

View File

@@ -0,0 +1,66 @@
<template>
<div class="blog-content-list blog-section card-item">
<div v-if="blogStore.blogList.length === 0"
class="blog-content blog-content-empty" >
</div>
<div class="blog-content blog-content-summary"
v-for="(item, index) in blogStore.blogList" :key="index">
<span class="title">{{ item.title }}</span>
<blog-label :basic-blog="getBasicBlog(item)"/>
<p class="content">
{{ item.summary }}
</p>
<el-button type="primary" @click="readBlogClick(index)">阅读全文 »</el-button>
<hr/>
</div>
<el-pagination
v-model:current-page="blogStore.pageInfo.currentPage"
:page-size="blogStore.pageInfo.pageSize"
:total="blogStore.pageInfo.totalSize"
layout="total, prev, pager, next"
@current-change="changePageClick"
/>
</div>
</template>
<script setup lang="ts">
import BlogLabel from '@/components/Content/BlogLabel.vue'
import { useRouter } from 'vue-router'
import { onMounted } from 'vue'
import { useBlogStore } from '@/store/blog.ts'
import { getBasicBlog } from '@/utils/blog/blogUtil.ts'
const router = useRouter()
const blogStore = useBlogStore()
onMounted(async () => {
await blogStore.queryBlog()
})
/**
* 点击阅读博客按钮
* @param index 索引
*/
const readBlogClick = async (index: number) => {
const blogId = blogStore.blogList[index].id
await router.push({ name: 'DetailId', params: { id: blogId } })
}
/**
* 点击切换博客页数按钮
* @param page 页码
*/
const changePageClick = async (page: number) => {
blogStore.pageInfo.currentPage = page
await blogStore.queryBlog()
}
</script>
<style lang="scss">
@use "@/styles/blog/blog.overview.module";
</style>

View File

@@ -16,5 +16,5 @@ const appStore = useAppStore()
</script>
<style lang="scss">
@use "@/styles/app.loading.module.scss";
@use "@/styles/app.loading.module";
</style>

View File

@@ -50,7 +50,7 @@
</template>
<script setup lang="ts">
import WeatherIcon from '@/components/Mobile/WeatherIcon.vue'
import WeatherIcon from '@/components/Common/WeatherIcon.vue'
import { onMounted, onUnmounted, reactive } from 'vue'
import axios from 'axios'
import { Solar } from 'lunar-javascript'

View File

@@ -10,12 +10,12 @@
</template>
<script setup lang="ts">
import FoodDailyItem from '@/components/Home/Food/FoodDailyItem.vue'
import FoodDailyItem from '@/components/Food/FoodDailyItem.vue'
import { reactive, watch, ref, onMounted } from 'vue'
import { useFoodStore } from '@/store/food.ts'
import { formatDate } from 'vue3-common/utils/dateUtil'
import { CalendarDay } from 'v-calendar/dist/types/src/utils/page'
import { useAppStore } from '@/store/app'
import { useAppStore } from '@/store/app.ts'
const calendarRef = ref()
const foodStore = useFoodStore()

View File

@@ -65,7 +65,7 @@
<script setup lang="ts">
import { Edit, MoreFilled, DeleteFilled } from '@element-plus/icons-vue'
import { useFoodStore } from '@/store/food'
import { useFoodStore } from '@/store/food.ts'
import { defineProps, onMounted, PropType, reactive } from 'vue'
import { IFoodRecipe, IFoodRecord } from '@/types/food.ts'
import { useRouter } from 'vue-router'
@@ -110,11 +110,7 @@ const editFoodRecipeClick = async () => {
}
const viewFoodRecipeClick = async () => {
if (isMobile()) {
await router.push({ name: 'MobileHomeFoodDetailId', params: { id: props.foodItem?.id } })
} else {
await router.push({ name: 'HomeLifeFoodId', params: { id: props.foodItem?.id } })
}
await router.push({ name: 'FoodDetailId', params: { id: props.foodItem?.id } })
}
const deleteFoodRecipeClick = () => {
@@ -130,5 +126,5 @@ const changeFoodEvent = (current: number) => {
</script>
<style lang="scss">
@use "@/styles/home/life.record.module.scss";
@use "@/styles/home/life.record.module";
</style>

View File

@@ -22,8 +22,8 @@
</template>
<script setup lang="ts">
import DailySummary from '@/components/Home/DailySummary.vue'
import DailyCard from '@/components/Home/DailyCard.vue'
import DailySummary from '@/components/DailySummary.vue'
import DailyCard from '@/components/DailyCard.vue'
import { defineProps, onMounted, reactive, watch } from 'vue'
import { useFoodStore } from '@/store/food.ts'
import { useRouter } from 'vue-router'
@@ -89,7 +89,7 @@ const selectFoodRecordClick = async (foodRecord: IFoodRecord) => {
if (isMobile()) {
appStore.isShowMobileBack = true
foodStore.currentFoodRecord = foodRecord
await router.push({ name: 'MobileHomeFoodRecordForm' })
await router.push({ name: 'FoodRecordForm' })
} else {
foodStore.foodRecordDialog = {
title: '编辑记录',

View File

@@ -14,7 +14,7 @@
</template>
<script setup lang="ts">
import FoodDailyItem from '@/components/Home/Food/FoodDailyItem.vue'
import FoodDailyItem from '@/components/Food/FoodDailyItem.vue'
import { reactive, watch } from 'vue'
import { useFoodStore } from '@/store/food.ts'

View File

@@ -54,12 +54,12 @@
</template>
<script lang="ts" setup>
import FoodMaterialForm from '@/components/Home/Food/Form/FoodMaterialForm.vue'
import FoodStepForm from '@/components/Home/Food/Form/FoodStepForm.vue'
import { useFoodStore } from '@/store/food'
import FoodMaterialForm from '@/components/Food/Form/FoodMaterialForm.vue'
import FoodStepForm from '@/components/Food/Form/FoodStepForm.vue'
import { useFoodStore } from '@/store/food.ts'
import { FormInstance, FormRules } from 'element-plus'
import { computed, nextTick, ref, reactive } from 'vue'
import { foodRules } from '@/utils/element/elRules'
import { foodRules } from '@/utils/element/elRules.ts'
const rules = reactive<FormRules>(foodRules)
const formRef = ref<FormInstance>()

View File

@@ -19,7 +19,7 @@
</template>
<script setup lang="ts">
import { useFoodStore } from '@/store/food'
import { useFoodStore } from '@/store/food.ts'
import { isMobile } from 'vue3-common/utils/layoutUtil'
import { onMounted, ref } from 'vue'
import { ICategory } from '@/types'

View File

@@ -23,7 +23,7 @@
<script setup lang="ts">
import { Plus } from '@element-plus/icons-vue'
import FoodCard from '@/components/Home/Food/FoodCard.vue'
import FoodCard from '@/components/Food/FoodCard.vue'
import { useFoodStore } from '@/store/food.ts'
import { isLargeScreen } from '@/utils'

View File

@@ -19,9 +19,9 @@
</template>
<script setup lang="ts">
import StatsCard from '@/components/Home/StatsCard.vue'
import StatsCard from '@/components/StatsCard.vue'
import { onMounted } from 'vue'
import { useFoodStore } from '@/store/food'
import { useFoodStore } from '@/store/food.ts'
const foodStore = useFoodStore()

View File

@@ -41,10 +41,10 @@
</template>
<script lang="ts" setup>
import { useFoodStore } from '@/store/food'
import { useFoodStore } from '@/store/food.ts'
import { nextTick, reactive, ref } from 'vue'
import { FormRules } from 'element-plus'
import { foodMaterialRules } from '@/utils/element/elRules'
import { foodMaterialRules } from '@/utils/element/elRules.ts'
const rules = reactive<FormRules>(foodMaterialRules)
const formRef = ref()

View File

@@ -21,8 +21,8 @@
</template>
<script setup lang="ts">
import { useFoodStore } from '@/store/food'
import { IFoodMaterial } from '@/types/food'
import { useFoodStore } from '@/store/food.ts'
import { IFoodMaterial } from '@/types/food.ts'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { commonElMessageBox } from 'vue3-common/utils/elUtil'

View File

@@ -56,10 +56,10 @@
<script lang="ts" setup>
import { UploadImage } from 'vue3-common'
import { useFoodStore } from '@/store/food'
import { useFoodStore } from '@/store/food.ts'
import { computed, ref, reactive, nextTick } from 'vue'
import { FormInstance, FormRules } from 'element-plus'
import { foodRecordRules } from '@/utils/element/elRules'
import { foodRecordRules } from '@/utils/element/elRules.ts'
import { fileServiceUrl, serviceFileRootPath } from '@/utils'
import { commonElMessageBox } from 'vue3-common/utils/elUtil'

View File

@@ -32,10 +32,10 @@
<script lang="ts" setup>
import { UploadImage } from 'vue3-common'
import { useFoodStore } from '@/store/food'
import { useFoodStore } from '@/store/food.ts'
import { ref, reactive, nextTick } from 'vue'
import { FormRules } from 'element-plus'
import { foodStepRules } from '@/utils/element/elRules'
import { foodStepRules } from '@/utils/element/elRules.ts'
import { fileServiceUrl, serviceFileRootPath } from '@/utils'
const rules = reactive<FormRules>(foodStepRules)

View File

@@ -25,8 +25,8 @@
</template>
<script setup lang="ts">
import { useFoodStore } from '@/store/food'
import { IFoodStep } from '@/types/food'
import { useFoodStore } from '@/store/food.ts'
import { IFoodStep } from '@/types/food.ts'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { commonElMessageBox } from 'vue3-common/utils/elUtil'
import { serviceFileRootPath } from '@/utils'

View File

@@ -1,40 +0,0 @@
<template>
<div class="budget-chart">
<div class="budget-rank-chart card-item" ref="budgetRankChartRef"/>
<div class="budget-project-chart card-item" ref="budgetProjectChartRef"/>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
import { useBudgetStore } from '@/store/budget'
import { barChartOptions, pieChartOptions } from 'vue3-common/utils/eChartsUtil'
const budgetStore = useBudgetStore()
const budgetRankChartRef = ref<HTMLElement>()
const budgetProjectChartRef = ref<HTMLElement>()
let budgetRankChart: echarts.ECharts
let budgetProjectChart: echarts.ECharts
watch(() => budgetStore.isRefresh, () => {
updateChart()
})
onMounted(() => {
budgetRankChart = echarts.init(budgetRankChartRef.value as HTMLElement)
budgetProjectChart = echarts.init(budgetProjectChartRef.value as HTMLElement)
})
const updateChart = () => {
// 预算排行统计图
const rankNameList = budgetStore.budgetRankStatsList.map((item) => item.name)
const rankValueList = budgetStore.budgetRankStatsList.map((item) => item.value)
budgetRankChart.setOption(barChartOptions('📊预算排行', '项目', rankNameList, '金额', rankValueList))
// 预算项目统计图
budgetProjectChart.setOption(pieChartOptions('📊预算项目', '项目', '', budgetStore.budgetProjectStatsList))
}
</script>

View File

@@ -1,114 +0,0 @@
<template>
<el-dialog v-model="budgetStore.budgetDialog.visible"
:title="budgetStore.budgetDialog.title"
center @open="openDialogEvent"
width="50%" class="budget-dialog">
<el-form ref="formRef" :model="budgetStore.budgetDialog.data"
:rules="rules" label-width="100px">
<el-form-item label="预算类别" prop="category">
<el-select
v-model="budgetStore.budgetDialog.data.category"
allow-create filterable placeholder="请输入或选择预算类别">
<el-option
v-for="(item, index) in budgetStore.budgetCategoryList"
:key="index" :label="item" :value="item"
/>
</el-select>
</el-form-item>
<el-form-item label="预算项目" prop="project">
<el-input v-model="budgetStore.budgetDialog.data.project" autocomplete="off"
placeholder="请输入预算项目" clearable
show-word-limit maxlength="20">
</el-input>
</el-form-item>
<el-form-item label="预算内容" prop="content">
<el-input v-model="budgetStore.budgetDialog.data.content" autocomplete="off"
placeholder="请输入预算内容" clearable
show-word-limit maxlength="20">
</el-input>
</el-form-item>
<el-form-item label="供应商" prop="vendor">
<el-input v-model="budgetStore.budgetDialog.data.vendor" autocomplete="off"
placeholder="请输入预算供应商" clearable
show-word-limit maxlength="20">
</el-input>
</el-form-item>
<el-form-item label="预算支出" prop="budget">
<el-input
v-model="budgetStore.budgetDialog.data.budget"
placeholder="请输入预算支出" clearable
:formatter="(value: string) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="(value: string) => value.replace(/\$\s?|(,*)/g, '')"
/>
</el-form-item>
<el-form-item label="实际支出" prop="actual">
<el-input
v-model="budgetStore.budgetDialog.data.actual"
placeholder="请输入实际支出" clearable
:formatter="(value: string) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="(value: string) => value.replace(/\$\s?|(,*)/g, '')"
/>
</el-form-item>
<el-form-item label="支付时间">
<el-date-picker
v-model="budgetStore.budgetDialog.data.payTime"
type="datetime" placeholder="请选择支付时间"
value-format="YYYY-MM-DD HH:mm:ss"/>
</el-form-item>
<el-form-item label="备注" prop="remake">
<el-input v-model="budgetStore.budgetDialog.data.remake" autocomplete="off"
placeholder="请输入备注" clearable
show-word-limit maxlength="20">
</el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="cancelClick">取消</el-button>
<el-button type="primary" @click="confirmClick">确认</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { useBudgetStore } from '@/store/budget'
import { FormRules } from 'element-plus'
import { budgetRules } from '@/utils/element/elRules'
import { nextTick, reactive, ref } from 'vue'
const formRef = ref()
const rules = reactive<FormRules>(budgetRules)
const budgetStore = useBudgetStore()
/**
* 打开对话框事件
*/
const openDialogEvent = async () => {
await nextTick(() => {
formRef.value.clearValidate()
})
}
/**
* 点击确认按钮
*/
const confirmClick = () => {
formRef.value.validate().then(async () => {
await budgetStore.handleBlogApi(budgetStore.budgetDialog.data.id)
budgetStore.queryInfo.category = budgetStore.budgetDialog.data.category
})
}
const cancelClick = () => {
budgetStore.budgetDialog.visible = false
}
</script>

View File

@@ -1,54 +0,0 @@
<template>
<div class="budget-query common-query">
<el-switch
v-model="budgetStore.showDataType"
inline-prompt
style="--el-switch-on-color: #CA6C65; --el-switch-off-color: #009FA8"
active-value="CHART" inactive-value="DATA"
active-text="图表统计" inactive-text="数据显示"
@change="changeShowDataTypeEvent"
/>
<el-select
v-model="budgetStore.queryInfo.category"
placeholder="请选择类别" style="width: 120px"
@focus="focusCategoryEvent" @change="changeCategoryEvent">
<el-option
v-for="(item, index) in budgetStore.budgetCategoryList"
:key="index" :label="item" :value="item"
/>
</el-select>
<el-button v-if="budgetStore.showDataType === 'DATA'"
type="primary" @click="addBudgeClick">新增预算
</el-button>
</div>
</template>
<script lang="ts" setup>
import { useBudgetStore } from '@/store/budget'
const budgetStore = useBudgetStore()
const focusCategoryEvent = async () => {
await budgetStore.queryBudgetCategory()
}
const changeCategoryEvent = async () => {
await budgetStore.refreshInfo()
}
const addBudgeClick = () => {
budgetStore.budgetApiType = 'ADD'
budgetStore.budgetDialog = {
title: '新增预算',
visible: true,
data: budgetStore.getEmptyBudget()
}
budgetStore.budgetDialog.data.category = budgetStore.queryInfo.category
}
const changeShowDataTypeEvent = async () => {
await budgetStore.refreshInfo()
}
</script>

View File

@@ -1,98 +0,0 @@
<template>
<el-table :data="budgetStore.budgetList"
border stripe show-summary
:span-method="spanMethod" :summary-method="summaryMethod"
:header-cell-style="tableHeaderStyle()"
:row-style="tableRowStyle()" :cell-style="tableCellStyle()"
class="budget-table card-item">
<el-table-column type="index" align="center" width="80"/>
<el-table-column prop="project" label="项目" align="center" min-width="5%"/>
<el-table-column prop="content" label="内容" align="center" min-width="10%"/>
<el-table-column prop="vendor" label="供应商" align="center" min-width="10%"/>
<el-table-column prop="budget" label="预算支出(元)" align="center" min-width="10%">
<template #default="scope">
{{ formatAmount(scope.row.budget) }}
</template>
</el-table-column>
<el-table-column prop="actual" label="实际支出(元)" align="center" min-width="10%">
<template #default="scope">
{{ formatAmount(scope.row.actual) }}
</template>
</el-table-column>
<el-table-column prop="save" label="节省预算(元)" align="center" min-width="10%">
<template #default="scope">
{{ formatAmount(scope.row.budget - scope.row.actual) }}
</template>
</el-table-column>
<el-table-column prop="percent" label="支出占比" align="center" min-width="10%">
<template #default="scope">
{{ `${((scope.row.actual / totalActual) * 100).toFixed(2)}%` }}
</template>
</el-table-column>
<el-table-column prop="remake" label="备注" align="center" min-width="10%"/>
<el-table-column fixed="right" label="操作" align="center" width="250">
<template #default="scope">
<el-button type="primary" @click="editBudget(scope.row)">编辑</el-button>
<el-button type="primary" @click="editBudget(scope.row)">账单</el-button>
<el-button type="danger" @click="deleteBudget(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
import { useBudgetStore } from '@/store/budget'
import { IBudgetInfo } from '@/types/budget.ts'
import { computed } from 'vue'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { formatAmount } from 'vue3-common/utils/numberUtil'
import { getRowspan, getSummaryData } from 'vue3-common/utils/elUtil'
import { commonElMessageBox, tableHeaderStyle, tableCellStyle, tableRowStyle } from 'vue3-common/utils/elUtil'
const budgetStore = useBudgetStore()
const spanIndex = 1
const summaryColumnList = ['budget', 'actual', 'save']
const totalActual = computed(() => {
return budgetStore.budgetList.reduce((sum, item: IBudgetInfo) => {
return sum + Number(item.actual || 0)
}, 0)
})
const spanMethod = (data: { row: any; column: any; rowIndex: number; columnIndex: number }) => {
// 需要合并的列索引
if (data.columnIndex === spanIndex) {
return getRowspan(budgetStore.budgetList, data.column.property, data.rowIndex, data.row)
}
}
const summaryMethod = (data: { columns: any[]; data: any[] }) => {
const sums = getSummaryData(data.columns, data.data, summaryColumnList)
// 格式化输出
sums[6] = formatAmount(parseFloat(sums[4] as string) - parseFloat(sums[5] as string))
sums[4] = formatAmount(parseFloat(sums[4] as string))
sums[5] = formatAmount(parseFloat(sums[5] as string))
sums[7] = '100%'
return sums
}
const editBudget = (budget: IBudgetInfo) => {
budgetStore.budgetApiType = 'UPDATE'
budgetStore.budgetDialog = {
title: '编辑预算',
visible: true,
data: deepCopyObject(budget)
}
}
const deleteBudget = (budget: IBudgetInfo) => {
budgetStore.budgetApiType = 'DELETE'
commonElMessageBox('是否删除该预算?').then(() => {
budgetStore.handleBlogApi(budget.id as number)
})
}
</script>

View File

@@ -13,11 +13,11 @@
</template>
<script setup lang="ts">
import JournalCard from '@/components/Home/Journal/JournalCard.vue'
import JournalCard from '@/components/Journal/JournalCard.vue'
import { reactive, watch, ref } from 'vue'
import { formatDate, getStartEndDate } from 'vue3-common/utils/dateUtil'
import { CalendarDay } from 'v-calendar/dist/types/src/utils/page'
import { useAppStore } from '@/store/app'
import { useAppStore } from '@/store/app.ts'
import { useJournalStore } from '@/store/journal.ts'
import { IJournal } from '@/types/journal.ts'

View File

@@ -115,7 +115,7 @@ const editClick = async () => {
if (isMobile()) {
appStore.isShowMobileBack = true
await router.push({ name: 'MobileHomeJournalDetailId', params: { id } })
await router.push({ name: 'JournalDetailId', params: { id } })
} else {
journalStore.journalDialog = {
title: '编辑日记',

View File

@@ -40,9 +40,9 @@ import { defineProps, PropType } from 'vue'
import { formatAmount } from 'vue3-common/utils/numberUtil'
import { isMobile } from 'vue3-common/utils/layoutUtil'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { useLedgerStore } from '@/store/ledger'
import { useLedgerStore } from '@/store/ledger.ts'
import { useRouter } from 'vue-router'
import { ILedger, ILegerItem } from '@/types/ledger'
import { ILedger, ILegerItem } from '@/types/ledger.ts'
const props = defineProps({
item: {
@@ -58,15 +58,7 @@ const editClick = async (leger: ILegerItem) => {
ledgerStore.ledgerApiType = 'UPDATE'
ledgerStore.currentLedgerRecord = ledgerStore.ledgerRecordList.find((item) => item.id === leger.id)
if (isMobile()) {
await router.push({ name: 'MobileHomeLedgerDetailId', params: { id: leger.id } })
} else {
ledgerStore.ledgerDialog = {
title: '编辑账本内容',
visible: true,
data: deepCopyObject(ledgerStore.currentLedgerRecord)
}
}
await router.push({ name: 'LedgerDetailId', params: { id: leger.id } })
}
</script>

View File

@@ -45,12 +45,6 @@
:loading="authStore.loginLoading"
@click.prevent="handleLogin('common')">登录
</el-button>
<div />
<el-button type="primary" style="width: 100%;"
:disabled="!authStore.isVerified"
:loading="authStore.loginAdminLoading"
@click.prevent="handleLogin('admin')">登录管理系统
</el-button>
<div class="login-type">
<el-button @click="authStore.changeLoginType('phone')">手机号登录</el-button>
@@ -76,15 +70,15 @@
</template>
<script setup lang="ts">
import LoginAuth from '@/components/Home/Login/LoginAuth.vue'
import { useAuthStore } from '@/store/auth'
import LoginAuth from '@/components/Login/LoginAuth.vue'
import { useAuthStore } from '@/store/auth.ts'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/store/user'
import { useUserStore } from '@/store/user.ts'
import { ElMessage, FormRules } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'
import { loginRules } from '@/utils/element/elRules'
import { loginRules } from '@/utils/element/elRules.ts'
import { getLocalStorage, setLocalStorage } from 'vue3-common/utils/storageUtil'
import { ILoginType } from '@/types/auth'
import { ILoginType } from '@/types/auth.ts'
import { isMobile } from 'vue3-common/utils/layoutUtil'
const rules = reactive<FormRules>(loginRules)
@@ -130,7 +124,7 @@ const handleLogin = async (type: ILoginType) => {
}
if (type === 'common') {
await router.push('/mobile-home')
await router.push('/home')
} else {
await router.push('/admin')
}

View File

@@ -46,11 +46,11 @@
</template>
<script setup lang="ts">
import { useAuthStore } from '@/store/auth'
import { useAuthStore } from '@/store/auth.ts'
import { useRouter } from 'vue-router'
import { ElMessage, FormRules } from 'element-plus'
import { reactive, ref } from 'vue'
import { loginRules } from '@/utils/element/elRules'
import { loginRules } from '@/utils/element/elRules.ts'
const rules = reactive<FormRules>(loginRules)
const authStore = useAuthStore()

View File

@@ -46,11 +46,11 @@
</template>
<script setup lang="ts">
import { useAuthStore } from '@/store/auth'
import { useAuthStore } from '@/store/auth.ts'
import { useRouter } from 'vue-router'
import { ElMessage, FormRules } from 'element-plus'
import { reactive, ref } from 'vue'
import { loginRules } from '@/utils/element/elRules'
import { loginRules } from '@/utils/element/elRules.ts'
const rules = reactive<FormRules>(loginRules)
const authStore = useAuthStore()

View File

@@ -43,7 +43,7 @@ const editClick = async () => {
passwordStore.passwordApiType = 'UPDATE'
passwordStore.currentPassword = props.passwordItem as IPassword
await router.push({ name: 'MobileHomePasswordDetailId', params: { id } })
await router.push({ name: 'PasswordDetailId', params: { id } })
}
const deleteClick = () => {

View File

@@ -5,7 +5,7 @@
<script lang="ts" setup>
import { onMounted, watch } from 'vue'
import { Calendar, DateSelectArg, EventClickArg } from '@fullcalendar/core'
import { initCommonCalendar, initMobileCalendar } from '@/utils/home/planUtil'
import { initCommonCalendar, initMobileCalendar } from '@/utils/home/planUtil.ts'
import { usePlanStore } from '@/store/plan.ts'
import { isMobile } from 'vue3-common/utils/layoutUtil'
@@ -83,7 +83,7 @@ const eventClickEvent = (eventClick: EventClickArg) => {
</script>
<style lang="scss">
@import "@/styles/home.variable.module.scss";
@import "@/styles/home.variable.module";
$cell-height: 3.8vh;
$time-slot-width: 70px;

View File

@@ -66,9 +66,9 @@
import { defineProps, PropType } from 'vue'
import { AlarmClock, Clock } from '@element-plus/icons-vue'
import { IPlanInfo } from '@/types/plan.ts'
import { getRemainDays, isBeforeToday } from '@/utils/home/planUtil'
import { getRemainDays, isBeforeToday } from '@/utils/home/planUtil.ts'
import { deepCopyObject } from 'vue3-common/utils/dataUtil'
import { usePlanStore } from '@/store/plan'
import { usePlanStore } from '@/store/plan.ts'
import { useRouter } from 'vue-router'
import { commonElMessageBox } from 'vue3-common/utils/elUtil'
import { isMobile } from 'vue3-common/utils/layoutUtil'

View File

@@ -103,9 +103,9 @@
<script lang="ts" setup>
import { ElMessage, FormInstance, FormRules } from 'element-plus'
import { planRules } from '@/utils/element/elRules'
import { planRules } from '@/utils/element/elRules.ts'
import { computed, nextTick, reactive, ref } from 'vue'
import { isBeforeTime } from '@/utils/home/planUtil'
import { isBeforeTime } from '@/utils/home/planUtil.ts'
import { commonElMessageBox } from 'vue3-common/utils/elUtil'
import { usePlanStore } from '@/store/plan.ts'
import { useUserStore } from '@/store/user.ts'

View File

@@ -11,7 +11,7 @@
</template>
<script lang="ts" setup>
import PlanCard from '@/components/Home/Plan/PlanCard.vue'
import PlanCard from '@/components/Plan/PlanCard.vue'
import { usePlanStore } from '@/store/plan.ts'
const planStore = usePlanStore()

View File

@@ -19,8 +19,8 @@
</template>
<script setup lang="ts">
import StatsCard from '@/components/Home/StatsCard.vue'
import { usePlanStore } from '@/store/plan'
import StatsCard from '@/components/StatsCard.vue'
import { usePlanStore } from '@/store/plan.ts'
const planStore = usePlanStore()
</script>

Some files were not shown because too many files have changed in this diff Show More