11 Commits

Author SHA1 Message Date
YunYouJun
fdfe1c4622 chore: release v1.1.5 2023-07-30 21:04:42 +08:00
YunYouJun
f6b285788f chore: add release badge 2023-07-30 21:04:26 +08:00
YunYouJun
ae6aaba912 chore: release v1.1.4 2023-07-30 21:01:43 +08:00
YunYouJun
b526aae2d0 feat: dynamic import recipe.json 2023-07-30 20:59:52 +08:00
YunYouJun
38b31a5654 fix: adjust user page width 2023-07-30 20:23:40 +08:00
YunYouJun
2db9fee8af feat: add user about page 2023-07-30 20:13:20 +08:00
YunYouJun
44c9631e70 ci: fix upload dir 2023-07-30 18:50:07 +08:00
YunYouJun
a60d5f37ed chore: release v1.1.3 2023-07-30 18:45:26 +08:00
YunYouJun
9cb0ca3c44 fix(test): fake indexedDB 2023-07-30 18:44:40 +08:00
YunYouJun
fffd6e398c chore: show pkg version in footer 2023-07-30 18:37:21 +08:00
YunYouJun
492513098a chore: bumpp 2023-07-30 18:33:36 +08:00
29 changed files with 335 additions and 1212 deletions

View File

@@ -3,9 +3,8 @@ name: Docker Image
on: on:
push: push:
branches: [main] tags:
pull_request: - 'v*'
branches: [main]
jobs: jobs:
build: build:

View File

@@ -30,8 +30,8 @@ jobs:
- run: npm run generate --if-present - run: npm run generate --if-present
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v3
with: with:
name: Dist name: Cook Dist
path: dist path: .output/public/
- run: npx changelogithub # or changelogithub@0.12 if ensure the stable result - run: npx changelogithub # or changelogithub@0.12 if ensure the stable result
env: env:

View File

