feat: add user about page

This commit is contained in:
YunYouJun
2023-07-30 20:13:20 +08:00
parent 44c9631e70
commit 2db9fee8af
20 changed files with 236 additions and 1191 deletions

View File

@@ -0,0 +1,5 @@
<template>
<h1 text-2xl font="bold" my="4">
<slot />
</h1>
</template>

View File

@@ -1,15 +1,28 @@
<script lang="ts" setup> <script lang="ts" setup>
const { random, randomRecipe } = useRandomRecipe() const { count, inc, dec } = useCount()
const { random, randomRecipes } = useRandomRecipe(count)
</script> </script>
<template> <template>
<div v-show="randomRecipe"> <div inline-flex m="y-3">
<div class="inline-flex items-center justify-center"> <button rounded-full p-2 btn @click="dec()">
<div>今天吃什么</div> <div i-carbon-subtract />
<div class="transition" hover="text-blue-500" i-ri-refresh-line inline-block cursor-pointer @click="random" /> </button>
<div font="mono" w="15" m-auto inline-block>
{{ count }}
</div> </div>
<div m="t-2"> <button rounded-full p-2 btn @click="inc()">
<DishTag v-if="randomRecipe" :dish="randomRecipe" /> <div i-carbon-add />
</button>
</div>
<div v-show="randomRecipes.length > 0">
<button cursor-pointer class="inline-flex inline-flex items-center justify-center rounded-md border-none bg-blue-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-blue-500 focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 focus-visible:outline" @click="random">
<div class="transition" hover="text-blue-500" i-ri-refresh-line mr-1 inline-flex />
<div>随机一下</div>
</button>
<div m="t-8" flex="~ col">
<DishTag v-for="recipe, i in randomRecipes" :key="i" :dish="recipe" />
</div> </div>
</div> </div>
</template> </template>

View File

