feat:更新个人中心UI
This commit is contained in:
@@ -21,12 +21,18 @@ export const deleteMomentApi = (id: number): Promise<boolean> =>
|
|||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
|
|
||||||
export const queryMomentApi = (): Promise<IMoment[]> =>
|
export const queryMomentListApi = (): Promise<IMoment[]> =>
|
||||||
cloudService({
|
cloudService({
|
||||||
url: '/food-service/moment',
|
url: '/food-service/moment',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const queryMomentByIdApi = (id: number): Promise<IMoment[]> =>
|
||||||
|
cloudService({
|
||||||
|
url: `/food-service/moment/${id}`,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
|
||||||
export const addCommentApi = (id: number, content: string): Promise<boolean> =>
|
export const addCommentApi = (id: number, content: string): Promise<boolean> =>
|
||||||
cloudService({
|
cloudService({
|
||||||
url: `/food-service/moment/${id}/comment`,
|
url: `/food-service/moment/${id}/comment`,
|
||||||
|
|||||||
49
src/components/Food/FoodQuery.vue
Normal file
49
src/components/Food/FoodQuery.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div class="search-container">
|
||||||
|
<el-input v-if="expanded" ref="inputRef"
|
||||||
|
v-model="searchText" placeholder="搜索菜友食谱"
|
||||||
|
style="width: 200px;"
|
||||||
|
show-word-limit :maxlength="10" clearable
|
||||||
|
@keyup.enter="handleSearch" @blur="handleBlur"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<el-button v-else :icon="Search"
|
||||||
|
circle size="small" @click="expandSearch"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, nextTick } from 'vue'
|
||||||
|
import { Search } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const expanded = ref(false)
|
||||||
|
const searchText = ref('')
|
||||||
|
const inputRef = ref(null)
|
||||||
|
|
||||||
|
// 展开搜索框
|
||||||
|
const expandSearch = () => {
|
||||||
|
expanded.value = true
|
||||||
|
// 等待DOM更新后自动聚焦输入框
|
||||||
|
nextTick(() => {
|
||||||
|
inputRef.value?.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理搜索
|
||||||
|
const handleSearch = () => {
|
||||||
|
if (searchText.value.trim()) {
|
||||||
|
console.log('搜索内容:', searchText.value)
|
||||||
|
// 这里可以触发搜索逻辑
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输入框失去焦点时的处理
|
||||||
|
const handleBlur = () => {
|
||||||
|
if (!searchText.value.trim()) {
|
||||||
|
expanded.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
</style>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
import FoodCard from '@/components/Food/FoodCard.vue'
|
import FoodCard from '@/components/Food/FoodCard.vue'
|
||||||
import ArriveBottom from '@/components/ArriveButton.vue'
|
import ArriveBottom from '@/components/ArriveButton.vue'
|
||||||
import { useFoodStore } from '@/store/food.ts'
|
import { useFoodStore } from '@/store/food.ts'
|
||||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||||
import type { ICategory } from '@/types'
|
import type { ICategory } from '@/types'
|
||||||
|
|
||||||
const foodRecipeRef = ref()
|
const foodRecipeRef = ref()
|
||||||
@@ -33,10 +33,7 @@ const foodStore = useFoodStore()
|
|||||||
const queryCategoryList = ref([] as ICategory[])
|
const queryCategoryList = ref([] as ICategory[])
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await foodStore.queryCategory()
|
|
||||||
initCategoryList()
|
|
||||||
// foodStore.foodRecipeList = []
|
// foodStore.foodRecipeList = []
|
||||||
await foodStore.refreshInfo()
|
|
||||||
// foodRecipeRef.value.addEventListener('scroll', handleScroll)
|
// foodRecipeRef.value.addEventListener('scroll', handleScroll)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -44,6 +41,10 @@ onBeforeUnmount(() => {
|
|||||||
// foodRecipeRef.value.removeEventListener('scroll', handleScroll)
|
// foodRecipeRef.value.removeEventListener('scroll', handleScroll)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(() => foodStore.isRefresh, () => {
|
||||||
|
initCategoryList()
|
||||||
|
})
|
||||||
|
|
||||||
const initCategoryList = () => {
|
const initCategoryList = () => {
|
||||||
queryCategoryList.value = []
|
queryCategoryList.value = []
|
||||||
queryCategoryList.value.push({
|
queryCategoryList.value.push({
|
||||||
|
|||||||
@@ -43,29 +43,26 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { CaretLeft, CaretRight } from '@element-plus/icons-vue'
|
import { CaretLeft, CaretRight } from '@element-plus/icons-vue'
|
||||||
import { useFoodStore } from '@/store/food.ts'
|
import { useFoodStore } from '@/store/food.ts'
|
||||||
import { onMounted, ref } from 'vue'
|
|
||||||
import { formatDate, getLastDate, getNextDate } from 'vue3-common/utils/dateUtil'
|
import { formatDate, getLastDate, getNextDate } from 'vue3-common/utils/dateUtil'
|
||||||
import { serviceFileRootPath } from '@/utils'
|
import { serviceFileRootPath } from '@/utils'
|
||||||
|
|
||||||
const currentYear = ref(new Date())
|
|
||||||
const foodStore = useFoodStore()
|
const foodStore = useFoodStore()
|
||||||
|
|
||||||
|
|
||||||
const changeDateEvent = async (value: Date) => {
|
const changeDateEvent = async (value: Date) => {
|
||||||
foodStore.queryRecord.year = String(value.getFullYear())
|
foodStore.queryRecord.year = String(value.getFullYear())
|
||||||
await foodStore.refreshInfo()
|
await foodStore.queryRecordList()
|
||||||
}
|
}
|
||||||
|
|
||||||
const previousYearClick = async () => {
|
const previousYearClick = async () => {
|
||||||
const lastYear = getLastDate(foodStore.queryRecord.year, 1, 'years')
|
const lastYear = getLastDate(foodStore.queryRecord.year, 1, 'years')
|
||||||
foodStore.queryRecord.year = String(new Date(lastYear).getFullYear())
|
foodStore.queryRecord.year = String(new Date(lastYear).getFullYear())
|
||||||
await foodStore.refreshInfo()
|
await foodStore.queryRecordList()
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextYearClick = async () => {
|
const nextYearClick = async () => {
|
||||||
const lastYear = getNextDate(foodStore.queryRecord.year, 1, 'years')
|
const lastYear = getNextDate(foodStore.queryRecord.year, 1, 'years')
|
||||||
foodStore.queryRecord.year = String(new Date(lastYear).getFullYear())
|
foodStore.queryRecord.year = String(new Date(lastYear).getFullYear())
|
||||||
await foodStore.refreshInfo()
|
await foodStore.queryRecordList()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -150,61 +150,3 @@ const viewProfileClick = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.moment-card {
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 50px 1fr;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
.moment-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: larger;
|
|
||||||
}
|
|
||||||
|
|
||||||
.moment-image-list {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-container {
|
|
||||||
display: flex;
|
|
||||||
gap: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.moment-comment {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 40px 60px;
|
|
||||||
justify-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.moment-comment-list {
|
|
||||||
padding: 10px;
|
|
||||||
background-color: var(--color-comment-bg);
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 5px;
|
|
||||||
|
|
||||||
.moment-comment-item {
|
|
||||||
.name {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
23
src/components/Moment/MomentList.vue
Normal file
23
src/components/Moment/MomentList.vue
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<div class="food-moment"
|
||||||
|
v-loading="foodStore.isLoading" element-loading-text="加载中">
|
||||||
|
<el-empty v-if="foodStore.momentList.length === 0" description="暂无朋友圈记录"/>
|
||||||
|
|
||||||
|
<div v-else class="moment-list">
|
||||||
|
<moment-card v-for="(item, index) in foodStore.momentList"
|
||||||
|
:key="index" :item="item"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import MomentCard from '@/components/Moment/MomentCard.vue'
|
||||||
|
import { useFoodStore } from '@/store/food'
|
||||||
|
|
||||||
|
const foodStore = useFoodStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@use "@/styles/moment.module.scss";
|
||||||
|
</style>
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
<div class="right-container">
|
<div class="right-container">
|
||||||
<svg-icon v-if="appStore.isWebSocket"
|
<svg-icon v-if="appStore.isWebSocket"
|
||||||
name="home-websocket" style="color: #FFFFFF;"></svg-icon>
|
name="home-websocket" style="color: #FFFFFF;"></svg-icon>
|
||||||
|
<food-query />
|
||||||
<el-button type="info" :icon="Setting" size="small"
|
<el-button type="info" :icon="Setting" size="small"
|
||||||
circle color="#FFFFFF" @click="openSettingClick"/>
|
circle color="#FFFFFF" @click="openSettingClick"/>
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import FoodQuery from '@/components/Food/FoodQuery.vue'
|
||||||
import { SvgIcon } from 'vue3-common'
|
import { SvgIcon } from 'vue3-common'
|
||||||
import MobileSetting from '@/components/MobileSetting.vue'
|
import MobileSetting from '@/components/MobileSetting.vue'
|
||||||
import { Back } from '@element-plus/icons-vue'
|
import { Back } from '@element-plus/icons-vue'
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ import {
|
|||||||
addLikeApi,
|
addLikeApi,
|
||||||
addMomentApi,
|
addMomentApi,
|
||||||
deleteLikeApi,
|
deleteLikeApi,
|
||||||
deleteMomentApi,
|
deleteMomentApi, queryMomentByIdApi,
|
||||||
queryMomentApi,
|
queryMomentListApi,
|
||||||
updateMomentApi
|
updateMomentApi
|
||||||
} from '@/apis/moment'
|
} from '@/apis/moment'
|
||||||
|
|
||||||
@@ -105,7 +105,8 @@ export const useFoodStore = defineStore('food', {
|
|||||||
recordStats: [] as IStatsChart[],
|
recordStats: [] as IStatsChart[],
|
||||||
categoryStats: [] as IStatsChart[],
|
categoryStats: [] as IStatsChart[],
|
||||||
rankStats: [] as IStatsChart[],
|
rankStats: [] as IStatsChart[],
|
||||||
isRefresh: false
|
isRefresh: false,
|
||||||
|
isLoading: false
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
async queryRecipeList() {
|
async queryRecipeList() {
|
||||||
@@ -113,16 +114,24 @@ export const useFoodStore = defineStore('food', {
|
|||||||
// const result = await queryFoodRecipeByPageApi(currentPage, pageSize, this.queryRecipe)
|
// const result = await queryFoodRecipeByPageApi(currentPage, pageSize, this.queryRecipe)
|
||||||
// this.foodRecipeList.push(...result.records)
|
// this.foodRecipeList.push(...result.records)
|
||||||
// this.pageInfo.totalSize = result.total
|
// this.pageInfo.totalSize = result.total
|
||||||
|
this.isLoading = true
|
||||||
this.recipeList = await queryRecipeApi(this.queryRecipeSegment)
|
this.recipeList = await queryRecipeApi(this.queryRecipeSegment)
|
||||||
|
this.isRefresh = !this.isRefresh
|
||||||
|
this.isLoading = false
|
||||||
},
|
},
|
||||||
async queryRecordList() {
|
async queryRecordList() {
|
||||||
const { year, month } = this.queryRecord
|
const { year, month } = this.queryRecord
|
||||||
const date = this.queryDateType === 'year' ? year : month
|
const date = this.queryDateType === 'year' ? year : month
|
||||||
this.queryDateList = getStartEndDate(date, this.queryDateType)
|
this.queryDateList = getStartEndDate(date, this.queryDateType)
|
||||||
|
this.isLoading = true
|
||||||
this.recordList = await queryRecordApi(this.queryDateList[0], this.queryDateList[1])
|
this.recordList = await queryRecordApi(this.queryDateList[0], this.queryDateList[1])
|
||||||
|
this.isRefresh = !this.isRefresh
|
||||||
|
this.isLoading = false
|
||||||
},
|
},
|
||||||
async queryMomentList() {
|
async queryMomentList() {
|
||||||
this.momentList = await queryMomentApi()
|
this.isLoading = true
|
||||||
|
this.momentList = await queryMomentListApi()
|
||||||
|
this.isLoading = false
|
||||||
},
|
},
|
||||||
async queryFoodNameList() {
|
async queryFoodNameList() {
|
||||||
this.foodNameList = await queryFoodNameListApi()
|
this.foodNameList = await queryFoodNameListApi()
|
||||||
@@ -130,6 +139,11 @@ export const useFoodStore = defineStore('food', {
|
|||||||
async queryRecipe(id: number) {
|
async queryRecipe(id: number) {
|
||||||
this.currentRecipe = await queryRecipeByIdApi(id)
|
this.currentRecipe = await queryRecipeByIdApi(id)
|
||||||
},
|
},
|
||||||
|
async queryMoment(id: number) {
|
||||||
|
this.isLoading = true
|
||||||
|
this.momentList = await queryMomentByIdApi(id)
|
||||||
|
this.isLoading = false
|
||||||
|
},
|
||||||
async queryStats() {
|
async queryStats() {
|
||||||
this.stats = await queryStatsApi()
|
this.stats = await queryStatsApi()
|
||||||
this.recordStats = await queryRecordStatsApi()
|
this.recordStats = await queryRecordStatsApi()
|
||||||
@@ -157,7 +171,7 @@ export const useFoodStore = defineStore('food', {
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
await this.refreshInfo()
|
await this.queryRecipeList()
|
||||||
},
|
},
|
||||||
async handleRecordApi(record: IRecord) {
|
async handleRecordApi(record: IRecord) {
|
||||||
switch (this.recordApiType) {
|
switch (this.recordApiType) {
|
||||||
@@ -176,7 +190,7 @@ export const useFoodStore = defineStore('food', {
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
await this.refreshInfo()
|
await this.queryRecordList()
|
||||||
},
|
},
|
||||||
async handleMomentApi(moment: IMoment) {
|
async handleMomentApi(moment: IMoment) {
|
||||||
switch (this.momentApiType) {
|
switch (this.momentApiType) {
|
||||||
@@ -195,7 +209,7 @@ export const useFoodStore = defineStore('food', {
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
await queryMomentApi()
|
await this.queryMomentList()
|
||||||
},
|
},
|
||||||
async addComment(id: number, content: string) {
|
async addComment(id: number, content: string) {
|
||||||
await addCommentApi(id, content)
|
await addCommentApi(id, content)
|
||||||
@@ -209,11 +223,6 @@ export const useFoodStore = defineStore('food', {
|
|||||||
await deleteLikeApi(id)
|
await deleteLikeApi(id)
|
||||||
await this.queryMomentList()
|
await this.queryMomentList()
|
||||||
},
|
},
|
||||||
async refreshInfo() {
|
|
||||||
await this.queryRecipeList()
|
|
||||||
await this.queryRecordList()
|
|
||||||
this.isRefresh = !this.isRefresh
|
|
||||||
},
|
|
||||||
getEmptyRecipe(): IRecipe {
|
getEmptyRecipe(): IRecipe {
|
||||||
return {
|
return {
|
||||||
category: '',
|
category: '',
|
||||||
|
|||||||
67
src/styles/moment.module.scss
Normal file
67
src/styles/moment.module.scss
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
.food-moment {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.moment-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.moment-card {
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 50px 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.moment-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: larger;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moment-image-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moment-comment {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 40px 60px;
|
||||||
|
justify-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moment-comment-list {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: var(--color-comment-bg);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
.moment-comment-item {
|
||||||
|
.name {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="common-mobile-view food-moment">
|
<div class="common-mobile-view">
|
||||||
<el-empty v-if="foodStore.momentList.length === 0" description="暂无朋友圈记录"/>
|
<moment-list />
|
||||||
|
|
||||||
<div v-else class="moment-list">
|
|
||||||
<moment-card v-for="(item, index) in foodStore.momentList"
|
|
||||||
:key="index" :item="item"/>
|
|
||||||
|
|
||||||
<el-button type="primary" circle :icon="Refresh"
|
<el-button type="primary" circle :icon="Refresh"
|
||||||
class="refresh-button" @click="foodStore.queryMomentList()"/>
|
class="refresh-button" @click="foodStore.queryMomentList()"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import MomentList from '@/components/Moment/MomentList.vue'
|
||||||
import { Refresh } from '@element-plus/icons-vue'
|
import { Refresh } from '@element-plus/icons-vue'
|
||||||
import MomentCard from '@/components/Moment/MomentCard.vue'
|
|
||||||
import { useFoodStore } from '@/store/food'
|
import { useFoodStore } from '@/store/food'
|
||||||
import { onMounted } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
|
|
||||||
@@ -26,21 +21,9 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.food-moment {
|
.refresh-button {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
.moment-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
.refresh-button {
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 60px;
|
top: 60px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,22 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="moment-profile-view common-mobile-view">
|
<div class="moment-profile-view common-mobile-view">
|
||||||
<profile-card />
|
<profile-card />
|
||||||
|
|
||||||
|
<el-tabs v-model="activeName"
|
||||||
|
stretch class="profile-tabs"
|
||||||
|
@tab-click="handleClick">
|
||||||
|
<el-tab-pane label="朋友圈" name="moment">
|
||||||
|
<moment-list />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="菜谱记录" name="recipe">
|
||||||
|
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import ProfileCard from '@/components/Profile/ProfileCard.vue'
|
import ProfileCard from '@/components/Profile/ProfileCard.vue'
|
||||||
import { useUserStore } from '@/store/user.ts'
|
import { useFoodStore } from '@/store/food.ts'
|
||||||
import { useAppStore } from '@/store/app.ts'
|
import { onMounted, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import MomentList from '@/components/Moment/MomentList.vue'
|
||||||
import { onMounted } from 'vue'
|
import type { TabsPaneContext } from 'element-plus'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const foodStore = useFoodStore()
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
onMounted(() => {
|
const activeName = ref('moment')
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await foodStore.queryMoment(foodStore.currentMomentUserId)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const handleClick = async (tab: TabsPaneContext) => {
|
||||||
|
switch (tab.paneName) {
|
||||||
|
case 'moment':
|
||||||
|
await foodStore.queryMoment(foodStore.currentMomentUserId)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<div class="profile-view common-mobile-view">
|
<div class="profile-view common-mobile-view">
|
||||||
<profile-card />
|
<profile-card />
|
||||||
|
|
||||||
|
<el-tabs v-model="activeName"
|
||||||
|
stretch class="profile-tabs"
|
||||||
|
@tab-click="handleClick">
|
||||||
|
<el-tab-pane label="基本资料" name="basic">
|
||||||
<div class="menu-card card-item">
|
<div class="menu-card card-item">
|
||||||
<div class="menu-item" @click="infoClick">
|
<div class="menu-item" @click="infoClick">
|
||||||
<i class="fas fa-user"></i>
|
<i class="fas fa-user"></i>
|
||||||
@@ -19,19 +23,26 @@
|
|||||||
|
|
||||||
<div class="menu-divider"></div>
|
<div class="menu-divider"></div>
|
||||||
|
|
||||||
<div class="menu-item">
|
|
||||||
<i class="fa-solid fa-comment-dots"></i>
|
|
||||||
<span>反馈意见</span>
|
|
||||||
<i class="fas fa-chevron-right"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="menu-divider"></div>
|
|
||||||
|
|
||||||
<div class="menu-item" @click="passwordClick">
|
<div class="menu-item" @click="passwordClick">
|
||||||
<i class="fas fa-key"></i>
|
<i class="fas fa-key"></i>
|
||||||
<span>更改密码</span>
|
<span>更改密码</span>
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="朋友圈" name="moment">
|
||||||
|
<moment-list />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="菜谱收藏" name="recipe">
|
||||||
|
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="系统设置" name="system">
|
||||||
|
<div class="menu-card card-item">
|
||||||
|
<div class="menu-item">
|
||||||
|
<i class="fa-solid fa-comment-dots"></i>
|
||||||
|
<span>反馈意见</span>
|
||||||
|
<i class="fas fa-chevron-right"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="menu-divider"></div>
|
<div class="menu-divider"></div>
|
||||||
|
|
||||||
@@ -57,6 +68,8 @@
|
|||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
<div class="version">版本号 {{ appStore.version }}</div>
|
<div class="version">版本号 {{ appStore.version }}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -64,18 +77,24 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import ProfileCard from '@/components/Profile/ProfileCard.vue'
|
import ProfileCard from '@/components/Profile/ProfileCard.vue'
|
||||||
|
import MomentList from '@/components/Moment/MomentList.vue'
|
||||||
import { useUserStore } from '@/store/user.ts'
|
import { useUserStore } from '@/store/user.ts'
|
||||||
import { useAppStore } from '@/store/app.ts'
|
import { useAppStore } from '@/store/app.ts'
|
||||||
import { useAuthStore } from '@/store/auth'
|
import { useAuthStore } from '@/store/auth'
|
||||||
|
import { useFoodStore } from '@/store/food.ts'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { commonElMessageBox } from 'vue3-common/utils/elUtil'
|
import { commonElMessageBox } from 'vue3-common/utils/elUtil'
|
||||||
import { onMounted } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
|
import type { TabsPaneContext } from 'element-plus'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
const foodStore = useFoodStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
const activeName = ref('basic')
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
userStore.queryUser(userStore.getUserId() as number)
|
userStore.queryUser(userStore.getUserId() as number)
|
||||||
})
|
})
|
||||||
@@ -89,6 +108,16 @@ const passwordClick = () => {
|
|||||||
// router.push('/mobile-home/profile/password')
|
// router.push('/mobile-home/profile/password')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleClick = async (tab: TabsPaneContext) => {
|
||||||
|
switch (tab.paneName) {
|
||||||
|
case 'moment':
|
||||||
|
await foodStore.queryMoment(userStore.getUserId())
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const refreshClick = async () => {
|
const refreshClick = async () => {
|
||||||
await router.push('/')
|
await router.push('/')
|
||||||
location.reload()
|
location.reload()
|
||||||
|
|||||||
@@ -1,26 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="common-mobile-view food-record">
|
<div class="common-mobile-view food-record">
|
||||||
<div class="food-query">
|
|
||||||
<el-input
|
|
||||||
v-model="foodInfo.query"
|
|
||||||
placeholder="搜索菜友食谱" :prefix-icon="Search" clearable
|
|
||||||
:maxlength="20" show-word-limit
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr style="width: 100%;"/>
|
|
||||||
|
|
||||||
<el-tabs v-model="foodStore.recordSegment"
|
<el-tabs v-model="foodStore.recordSegment"
|
||||||
stretch class="record-tabs"
|
stretch class="record-tabs"
|
||||||
@tab-click="handleClick">
|
@tab-click="handleClick">
|
||||||
<el-tab-pane label="菜谱" name="recipe">
|
<el-tab-pane label="菜谱" name="recipe">
|
||||||
<food-recipe />
|
<food-recipe v-loading="foodStore.isLoading" element-loading-text="加载中"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="日历" name="daily">
|
<el-tab-pane label="日历" name="daily">
|
||||||
<food-daily />
|
<food-daily v-loading="foodStore.isLoading" element-loading-text="加载中"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="时间轴" name="timeline">
|
<el-tab-pane label="时间轴" name="timeline">
|
||||||
<food-timeline />
|
<food-timeline v-loading="foodStore.isLoading" element-loading-text="加载中"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,41 +20,30 @@
|
|||||||
import FoodRecipe from '@/components/Food/FoodRecipe.vue'
|
import FoodRecipe from '@/components/Food/FoodRecipe.vue'
|
||||||
import FoodDaily from '@/components/Food/FoodDaily.vue'
|
import FoodDaily from '@/components/Food/FoodDaily.vue'
|
||||||
import FoodTimeline from '@/components/Food/FoodTimeline.vue'
|
import FoodTimeline from '@/components/Food/FoodTimeline.vue'
|
||||||
import { Search } from '@element-plus/icons-vue'
|
|
||||||
import { reactive } from 'vue'
|
|
||||||
import { useFoodStore } from '@/store/food'
|
import { useFoodStore } from '@/store/food'
|
||||||
import { TabsPaneContext } from 'element-plus'
|
import type { TabsPaneContext } from 'element-plus'
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
|
||||||
const foodStore = useFoodStore()
|
const foodStore = useFoodStore()
|
||||||
|
|
||||||
const foodInfo = reactive({
|
onMounted(async () => {
|
||||||
query: ''
|
await foodStore.queryCategory()
|
||||||
|
await foodStore.queryRecipeList()
|
||||||
})
|
})
|
||||||
|
|
||||||
const recordSegmentList = [{
|
const handleClick = async (tab: TabsPaneContext) => {
|
||||||
label: '菜谱',
|
|
||||||
value: 'recipe'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '日历',
|
|
||||||
value: 'daily'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '时间轴',
|
|
||||||
value: 'timeline'
|
|
||||||
}]
|
|
||||||
|
|
||||||
const handleClick = async (tab: TabsPaneContext, event: Event) => {
|
|
||||||
switch (tab.paneName) {
|
switch (tab.paneName) {
|
||||||
case 'recipe':
|
case 'recipe':
|
||||||
|
await foodStore.queryCategory()
|
||||||
|
await foodStore.queryRecipeList()
|
||||||
break
|
break
|
||||||
case 'daily':
|
case 'daily':
|
||||||
foodStore.queryDateType = 'month'
|
foodStore.queryDateType = 'month'
|
||||||
await foodStore.refreshInfo()
|
await foodStore.queryRecordList()
|
||||||
break
|
break
|
||||||
case 'timeline':
|
case 'timeline':
|
||||||
foodStore.queryDateType = 'year'
|
foodStore.queryDateType = 'year'
|
||||||
await foodStore.refreshInfo()
|
await foodStore.queryRecordList()
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@@ -77,12 +56,5 @@ const handleClick = async (tab: TabsPaneContext, event: Event) => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
|
||||||
.food-query {
|
|
||||||
}
|
|
||||||
|
|
||||||
.record-tabs {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user