@@ -5,10 +5,13 @@
## 版本 ## 版本
[![Release](https://github.com/YunYouJun/cook/actions/workflows/release.yml/badge.svg)](https://github.com/YunYouJun/cook/actions/workflows/release.yml)
### 网页版本 ### 网页版本
- 网站链接:[cook.yunyoujun.cn](https://cook.yunyoujun.cn) - 网站链接:[cook.yunyoujun.cn](https://cook.yunyoujun.cn)
- 备用:[cook.yyj.moe](https://cook.yyj.moe) - 备用:[cook.yyj.moe](https://cook.yyj.moe)
- 开发版:[cook.yunle.app](https://cook.yunle.app)
### 小程序版本 ### 小程序版本

View File

@@ -1,5 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { isClient } from '@vueuse/core' import { isClient } from '@vueuse/core'
import pkg from '~/package.json'
const displayICP = ref(true) const displayICP = ref(true)
@@ -17,7 +18,7 @@ const buildDate = (new Date(Number.parseInt(now) * 1000)).toLocaleDateString()
<div p="4 t-2" class="flex flex-col items-center justify-center" text="sm"> <div p="4 t-2" class="flex flex-col items-center justify-center" text="sm">
<div v-if="commitSha && buildDate" mb-2> <div v-if="commitSha && buildDate" mb-2>
<span> <span>
当前版本{{ buildDate }}: 当前版本 v{{ pkg.version }}{{ buildDate }}:
</span> </span>
<span> <span>
<a border="b-1 dashed" :href="`https://github.com/YunYouJun/cook/commit/${commitSha}`" target="_blank" alt="Cook | GitHub Commit"> <a border="b-1 dashed" :href="`https://github.com/YunYouJun/cook/commit/${commitSha}`" target="_blank" alt="Cook | GitHub Commit">

View File

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

View File

@@ -1,15 +1,30 @@
<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">
<template v-for="recipe, i in randomRecipes" :key="i">
<DishTag v-if="recipe" :dish="recipe" />
</template>
</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()

View File

@@ -1,10 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DbRecipeItem } from 'utils/db'
import { tools } from '~/data/food' import { tools } from '~/data/food'
import type { RecipeItem } from '~/types' import type { RecipeItem } from '~/types'
import { getEmojisFromStuff } from '~/utils' import { getEmojisFromStuff } from '~/utils'
const props = defineProps<{ const props = defineProps<{
dish: RecipeItem dish: RecipeItem | DbRecipeItem
}>() }>()
const gtm = useGtm() const gtm = useGtm()

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

@@ -5,13 +5,11 @@ export function useIndexedDB() {
const dbUpdated = useStorage(`${namespace}:lastDbUpdated`, lastDbUpdated) const dbUpdated = useStorage(`${namespace}:lastDbUpdated`, lastDbUpdated)
return { return {
// db,
// initDb,
init: async () => { init: async () => {
const count = await db.recipes.count() const count = await db.recipes.count()
if (!count || dbUpdated.value !== lastDbUpdated) { if (!count || dbUpdated.value !== lastDbUpdated) {
await initDb()
dbUpdated.value = lastDbUpdated dbUpdated.value = lastDbUpdated
initDb()
} }
}, },
} }

View File

@@ -1,12 +1,24 @@
import recipeData from '~/data/recipe.json' import type { DbRecipeItem } from 'utils/db'
import type { RecipeItem, Recipes } from '~/types'
export function useRandomRecipe() { /**
const randomRecipe = ref<RecipeItem>() * 随机几道菜
function random() { * @param total
randomRecipe.value = generateRandomRecipe(recipeData as Recipes) * @returns
*/
export function useRandomRecipe(total: Ref<number>) {
const randomRecipes = ref<(DbRecipeItem | undefined)[]>([])
async function random() {
const length = await db.recipes.count()
const randomArr = generateRandomArray(length, total.value)
const result = await db.recipes.bulkGet(randomArr)
if (result)
randomRecipes.value = result.filter(item => !!item)
} }
watch(total, () => {
random()
})
onMounted(() => { onMounted(() => {
random() random()
}) })
@@ -14,6 +26,6 @@ export function useRandomRecipe() {
return { return {
random, random,
randomRecipe, randomRecipes,
} }
} }

View File

@@ -1,9 +1,10 @@
import { acceptHMRUpdate, defineStore } from 'pinia' import { acceptHMRUpdate, defineStore } from 'pinia'
import { useStorage } from '@vueuse/core' import { useStorage } from '@vueuse/core'
import { computed, ref } from 'vue' import { computed, onMounted, ref, watch } from 'vue'
import { useGtm } from '@gtm-support/vue-gtm' import { useGtm } from '@gtm-support/vue-gtm'
import type { RecipeItem } from 'types' import type { RecipeItem } from 'types'
import type { StuffItem } from '../../data/food' import type { StuffItem } from '../../data/food'
import { db } from '../../utils/db'
const namespace = 'cook' const namespace = 'cook'
@@ -69,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))
@@ -107,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
} }
// 默认严格模式 // 默认严格模式
@@ -158,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

@@ -1,6 +1,6 @@
{ {
"private": true, "private": true,
"version": "1.1.2", "version": "1.1.5",
"packageManager": "pnpm@8.6.10", "packageManager": "pnpm@8.6.10",
"engines": { "engines": {
"node": ">=14" "node": ">=14"
@@ -16,7 +16,7 @@
"lint": "eslint .", "lint": "eslint .",
"postinstall": "nuxi prepare && npm run convert", "postinstall": "nuxi prepare && npm run convert",
"preview-https": "serve dist", "preview-https": "serve dist",
"release": "bumpp --commit --push --tag", "release": "bumpp",
"test": "vitest", "test": "vitest",
"typecheck": "vue-tsc --noEmit" "typecheck": "vue-tsc --noEmit"
}, },
@@ -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",
@@ -49,6 +48,7 @@
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"dexie": "^3.2.4", "dexie": "^3.2.4",
"eslint": "^8.46.0", "eslint": "^8.46.0",
"fake-indexeddb": "^4.0.2",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",
"nuxt": "^3.6.5", "nuxt": "^3.6.5",
"pinia": "^2.1.6", "pinia": "^2.1.6",

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 />
</div>
</div>
</template>

View File

@@ -1,7 +1,85 @@
<template> <template>
<div> <div px-2>
<button> <CommonHeader>
<div i-ri-user-line /> 我的
</button> </CommonHeader>
<FeedbackActions />
<div class="mx-auto max-w-md w-full rounded-2xl p-2" text-left>
<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>
</div>
<BaseFooter mt-4 />
</div> </div>
</template> </template>

1092
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

3
test/setup.ts Normal file
View File

@@ -0,0 +1,3 @@
import indexeddb from 'fake-indexeddb'
globalThis.indexedDB = indexeddb

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,7 +1,6 @@
import type { Table } from 'dexie' import type { Table } from 'dexie'
import Dexie from 'dexie' import Dexie from 'dexie'
import recipeData from '../data/recipe.json'
import type { RecipeItem } from '~/types' import type { RecipeItem } from '~/types'
export interface DbRecipeItem extends RecipeItem { export interface DbRecipeItem extends RecipeItem {
@@ -21,8 +20,10 @@ export class MySubClassedDexie extends Dexie {
export const db = new MySubClassedDexie() export const db = new MySubClassedDexie()
export function initDb() { export async function initDb() {
db.recipes.bulkPut( const { default: recipeData } = await import('../data/recipe.json')
return db.recipes.bulkPut(
(recipeData as RecipeItem[]).map((item, i) => ({ (recipeData as RecipeItem[]).map((item, i) => ({
id: i, id: i,
...item, ...item,

View File

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

View File

@@ -7,5 +7,7 @@ export default defineConfig({
deps: { deps: {
inline: ['@vue', '@vueuse', 'vue-demi'], inline: ['@vue', '@vueuse', 'vue-demi'],
}, },
setupFiles: ['test/setup.ts'],
}, },
}) })