@@ -34,6 +34,14 @@ const showTooltip = computed(() => !selectedStuff.value.length && !curTool.value
你要先选食材或工具哦 你要先选食材或工具哦
</span> </span>
<div
v-else-if="rStore.isSearching"
relative flex items-center justify-center p-6
text-xl
>
<div class="magnifying-glass" i-ri-search-line inline-flex />
</div>
<div v-else-if="rStore.displayedRecipe.length"> <div v-else-if="rStore.displayedRecipe.length">
<DishTag v-for="item, i in rStore.displayedRecipe" :key="i" :dish="item" /> <DishTag v-for="item, i in rStore.displayedRecipe" :key="i" :dish="item" />
</div> </div>
@@ -55,10 +63,22 @@ const showTooltip = computed(() => !selectedStuff.value.length && !curTool.value
</div> </div>
</div> </div>
</Transition> </Transition>
<hr m="y-2">
<RandomRecipe />
</div> </div>
</div> </div>
</template> </template>
<style>
@keyframes circle-rotate {
from {
transform: rotate(0turn) translateY(60%) rotate(1turn);
}
to {
transform: rotate(1turn) translateY(60%) rotate(0turn);
}
}
.magnifying-glass {
margin: auto;
animation: circle-rotate 4s linear infinite;
}
</style>

View File

@@ -12,14 +12,14 @@ const items: BottomMenuItem[] = [
{ {
icon: 'i-ri-compass-2-line', icon: 'i-ri-compass-2-line',
activeIcon: 'i-ri-compass-2-fill', activeIcon: 'i-ri-compass-2-fill',
title: '关于', title: '吃什么',
to: '/about', to: '/random',
}, },
// { // {
// icon: 'i-ri-user-line', // icon: 'i-ri-compass-2-line',
// activeIcon: 'i-ri-user-fill', // activeIcon: 'i-ri-compass-2-fill',
// title: '我的', // title: '吃什么',
// to: '/user', // to: '/about',
// }, // },
{ {
icon: 'i-ri-question-line', icon: 'i-ri-question-line',
@@ -27,6 +27,12 @@ const items: BottomMenuItem[] = [
title: '帮助', title: '帮助',
to: '/help', to: '/help',
}, },
{
icon: 'i-ri-user-line',
activeIcon: 'i-ri-user-fill',
title: '我的',
to: '/user',
},
] ]
const route = useRoute() const route = useRoute()

20
composables/count.ts Normal file
View File

@@ -0,0 +1,20 @@
import { useStorage } from '@vueuse/core'
export function useCount() {
const count = useStorage('count', 5)
function inc() {
count.value += 1
}
function dec() {
if (count.value <= 1)
return
count.value -= 1
}
return {
count,
inc,
dec,
}
}

View File

@@ -1,12 +1,21 @@
import recipeData from '~/data/recipe.json' import recipeData from '~/data/recipe.json'
import type { RecipeItem, Recipes } from '~/types' import type { RecipeItem, Recipes } from '~/types'
export function useRandomRecipe() { /**
const randomRecipe = ref<RecipeItem>() * 随机几道菜
* @param total
* @returns
*/
export function useRandomRecipe(total: Ref<number>) {
const randomRecipes = ref<RecipeItem[]>([])
function random() { function random() {
randomRecipe.value = generateRandomRecipe(recipeData as Recipes) randomRecipes.value = generateRandomRecipe(recipeData as Recipes, total.value)
} }
watch(total, () => {
random()
})
onMounted(() => { onMounted(() => {
random() random()
}) })
@@ -14,6 +23,6 @@ export function useRandomRecipe() {
return { return {
random, random,
randomRecipe, randomRecipes,
} }
} }

View File

@@ -70,25 +70,26 @@ export const useRecipeStore = defineStore('recipe', () => {
curStuff.value.add(name) curStuff.value.add(name)
} }
const isSearching = ref(false)
/** /**
* 搜索菜谱 * 搜索菜谱
* @returns * @returns
*/ */
async function searchRecipes() { async function searchRecipes() {
if (keyword.value) { isSearching.value = true
const result = await db.recipes.filter(item => item.name.includes(keyword.value)).toArray() let result: RecipeItem[] = []
return result if (keyword.value)
} result = await db.recipes.filter(item => item.name.includes(keyword.value)).toArray()
if (curMode.value === 'strict') { if (curMode.value === 'strict') {
return await db.recipes.filter((item) => { result = await db.recipes.filter((item) => {
const stuffFlag = selectedStuff.value.every(stuff => item.stuff.includes(stuff)) const stuffFlag = selectedStuff.value.every(stuff => item.stuff.includes(stuff))
const toolFlag = item.tools.includes(curTool.value) const toolFlag = item.tools.includes(curTool.value)
return curTool.value ? (stuffFlag && toolFlag) : stuffFlag return curTool.value ? (stuffFlag && toolFlag) : stuffFlag
}).toArray() }).toArray()
} }
else if (curMode.value === 'loose') { else if (curMode.value === 'loose') {
return await db.recipes.filter((item) => { result = await db.recipes.filter((item) => {
const stuffFlag = selectedStuff.value.some(stuff => item.stuff.includes(stuff)) const stuffFlag = selectedStuff.value.some(stuff => item.stuff.includes(stuff))
const toolFlag = Boolean(item.tools?.includes(curTool.value)) const toolFlag = Boolean(item.tools?.includes(curTool.value))
@@ -108,12 +109,15 @@ export const useRecipeStore = defineStore('recipe', () => {
} }
// survival // survival
else { else {
return await db.recipes.filter((item) => { result = await db.recipes.filter((item) => {
const stuffFlag = item.stuff.every(stuff => selectedStuff.value.includes(stuff)) const stuffFlag = item.stuff.every(stuff => selectedStuff.value.includes(stuff))
const toolFlag = item.tools?.includes(curTool.value) const toolFlag = item.tools?.includes(curTool.value)
return Boolean(curTool.value ? (stuffFlag && toolFlag) : stuffFlag) return Boolean(curTool.value ? (stuffFlag && toolFlag) : stuffFlag)
}).toArray() }).toArray()
} }
isSearching.value = false
return result
} }
// 默认严格模式 // 默认严格模式
@@ -159,6 +163,8 @@ export const useRecipeStore = defineStore('recipe', () => {
curMode, curMode,
selectedStuff, selectedStuff,
isSearching,
clearKeyWord: () => { keyword.value = '' }, clearKeyWord: () => { keyword.value = '' },
toggleStuff, toggleStuff,
toggleTools, toggleTools,

View File

@@ -1,64 +0,0 @@
---
title: 关于
---
:AboutMenu
### **🍜 好的,今天我们来做菜!**
> 希望大家吃的开心!
<div class="inline-flex justify-center items-center">
- 代码仓库:<a class="inline-flex items-center justify-center" href="https://github.com/YunYouJun/cook" target="_blank">
<div m="r-1" inline-flex i-ri-github-line></div>YunYouJun/cook</a>
</div>
<br />
<div class="inline-flex justify-center items-center">
- 菜谱主要视频来源:
<a class="inline-flex items-center text-sm text-blue-600 dark:text-blue-400" href="https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS" target="_blank">
<div m="r-1" inline-flex i-ri-bilibili-line></div>
<span class="inline-flex">隔离食用手册大全</span>
</a>
</div>
相关使用请查看 <router-link to="/help">帮助</router-link>。
## **致谢**
感谢以下小伙伴为本项目提供的数据支持和 QA
- [Runny](https://weibo.com/runny)
- 山竹太凉
- leo
- 麒麟
- 晴方啾
- 课代表阿伟
## **关于我**
Hello我是云游君。
很高兴能在这里与你相遇,也很希望这个网站可以真的帮助到你。
同时,我也以我或许不值一提的脸面保证它会以免费开源的形式维护运营下去。
此外,我也会继续尝试做一些有趣或有用的东西,并分享给大家。
你也可以在这些地方找到我。
:AboutMe
对了,给微信公众号「云游君」发送「做菜」也可以快速找到这个网址。
## 赞助者
也非常感谢至今以来的所有赞助者们!
如果觉得我的[小项目们](https://sponsors.yunyoujun.cn/projects)还算有趣的话,要不要考虑[赞助](https://sponsors.yunyoujun.cn/)我?
我会将其公开在[账簿](https://sponsors.yunyoujun.cn/account)中并投入在周边的服务器、域名、CDN 等费用上。
<a href="https://sponsors.yunyoujun.cn" target="_blank">
<img src='https://sponsors.yunyoujun.cn/sponsors.svg'/>
</a>

View File

@@ -1,7 +0,0 @@
---
title: 微信公众号
---
我的个人微信公众号「云游君」,会分享一些生活和写的[小玩具们](https://sponsors.yunyoujun.cn/projects)。
![微信公众号 - 云游君](https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/about/white-qrcode-and-search.jpg)

View File

@@ -1,5 +1,5 @@
<template> <template>
<main class="text-center text-gray-700 dark:text-gray-200" p="b-15"> <main class="text-center text-gray-700 dark:text-gray-200" p="x-2 t-8 b-15">
<slot /> <slot />
<DarkToggle absolute right-5 top-5 /> <DarkToggle absolute right-5 top-5 />
<TheBottomMenu fixed bottom-0 left-0 right-0 /> <TheBottomMenu fixed bottom-0 left-0 right-0 />

View File

@@ -15,7 +15,6 @@ export default defineNuxtConfig({
'@pinia/nuxt', '@pinia/nuxt',
'@nuxtjs/color-mode', '@nuxtjs/color-mode',
'@vite-pwa/nuxt', '@vite-pwa/nuxt',
'@nuxt/content',
'@zadigetvoltaire/nuxt-gtm', '@zadigetvoltaire/nuxt-gtm',

View File

@@ -33,7 +33,6 @@
"@iconify-json/mdi": "^1.1.53", "@iconify-json/mdi": "^1.1.53",
"@iconify-json/ri": "^1.1.10", "@iconify-json/ri": "^1.1.10",
"@iconify-json/twemoji": "^1.1.11", "@iconify-json/twemoji": "^1.1.11",
"@nuxt/content": "^2.7.2",
"@nuxt/devtools": "^0.7.1", "@nuxt/devtools": "^0.7.1",
"@nuxtjs/color-mode": "^3.3.0", "@nuxtjs/color-mode": "^3.3.0",
"@pinia/nuxt": "^0.4.11", "@pinia/nuxt": "^0.4.11",

View File

@@ -1,9 +0,0 @@
<template>
<main class="markdown-body px-4 text-left">
<ContentDoc v-slot="{ doc }">
<h1>{{ doc.title }}</h1>
<ContentRenderer :value="doc" />
</ContentDoc>
</main>
<BaseFooter />
</template>

View File

@@ -1,8 +1,8 @@
<template> <template>
<div class="w-full px-2 pt-8"> <div class="w-full">
<h1 text-2xl font="bold" my="4"> <CommonHeader>
帮助 帮助
</h1> </CommonHeader>
<InstallPwa /> <InstallPwa />
@@ -26,6 +26,9 @@
<FAQItem title="是否有微信小程序?"> <FAQItem title="是否有微信小程序?">
因不可抗力小程序因跳转 B 站视频而被判定为导流违规下架 因不可抗力小程序因跳转 B 站视频而被判定为导流违规下架
将不再提供小程序版本 将不再提供小程序版本
<br>
<br>
搜索微信公众号<b>云游君</b>并发送<b>做菜</b>也可以快速找到本网站
</FAQItem> </FAQItem>
<FAQItem title="是否有 APP?"> <FAQItem title="是否有 APP?">
@@ -36,6 +39,21 @@
你可以使用浏览器打开点击上方的<b>安装到桌面</b>或在菜单中点击<b>添加到主屏幕</b> 你可以使用浏览器打开点击上方的<b>安装到桌面</b>或在菜单中点击<b>添加到主屏幕</b>
</FAQItem> </FAQItem>
<FAQItem title="未来是否会收费?">
该项目将以免费开源的形式运营
<br>
您可以考虑赞助本项目以支持我们的开发
我会将其投入在周边的服务器域名CDN 等费用上
<ul mt-1>
<li>
<a href="https://afdian.net/a/yunyoujun" target="_blank">爱发电赞助</a>
</li>
<li>
<a href="https://sponsors.yunyoujun.cn/" target="_blank">我要直接打钱</a>
</li>
</ul>
</FAQItem>
<FAQItem title="页面无法点击、资源加载失败?"> <FAQItem title="页面无法点击、资源加载失败?">
<blockquote> <blockquote>
试试无痕模式是否正常 试试无痕模式是否正常
@@ -62,35 +80,6 @@
</li> </li>
</ol> </ol>
</FAQItem> </FAQItem>
<FAQItem title="其他相关链接">
<ul>
<li>
相关链接
<ul>
<li>
<a href="https://docs.qq.com/form/page/DWk9GWW9oTmlXZU9V" target="_blank">居家菜谱投稿</a>
</li>
<li>
<a href="https://support.qq.com/products/507827" target="_blank">反馈建议分享兔小巢</a>
</li>
</ul>
</li>
<li>
网站相关
<ul>
<li>
故障/新功能反馈
<a href="https://github.com/YunYouJun/cook/issues" target="_blank">Issues</a>
</li>
<li>
交流/建议/分享
<a href="https://github.com/YunYouJun/cook/issues" target="_blank">Discussions</a>
</li>
</ul>
</li>
</ul>
</FAQItem>
</div> </div>
</div> </div>
<BaseFooter mt-4 /> <BaseFooter mt-4 />

View File

@@ -3,7 +3,7 @@ const rStore = useRecipeStore()
</script> </script>
<template> <template>
<div pt-4 text-4xl> <div text-4xl>
<button <button
class="cursor-pointer transition active:text-green-800 hover:(text-green-600)" class="cursor-pointer transition active:text-green-800 hover:(text-green-600)"
title="重置" title="重置"
@@ -16,5 +16,6 @@ const rStore = useRecipeStore()
<p text="sm" m="b-4"> <p text="sm" m="b-4">
好的今天我们来做菜 好的今天我们来做菜
</p> </p>
<ChooseFood /> <ChooseFood />
</template> </template>

10
pages/random.vue Normal file
View File

@@ -0,0 +1,10 @@
<template>
<div flex flex-col>
<CommonHeader>
今天吃什么
</CommonHeader>
<div flex flex-grow flex-col items-center justify-center>
<RandomRecipe mt-8 />
</div>
</div>
</template>

View File

@@ -1,7 +1,83 @@
<template> <template>
<div> <div px-2>
<button> <CommonHeader>
<div i-ri-user-line /> 我的
</button> </CommonHeader>
<FeedbackActions />
<p my-6 text-left text-base>
很高兴能在这里与你相遇也很希望这个网站可以真的帮助到你
</p>
<FAQItem title="关于">
<div text-left>
<ul>
<li>
<div class="inline-flex items-center justify-center">
代码仓库<a class="inline-flex items-center justify-center" href="https://github.com/YunYouJun/cook" target="_blank">
<div m="r-1" i-ri-github-line inline-flex />YunYouJun/cook</a>
</div>
</li>
<li>
<div class="inline-flex items-center justify-center">
菜谱视频来源
<a class="inline-flex items-center text-sm text-blue-600 dark:text-blue-400" href="https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS" target="_blank">
<div m="r-1" i-ri-bilibili-line inline-flex />
<span class="inline-flex">隔离食用手册大全</span>
</a>
</div>
</li>
</ul>
</div>
</FAQItem>
<FAQItem title="关于我">
<div text-left>
我的个人微信公众号云游君会分享一些生活和写的<a href="https://sponsors.yunyoujun.cn/projects" target="_blank">
小玩具们
</a>
<a inline-flex py-4 href="https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg" target="_blank">
<img src="https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg">
</a>
</div>
<AboutMe />
</FAQItem>
<FAQItem title="致谢">
<p>
感谢以下小伙伴为本项目提供的数据支持和 QA
</p>
<ul mt-2 text-left text-sm>
<li>
<a href="https://weibo.com/runny" target="_blank">Runny</a>
</li>
<li>
山竹太凉
</li>
<li>
leo
</li>
<li>
麒麟
</li>
<li>
晴方啾
</li>
<li>
课代表阿伟
</li>
</ul>
</FAQItem>
<FAQItem title="赞助者们">
<a href="https://sponsors.yunyoujun.cn" target="_blank">
<img src="https://sponsors.yunyoujun.cn/sponsors.svg">
</a>
</FAQItem>
<BaseFooter mt-4 />
</div> </div>
</template> </template>

1029
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -20,8 +20,8 @@ tools.forEach((item) => {
export default defineConfig({ export default defineConfig({
shortcuts: [ shortcuts: [
['tag', 'text-sm cursor-pointer inline-flex justify-center items-center transition shadow hover:shadow-md'], ['tag', 'text-sm cursor-pointer inline-flex justify-center items-center transition shadow hover:shadow-md'],
['btn', 'text-sm px-4 py-1 rounded inline-block bg-green-600 text-white cursor-pointer hover:bg-green-700 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'], ['btn', 'text-sm px-4 py-1 rounded inline-block bg-blue-600 text-white cursor-pointer hover:bg-blue-700 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
['icon-btn', 'text-[0.9em] inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-green-600'], ['icon-btn', 'text-[0.9em] inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-blue-600'],
], ],
presets: [ presets: [
presetUno(), presetUno(),
@@ -36,12 +36,4 @@ export default defineConfig({
transformerVariantGroup(), transformerVariantGroup(),
], ],
safelist, safelist,
content: {
pipeline: {
include: [
'./**/*.vue',
'./content/**/*.md',
],
},
},
}) })

View File

@@ -1,10 +1,19 @@
import type { Recipes } from '../types' import type { RecipeItem, Recipes } from '../types'
/** /**
* 生成随机菜谱 * 生成随机菜谱,默认一道
* @param recipes * @param recipes
* @returns * @returns
*/ */
export function generateRandomRecipe(recipes: Recipes) { export function generateRandomRecipe(recipes: Recipes, total = 1) {
return recipes[Math.floor(Math.random() * recipes.length)] const randomRecipes: RecipeItem[] = []
for (let i = 0; i < total; i++) {
const randomIndex = Math.floor(Math.random() * recipes.length)
if (randomRecipes.includes(recipes[randomIndex])) {
i--
continue
}
randomRecipes.push(recipes[randomIndex])
}
return randomRecipes
} }