Merge remote-tracking branch 'origin/master'

# Conflicts:
#	README.md
This commit is contained in:
zyronon 2024-04-28 15:46:04 +08:00
commit 4f80219a5e
50 changed files with 2564 additions and 3627 deletions

View File

@ -13,8 +13,9 @@
<a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a> <a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a>
</p> </p>
`douyin-vue` 是一个模仿 `抖音|TikTok` 的移动端短视频项目完全度90%。使用了最新的 `Vue` 全家桶技术栈,它基于 [`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/) `douyin-vue` 是一个模仿 `抖音|TikTok` 的移动端短视频项目。`Vue` 在移动端的"最佳实践",媲美原生 `App` 丝滑流畅的使用体验。使用了最新的 `Vue` 技术栈,基于 [`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)
、[`Pinia`](https://pinia.vuejs.org/)实现。数据保存在项目本地,视频采集自`抖音|TikTok`,图集采集自`小红书|Xiaohongshu`,通过 [`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter) 库拦截Api 并返回本地json数据模拟真实后端请求 、[`Pinia`](https://pinia.vuejs.org/)实现。数据保存在项目本地,通过 [`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter) 库拦截Api 并返回本地json数据模拟真实后端请求
<div> <div>
<img width="150px" src='docs/imgs/1.gif' /> <img width="150px" src='docs/imgs/1.gif' />
@ -31,12 +32,14 @@
## 在线访问 ## 在线访问
Gitee Pages: [https://zyronon.gitee.io/douyin/](https://zyronon.gitee.io/douyin/) (中国推荐访问这个地址) Gitee pages: [https://dy.ttentau.top/](https://dy.ttentau.top/) (中国地区推荐访问这个地址)
Github Pages: [https://zyronon.github.io/douyin/](https://zyronon.github.io/douyin/) Netlify: [https://douyins.netlify.app/](https://douyins.netlify.app/)
[//]: # (~~Vercel: [http://dy.ttentau.top/]&#40;http://dy.ttentau.top/&#41;~~) [//]: # (Vercel: [https://douyins.vercel.app]&#40;https://douyins.vercel.app&#41;)
[//]: # (~~Netlify: [https://douyins.netlify.app/]&#40;https://douyins.netlify.app/&#41;~~) [//]: # (Gitee pages: [https://zyronon.gitee.io/douyin/]&#40;https://zyronon.gitee.io/douyin/&#41; &#40;中国地区推荐访问这个地址&#41; )
[//]: # (Github pages: [https://zyronon.github.io/douyin/]&#40;https://zyronon.github.io/douyin/&#41; )
[//]: # (Vercel和Netlify分别送的100G免费流量已经用完了...🤣) [//]: # (Vercel和Netlify分别送的100G免费流量已经用完了...🤣)

View File

@ -3,8 +3,8 @@
</h1> </h1>
<p align="center"> <p align="center">
<a href="README.en.md">English</a> | <a href="README.es.md">Spanish</a> | <a href="README.de.md">German</a> | <a href="docs/README.en.md">English</a> | <a href="docs/README.es.md">Spanish</a> | <a href="docs/README.de.md">German</a> |
<a href="README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="README.ja.md">日本語</a> <a href="docs/README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="docs/README.ja.md">日本語</a>
</p> </p>
<p align="center"> <p align="center">
@ -13,7 +13,7 @@
<a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a> <a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a>
</p> </p>
`douyin-vue`ist eine Parodie`抖音|TikTok`Das mobile Kurzvideoprojekt weist eine Vollständigkeit von 90 % auf. Habe das Neueste verwendet`Vue`FamilyMart-Technologie-Stack, der auf basiert[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)erreichen. Die Daten werden lokal im Projekt gespeichert und das Video daraus gesammelt`抖音|TikTok`, der Atlas stammt aus`小红书|Xiaohongshu`,passieren[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)Die Bibliothek fängt die API ab und gibt lokale JSON-Daten zurück, um echte Backend-Anfragen zu simulieren. `douyin-vue`ist eine Parodie`抖音|TikTok`mobiles Kurzvideoprojekt.`Vue`„Best Practices“ auf der mobilen Seite, vergleichbar mit Native`App`Seidiges und geschmeidiges Erlebnis. Habe das Neueste verwendet`Vue`Technologie-Stack, basierend auf[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)erreichen. Die Daten werden lokal im Projekt gespeichert[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)Die Bibliothek fängt die API ab und gibt lokale JSON-Daten zurück, um echte Backend-Anfragen zu simulieren.
<div> <div>
<img width="150px" src='imgs/1.gif' /> <img width="150px" src='imgs/1.gif' />
@ -30,12 +30,14 @@
## Online-Zugang ## Online-Zugang
Gitee-Seiten:<https://zyronon.gitee.io/douyin/>(Es wird empfohlen, diese Adresse in China zu besuchen) Gitee-Seiten:<https://dy.ttentau.top/>(Es wird empfohlen, diese Adresse in China zu besuchen)
Github-Seiten:<https://zyronon.github.io/douyin/> Netlify:<https://douyins.netlify.app/>
[//]: # "~~Vercel: [http://dy.ttentau.top/](http://dy.ttentau.top/)~~" [//]: # "Vercel: [https://douyins.vercel.app](https://douyins.vercel.app)"
[//]: # "~~Netlify: [https://douyins.netlify.app/](https://douyins.netlify.app/)~~" [//]: # "Gitee pages: [https://zyronon.gitee.io/douyin/](https://zyronon.gitee.io/douyin/) (中国地区推荐访问这个地址) "
[//]: # "Github pages: [https://zyronon.github.io/douyin/](https://zyronon.github.io/douyin/) "
[//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣" [//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣"
@ -47,7 +49,7 @@ Github-Seiten:<https://zyronon.github.io/douyin/>
## Verknüpfung ## Verknüpfung
\[douyin-vue] Eins:[200 Codezeilen zur Implementierung einer Karussellkomponente ähnlich wie Swiper.js](https://juejin.cn/post/7360512664317018146) \[douyin-vue] Eins:[200 Codezeilen zur Implementierung einer Karussellkomponente ähnlich Swiper.js](https://juejin.cn/post/7360512664317018146)
\[douyin-vue] Zweitens:[Verwirklichen Sie den „unendlich gleitenden Video“-Effekt auf Douyin](https://juejin.cn/post/7361614921519054883) \[douyin-vue] Zweitens:[Verwirklichen Sie den „unendlich gleitenden Video“-Effekt auf Douyin](https://juejin.cn/post/7361614921519054883)
Weitere Artikel sind in Vorbereitung... Weitere Artikel sind in Vorbereitung...
@ -68,7 +70,7 @@ npm install
npm run dev npm run dev
``` ```
打开浏览器并访问: <http://127.0.0.1:3000> Öffnen Sie Ihren Browser und besuchen Sie:<http://127.0.0.1:3000>
**Hinweis: Sie müssen den Browser in den Mobilmodus schalten, indem Sie zuerst drücken`F12`Um die Konsole aufzurufen, drücken Sie`Ctrl+Shift+M`um eine normale Vorschau anzuzeigen** **Hinweis: Sie müssen den Browser in den Mobilmodus schalten, indem Sie zuerst drücken`F12`Um die Konsole aufzurufen, drücken Sie`Ctrl+Shift+M`um eine normale Vorschau anzuzeigen**

View File

@ -3,8 +3,8 @@
</h1> </h1>
<p align="center"> <p align="center">
<a href="README.en.md">English</a> | <a href="README.es.md">Spanish</a> | <a href="README.de.md">German</a> | <a href="docs/README.en.md">English</a> | <a href="docs/README.es.md">Spanish</a> | <a href="docs/README.de.md">German</a> |
<a href="README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="README.ja.md">日本語</a> <a href="docs/README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="docs/README.ja.md">日本語</a>
</p> </p>
<p align="center"> <p align="center">
@ -13,7 +13,7 @@
<a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a> <a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a>
</p> </p>
`douyin-vue`is a parody`抖音|TikTok`The mobile short video project has a completeness of 90%. Used the latest`Vue`FamilyMart technology stack, which is based on[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)accomplish. The data is saved locally in the project, and the video is collected from`抖音|TikTok`, the atlas is collected from`小红书|Xiaohongshu`,pass[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)The library intercepts the API and returns local json data to simulate real backend requests. `douyin-vue`is a parody`抖音|TikTok`mobile short video project.`Vue`"Best practices" on the mobile side, comparable to native`App`Silky and smooth experience. Used the latest`Vue`technology stack, based on[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)accomplish. The data is saved locally in the project through[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)The library intercepts the API and returns local json data to simulate real backend requests.
<div> <div>
<img width="150px" src='imgs/1.gif' /> <img width="150px" src='imgs/1.gif' />
@ -28,14 +28,16 @@
<img width="150px" src='imgs/img-5.jpg' /> <img width="150px" src='imgs/img-5.jpg' />
</div> </div>
## online access ## Online access
Gitee pages:<https://zyronon.gitee.io/douyin/>(It is recommended to visit this address in China) Gitee pages:<https://dy.ttentau.top/>(It is recommended to visit this address in China)
Github pages:<https://zyronon.github.io/douyin/> Netlify:<https://douyins.netlify.app/>
[//]: # "~~Vercel: [http://dy.ttentau.top/](http://dy.ttentau.top/)~~" [//]: # "Vercel: [https://douyins.vercel.app](https://douyins.vercel.app)"
[//]: # "~~Netlify: [https://douyins.netlify.app/](https://douyins.netlify.app/)~~" [//]: # "Gitee pages: [https://zyronon.gitee.io/douyin/](https://zyronon.gitee.io/douyin/) (中国地区推荐访问这个地址) "
[//]: # "Github pages: [https://zyronon.github.io/douyin/](https://zyronon.github.io/douyin/) "
[//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣" [//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣"
@ -49,11 +51,11 @@ Github pages:<https://zyronon.github.io/douyin/>
\[douyin-vue] One:[200 lines of code to implement a carousel component similar to Swiper.js](https://juejin.cn/post/7360512664317018146) \[douyin-vue] One:[200 lines of code to implement a carousel component similar to Swiper.js](https://juejin.cn/post/7360512664317018146)
\[douyin-vue] Second:[Realize the "infinite sliding video" effect on Douyin](https://juejin.cn/post/7361614921519054883) \[douyin-vue] Second:[Realize the "infinite sliding video" effect on Douyin](https://juejin.cn/post/7361614921519054883)
更多文章正在准备中... More articles are in preparation...
## run ## run
注意:本项目仅适用于学习和研究,不得用于商业使用 Note: This project is only suitable for study and research, not for commercial use
### Quickly deploy to Vercel ### Quickly deploy to Vercel
@ -68,7 +70,7 @@ npm install
npm run dev npm run dev
``` ```
打开浏览器并访问: <http://127.0.0.1:3000> Open your browser and visit:<http://127.0.0.1:3000>
**Note: You need to switch the browser to mobile mode, first press`F12`To bring up the console, press`Ctrl+Shift+M`to preview normally** **Note: You need to switch the browser to mobile mode, first press`F12`To bring up the console, press`Ctrl+Shift+M`to preview normally**
@ -96,7 +98,7 @@ The above content is all public information on the Internet
## Features and suggestions ## Features and suggestions
The project is currently in the early stages of development and new features are being added continuously. If you have any features or suggestions for the software, please feel free to contact us.`Issues`raised in The project is currently in the early stages of development, and new features are being added continuously. If you have any features or suggestions for the software, please feel free to contact us.`Issues`raised in
If you also like the design ideas of this software, please submit it`PR`, thank you very much for your support! If you also like the design ideas of this software, please submit it`PR`, thank you very much for your support!
## contact me ## contact me

View File

@ -3,8 +3,8 @@
</h1> </h1>
<p align="center"> <p align="center">
<a href="README.en.md">English</a> | <a href="README.es.md">Spanish</a> | <a href="README.de.md">German</a> | <a href="docs/README.en.md">English</a> | <a href="docs/README.es.md">Spanish</a> | <a href="docs/README.de.md">German</a> |
<a href="README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="README.ja.md">日本語</a> <a href="docs/README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="docs/README.ja.md">日本語</a>
</p> </p>
<p align="center"> <p align="center">
@ -13,7 +13,7 @@
<a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a> <a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a>
</p> </p>
`douyin-vue`es una parodia`抖音|TikTok`El proyecto de vídeo corto móvil tiene un avance del 90%. Usado lo último`Vue`Pila de tecnología FamilyMart, que se basa en[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)lograr. Los datos se guardan localmente en el proyecto y el vídeo se recopila de`抖音|TikTok`, el atlas se recoge de`小红书|Xiaohongshu`,aprobar[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)La biblioteca intercepta la API y devuelve datos json locales para simular solicitudes de backend reales. `douyin-vue`es una parodia`抖音|TikTok`Proyecto de vídeo corto móvil.`Vue`"Mejores prácticas" en el lado móvil, comparables a las nativas`App`Experiencia sedosa y suave. Usado lo último`Vue`pila de tecnología, basada en[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)lograr. Los datos se guardan localmente en el proyecto a través de[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)La biblioteca intercepta la API y devuelve datos json locales para simular solicitudes de backend reales.
<div> <div>
<img width="150px" src='imgs/1.gif' /> <img width="150px" src='imgs/1.gif' />
@ -30,12 +30,14 @@
## Acceso en linea ## Acceso en linea
Páginas del albergue:<https://zyronon.gitee.io/douyin/> (中国地区推荐访问这个地址) Páginas del albergue:<https://dy.ttentau.top/>(Se recomienda visitar esta dirección en China)
Páginas de Github:<https://zyronon.github.io/douyin/> Netlificar:<https://douyins.netlify.app/>
[//]: # "~~Vercel: [http://dy.ttentau.top/](http://dy.ttentau.top/)~~" [//]: # "Vercel: [https://douyins.vercel.app](https://douyins.vercel.app)"
[//]: # "~~Netlify: [https://douyins.netlify.app/](https://douyins.netlify.app/)~~" [//]: # "Gitee pages: [https://zyronon.gitee.io/douyin/](https://zyronon.gitee.io/douyin/) (中国地区推荐访问这个地址) "
[//]: # "Github pages: [https://zyronon.github.io/douyin/](https://zyronon.github.io/douyin/) "
[//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣" [//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣"
@ -77,7 +79,7 @@ Abra su navegador y visite:<http://127.0.0.1:3000>
El video proviene de las siguientes celebridades de Douyin. El video proviene de las siguientes celebridades de Douyin.
- `我是香秀 🐂🍺`:<https://v.douyin.com/iYRAPA2L/> - `我是香秀 🐂🍺`:<https://v.douyin.com/iYRAPA2L/>
- `杨老虎 🐯(磕穿下巴掉牙版)`: <https://v.douyin.com/iYRA56de/> - `杨老虎 🐯(磕穿下巴掉牙版)`:<https://v.douyin.com/iYRA56de/>
- `条子`:<https://v.douyin.com/iYRAaqjr/> - `条子`:<https://v.douyin.com/iYRAaqjr/>
- `达莎 Digi`<https://v.douyin.com/iYRA6rwT/> - `达莎 Digi`<https://v.douyin.com/iYRA6rwT/>
- `小橙子`:<https://v.douyin.com/iYRAnudw/> - `小橙子`:<https://v.douyin.com/iYRAnudw/>
@ -86,7 +88,7 @@ El video proviene de las siguientes celebridades de Douyin.
- `奶茶妹 ◕🌱`:<https://v.douyin.com/iYRACKhP/> - `奶茶妹 ◕🌱`:<https://v.douyin.com/iYRACKhP/>
- `我才是岚岚`:<https://v.douyin.com/iYRAQM1C/> - `我才是岚岚`:<https://v.douyin.com/iYRAQM1C/>
- `周憬艺 ziran`:<https://v.douyin.com/iYRAQs4h/> - `周憬艺 ziran`:<https://v.douyin.com/iYRAQs4h/>
- `刘思瑶 nice`: <https://v.douyin.com/iYRAaERn/> - `刘思瑶 nice`:<https://v.douyin.com/iYRAaERn/>
- `彭十六 elf`:<https://v.douyin.com/iYRAHrVG/> - `彭十六 elf`:<https://v.douyin.com/iYRAHrVG/>
- `李子柒`:<https://v.douyin.com/iYRA5B88/> - `李子柒`:<https://v.douyin.com/iYRA5B88/>
@ -97,7 +99,7 @@ El contenido anterior es toda información pública en Internet.
## Funciones y sugerencias ## Funciones y sugerencias
El proyecto se encuentra actualmente en las primeras etapas de desarrollo y continuamente se agregan nuevas funciones. Si tiene alguna característica o sugerencia para el software, no dude en contactarnos.`Issues`criado en El proyecto se encuentra actualmente en las primeras etapas de desarrollo y continuamente se agregan nuevas funciones. Si tiene alguna característica o sugerencia para el software, no dude en contactarnos.`Issues`criado en
Si también le gustan las ideas de diseño de este software, envíelas.`PR`, ¡Muchas gracias por tu apoyo! Si también le gustan las ideas de diseño de este software, envíelas.`PR`,非常感谢你对我们的支持!
## contáctame ## contáctame

View File

@ -3,8 +3,8 @@
</h1> </h1>
<p align="center"> <p align="center">
<a href="README.en.md">English</a> | <a href="README.es.md">Spanish</a> | <a href="README.de.md">German</a> | <a href="docs/README.en.md">English</a> | <a href="docs/README.es.md">Spanish</a> | <a href="docs/README.de.md">German</a> |
<a href="README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="README.ja.md">日本語</a> <a href="docs/README.fr.md">French</a> | <a href="README.md">简体中文</a> | <a href="docs/README.ja.md">日本語</a>
</p> </p>
<p align="center"> <p align="center">
@ -13,29 +13,31 @@
<a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a> <a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a>
</p> </p>
`douyin-vue`est une parodie`抖音|TikTok`Le projet de courte vidéo mobile a un taux d'exhaustivité de 90 %. Utilisé le dernier`Vue`Pile technologique FamilyMart, basée sur[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)accomplir. Les données sont enregistrées localement dans le projet et la vidéo est collectée à partir de`抖音|TikTok`, l'atlas est collecté auprès de`小红书|Xiaohongshu`,passer[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)La bibliothèque intercepte l'API et renvoie des données json locales pour simuler de véritables requêtes backend. `douyin-vue`est une parodie`抖音|TikTok`projet de courte vidéo mobile.`Vue`Des « bonnes pratiques » côté mobile, comparables au natif`App`Expérience soyeuse et douce. Utilisé le dernier`Vue`pile technologique, basée sur[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)accomplir. Les données sont enregistrées localement dans le projet via[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)La bibliothèque intercepte l'API et renvoie des données json locales pour simuler de véritables requêtes backend.
<div> <div>
<img width="150px" src='imgs/1.gif' /> <img width="150px" src='docs/imgs/1.gif' />
<img width="150px" src='imgs/2.gif' /> <img width="150px" src='docs/imgs/2.gif' />
<img width="150px" src='imgs/3.gif' /> <img width="150px" src='docs/imgs/3.gif' />
<img width="150px" src='imgs/4.gif' /> <img width="150px" src='docs/imgs/4.gif' />
<img width="150px" src='imgs/5.gif' /> <img width="150px" src='docs/imgs/5.gif' />
<img width="150px" src='imgs/img-1.jpg' /> <img width="150px" src='docs/imgs/img-1.jpg' />
<img width="150px" src='imgs/img-2.jpg' /> <img width="150px" src='docs/imgs/img-2.jpg' />
<img width="150px" src='imgs/img-3.jpg' /> <img width="150px" src='docs/imgs/img-3.jpg' />
<img width="150px" src='imgs/img-4.jpg' /> <img width="150px" src='docs/imgs/img-4.jpg' />
<img width="150px" src='imgs/img-5.jpg' /> <img width="150px" src='docs/imgs/img-5.jpg' />
</div> </div>
## accès en ligne ## Accès en ligne
Pages du gîte :<https://zyronon.gitee.io/douyin/>(Il est recommandé de visiter cette adresse en Chine) Pages du gîte :<https://dy.ttentau.top/>(Il est recommandé de visiter cette adresse en Chine)
Pages GitHub :<https://zyronon.github.io/douyin/> Netlifier :<https://douyins.netlify.app/>
[//]: # "~~Vercel: [http://dy.ttentau.top/](http://dy.ttentau.top/)~~" [//]: # "Vercel: [https://douyins.vercel.app](https://douyins.vercel.app)"
[//]: # "~~Netlify: [https://douyins.netlify.app/](https://douyins.netlify.app/)~~" [//]: # "Gitee pages: [https://zyronon.gitee.io/douyin/](https://zyronon.gitee.io/douyin/) (中国地区推荐访问这个地址) "
[//]: # "Github pages: [https://zyronon.github.io/douyin/](https://zyronon.github.io/douyin/) "
[//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣" [//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣"
@ -47,7 +49,7 @@ Pages GitHub :<https://zyronon.github.io/douyin/>
## Lien ## Lien
\[douyin-vue] Un :[200 lignes de code pour implémenter un composant carrousel similaire à Swiper.js](https://juejin.cn/post/7360512664317018146) \[douyin-vue] Un :[200行代码实现类似Swiper.js的轮播组件](https://juejin.cn/post/7360512664317018146)
\[douyin-vue] Deuxièmement :[Réaliser l'effet "vidéo coulissante infinie" sur Douyin](https://juejin.cn/post/7361614921519054883) \[douyin-vue] Deuxièmement :[Réaliser l'effet "vidéo coulissante infinie" sur Douyin](https://juejin.cn/post/7361614921519054883)
D'autres articles sont en préparation... D'autres articles sont en préparation...
@ -85,7 +87,7 @@ La vidéo provient des célébrités Douyin suivantes
- `小霸宠牛排 🥩`<https://v.douyin.com/iYRSosVB/> - `小霸宠牛排 🥩`<https://v.douyin.com/iYRSosVB/>
- `奶茶妹 ◕🌱`:<https://v.douyin.com/iYRACKhP/> - `奶茶妹 ◕🌱`:<https://v.douyin.com/iYRACKhP/>
- `我才是岚岚`:<https://v.douyin.com/iYRAQM1C/> - `我才是岚岚`:<https://v.douyin.com/iYRAQM1C/>
- `周憬艺 ziran`: <https://v.douyin.com/iYRAQs4h/> - `周憬艺 ziran`:<https://v.douyin.com/iYRAQs4h/>
- `刘思瑶 nice`:<https://v.douyin.com/iYRAaERn/> - `刘思瑶 nice`:<https://v.douyin.com/iYRAaERn/>
- `彭十六 elf`:<https://v.douyin.com/iYRAHrVG/> - `彭十六 elf`:<https://v.douyin.com/iYRAHrVG/>
- `李子柒`:<https://v.douyin.com/iYRA5B88/> - `李子柒`:<https://v.douyin.com/iYRA5B88/>

View File

@ -3,8 +3,8 @@
</h1> </h1>
<p align="center"> <p align="center">
<a href="README.en.md">English</a> | <a href="README.es.md">Spanish</a> | <a href="README.de.md">German</a> | <a href="docs/README.en.md">English</a> | <a href="docs/README.es.md">Spanish</a> | <a href="docs/README.de.md">German</a> |
<a href="README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="README.ja.md">日本語</a> <a href="docs/README.fr.md">French</a> | <a href="../README.md">简体中文</a> | <a href="docs/README.ja.md">日本語</a>
</p> </p>
<p align="center"> <p align="center">
@ -13,7 +13,7 @@
<a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a> <a><img src="https://img.shields.io/badge/Powered%20by-Vue-blue"/></a>
</p> </p>
`douyin-vue`パロディです`抖音|TikTok`モバイル向けショートビデオプロジェクトの完成度は90。最新のものを使用しました`Vue` 全家桶技术栈,它基于 [`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)成し遂げる。データはプロジェクトのローカルに保存され、ビデオは次から収集されます。`抖音|TikTok`、アトラスはから収集されています`小红书|Xiaohongshu`、合格[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)ライブラリは API をインターセプトし、ローカルの JSON データを返して、実際のバックエンド リクエストをシミュレートします。 `douyin-vue`パロディです`抖音|TikTok`モバイルショートビデオプロジェクト。`Vue`ネイティブと同等のモバイル側の「ベスト プラクティス」`App`シルキーで滑らかな使い心地。最新のものを使用しました`Vue`テクノロジースタック、に基づく[`Vue3`](https://cn.vuejs.org/)、[`Vite5`](https://cn.vitejs.dev/)、[`Pinia`](https://pinia.vuejs.org/)成し遂げる。データはプロジェクト内でローカルに保存されます。[`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter)ライブラリは API をインターセプトし、ローカルの JSON データを返して、実際のバックエンド リクエストをシミュレートします。
<div> <div>
<img width="150px" src='imgs/1.gif' /> <img width="150px" src='imgs/1.gif' />
@ -30,12 +30,14 @@
## オンラインアクセス ## オンラインアクセス
Gite ページ:[hっtps://zyろのん。ぎてえ。いお/どうyいん/](https://zyronon.gitee.io/douyin/)(中国ではこのアドレスにアクセスすることをお勧めします) Gite ページ:[hっtps://dy。ってんたう。とp/](https://dy.ttentau.top/)(中国ではこのアドレスにアクセスすることをお勧めします)
Github ページ:[hっtps://zyろのん。ぎてゅb。いお/どうyいん/](https://zyronon.github.io/douyin/) ネットリファイ:[hっtps://どうyいんs。ねtぃfy。あっp/](https://douyins.netlify.app/)
[//]: # "~~Vercel: [http://dy.ttentau.top/](http://dy.ttentau.top/)~~" [//]: # "Vercel: [https://douyins.vercel.app](https://douyins.vercel.app)"
[//]: # "~~Netlify: [https://douyins.netlify.app/](https://douyins.netlify.app/)~~" [//]: # "Gitee pages: [https://zyronon.gitee.io/douyin/](https://zyronon.gitee.io/douyin/) (中国地区推荐访问这个地址) "
[//]: # "Github pages: [https://zyronon.github.io/douyin/](https://zyronon.github.io/douyin/) "
[//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣" [//]: # "Vercel和Netlify分别送的100G免费流量已经用完了...🤣"
@ -96,12 +98,12 @@ npm run dev
## 特徴と提案 ## 特徴と提案
プロジェクトは現在開発の初期段階にあり、ソフトウェアの新機能や提案があれば、お気軽にお問い合わせください。`Issues`で育ちました プロジェクトは現在開発の初期段階にあり、新しい機能が継続的に追加されています。ソフトウェアに関する機能や提案がありましたら、お気軽にお問い合わせください。`Issues`で育ちました
このソフトウェアのデザインアイデアも気に入っていただけましたら、ぜひ送信してください`PR`、 ご支援ありがとうございました! このソフトウェアのデザインアイデアも気に入っていただけましたら、ぜひ送信してください`PR`、 ご支援ありがとうございました!
## 私に連絡して ## 私に連絡して
私のメールアドレスにご連絡いただけます<a href="mailto:zyronon@163.com">zyろのん@163。こm</a> 您可以联系我的邮箱 <a href="mailto:zyronon@163.com">zyろのん@163。こm</a>
> 私の他のオープンソース プロジェクトを共有してください: > 私の他のオープンソース プロジェクトを共有してください:
> >

3
env.d.ts vendored
View File

@ -1,10 +1,13 @@
/// <reference types="vite/client" /> /// <reference types="vite/client" />
/// <reference types="unplugin-vue-macros/macros-global" />
declare const LATEST_COMMIT_HASH: string declare const LATEST_COMMIT_HASH: string
declare global { declare global {
interface Window { interface Window {
isMoved: boolean isMoved: boolean
isMuted: boolean
showMutedNotice: boolean
} }
interface Navigator { interface Navigator {

View File

@ -27,7 +27,6 @@
"axios-mock-adapter": "^1.22.0", "axios-mock-adapter": "^1.22.0",
"core-js": "3.21.1", "core-js": "3.21.1",
"libarchive-wasm": "^1.1.0", "libarchive-wasm": "^1.1.0",
"mitt": "3.0.0",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"vue": "3.4.21", "vue": "3.4.21",
@ -58,7 +57,7 @@
"prettier": "^3.2.5", "prettier": "^3.2.5",
"rollup-plugin-visualizer": "^5.9.2", "rollup-plugin-visualizer": "^5.9.2",
"typescript": "5.3.3", "typescript": "5.3.3",
"unplugin-vue-define-options": "^1.4.1", "unplugin-vue-macros": "^2.9.1",
"vite": "^5.1.7", "vite": "^5.1.7",
"vite-plugin-cdn-import": "0.3.5", "vite-plugin-cdn-import": "0.3.5",
"vite-plugin-commonjs": "^0.10.1", "vite-plugin-commonjs": "^0.10.1",

View File

@ -20,9 +20,6 @@ dependencies:
libarchive-wasm: libarchive-wasm:
specifier: ^1.1.0 specifier: ^1.1.0
version: 1.1.0 version: 1.1.0
mitt:
specifier: 3.0.0
version: 3.0.0
mockjs: mockjs:
specifier: ^1.1.0 specifier: ^1.1.0
version: 1.1.0 version: 1.1.0
@ -109,9 +106,9 @@ devDependencies:
typescript: typescript:
specifier: 5.3.3 specifier: 5.3.3
version: 5.3.3 version: 5.3.3
unplugin-vue-define-options: unplugin-vue-macros:
specifier: ^1.4.1 specifier: ^2.9.1
version: 1.4.2(rollup@2.79.1)(vue@3.4.21) version: 2.9.1(rollup@2.79.1)(typescript@5.3.3)(vite@5.1.7)(vue@3.4.21)
vite: vite:
specifier: ^5.1.7 specifier: ^5.1.7
version: 5.1.7(@types/node@20.12.4)(less@4.1.3) version: 5.1.7(@types/node@20.12.4)(less@4.1.3)
@ -140,6 +137,10 @@ packages:
'@jridgewell/trace-mapping': 0.3.20 '@jridgewell/trace-mapping': 0.3.20
dev: true dev: true
/@antfu/utils@0.7.7:
resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==}
dev: true
/@babel/code-frame@7.22.13: /@babel/code-frame@7.22.13:
resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -401,6 +402,14 @@ packages:
'@babel/types': 7.24.0 '@babel/types': 7.24.0
dev: true dev: true
/@babel/parser@7.24.4:
resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.24.0
dev: true
/@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.24.3): /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.24.3):
resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -1034,6 +1043,10 @@ packages:
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
dev: true dev: true
/@polka/url@1.0.0-next.25:
resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==}
dev: true
/@rollup/plugin-commonjs@25.0.7(rollup@2.79.1): /@rollup/plugin-commonjs@25.0.7(rollup@2.79.1):
resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@ -1426,8 +1439,54 @@ packages:
path-browserify: r2.cnpmjs.org/path-browserify@1.0.1 path-browserify: r2.cnpmjs.org/path-browserify@1.0.1
dev: true dev: true
/@vue-macros/common@1.10.1(rollup@2.79.1)(vue@3.4.21): /@vue-macros/api@0.9.5(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-uftSpfwdwitcQT2lM8aVxcfe5rKQBzC9jMrtJM5sG4hEuFyfIvnJihpPpnaWxY+X4p64k+YYXtBFv+1O5Bq3dg==} resolution: {integrity: sha512-ybaOuoB3HIMJsH2Cj3903cf6YM65UOl7U1Vbq4ZH4drDLymlgIqEri5ufhq76XXn6mi6xx4cZ3JUqo5VwteHkQ==}
engines: {node: '>=16.14.0'}
dependencies:
'@babel/types': 7.24.0
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
resolve.exports: 2.0.2
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/better-define@1.7.5(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-XKByxQ+867gujPUKfRWnC5ajBfFChX2bgqVGK5fSVr+EAbkxZmMAa6KhxkGTWSn0R0T7TJIULXGlRj0TV4j6EQ==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/api': 0.9.5(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/boolean-prop@0.3.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-FAHBAXtI0qcoLIfq5AAfHokz191nC/ciYcqbBUygvI4DEPINOnrb/QN0M56LkszJUl7girx/JxUOixUDHozUyA==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue/compiler-core': 3.4.21
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/chain-call@0.2.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-THXfqdpqcdcz0ugCW3AfTcAqa6vXeHHCgKsDc9wvdITjsxIwiXmGIiA22rNZxdXGnXVSY+v18VdzChv/dbZ0RA==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/common@1.10.2(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-WC66NPVh2mJWqm4L0l/u/cOqm4pNOIwVdMGnDYAH2rHcOWy5x68GkhpkYTBu1+xwCSeHWOQn1TCGGbD+98fFpA==}
engines: {node: '>=16.14.0'} engines: {node: '>=16.14.0'}
peerDependencies: peerDependencies:
vue: ^2.7.0 || ^3.2.25 vue: ^2.7.0 || ^3.2.25
@ -1438,7 +1497,7 @@ packages:
'@babel/types': 7.24.0 '@babel/types': 7.24.0
'@rollup/pluginutils': 5.1.0(rollup@2.79.1) '@rollup/pluginutils': 5.1.0(rollup@2.79.1)
'@vue/compiler-sfc': 3.4.21 '@vue/compiler-sfc': 3.4.21
ast-kit: 0.11.3(rollup@2.79.1) ast-kit: 0.12.1
local-pkg: 0.5.0 local-pkg: 0.5.0
magic-string-ast: 0.3.0 magic-string-ast: 0.3.0
vue: 3.4.21(typescript@5.3.3) vue: 3.4.21(typescript@5.3.3)
@ -1446,6 +1505,280 @@ packages:
- rollup - rollup
dev: true dev: true
/@vue-macros/define-emit@0.2.5(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-QsmzVLkxYdPaJr5hi/S3K9hr9hQ8Q55SIMmDiUsYABJpmSzczGv6HcJKkvP3k1J5UHxGx9rkytTv5KKxEaAYyw==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.2.25
dependencies:
'@vue-macros/api': 0.9.5(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/define-models@1.2.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-yeAcE3W9wZG1tePzY6+Ldpzj+zZJs7YZcQGLYxoXiEOii5Koh5VLaLm+qEQaXToMwjV/904YaJHKPH7Gsi0Tfg==}
engines: {node: '>=16.14.0'}
peerDependencies:
'@vueuse/core': '>=9.0.0'
peerDependenciesMeta:
'@vueuse/core':
optional: true
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
ast-walker-scope: 0.6.1
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/define-prop@0.3.5(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-1eTmUQh5Oz2UldFPlsK6CuNw8N+zIUGIQB8SxgN8m0V0xKvyJpjJrSWs0WfFBivCl+gxYJUZ7ZjiwTuCc9Z7kA==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.2.25
dependencies:
'@vue-macros/api': 0.9.5(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/define-props-refs@1.2.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-7nZKCZhr5CsQ93wBHauvwO3/NxYe6+IP2mvKYBxAlq9oADGptZbrK6jarUpBE2V0tTyq0AynfAOG6GueGxvJEg==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.2.25
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/define-props@2.0.4(@vue-macros/reactivity-transform@0.4.4)(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-opifxLT9yF+A/bEfEpuFxNcAMPEmnPv/ewlCDmOH8VX+CBnlWbDqY0n0LcimPGRTYkRDAkNBHRRQulxNfRXNpw==}
engines: {node: '>=16.14.0'}
peerDependencies:
'@vue-macros/reactivity-transform': ^0.4.4
vue: ^2.7.0 || ^3.2.25
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/reactivity-transform': 0.4.4(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/define-render@1.5.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-phdDLTHvZi0AxK2kEJ1Gt6TDMH9vHQib+eU5k+GXV/WPz43n+Cp4a9tq5Mpkc1rojc796w/+O1bE6jE0fyGxjw==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.0.0
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/define-slots@1.1.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-b8lhEOMS8kl3x2ihOIrfz9xjCCUdBKliLzs5mqdQlaLRVRSxHxXVnBq1Ek7dCIxrc2Mp9VyvBn7E4Q4i0StpmQ==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.0.0
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/devtools@0.2.0(typescript@5.3.3)(vite@5.1.7):
resolution: {integrity: sha512-jHjvY1bFgQLe/2+5pBOG4fgmL5MPhsqQDj7Barhj8YN+Oe7U2hBImvfAyOGpqd2uucLOWQTP1cWrp3q9b1svsg==}
engines: {node: '>=16.14.0'}
peerDependencies:
vite: ^4.0.0 || ^5.0.0-0
peerDependenciesMeta:
vite:
optional: true
dependencies:
sirv: 2.0.4
vite: 5.1.7(@types/node@20.12.4)(less@4.1.3)
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- typescript
dev: true
/@vue-macros/export-expose@0.1.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-K2cFoVXqzLjVe0kpOKS+QlLdI3P9+zjDDj8LQQreaWTBuAYQIyEIIjEt5aw5MImLrmmoSqbWNFf/iiZNJrDl1w==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.2.25
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue/compiler-sfc': 3.4.21
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/export-props@0.4.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-UhIZFb9lwuZfuOdPTUIRs4D74YGdZjBKpUZNjDQG1P2VbIsqXZ5nwKo1nPH4XYoAzXmJcpGqP+gwemCITpTewA==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.2.25
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/export-render@0.2.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-0iQnVNxMuTjfmF1N6mWR+21dClHwJRd/WJXwGhjABOBX8g90JM7kj0pXvhdpQZ4CBiDTHrNMl0s4C0c3tjwjnw==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.2.25
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue/compiler-sfc': 3.4.21
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/hoist-static@1.5.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-17IcyI2EnMRgC7YtDr1PpjI4inca7jqSeRJZVHemU9oYZxYes1lIh5A/x18vVh1+ZP2xFFHjJr69AEhPzedk1g==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/jsx-directive@0.8.12(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-+50MSQfcG5d+Sv2AVi3DAOSxcVmEuxdpghZzismg1dYWPikbFu7f4RH6wvexFnCjKoYKDw/E02DBup5wLEGJSA==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/named-template@0.4.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-d3PcaVE/aSF7sHOJrbQlNZaODQYpTidbSk4DK6i/ucgYBD5eOx3dwr/37gtmjLu4vXM1l8igouaSLhWVf3bPsg==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue/compiler-dom': 3.4.21
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/reactivity-transform@0.4.4(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-Yn22Ls+KAJzjwdjrjwaDkjx+lxSXlk4ev+s0hD9biTpjaf1Sv7AKYq5381TGZIeDadklkhHzYwQWueROqvpG6w==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.2.25
dependencies:
'@babel/parser': 7.24.4
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue/compiler-core': 3.4.21
'@vue/shared': 3.4.21
magic-string: 0.30.10
unplugin: 1.10.1
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- rollup
dev: true
/@vue-macros/setup-block@0.3.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-06UnxX8wDKJcJHvSgnxi7aJo2jdGvbeAur+aSLcmYgTfNUwRtuC2KmJKQohjos24USpQEYyGqMKPYuxkdoQ+Wg==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue/compiler-dom': 3.4.21
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/setup-component@0.17.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-zBZCPBhVh5gZMKQKE/K+SJYiXjIoK+Hc/FxhHkijZd4njx2a3CtpW5BX3bDr0498E78+f7vlqcPHaE9IRNUGsQ==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/setup-sfc@0.17.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-6D6UMLi1qdgpBhgwRo2VevVpNlo9QtnzsOIag4seAl3zEI1jB5KfOoUWl8yHZ5MUGfs5jSPzOhlQfEzefrgO4g==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/short-bind@0.2.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-3QwHQQDVNpsWh36/q4sB5QmGGedwIZUmL2rvQ8YQD6EA455samG0r2zB9Q6Z7DA8+qk6TjpmkvltubDY9TWtEQ==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue/compiler-core': 3.4.21
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/short-emits@1.5.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-DTzJ1Bj2cwJK9kCRWw9VUeNjuAnmyXoTC05J76lGBa7Ftr/04UZM31h8/NyTKqG/oXHBnNa4X8kGy9A7kRwG9g==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue-macros/short-vmodel@1.4.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-ZQph4GuKl4kEXtzGDddqSgfykAZ9cT7tu14G4K3ZGJ8wsLmhuLGWfFL596UVg5zfVyMWuC/SbTmR8UEp/eMPJA==}
engines: {node: '>=16.14.0'}
dependencies:
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue/compiler-core': 3.4.21
transitivePeerDependencies:
- rollup
- vue
dev: true
/@vue/babel-helper-vue-transform-on@1.1.5: /@vue/babel-helper-vue-transform-on@1.1.5:
resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==} resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==}
dev: true dev: true
@ -1679,36 +2012,20 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/ast-kit@0.11.3(rollup@2.79.1): /ast-kit@0.12.1:
resolution: {integrity: sha512-qdwwKEhckRk0XE22/xDdmU3v/60E8Edu4qFhgTLIhGGDs/PAJwLw9pQn8Rj99PitlbBZbYpx0k/lbir4kg0SuA==} resolution: {integrity: sha512-O+33g7x6irsESUcd47KdfWUrS2F6aGp9KeVJFGj0YjIznfXpBxVGjA0w+y/1OKqX4mFOfmZ9Xpf1ixPT4n9xxw==}
engines: {node: '>=16.14.0'} engines: {node: '>=16.14.0'}
dependencies: dependencies:
'@babel/parser': 7.24.0 '@babel/parser': 7.24.4
'@rollup/pluginutils': 5.1.0(rollup@2.79.1)
pathe: 1.1.2 pathe: 1.1.2
transitivePeerDependencies:
- rollup
dev: true dev: true
/ast-kit@0.9.5(rollup@2.79.1): /ast-walker-scope@0.6.1:
resolution: {integrity: sha512-kbL7ERlqjXubdDd+szuwdlQ1xUxEz9mCz1+m07ftNVStgwRb2RWw+U6oKo08PAvOishMxiqz1mlJyLl8yQx2Qg==} resolution: {integrity: sha512-0ZdQEsSfH3mX4BFbRCc3xOBjx5bDbm73+aAdQOHerPQNf8K0XFMAv79ucd2BpnSc4UMyvBDixiroT8yjm2Y6bw==}
engines: {node: '>=16.14.0'} engines: {node: '>=16.14.0'}
dependencies: dependencies:
'@babel/parser': 7.24.0 '@babel/parser': 7.24.4
'@rollup/pluginutils': 5.1.0(rollup@2.79.1) ast-kit: 0.12.1
pathe: 1.1.2
transitivePeerDependencies:
- rollup
dev: true
/ast-walker-scope@0.5.0(rollup@2.79.1):
resolution: {integrity: sha512-NsyHMxBh4dmdEHjBo1/TBZvCKxffmZxRYhmclfu0PP6Aftre47jOHYaYaNqJcV0bxihxFXhDkzLHUwHc0ocd0Q==}
engines: {node: '>=16.14.0'}
dependencies:
'@babel/parser': 7.24.0
ast-kit: 0.9.5(rollup@2.79.1)
transitivePeerDependencies:
- rollup
dev: true dev: true
/axios-mock-adapter@1.22.0(axios@1.6.8): /axios-mock-adapter@1.22.0(axios@1.6.8):
@ -2888,6 +3205,12 @@ packages:
sourcemap-codec: 1.4.8 sourcemap-codec: 1.4.8
dev: true dev: true
/magic-string@0.30.10:
resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
/magic-string@0.30.7: /magic-string@0.30.7:
resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -2980,10 +3303,6 @@ packages:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
dev: true dev: true
/mitt@3.0.0:
resolution: {integrity: sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==}
dev: false
/mlly@1.6.1: /mlly@1.6.1:
resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==}
dependencies: dependencies:
@ -3000,6 +3319,11 @@ packages:
commander: 1.1.1 commander: 1.1.1
dev: false dev: false
/mrmime@2.0.0:
resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==}
engines: {node: '>=10'}
dev: true
/ms@2.1.2: /ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true dev: true
@ -3257,6 +3581,11 @@ packages:
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
/resolve.exports@2.0.2:
resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==}
engines: {node: '>=10'}
dev: true
/restore-cursor@4.0.0: /restore-cursor@4.0.0:
resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -3409,6 +3738,15 @@ packages:
engines: {node: '>=14'} engines: {node: '>=14'}
dev: true dev: true
/sirv@2.0.4:
resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
engines: {node: '>= 10'}
dependencies:
'@polka/url': 1.0.0-next.25
mrmime: 2.0.0
totalist: 3.0.1
dev: true
/slash@3.0.0: /slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -3546,6 +3884,11 @@ packages:
is-number: 7.0.0 is-number: 7.0.0
dev: true dev: true
/totalist@3.0.1:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
dev: true
/ts-api-utils@1.3.0(typescript@5.3.3): /ts-api-utils@1.3.0(typescript@5.3.3):
resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
engines: {node: '>=16'} engines: {node: '>=16'}
@ -3594,20 +3937,89 @@ packages:
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
dev: true dev: true
/unplugin-vue-define-options@1.4.2(rollup@2.79.1)(vue@3.4.21): /unplugin-combine@0.9.0(rollup@2.79.1)(vite@5.1.7):
resolution: {integrity: sha512-jQ3nJ1olC107QUA67UEB1CWJXnbVA7SF4UibKQF+jvME7UZ/XomctISHtAkJSJ9YHn0eqnqqzyNkng/KnLUZBw==} resolution: {integrity: sha512-1bXgHXIhw/bNEFCwNnYRlOOcamsBNQObSWBuy3FcDcnMoFLIi4ZaMsi/L0cNxltfYBTS+QvGSZ1F+LgQ0vbcLg==}
engines: {node: '>=16.14.0'}
peerDependencies:
esbuild: '>=0.13'
rollup: ^3.2.0 || ^4.0.0
vite: ^2.3.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
webpack: 4 || 5
peerDependenciesMeta:
esbuild:
optional: true
rollup:
optional: true
vite:
optional: true
webpack:
optional: true
dependencies:
'@antfu/utils': 0.7.7
rollup: 2.79.1
unplugin: 1.10.1
vite: 5.1.7(@types/node@20.12.4)(less@4.1.3)
dev: true
/unplugin-vue-define-options@1.4.3(rollup@2.79.1)(vue@3.4.21):
resolution: {integrity: sha512-CN5xF8l8bySD6okw6PCt1zWFHf5vX+q4Cg2ssn9usANHtxmeyCgMccC7ywZyzI32dQS+pq6hvuSz/GewtYnbEQ==}
engines: {node: '>=16.14.0'} engines: {node: '>=16.14.0'}
dependencies: dependencies:
'@vue-macros/common': 1.10.1(rollup@2.79.1)(vue@3.4.21) '@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
ast-walker-scope: 0.5.0(rollup@2.79.1) ast-walker-scope: 0.6.1
unplugin: 1.7.1 unplugin: 1.10.1
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
- vue - vue
dev: true dev: true
/unplugin@1.7.1: /unplugin-vue-macros@2.9.1(rollup@2.79.1)(typescript@5.3.3)(vite@5.1.7)(vue@3.4.21):
resolution: {integrity: sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw==} resolution: {integrity: sha512-r9y6e5GhUgRGzHr+Od9X6S2irdzwSAdU2BvSz0dXN00tDHNm/Y/iCn/Iypdzbe4ai9b09lMfB5MFUpT3jfOlQA==}
engines: {node: '>=16.14.0'}
peerDependencies:
vue: ^2.7.0 || ^3.2.25
dependencies:
'@vue-macros/better-define': 1.7.5(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/boolean-prop': 0.3.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/chain-call': 0.2.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/common': 1.10.2(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/define-emit': 0.2.5(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/define-models': 1.2.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/define-prop': 0.3.5(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/define-props': 2.0.4(@vue-macros/reactivity-transform@0.4.4)(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/define-props-refs': 1.2.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/define-render': 1.5.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/define-slots': 1.1.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/devtools': 0.2.0(typescript@5.3.3)(vite@5.1.7)
'@vue-macros/export-expose': 0.1.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/export-props': 0.4.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/export-render': 0.2.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/hoist-static': 1.5.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/jsx-directive': 0.8.12(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/named-template': 0.4.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/reactivity-transform': 0.4.4(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/setup-block': 0.3.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/setup-component': 0.17.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/setup-sfc': 0.17.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/short-bind': 0.2.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/short-emits': 1.5.3(rollup@2.79.1)(vue@3.4.21)
'@vue-macros/short-vmodel': 1.4.3(rollup@2.79.1)(vue@3.4.21)
unplugin: 1.10.1
unplugin-combine: 0.9.0(rollup@2.79.1)(vite@5.1.7)
unplugin-vue-define-options: 1.4.3(rollup@2.79.1)(vue@3.4.21)
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- '@vueuse/core'
- esbuild
- rollup
- typescript
- vite
- webpack
dev: true
/unplugin@1.10.1:
resolution: {integrity: sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==}
engines: {node: '>=14.0.0'}
dependencies: dependencies:
acorn: 8.11.3 acorn: 8.11.3
chokidar: 3.6.0 chokidar: 3.6.0

View File

@ -400,163 +400,6 @@
] ]
} }
}, },
{
"aweme_id": "7346191904205327631",
"desc": "我的女友",
"create_time": 1710418599,
"music": {
"id": 7346191940615933000,
"title": "@条子创作的原声",
"author": "条子",
"cover_medium": {
"uri": "720x720/aweme-avatar/tos-cn-avt-0015_75c5ef8973e1d665252306ea58f7d10b",
"url_list": [
"https://p3-pc.douyinpic.com/aweme/720x720/aweme-avatar/tos-cn-avt-0015_75c5ef8973e1d665252306ea58f7d10b.jpeg?from=116350172"
],
"width": 720,
"height": 720
},
"cover_thumb": {
"uri": "100x100/aweme-avatar/tos-cn-avt-0015_75c5ef8973e1d665252306ea58f7d10b",
"url_list": [
"https://p3-pc.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-avt-0015_75c5ef8973e1d665252306ea58f7d10b.jpeg?from=116350172"
],
"width": 720,
"height": 720
},
"play_url": {
"uri": "https://sf5-hl-cdn-tos.douyinstatic.com/obj/ies-music/7346191933737356059.mp3",
"url_list": [
"https://sf5-hl-cdn-tos.douyinstatic.com/obj/ies-music/7346191933737356059.mp3",
"https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/7346191933737356059.mp3"
],
"width": 720,
"height": 720,
"url_key": "7346191940615932722"
},
"duration": 7,
"user_count": 0,
"owner_id": "83160533866",
"owner_nickname": "条子",
"is_original": false
},
"video": {
"play_addr": {
"uri": "v0300fg10000cnpel5bc77u9pqctt5hg",
"url_list": [
"https://www.douyin.com/aweme/v1/play/?video_id=v0300fg10000cnpel5bc77u9pqctt5hg&line=0&file_id=0ab371e7a5ac419fb88d8b616f1b9a70&sign=c689ddfb4d16aec5ae605822e5b2c4f6&is_play_url=1&source=PackSourceEnum_PUBLISH"
],
"width": 1870,
"height": 1052,
"url_key": "v0300fg10000cnpel5bc77u9pqctt5hg_h264_1080p_2690491",
"data_size": 2467517,
"file_hash": "c689ddfb4d16aec5ae605822e5b2c4f6",
"file_cs": "c:0-7442-daae|d:0-1233757-8a1a,1233758-2467516-f27e|a:v0300fg10000cnpel5bc77u9pqctt5hg"
},
"cover": {
"uri": "tos-cn-i-0813/owgAVhXilAAZ6yTAAzCsDnqefAVEDIN9qALqyg",
"url_list": ["Ig9gQdI0FjieZ_SnquVR-.png"],
"width": 720,
"height": 720
},
"height": 1052,
"width": 1870,
"ratio": "1080p",
"use_static_cover": true,
"duration": 7337,
"horizontal_type": 1
},
"share_url": "https://www.iesdouyin.com/share/video/7346191904205327631/?region=CN&mid=7346191940615932722&u_code=13kgm680k&did=MS4wLjABAAAAiOgYyZm8XbWZMr5o3OvhR-TEOuNygb_hQOwkie-VXJpDYaR4vZfpiIGBfAWKCFHB&iid=MS4wLjABAAAANwkJuWIRFOzg5uCpDRpMj4OX-QryoDgn-yYlXQnRwQQ&with_sec_did=1&titleType=title&share_sign=GBtbcDEKOakwrzsCjMztEGgSeaHW_xrERQNESLGFXFw-&share_version=170400&ts=1710489511&from_aid=6383&from_ssr=1",
"statistics": {
"admire_count": 1,
"comment_count": 602,
"digg_count": 17913,
"collect_count": 2393,
"play_count": 0,
"share_count": 13227
},
"status": {
"listen_video_status": 0,
"is_delete": false,
"allow_share": true,
"is_prohibited": false,
"in_reviewing": false,
"part_see": 0,
"private_status": 0,
"review_result": {
"review_status": 0
}
},
"text_extra": [],
"is_top": 0,
"share_info": {
"share_url": "https://www.iesdouyin.com/share/video/7346191904205327631/?region=CN&mid=7346191940615932722&u_code=13kgm680k&did=MS4wLjABAAAAiOgYyZm8XbWZMr5o3OvhR-TEOuNygb_hQOwkie-VXJpDYaR4vZfpiIGBfAWKCFHB&iid=MS4wLjABAAAANwkJuWIRFOzg5uCpDRpMj4OX-QryoDgn-yYlXQnRwQQ&with_sec_did=1&titleType=title&share_sign=GBtbcDEKOakwrzsCjMztEGgSeaHW_xrERQNESLGFXFw-&share_version=170400&ts=1710489511&from_aid=6383&from_ssr=1",
"share_link_desc": "2.89 G@V.LW mDU:/ 11/22 我的女友 %s 复制此链接打开Dou音搜索直接观看视频"
},
"duration": 7337,
"image_infos": null,
"risk_infos": {
"vote": false,
"warn": false,
"risk_sink": false,
"type": 0,
"content": ""
},
"position": null,
"author_user_id": 83160533866,
"prevent_download": false,
"long_video": null,
"aweme_control": {
"can_forward": true,
"can_share": true,
"can_comment": true,
"can_show_comment": true
},
"images": null,
"suggest_words": {
"suggest_words": [
{
"words": [
{
"word": "条子被黑社会堵到超市后续",
"word_id": "7129083023886554400",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "comment_top_rec",
"icon_url": "",
"hint_text": "大家都在搜:",
"extra_info": "{}"
},
{
"words": [
{
"word": "埃安y plus70乐享版",
"word_id": "7147998601692026127",
"info": "{\"qrec_for_search\":\"{\\\"query_ecom\\\":\\\"1\\\"}\"}"
}
],
"scene": "feed_bottom_rec",
"icon_url": "",
"hint_text": "相关搜索",
"extra_info": "{}"
},
{
"words": [
{
"word": "条子被黑社会堵到超市后续",
"word_id": "7129083023886554400",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "detail_inbox_rex",
"icon_url": "",
"hint_text": "",
"extra_info": "{}"
}
]
}
},
{ {
"aweme_id": "7345439525113433384", "aweme_id": "7345439525113433384",
"desc": "", "desc": "",

View File

@ -455,160 +455,6 @@
] ]
} }
}, },
{
"aweme_id": "7346457849054235913",
"desc": "#小蛮腰马甲线 他居然把脸转过去",
"create_time": 1710480523,
"music": {
"id": 7346457898803154000,
"title": "@奶茶妹◕🌱创作的原声",
"author": "奶茶妹◕🌱",
"cover_medium": {
"uri": "720x720/aweme-avatar/tos-cn-avt-0015_c7784af3a0bd2e7c5fc92ece450f12e0",
"url_list": [
"https://p3-pc.douyinpic.com/aweme/720x720/aweme-avatar/tos-cn-avt-0015_c7784af3a0bd2e7c5fc92ece450f12e0.jpeg?from=116350172"
],
"width": 720,
"height": 720
},
"cover_thumb": {
"uri": "100x100/aweme-avatar/tos-cn-avt-0015_c7784af3a0bd2e7c5fc92ece450f12e0",
"url_list": [
"https://p3-pc.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-avt-0015_c7784af3a0bd2e7c5fc92ece450f12e0.jpeg?from=116350172"
],
"width": 720,
"height": 720
},
"play_url": {
"uri": "https://sf5-hl-cdn-tos.douyinstatic.com/obj/ies-music/7346457902686882570.mp3",
"url_list": [
"https://sf5-hl-cdn-tos.douyinstatic.com/obj/ies-music/7346457902686882570.mp3",
"https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/7346457902686882570.mp3"
],
"width": 720,
"height": 720,
"url_key": "7346457898803153673"
},
"duration": 11,
"user_count": 0,
"owner_id": "62790495105",
"owner_nickname": "奶茶妹◕🌱",
"is_original": false
},
"video": {
"play_addr": {
"uri": "v0d00fg10000cnptoirc77u3atmcsskg",
"url_list": [
"https://www.douyin.com/aweme/v1/play/?video_id=v0d00fg10000cnptoirc77u3atmcsskg&line=0&file_id=3b2bcdfe44f0468aacc265bb778c2e2c&sign=fccec71c7a910d752161cb82b89c8474&is_play_url=1&source=PackSourceEnum_PUBLISH"
],
"width": 1080,
"height": 1920,
"url_key": "v0d00fg10000cnptoirc77u3atmcsskg_h264_1080p_2062873",
"data_size": 3017468,
"file_hash": "fccec71c7a910d752161cb82b89c8474",
"file_cs": "c:0-10842-2631|d:0-1508733-7add,1508734-3017467-357f|a:v0d00fg10000cnptoirc77u3atmcsskg"
},
"cover": {
"uri": "tos-cn-i-0813c001/oIzsg8zAAIlAfDH5ANtC9BE6IANk3eAyAhAn0E",
"url_list": ["R3o8KAoPnLSiZLkSs66H3.png"],
"width": 720,
"height": 720
},
"height": 1920,
"width": 1080,
"ratio": "1080p",
"use_static_cover": true,
"duration": 11702
},
"share_url": "https://www.iesdouyin.com/share/video/7346457849054235913/?region=CN&mid=7346457898803153673&u_code=13kgm680k&did=MS4wLjABAAAAiOgYyZm8XbWZMr5o3OvhR-TEOuNygb_hQOwkie-VXJpDYaR4vZfpiIGBfAWKCFHB&iid=MS4wLjABAAAANwkJuWIRFOzg5uCpDRpMj4OX-QryoDgn-yYlXQnRwQQ&with_sec_did=1&titleType=title&share_sign=KmI.XiEwwiCE.iLBUp3QNtoJoUyXFirMExGYSa9SBI8-&share_version=170400&ts=1710488702&from_aid=6383&from_ssr=1",
"statistics": {
"admire_count": 0,
"comment_count": 20,
"digg_count": 1572,
"collect_count": 137,
"play_count": 0,
"share_count": 112
},
"status": {
"listen_video_status": 0,
"is_delete": false,
"allow_share": true,
"is_prohibited": false,
"in_reviewing": false,
"part_see": 0,
"private_status": 0,
"review_result": {
"review_status": 0
}
},
"text_extra": [
{
"start": 0,
"end": 7,
"type": 1,
"hashtag_name": "小蛮腰马甲线",
"hashtag_id": "1622790756032686",
"is_commerce": false,
"caption_start": 0,
"caption_end": 7
}
],
"is_top": 0,
"share_info": {
"share_url": "https://www.iesdouyin.com/share/video/7346457849054235913/?region=CN&mid=7346457898803153673&u_code=13kgm680k&did=MS4wLjABAAAAiOgYyZm8XbWZMr5o3OvhR-TEOuNygb_hQOwkie-VXJpDYaR4vZfpiIGBfAWKCFHB&iid=MS4wLjABAAAANwkJuWIRFOzg5uCpDRpMj4OX-QryoDgn-yYlXQnRwQQ&with_sec_did=1&titleType=title&share_sign=KmI.XiEwwiCE.iLBUp3QNtoJoUyXFirMExGYSa9SBI8-&share_version=170400&ts=1710488702&from_aid=6383&from_ssr=1",
"share_link_desc": "8.99 09/14 P@X.MJ dAT:/ # 小蛮腰马甲线 他居然把脸转过去 %s 复制此链接打开Dou音搜索直接观看视频"
},
"duration": 11702,
"image_infos": null,
"risk_infos": {
"vote": false,
"warn": false,
"risk_sink": false,
"type": 0,
"content": ""
},
"position": null,
"author_user_id": 62790495105,
"prevent_download": false,
"long_video": null,
"aweme_control": {
"can_forward": true,
"can_share": true,
"can_comment": true,
"can_show_comment": true
},
"images": null,
"suggest_words": {
"suggest_words": [
{
"words": [
{
"word": "章若楠",
"word_id": "6585508016810890499",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "comment_top_rec",
"icon_url": "",
"hint_text": "大家都在搜:",
"extra_info": "{}"
},
{
"words": [
{
"word": "章若楠",
"word_id": "6585508016810890499",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "detail_inbox_rex",
"icon_url": "",
"hint_text": "",
"extra_info": "{}"
}
]
}
},
{ {
"aweme_id": "7346190579807702310", "aweme_id": "7346190579807702310",
"desc": "#背影杀 哈~", "desc": "#背影杀 哈~",

View File

@ -449,184 +449,6 @@
] ]
} }
}, },
{
"aweme_id": "7345796955571784997",
"desc": "体验调酒师的一天🍸 Bartender\n#微醺时刻 #记录生活",
"create_time": 1710326646,
"music": {
"id": 7023044224681511000,
"title": "Starboy (抖音热播)",
"author": "佐助",
"cover_medium": {
"uri": "tos-cn-v-2774c002/b3583f56f54e4451b7d301187585bcdb",
"url_list": [
"https://p11.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/b3583f56f54e4451b7d301187585bcdb.jpeg",
"https://p3.douyinpic.com/aweme/200x200/tos-cn-v-2774c002/b3583f56f54e4451b7d301187585bcdb.jpeg"
],
"width": 720,
"height": 720
},
"cover_thumb": {
"uri": "tos-cn-v-2774c002/b3583f56f54e4451b7d301187585bcdb",
"url_list": [
"https://p11.douyinpic.com/aweme/100x100/tos-cn-v-2774c002/b3583f56f54e4451b7d301187585bcdb.jpeg",
"https://p3.douyinpic.com/aweme/100x100/tos-cn-v-2774c002/b3583f56f54e4451b7d301187585bcdb.jpeg"
],
"width": 720,
"height": 720
},
"play_url": {
"uri": "https://sf5-hl-cdn-tos.douyinstatic.com/obj/tos-cn-ve-2774/ogjEQCutCnDe2gAG2KGBb8ieUACWSoFhZRgMQg",
"url_list": [
"https://sf5-hl-cdn-tos.douyinstatic.com/obj/tos-cn-ve-2774/ogjEQCutCnDe2gAG2KGBb8ieUACWSoFhZRgMQg",
"https://sf3-cdn-tos.douyinstatic.com/obj/tos-cn-ve-2774/ogjEQCutCnDe2gAG2KGBb8ieUACWSoFhZRgMQg"
],
"width": 720,
"height": 720,
"url_key": "7023044224681510949"
},
"duration": 194,
"user_count": 0,
"owner_nickname": "",
"is_original": false
},
"video": {
"play_addr": {
"uri": "v0d00fg10000cnoo6mjc77ubta3125dg",
"url_list": [
"https://www.douyin.com/aweme/v1/play/?video_id=v0d00fg10000cnoo6mjc77ubta3125dg&line=0&file_id=b4fc9157732e4eee81b0d3d071b4d32f&sign=8057edcee0fd27ffce9615b1048d2e2c&is_play_url=1&source=PackSourceEnum_PUBLISH"
],
"width": 1080,
"height": 1920,
"url_key": "v0d00fg10000cnoo6mjc77ubta3125dg_h264_1080p_2264177",
"data_size": 5443649,
"file_hash": "8057edcee0fd27ffce9615b1048d2e2c",
"file_cs": "c:0-17318-d0c8|d:0-2721823-7d6d,2721824-5443648-e625|a:v0d00fg10000cnoo6mjc77ubta3125dg"
},
"cover": {
"uri": "tos-cn-i-0813c001/oo3M3ze0IAN67MAAJAghvhGARED9gAfElxC0BN",
"url_list": ["2ww4W1Pu86xeLjl07K28u.png"],
"width": 720,
"height": 720
},
"height": 1920,
"width": 1080,
"ratio": "1080p",
"use_static_cover": true,
"duration": 19234
},
"share_url": "https://www.iesdouyin.com/share/video/7345796955571784997/?region=CN&mid=7023044224681510949&u_code=13kgm680k&did=MS4wLjABAAAAiOgYyZm8XbWZMr5o3OvhR-TEOuNygb_hQOwkie-VXJpDYaR4vZfpiIGBfAWKCFHB&iid=MS4wLjABAAAANwkJuWIRFOzg5uCpDRpMj4OX-QryoDgn-yYlXQnRwQQ&with_sec_did=1&titleType=title&share_sign=XUuhtQ9LwR_2_xNHoNSw2nfWpq_SiDhebnwzUPGq.Yw-&share_version=170400&ts=1710491939&from_aid=6383&from_ssr=1",
"statistics": {
"admire_count": 59,
"comment_count": 1644,
"digg_count": 256919,
"collect_count": 5279,
"play_count": 0,
"share_count": 8961
},
"status": {
"listen_video_status": 0,
"is_delete": false,
"allow_share": true,
"is_prohibited": false,
"in_reviewing": false,
"part_see": 0,
"private_status": 0,
"review_result": {
"review_status": 0
}
},
"text_extra": [
{
"start": 21,
"end": 26,
"type": 1,
"hashtag_name": "微醺时刻",
"hashtag_id": "1647996185380875",
"is_commerce": false,
"caption_start": 21,
"caption_end": 26
},
{
"start": 27,
"end": 32,
"type": 1,
"hashtag_name": "记录生活",
"hashtag_id": "1767586437643341",
"is_commerce": false,
"caption_start": 27,
"caption_end": 32
}
],
"is_top": 0,
"share_info": {
"share_url": "https://www.iesdouyin.com/share/video/7345796955571784997/?region=CN&mid=7023044224681510949&u_code=13kgm680k&did=MS4wLjABAAAAiOgYyZm8XbWZMr5o3OvhR-TEOuNygb_hQOwkie-VXJpDYaR4vZfpiIGBfAWKCFHB&iid=MS4wLjABAAAANwkJuWIRFOzg5uCpDRpMj4OX-QryoDgn-yYlXQnRwQQ&with_sec_did=1&titleType=title&share_sign=XUuhtQ9LwR_2_xNHoNSw2nfWpq_SiDhebnwzUPGq.Yw-&share_version=170400&ts=1710491939&from_aid=6383&from_ssr=1",
"share_link_desc": "5.10 02/04 z@t.eo GvF:/ 体验调酒师的一天🍸 Bartender # 微醺时刻 # 记录生活 %s 复制此链接打开Dou音搜索直接观看视频"
},
"duration": 19234,
"image_infos": null,
"risk_infos": {
"vote": false,
"warn": false,
"risk_sink": false,
"type": 0,
"content": ""
},
"position": null,
"author_user_id": 24058267831,
"prevent_download": false,
"long_video": null,
"aweme_control": {
"can_forward": true,
"can_share": true,
"can_comment": true,
"can_show_comment": true
},
"images": null,
"suggest_words": {
"suggest_words": [
{
"words": [
{
"word": "冰淇淋kiki",
"word_id": "6732949666079446276",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "comment_top_rec",
"icon_url": "",
"hint_text": "大家都在搜:",
"extra_info": "{}"
},
{
"words": [
{
"word": "调酒师工资一般是多少",
"word_id": "6572390336566400259",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "feed_bottom_rec",
"icon_url": "",
"hint_text": "相关搜索",
"extra_info": "{}"
},
{
"words": [
{
"word": "冰淇淋kiki",
"word_id": "6732949666079446276",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "detail_inbox_rex",
"icon_url": "",
"hint_text": "",
"extra_info": "{}"
}
]
}
},
{ {
"aweme_id": "7345057414233836850", "aweme_id": "7345057414233836850",
"desc": "开在酒瓶里的春天呀🌷🌸", "desc": "开在酒瓶里的春天呀🌷🌸",

View File

@ -425,149 +425,6 @@
] ]
} }
}, },
{
"aweme_id": "7338089394705894682",
"desc": "陈年老库存🐿️",
"create_time": 1708532099,
"music": {
"id": 7338089490520509000,
"title": "@周子然JingYi创作的原声",
"author": "周子然JingYi",
"cover_medium": {
"uri": "720x720/aweme-avatar/tos-cn-avt-0015_f59bfced5c6a3b56d152f1e0437f06ec",
"url_list": [
"https://p3-pc.douyinpic.com/aweme/720x720/aweme-avatar/tos-cn-avt-0015_f59bfced5c6a3b56d152f1e0437f06ec.jpeg?from=116350172"
],
"width": 720,
"height": 720
},
"cover_thumb": {
"uri": "100x100/aweme-avatar/tos-cn-avt-0015_f59bfced5c6a3b56d152f1e0437f06ec",
"url_list": [
"https://p3-pc.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-avt-0015_f59bfced5c6a3b56d152f1e0437f06ec.jpeg?from=116350172"
],
"width": 720,
"height": 720
},
"play_url": {
"uri": "https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/7338089476511550234.mp3",
"url_list": [
"https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/7338089476511550234.mp3",
"https://sf5-hl-cdn-tos.douyinstatic.com/obj/ies-music/7338089476511550234.mp3"
],
"width": 720,
"height": 720,
"url_key": "7338089490520509235"
},
"duration": 9,
"user_count": 0,
"owner_id": "62839305427",
"owner_nickname": "周子然JingYi",
"is_original": false
},
"video": {
"play_addr": {
"uri": "v0300fg10000cnb217rc77uah3ri5o00",
"url_list": [
"https://www.douyin.com/aweme/v1/play/?video_id=v0300fg10000cnb217rc77uah3ri5o00&line=0&file_id=d0de6a0d7fc0498a812e8527e94a887a&sign=ab93708a219baa2ffde338e8bf652e0d&is_play_url=1&source=PackSourceEnum_PUBLISH"
],
"width": 1080,
"height": 1920,
"url_key": "v0300fg10000cnb217rc77uah3ri5o00_h264_1080p_2556391",
"data_size": 3078535,
"file_hash": "ab93708a219baa2ffde338e8bf652e0d",
"file_cs": "c:0-9310-07ec|d:0-1539266-16e6,1539267-3078534-e6cd|a:v0300fg10000cnb217rc77uah3ri5o00"
},
"cover": {
"uri": "tos-cn-i-0813c001/oAiCAVAbDWOleAAIEGYb9IengDrADCAjAW1pIA",
"url_list": ["7SFxN5HcILUxUdJe-EXfX.png"],
"width": 720,
"height": 720
},
"height": 3840,
"width": 2160,
"ratio": "1080p",
"use_static_cover": true,
"duration": 9634
},
"share_url": "https://www.iesdouyin.com/share/video/7338089394705894682/?region=CN&mid=7338089490520509235&u_code=13kgm680k&did=MS4wLjABAAAAiOgYyZm8XbWZMr5o3OvhR-TEOuNygb_hQOwkie-VXJpDYaR4vZfpiIGBfAWKCFHB&iid=MS4wLjABAAAANwkJuWIRFOzg5uCpDRpMj4OX-QryoDgn-yYlXQnRwQQ&with_sec_did=1&titleType=title&share_sign=ig8SDm7Oq1NBxQweWS4eMzrdjlHmjkr7WIazmFWKoZY-&share_version=170400&ts=1710490324&from_aid=6383&from_ssr=1",
"statistics": {
"admire_count": 2,
"comment_count": 149,
"digg_count": 6367,
"collect_count": 635,
"play_count": 0,
"share_count": 784
},
"status": {
"listen_video_status": 0,
"is_delete": false,
"allow_share": true,
"is_prohibited": false,
"in_reviewing": false,
"part_see": 0,
"private_status": 0,
"review_result": {
"review_status": 0
}
},
"text_extra": [],
"is_top": 0,
"share_info": {
"share_url": "https://www.iesdouyin.com/share/video/7338089394705894682/?region=CN&mid=7338089490520509235&u_code=13kgm680k&did=MS4wLjABAAAAiOgYyZm8XbWZMr5o3OvhR-TEOuNygb_hQOwkie-VXJpDYaR4vZfpiIGBfAWKCFHB&iid=MS4wLjABAAAANwkJuWIRFOzg5uCpDRpMj4OX-QryoDgn-yYlXQnRwQQ&with_sec_did=1&titleType=title&share_sign=ig8SDm7Oq1NBxQweWS4eMzrdjlHmjkr7WIazmFWKoZY-&share_version=170400&ts=1710490324&from_aid=6383&from_ssr=1",
"share_link_desc": "3.07 CUL:/ 05/15 n@Q.kp 陈年老库存🐿️ %s 复制此链接打开Dou音搜索直接观看视频"
},
"duration": 9634,
"image_infos": null,
"risk_infos": {
"vote": false,
"warn": false,
"risk_sink": false,
"type": 0,
"content": ""
},
"position": null,
"author_user_id": 62839305427,
"prevent_download": false,
"long_video": null,
"aweme_control": {
"can_forward": true,
"can_share": true,
"can_comment": true,
"can_show_comment": true
},
"images": null,
"suggest_words": {
"suggest_words": [
{
"words": [
{
"word": "周子然早期照片",
"word_id": "6900178207296673032",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "comment_top_rec",
"icon_url": "",
"hint_text": "大家都在搜:",
"extra_info": "{}"
},
{
"words": [
{
"word": "我有个朋友周子然",
"word_id": "6925278082983957772",
"info": "{\"qrec_for_search\":\"{}\"}"
}
],
"scene": "detail_inbox_rex",
"icon_url": "",
"hint_text": "",
"extra_info": "{}"
}
]
}
},
{ {
"aweme_id": "7322483619946040585", "aweme_id": "7322483619946040585",
"desc": "🍦。我是难伺候的小雪糕\n没有礼貌随时在考虑化掉", "desc": "🍦。我是难伺候的小雪糕\n没有礼貌随时在考虑化掉",

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,14 @@
<template> <template>
<img class="close" ref="img" :src="src" /> <img class="close" ref="imgEl" :src="src" />
</template> </template>
<script> <script setup lang="ts">
import { _css } from '@/utils/dom' import { _css } from '@/utils/dom'
import { onMounted } from 'vue'
export default { defineOptions({
name: 'Back', name: 'Back'
props: { })
const props = defineProps({
mode: { mode: {
type: String, type: String,
default: 'gray' default: 'gray'
@ -23,25 +25,21 @@ export default {
type: [Number, String], type: [Number, String],
default: 1 default: 1
} }
}, })
data() {
return {} const imgEl = $ref()
}, const src = $computed(() => {
computed: { return new URL(`../assets/img/icon/components/${props.mode}-${props.img}.png`, import.meta.url)
src() {
return new URL(`../assets/img/icon/components/${this.mode}-${this.img}.png`, import.meta.url)
.href .href
} })
},
mounted() { onMounted(() => {
_css( _css(
this.$refs.img, imgEl,
'transform', 'transform',
`rotate(${this.direction === 'left' ? '0' : '180'}deg) scale(${this.scale})` `rotate(${props.direction === 'left' ? '0' : '180'}deg) scale(${props.scale})`
) )
}, })
methods: {}
}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

View File

@ -1,36 +1,50 @@
<template> <template>
<div class="music-wrapper"> <div class="music-wrapper">
<div
class="mute-icon"
:class="showMutedNotice && 'notice'"
v-click="() => bus.emit(EVENT_KEY.REMOVE_MUTED)"
v-if="isMuted"
>
<div class="wrap">
<Icon icon="flowbite:volume-mute-solid" />
<span :style="{ opacity: showMutedNotice ? 1 : 0 }">取消静音</span>
</div>
</div>
<img <img
class="music" class="music"
:src="props.item.music?.cover_thumb.url_list[0]" :src="item.music?.cover_thumb.url_list[0]"
:style="style" :style="style"
@click.stop=" v-click="
() =>
bus.emit(EVENT_KEY.NAV, { bus.emit(EVENT_KEY.NAV, {
path: '/home/music', path: '/home/music',
query: { id: props.item.id } query: { id: item.aweme_id }
}) })
" "
/> />
</div> </div>
</template> </template>
<script setup> <script setup lang="ts">
import { computed, inject } from 'vue' import { inject, onMounted } from 'vue'
import bus, { EVENT_KEY } from '@/utils/bus' import bus, { EVENT_KEY } from '@/utils/bus'
import { Icon } from '@iconify/vue'
import { useClick } from '@/utils/hooks/useClick'
const props = defineProps({ const isPlaying = inject<boolean>('isPlaying')
item: { const isMuted = inject('isMuted')
type: Object, const item = inject<any>('item')
default: () => { const vClick = useClick()
return {} let showMutedNotice = $ref(window.showMutedNotice)
}
}
})
const isPlaying = inject('isPlaying') const style = $computed(() => {
const style = computed(() => {
return { webkitAnimationPlayState: isPlaying.value ? 'running' : 'paused' } return { webkitAnimationPlayState: isPlaying.value ? 'running' : 'paused' }
}) })
onMounted(() => {
bus.on(EVENT_KEY.HIDE_MUTED_NOTICE, () => {
showMutedNotice = false
})
})
</script> </script>
<style lang="less"> <style lang="less">
@ -38,11 +52,14 @@ const style = computed(() => {
display: flex; display: flex;
justify-content: center; justify-content: center;
@w: 45rem; @w: 45rem;
width: @w;
height: @w;
position: relative;
.music { .music {
border-radius: 50%; border-radius: 50%;
width: @w; width: 100%;
height: @w; height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -59,5 +76,43 @@ const style = computed(() => {
transform: rotate(360deg); transform: rotate(360deg);
} }
} }
.mute-icon {
.music;
cursor: pointer;
position: absolute;
z-index: 1;
right: 0;
background: white;
animation: unset;
color: black;
transition: all 0.5s;
overflow: hidden;
.wrap {
width: 100rem;
position: absolute;
left: 0;
display: flex;
align-items: center;
justify-content: center;
}
&.notice {
border-radius: 50rem;
width: 100rem;
}
svg {
font-size: 22rem;
}
span {
margin-left: 5rem;
font-size: 13rem;
word-break: keep-all;
transition: all 0.5s;
}
}
} }
</style> </style>

View File

@ -1,11 +1,11 @@
<template> <template>
<div <div
class="call-float" class="call-float"
v-if="isSmall" v-if="state.isSmall"
:style="callFloatStyle" :style="callFloatStyle"
@touchmove="touchmove" @touchmove="touchmove"
@touchend="touchend" @touchend="touchend"
@click="isSmall = false" @click="state.isSmall = false"
> >
<img src="@/assets/img/icon/message/chat/call-float.png" alt="" /> <img src="@/assets/img/icon/message/chat/call-float.png" alt="" />
<span>呼叫中</span> <span>呼叫中</span>
@ -14,79 +14,91 @@
<transition name="scale"> <transition name="scale">
<div <div
class="audio-call" class="audio-call"
:style="isSmall ? callFloatStyle : { zIndex: 10 }" :style="state.isSmall ? callFloatStyle : { zIndex: 10 }"
:class="isSmall ? 'small' : ''" :class="state.isSmall ? 'small' : ''"
v-if="isShowAudioCall" v-if="state.isShowAudioCall"
> >
<div class="float"> <div class="float">
<div class="header"> <div class="header">
<div class="left"> <div class="left">
<img @click="isSmall = true" src="@/assets/img/icon/message/chat/narrow.png" alt="" /> <img
@click="state.isSmall = true"
src="@/assets/img/icon/message/chat/narrow.png"
alt=""
/>
</div> </div>
<span class="center">等待对方接听...</span> <span class="center">等待对方接听...</span>
<div class="right"> <div class="right">
<div class="option"> <div class="option">
<img <img
v-show="!isOpenCamera" v-show="!state.isOpenCamera"
@click="isOpenCamera = !isOpenCamera" @click="state.isOpenCamera = !state.isOpenCamera"
src="@/assets/img/icon/message/chat/disabled-camera.png" src="@/assets/img/icon/message/chat/disabled-camera.png"
alt="" alt=""
/> />
<img <img
v-show="isOpenCamera" v-show="state.isOpenCamera"
@click="isOpenCamera = !isOpenCamera" @click="state.isOpenCamera = !state.isOpenCamera"
src="@/assets/img/icon/message/chat/able-camera.png" src="@/assets/img/icon/message/chat/able-camera.png"
alt="" alt=""
/> />
<span>摄像头</span> <span>摄像头</span>
</div> </div>
<div class="option" v-if="isExpand"> <div class="option" v-if="state.isExpand">
<img <img
v-show="!isOpenAudio" v-show="!state.isOpenAudio"
@click="isOpenAudio = !isOpenAudio" @click="state.isOpenAudio = !state.isOpenAudio"
src="@/assets/img/icon/message/chat/disabled-volume.png" src="@/assets/img/icon/message/chat/disabled-volume.png"
alt="" alt=""
/> />
<img <img
v-show="isOpenAudio" v-show="state.isOpenAudio"
@click="isOpenAudio = !isOpenAudio" @click="state.isOpenAudio = !state.isOpenAudio"
src="@/assets/img/icon/message/chat/able-volume.png" src="@/assets/img/icon/message/chat/able-volume.png"
alt="" alt=""
/> />
<span>免提</span> <span>免提</span>
</div> </div>
<div class="option"> <div class="option">
<dy-back mode="light" @click="isExpand = !isExpand" img="back" class="shrink" /> <dy-back
mode="light"
@click="state.isExpand = !state.isExpand"
img="back"
class="shrink"
/>
<!-- <img src="@/assets/img/icon/message/chat/narrow.png" alt="">--> <!-- <img src="@/assets/img/icon/message/chat/narrow.png" alt="">-->
</div> </div>
</div> </div>
</div> </div>
<img src="@/assets/img/icon/avatar/2.png" alt="" class="big-avatar" /> <img src="@/assets/img/icon/avatar/2.png" alt="" class="big-avatar" />
<div class="footer"> <div class="footer">
<img @click="isShowAudioCall = false" src="@/assets/img/icon/message/chat/call-end.png" /> <img
@click="state.isShowAudioCall = false"
src="@/assets/img/icon/message/chat/call-end.png"
/>
<span>挂断</span> <span>挂断</span>
</div> </div>
</div> </div>
</div> </div>
</transition> </transition>
</template> </template>
<script> <script setup lang="ts">
import { inject } from 'vue' import { onMounted, reactive, watch } from 'vue'
import bus, { EVENT_KEY } from '@/utils/bus'
export default { defineOptions({
name: 'Call', name: 'Call'
components: {}, })
props: { defineProps({
modelValue: { modelValue: {
type: Boolean, type: Boolean,
default() { default() {
return false return false
} }
} }
}, })
data() {
return { const state = reactive({
mitt: inject('mitt'),
callFloatTransitionTime: 300, callFloatTransitionTime: 300,
callFloatLeft: 15, callFloatLeft: 15,
callFloatTop: 100, callFloatTop: 100,
@ -97,51 +109,50 @@ export default {
isShowAudioCall: false, isShowAudioCall: false,
height: 0, height: 0,
width: 0 width: 0
} })
},
computed: { const callFloatStyle = $computed(() => {
callFloatStyle() {
return { return {
'transition-duration': this.callFloatTransitionTime + 'ms', 'transition-duration': state.callFloatTransitionTime + 'ms',
left: this.callFloatLeft + 'px', left: state.callFloatLeft + 'px',
top: this.callFloatTop + 'px' top: state.callFloatTop + 'px'
} }
} })
},
watch: { watch(
isShowAudioCall(newVal) { () => state.isShowAudioCall,
(newVal) => {
if (!newVal) { if (!newVal) {
this.isOpenCamera = false state.isOpenCamera = false
this.isOpenAudio = true state.isOpenAudio = true
} }
} }
}, )
created() {},
methods: { onMounted(() => {
touchmove(e) { bus.on(EVENT_KEY.SHOW_AUDIO_CALL, () => {
this.callFloatTransitionTime = 0 if (state.isShowAudioCall) {
this.callFloatLeft = e.touches[0].pageX - 35 state.isSmall = false
this.callFloatTop = e.touches[0].pageY - 40
},
touchend() {
this.callFloatTransitionTime = 300
if (this.callFloatLeft < this.width / 2) {
this.callFloatLeft = 15
} else { } else {
this.callFloatLeft = this.width - 15 - 70 state.isShowAudioCall = true
}
}
},
mounted() {
this.mitt.on('showAudioCall', () => {
if (this.isShowAudioCall) {
this.isSmall = false
} else {
this.isShowAudioCall = true
} }
}) })
this.height = document.body.clientHeight state.height = document.body.clientHeight
this.width = document.body.clientWidth state.width = document.body.clientWidth
})
function touchmove(e) {
state.callFloatTransitionTime = 0
state.callFloatLeft = e.touches[0].pageX - 35
state.callFloatTop = e.touches[0].pageY - 40
}
function touchend() {
state.callFloatTransitionTime = 300
if (state.callFloatLeft < state.width / 2) {
state.callFloatLeft = 15
} else {
state.callFloatLeft = state.width - 15 - 70
} }
} }
</script> </script>

View File

@ -35,7 +35,7 @@
src="../assets/img/icon/components/check/check-red-share.png" src="../assets/img/icon/components/check/check-red-share.png"
/> />
</div> </div>
<div class="option" @click.stop="closeShare($nav('/message/share-to-friend'))"> <div class="option" @click.stop="closeShare($router.push('/message/share-to-friend'))">
<dy-back class="more" mode="light" direction="right"></dy-back> <dy-back class="more" mode="light" direction="right"></dy-back>
<span>更多朋友</span> <span>更多朋友</span>
</div> </div>
@ -62,7 +62,7 @@
<img class="small" src="../assets/img/icon/components/video/dou.webp" alt="" /> <img class="small" src="../assets/img/icon/components/video/dou.webp" alt="" />
<span>帮上热门</span> <span>帮上热门</span>
</div> </div>
<div class="option" @click.stop="$nav('/home/report', { mode: this.mode })"> <div class="option" @click.stop="$router.push('/home/report', { mode: this.mode })">
<img class="small" src="../assets/img/icon/components/video/warring.png" alt="" /> <img class="small" src="../assets/img/icon/components/video/warring.png" alt="" />
<span>举报</span> <span>举报</span>
</div> </div>
@ -105,7 +105,7 @@
<img class="small" src="../assets/img/icon/components/video/tofriend.webp" alt="" /> <img class="small" src="../assets/img/icon/components/video/tofriend.webp" alt="" />
<span>私信朋友</span> <span>私信朋友</span>
</div> </div>
<div class="option" @click.stop="$nav('/home/report', { mode: this.mode })"> <div class="option" @click.stop="$router.push('/home/report', { mode: this.mode })">
<img class="small" src="../assets/img/icon/components/video/warring.png" alt="" /> <img class="small" src="../assets/img/icon/components/video/warring.png" alt="" />
<span>举报音乐</span> <span>举报音乐</span>
</div> </div>

View File

@ -1,13 +1,13 @@
<template> <template>
<div class="video-wrapper" ref="videoWrapper" :class="positionName"> <div class="video-wrapper" ref="videoWrapper" :class="positionName">
<Loading v-if="loading" style="position: absolute" /> <Loading v-if="state.loading" style="position: absolute" />
<!-- <video :src="item.video + '?v=123'"--> <!-- <video :src="item.video + '?v=123'"-->
<video <video
:src="item.video.play_addr.url_list[0]" :src="item.video.play_addr.url_list[0]"
:poster="poster" :poster="poster"
ref="video" ref="videoEl"
muted :muted="state.isMuted"
preload preload="true"
loop loop
x5-video-player-type="h5-page" x5-video-player-type="h5-page"
:x5-video-player-fullscreen="false" :x5-video-player-fullscreen="false"
@ -23,13 +23,13 @@
<div class="float"> <div class="float">
<template v-if="isLive"> <template v-if="isLive">
<div class="living">点击进入直播间</div> <div class="living">点击进入直播间</div>
<ItemDesc :is-live="true" v-model:item="localItem" :position="position" /> <ItemDesc :is-live="true" v-model:item="state.localItem" :position="position" />
</template> </template>
<template v-else> <template v-else>
<div :style="{ opacity: isMove ? 0 : 1 }" class="normal"> <div :style="{ opacity: state.isMove ? 0 : 1 }" class="normal">
<template v-if="!commentVisible"> <template v-if="!state.commentVisible">
<ItemToolbar v-model:item="localItem" :position="position" v-bind="$attrs" /> <ItemToolbar v-model:item="state.localItem" />
<ItemDesc v-model:item="localItem" :position="position" /> <ItemDesc v-model:item="state.localItem" />
</template> </template>
<div v-if="isMy" class="comment-status"> <div v-if="isMy" class="comment-status">
<div class="comment"> <div class="comment">
@ -44,7 +44,7 @@
</div> </div>
</div> </div>
<transition-group name="comment-status" tag="div" class="loveds"> <transition-group name="comment-status" tag="div" class="loveds">
<div class="type-loved" :key="i" v-for="i in test"> <div class="type-loved" :key="i" v-for="i in state.test">
<img src="../../assets/img/icon/head-image.jpeg" alt="" class="avatar" /> <img src="../../assets/img/icon/head-image.jpeg" alt="" class="avatar" />
<img src="../../assets/img/icon/love.svg" alt="" class="loved" /> <img src="../../assets/img/icon/love.svg" alt="" class="loved" />
</div> </div>
@ -55,17 +55,17 @@
<div <div
class="progress" class="progress"
:class="progressClass" :class="progressClass"
ref="progress" ref="progressEl"
@click="null" @click="null"
@touchstart="touchstart" @touchstart="touchstart"
@touchmove="touchmove" @touchmove="touchmove"
@touchend="touchend" @touchend="touchend"
> >
<div class="time" v-if="isMove"> <div class="time" v-if="state.isMove">
<span class="currentTime">{{ _duration(currentTime) }}</span> <span class="currentTime">{{ _duration(state.currentTime) }}</span>
<span class="duration"> / {{ _duration(duration) }}</span> <span class="duration"> / {{ _duration(state.duration) }}</span>
</div> </div>
<template v-if="duration > 15 || isMove || !isPlaying"> <template v-if="state.duration > 15 || state.isMove || !isPlaying">
<div class="bg"></div> <div class="bg"></div>
<div class="progress-line" :style="durationStyle"></div> <div class="progress-line" :style="durationStyle"></div>
<div class="point"></div> <div class="point"></div>
@ -76,32 +76,22 @@
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import { _checkImgUrl, _duration, _stopPropagation } from '@/utils' import { _checkImgUrl, _duration, _stopPropagation } from '@/utils'
import Loading from '../Loading' import Loading from '../Loading.vue'
import ItemToolbar from './ItemToolbar' import ItemToolbar from './ItemToolbar.vue'
import ItemDesc from './ItemDesc' import ItemDesc from './ItemDesc.vue'
import bus, { EVENT_KEY } from '../../utils/bus' import bus, { EVENT_KEY } from '../../utils/bus'
import { SlideItemPlayStatus } from '@/utils/const_var' import { SlideItemPlayStatus } from '@/utils/const_var'
import { computed } from 'vue' import { computed, onMounted, onUnmounted, provide, reactive } from 'vue'
import { Icon } from '@iconify/vue' import { Icon } from '@iconify/vue'
import { _css } from '@/utils/dom' import { _css } from '@/utils/dom'
export default { defineOptions({
name: 'BaseVideo', name: 'BaseVideo'
components: { })
Loading,
ItemToolbar, const props = defineProps({
ItemDesc,
Icon
},
provide() {
return {
// isPlaying: computed(() => this.status)
isPlaying: computed(() => this.isPlaying)
}
},
props: {
item: { item: {
type: Object, type: Object,
default: () => { default: () => {
@ -133,33 +123,32 @@ export default {
return false return false
} }
} }
}, })
computed: {
poster() { provide(
return _checkImgUrl(this.item.video.poster ?? this.item.video.cover.url_list[0]) 'isPlaying',
}, computed(() => isPlaying)
durationStyle() { )
return { width: this.playX + 'px' } provide(
}, 'isMuted',
progressClass() { computed(() => state.isMuted)
if (this.isMove) { )
return 'move' provide(
} else { 'position',
return this.isPlaying ? '' : 'stop' computed(() => props.position)
} )
}, provide(
positionName() { 'item',
return 'item-' + Object.values(this.position).join('-') computed(() => props.item)
}, )
isPlaying() {
return this.status === SlideItemPlayStatus.Play const videoEl = $ref<HTMLVideoElement>()
} const progressEl = $ref<HTMLDivElement>()
}, let state = reactive({
data() {
return {
loading: false, loading: false,
paused: false, paused: false,
status: this.isPlay ? SlideItemPlayStatus.Play : SlideItemPlayStatus.Pause, isMuted: window.isMuted,
status: props.isPlay ? SlideItemPlayStatus.Play : SlideItemPlayStatus.Pause,
duration: 0, duration: 0,
step: 0, step: 0,
currentTime: -1, currentTime: -1,
@ -171,43 +160,67 @@ export default {
isMove: false, isMove: false,
ignoreWaiting: false, //waitingwaiting ignoreWaiting: false, //waitingwaiting
test: [1, 2], test: [1, 2],
localItem: this.item, localItem: props.item,
progressBarRect: {}, progressBarRect: {
height: 0,
width: 0
},
videoScreenHeight: 0, videoScreenHeight: 0,
commentVisible: false commentVisible: false
})
const poster = $computed(() => {
return _checkImgUrl(props.item.video.poster ?? props.item.video.cover.url_list[0])
})
const durationStyle = $computed(() => {
return { width: state.playX + 'px' }
})
const isPlaying = $computed(() => {
return state.status === SlideItemPlayStatus.Play
})
const positionName = $computed(() => {
return 'item-' + Object.values(props.position).join('-')
})
const progressClass = $computed(() => {
if (state.isMove) {
return 'move'
} else {
return isPlaying ? '' : 'stop'
} }
}, })
mounted() {
onMounted(() => {
// console.log('video', this.localItem.aweme_id) // console.log('video', this.localItem.aweme_id)
// console.log(this.commentVisible) // console.log(this.commentVisible)
this.height = document.body.clientHeight state.height = document.body.clientHeight
this.width = document.body.clientWidth state.width = document.body.clientWidth
let video = this.$refs.video videoEl.currentTime = 0
video.currentTime = 0
let fun = (e) => { let fun = (e) => {
this.currentTime = Math.ceil(e.target.currentTime) state.currentTime = Math.ceil(e.target.currentTime)
this.playX = (this.currentTime - 1) * this.step state.playX = (state.currentTime - 1) * state.step
} }
video.addEventListener('loadedmetadata', () => { videoEl.addEventListener('loadedmetadata', () => {
this.videoScreenHeight = video.videoHeight / (video.videoWidth / this.width) state.videoScreenHeight = videoEl.videoHeight / (videoEl.videoWidth / state.width)
this.duration = video.duration state.duration = videoEl.duration
this.progressBarRect = this.$refs.progress.getBoundingClientRect() state.progressBarRect = progressEl.getBoundingClientRect()
this.step = this.progressBarRect.width / Math.floor(this.duration) state.step = state.progressBarRect.width / Math.floor(state.duration)
video.addEventListener('timeupdate', fun) videoEl.addEventListener('timeupdate', fun)
}) })
let eventTester = (e) => { let eventTester = (e, t: string) => {
video.addEventListener( videoEl.addEventListener(
e, e,
() => { () => {
// console.log('eventTester', e, this.item.aweme_id) // console.log('eventTester', e, state.item.aweme_id)
if (e === 'playing') this.loading = false if (e === 'playing') state.loading = false
if (e === 'waiting') { if (e === 'waiting') {
if (!this.paused && !this.ignoreWaiting) { if (!state.paused && !state.ignoreWaiting) {
this.loading = true state.loading = true
} }
} }
// console.log(e, t) let s = false
if (s) {
console.log(e, t)
}
}, },
false false
) )
@ -239,147 +252,150 @@ export default {
// console.log('mounted') // console.log('mounted')
// bus.off('singleClickBroadcast') // bus.off('singleClickBroadcast')
bus.on(EVENT_KEY.SINGLE_CLICK_BROADCAST, this.click) bus.on(EVENT_KEY.SINGLE_CLICK_BROADCAST, click)
bus.on(EVENT_KEY.DIALOG_MOVE, this.onDialogMove) bus.on(EVENT_KEY.DIALOG_MOVE, onDialogMove)
bus.on(EVENT_KEY.DIALOG_END, this.onDialogEnd) bus.on(EVENT_KEY.DIALOG_END, onDialogEnd)
bus.on(EVENT_KEY.OPEN_COMMENTS, this.onOpenComments) bus.on(EVENT_KEY.OPEN_COMMENTS, onOpenComments)
bus.on(EVENT_KEY.CLOSE_COMMENTS, this.onCloseComments) bus.on(EVENT_KEY.CLOSE_COMMENTS, onCloseComments)
bus.on(EVENT_KEY.OPEN_SUB_TYPE, this.onOpenSubType) bus.on(EVENT_KEY.OPEN_SUB_TYPE, onOpenSubType)
bus.on(EVENT_KEY.CLOSE_SUB_TYPE, this.onCloseSubType) bus.on(EVENT_KEY.CLOSE_SUB_TYPE, onCloseSubType)
},
unmounted() { bus.on(EVENT_KEY.REMOVE_MUTED, removeMuted)
})
onUnmounted(() => {
// console.log('unmounted') // console.log('unmounted')
bus.off(EVENT_KEY.SINGLE_CLICK_BROADCAST, this.click) bus.off(EVENT_KEY.SINGLE_CLICK_BROADCAST, click)
bus.off(EVENT_KEY.DIALOG_MOVE, this.onDialogMove) bus.off(EVENT_KEY.DIALOG_MOVE, onDialogMove)
bus.off(EVENT_KEY.DIALOG_END, this.onDialogEnd) bus.off(EVENT_KEY.DIALOG_END, onDialogEnd)
bus.off(EVENT_KEY.OPEN_COMMENTS, this.onOpenComments) bus.off(EVENT_KEY.OPEN_COMMENTS, onOpenComments)
bus.off(EVENT_KEY.CLOSE_COMMENTS, this.onCloseComments) bus.off(EVENT_KEY.CLOSE_COMMENTS, onCloseComments)
bus.off(EVENT_KEY.OPEN_SUB_TYPE, this.onOpenSubType) bus.off(EVENT_KEY.OPEN_SUB_TYPE, onOpenSubType)
bus.off(EVENT_KEY.CLOSE_SUB_TYPE, this.onCloseSubType) bus.off(EVENT_KEY.CLOSE_SUB_TYPE, onCloseSubType)
}, bus.off(EVENT_KEY.REMOVE_MUTED, removeMuted)
methods: { })
_duration,
_checkImgUrl, function removeMuted() {
onOpenSubType() { state.isMuted = false
this.commentVisible = true }
},
onCloseSubType() { function onOpenSubType() {
this.commentVisible = false state.commentVisible = true
}, }
onDialogMove({ tag, e }) {
if (this.commentVisible && tag === 'comment') { function onCloseSubType() {
_css(this.$refs.video, 'transition-duration', `0ms`) state.commentVisible = false
_css(this.$refs.video, 'height', `calc(var(--vh, 1vh) * 30 + ${e}px)`) }
function onDialogMove({ tag, e }) {
if (state.commentVisible && tag === 'comment') {
_css(videoEl, 'transition-duration', `0ms`)
_css(videoEl, 'height', `calc(var(--vh, 1vh) * 30 + ${e}px)`)
} }
}, }
onDialogEnd({ tag, isClose }) {
if (this.commentVisible && tag === 'comment') { function onDialogEnd({ tag, isClose }) {
if (state.commentVisible && tag === 'comment') {
console.log('isClose', isClose) console.log('isClose', isClose)
_css(this.$refs.video, 'transition-duration', `300ms`) _css(videoEl, 'transition-duration', `300ms`)
if (isClose) { if (isClose) {
this.commentVisible = false state.commentVisible = false
_css(this.$refs.video, 'height', '100%') _css(videoEl, 'height', '100%')
} else { } else {
_css(this.$refs.video, 'height', 'calc(var(--vh, 1vh) * 30)') _css(videoEl, 'height', 'calc(var(--vh, 1vh) * 30)')
} }
} }
}, }
onOpenComments(id) {
if (id === this.item.aweme_id) { function onOpenComments(id) {
_css(this.$refs.video, 'transition-duration', `300ms`) if (id === props.item.aweme_id) {
_css(this.$refs.video, 'height', 'calc(var(--vh, 1vh) * 30)') _css(videoEl, 'transition-duration', `300ms`)
this.commentVisible = true _css(videoEl, 'height', 'calc(var(--vh, 1vh) * 30)')
state.commentVisible = true
} }
}, }
onCloseComments() {
if (this.commentVisible) { function onCloseComments() {
_css(this.$refs.video, 'transition-duration', `300ms`) if (state.commentVisible) {
_css(this.$refs.video, 'height', '100%') _css(videoEl, 'transition-duration', `300ms`)
this.commentVisible = false _css(videoEl, 'height', '100%')
state.commentVisible = false
} }
}, }
click({ uniqueId, index, type }) {
if (this.position.uniqueId === uniqueId && this.position.index === index) { function click({ uniqueId, index, type }) {
if (props.position.uniqueId === uniqueId && props.position.index === index) {
if (type === EVENT_KEY.ITEM_TOGGLE) { if (type === EVENT_KEY.ITEM_TOGGLE) {
if (this.isLive) { if (props.isLive) {
if (type === EVENT_KEY.ITEM_TOGGLE) { pause()
this.pause()
bus.emit(EVENT_KEY.NAV, { bus.emit(EVENT_KEY.NAV, {
path: '/home/live', path: '/home/live',
query: { id: this.item.aweme_id } query: { id: props.item.aweme_id }
}) })
}
} else { } else {
if (this.status === SlideItemPlayStatus.Play) { if (state.status === SlideItemPlayStatus.Play) {
this.pause() pause()
} else { } else {
this.play() play()
} }
} }
} }
if (type === EVENT_KEY.ITEM_STOP) { if (type === EVENT_KEY.ITEM_STOP) {
this.$refs.video.currentTime = 0 videoEl.currentTime = 0
this.ignoreWaiting = true state.ignoreWaiting = true
this.pause() pause()
setTimeout(() => (this.ignoreWaiting = false), 300) setTimeout(() => (state.ignoreWaiting = false), 300)
} }
if (type === EVENT_KEY.ITEM_PLAY) { if (type === EVENT_KEY.ITEM_PLAY) {
this.$refs.video.currentTime = 0 videoEl.currentTime = 0
this.ignoreWaiting = true state.ignoreWaiting = true
this.play() play()
setTimeout(() => (this.ignoreWaiting = false), 300) setTimeout(() => (state.ignoreWaiting = false), 300)
} }
} }
}, }
play() {
this.status = SlideItemPlayStatus.Play function play() {
this.$refs.video.volume = 1 state.status = SlideItemPlayStatus.Play
this.$refs.video.play() videoEl.volume = 1
}, videoEl.play()
pause() { }
this.status = SlideItemPlayStatus.Pause
this.$refs.video.pause() function pause() {
}, state.status = SlideItemPlayStatus.Pause
touchstart(e) { videoEl.pause()
}
function touchstart(e) {
_stopPropagation(e) _stopPropagation(e)
this.start.x = e.touches[0].pageX state.start.x = e.touches[0].pageX
this.last.x = this.playX state.last.x = state.playX
this.last.time = this.currentTime state.last.time = state.currentTime
}, }
touchmove(e) {
function touchmove(e) {
// console.log('move',e) // console.log('move',e)
_stopPropagation(e) _stopPropagation(e)
this.isMove = true state.isMove = true
this.pause() pause()
let dx = e.touches[0].pageX - this.start.x let dx = e.touches[0].pageX - state.start.x
this.playX = this.last.x + dx state.playX = state.last.x + dx
this.currentTime = this.last.time + Math.ceil(Math.ceil(dx) / this.step) state.currentTime = state.last.time + Math.ceil(Math.ceil(dx) / state.step)
if (this.currentTime <= 0) this.currentTime = 0 if (state.currentTime <= 0) state.currentTime = 0
if (this.currentTime >= this.duration) this.currentTime = this.duration if (state.currentTime >= state.duration) state.currentTime = state.duration
}, }
touchend(e) {
function touchend(e) {
// console.log('end', e) // console.log('end', e)
_stopPropagation(e) _stopPropagation(e)
if (this.isPlaying) return if (isPlaying) return
setTimeout(() => (this.isMove = false), 1000) setTimeout(() => (state.isMove = false), 1000)
this.$refs.video.currentTime = this.currentTime videoEl.currentTime = state.currentTime
this.play() play()
}
}
} }
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.fade-enter-active,
.fade-leave-active {
transition: transform 0.5s linear;
}
.fade-enter-from,
.fade-leave-to {
transform: scale(0);
}
.video-wrapper { .video-wrapper {
position: relative; position: relative;
font-size: 14rem; font-size: 14rem;
@ -410,140 +426,6 @@ export default {
width: 100%; width: 100%;
transition: all 0.3s; transition: all 0.3s;
.toolbar {
//width: 40px;
position: absolute;
bottom: 0;
right: 5px;
color: #fff;
.avatar-ctn {
position: relative;
.avatar {
width: 55px;
height: 55px;
border-radius: 50%;
}
.options {
position: absolute;
border-radius: 50%;
margin: auto;
left: 0;
right: 0;
bottom: -5px;
background: red;
//background: black;
width: 18px;
height: 18px;
display: flex;
justify-content: center;
align-items: center;
transition: all 1s;
img {
position: absolute;
width: 12px;
height: 12px;
transition: all 1s;
}
.yes {
opacity: 0;
transform: rotate(-180deg);
}
&.attention {
background: white;
.no {
opacity: 0;
transform: rotate(180deg);
}
.yes {
opacity: 1;
transform: rotate(0deg);
}
}
}
}
.love,
.message,
.share {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
@width: 35rem;
img {
width: @width;
height: @width;
}
span {
font-size: 12rem;
}
}
.loved {
background: red;
}
}
.content {
color: #fff;
position: absolute;
bottom: 0;
width: 75%;
//display: flex;
//flex-direction: column;
.location-wrapper {
display: flex;
.location {
margin-bottom: 10rem;
display: flex;
align-items: center;
font-size: 12rem;
padding: 4rem;
border-radius: 3rem;
background: var(--second-btn-color-tran);
.gang {
height: 8rem;
width: 1.5px;
margin: 0 5rem;
background: gray;
}
img {
margin-right: 7rem;
width: 18rem;
}
}
}
.music {
position: relative;
width: 60%;
display: flex;
align-items: center;
.music-image {
width: 20px;
height: 20px;
margin-top: 3px;
}
}
}
.comment-status { .comment-status {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -1,19 +1,7 @@
<script setup> <script setup lang="ts">
import { reactive } from 'vue' import { inject, reactive } from 'vue'
const props = defineProps({ const props = defineProps({
item: {
type: Object,
default: () => {
return {}
}
},
position: {
type: Object,
default: () => {
return {}
}
},
isMy: { isMy: {
type: Boolean, type: Boolean,
default: () => { default: () => {
@ -28,6 +16,8 @@ const props = defineProps({
} }
}) })
const item = inject<any>('item')
const state = reactive({ const state = reactive({
isAttention: false, isAttention: false,
test: [1, 2] test: [1, 2]
@ -36,26 +26,26 @@ const state = reactive({
<template> <template>
<div class="item-desc ml1r mb1r"> <div class="item-desc ml1r mb1r">
<div class="content" v-if="!props.isMy"> <div class="content" v-if="!props.isMy">
<div class="location-wrapper" v-if="props.item.city || item.address"> <div class="location-wrapper" v-if="item.city || item.address">
<div class="location"> <div class="location">
<img src="../../assets/img/icon/location.webp" alt="" /> <img src="../../assets/img/icon/location.webp" alt="" />
<span>{{ props.item.city }}</span> <span>{{ item.city }}</span>
<template v-if="props.item.address"> <template v-if="item.address">
<div class="gang"></div> <div class="gang"></div>
</template> </template>
<span>{{ props.item.address }}</span> <span>{{ item.address }}</span>
</div> </div>
</div> </div>
<div class="live" v-if="props.isLive">直播中</div> <div class="live" v-if="props.isLive">直播中</div>
<div class="name mb1r f18 fb" @click.stop="$emit('goUserInfo')"> <div class="name mb1r f18 fb" @click.stop="$emit('goUserInfo')">
@{{ props.item.author.nickname }} @{{ item.author.nickname }}
</div> </div>
<div class="description"> <div class="description">
{{ props.item.desc }} {{ item.desc }}
</div> </div>
<!-- <div class="music" @click.stop="bus.emit('nav','/home/music')">--> <!-- <div class="music" @click.stop="bus.emit('nav','/home/music')">-->
<!-- <img src="../../assets/img/icon/music.svg" alt="" class="music-image">--> <!-- <img src="../../assets/img/icon/music.svg" alt="" class="music-image">-->
<!-- <span>{{ props.item.music.title }}</span>--> <!-- <span>{{ item.music.title }}</span>-->
<!-- </div>--> <!-- </div>-->
</div> </div>
<div v-else class="comment-status"> <div v-else class="comment-status">
@ -88,7 +78,7 @@ const state = reactive({
.content { .content {
color: #fff; color: #fff;
width: 75vw; width: 70vw;
text-align: left; text-align: left;
.location-wrapper { .location-wrapper {

View File

@ -1,23 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import BaseMusic from '../BaseMusic.vue' import BaseMusic from '../BaseMusic.vue'
import { _dateFormat, _formatNumber, _stopPropagation, _updateItem } from '@/utils' import { _formatNumber, _updateItem } from '@/utils'
import bus, { EVENT_KEY } from '@/utils/bus' import bus, { EVENT_KEY } from '@/utils/bus'
import { Icon } from '@iconify/vue' import { Icon } from '@iconify/vue'
import { useClick } from '@/utils/hooks/useClick' import { useClick } from '@/utils/hooks/useClick'
import { inject } from 'vue'
const props = defineProps({ const props = defineProps({
item: {
type: Object,
default: () => {
return {}
}
},
position: {
type: Object,
default: () => {
return {}
}
},
isMy: { isMy: {
type: Boolean, type: Boolean,
default: () => { default: () => {
@ -25,10 +14,13 @@ const props = defineProps({
} }
} }
}) })
const item = inject<any>('item')
const emit = defineEmits(['update:item', 'goUserInfo', 'showComments', 'showShare', 'goMusic']) const emit = defineEmits(['update:item', 'goUserInfo', 'showComments', 'showShare', 'goMusic'])
function loved() { function loved() {
_updateItem(props, 'isLoved', !props.item.isLoved, emit) _updateItem(props, 'isLoved', !item.value.isLoved, emit)
} }
function attention(e) { function attention(e) {
@ -39,7 +31,7 @@ function attention(e) {
} }
function showComments() { function showComments() {
bus.emit(EVENT_KEY.OPEN_COMMENTS, props.item.aweme_id) bus.emit(EVENT_KEY.OPEN_COMMENTS, item.value.aweme_id)
} }
const vClick = useClick() const vClick = useClick()
@ -50,12 +42,12 @@ const vClick = useClick()
<div class="avatar-ctn mb2r"> <div class="avatar-ctn mb2r">
<img <img
class="avatar" class="avatar"
:src="props.item.author.avatar_168x168.url_list[0]" :src="item.author.avatar_168x168.url_list[0]"
alt="" alt=""
v-click="() => bus.emit(EVENT_KEY.GO_USERINFO)" v-click="() => bus.emit(EVENT_KEY.GO_USERINFO)"
/> />
<transition name="fade"> <transition name="fade">
<div v-if="!props.item.isAttention" v-click="attention" class="options"> <div v-if="!item.isAttention" v-click="attention" class="options">
<img class="no" src="../../assets/img/icon/add-light.png" alt="" /> <img class="no" src="../../assets/img/icon/add-light.png" alt="" />
<img class="yes" src="../../assets/img/icon/ok-red.png" alt="" /> <img class="yes" src="../../assets/img/icon/ok-red.png" alt="" />
</div> </div>
@ -63,36 +55,36 @@ const vClick = useClick()
</div> </div>
<div class="love mb2r" v-click="loved"> <div class="love mb2r" v-click="loved">
<div> <div>
<img src="../../assets/img/icon/love.svg" class="love-image" v-if="!props.item.isLoved" /> <img src="../../assets/img/icon/love.svg" class="love-image" v-if="!item.isLoved" />
<img src="../../assets/img/icon/loved.svg" class="love-image" v-if="props.item.isLoved" /> <img src="../../assets/img/icon/loved.svg" class="love-image" v-if="item.isLoved" />
</div> </div>
<span>{{ _formatNumber(props.item.statistics.digg_count) }}</span> <span>{{ _formatNumber(item.statistics.digg_count) }}</span>
</div> </div>
<div class="message mb2r" v-click="showComments"> <div class="message mb2r" v-click="showComments">
<Icon icon="mage:message-dots-round-fill" class="icon" style="color: white" /> <Icon icon="mage:message-dots-round-fill" class="icon" style="color: white" />
<span>{{ _formatNumber(props.item.statistics.comment_count) }}</span> <span>{{ _formatNumber(item.statistics.comment_count) }}</span>
</div> </div>
<!--TODO --> <!--TODO -->
<div <div
class="message mb2r" class="message mb2r"
v-click="() => _updateItem(props, 'isCollect', !props.item.isCollect, emit)" v-click="() => _updateItem(props, 'isCollect', !item.isCollect, emit)"
> >
<Icon v-if="props.item.isCollect" icon="ic:round-star" class="icon" style="color: yellow" /> <Icon v-if="item.isCollect" icon="ic:round-star" class="icon" style="color: yellow" />
<Icon v-else icon="ic:round-star" class="icon" style="color: white" /> <Icon v-else icon="ic:round-star" class="icon" style="color: white" />
<span>{{ _formatNumber(props.item.statistics.comment_count) }}</span> <span>{{ _formatNumber(item.statistics.comment_count) }}</span>
</div> </div>
<div v-if="!props.isMy" class="share mb2r" v-click="() => bus.emit(EVENT_KEY.SHOW_SHARE)"> <div v-if="!props.isMy" class="share mb2r" v-click="() => bus.emit(EVENT_KEY.SHOW_SHARE)">
<img src="../../assets/img/icon/share-white-full.png" alt="" class="share-image" /> <img src="../../assets/img/icon/share-white-full.png" alt="" class="share-image" />
<span>{{ _formatNumber(props.item.statistics.share_count) }}</span> <span>{{ _formatNumber(item.statistics.share_count) }}</span>
</div> </div>
<div v-else class="share mb2r" v-click="() => bus.emit(EVENT_KEY.SHOW_SHARE)"> <div v-else class="share mb2r" v-click="() => bus.emit(EVENT_KEY.SHOW_SHARE)">
<img src="../../assets/img/icon/menu-white.png" alt="" class="share-image" /> <img src="../../assets/img/icon/menu-white.png" alt="" class="share-image" />
</div> </div>
<!-- <BaseMusic--> <!-- <BaseMusic-->
<!-- :cover="props.item.music.cover"--> <!-- :cover="item.music.cover"-->
<!-- v-click="$nav('/home/music')"--> <!-- v-click="$router.push('/home/music')"-->
<!-- /> --> <!-- /> -->
<BaseMusic :item="props.item" /> <BaseMusic />
</div> </div>
</template> </template>
@ -101,8 +93,11 @@ const vClick = useClick()
//width: 40px; //width: 40px;
position: absolute; position: absolute;
bottom: 0; bottom: 0;
right: 5px; right: 10rem;
color: #fff; color: #fff;
display: flex;
flex-direction: column;
align-items: center;
.avatar-ctn { .avatar-ctn {
position: relative; position: relative;

View File

@ -139,15 +139,18 @@ watch(
if (newVal && !props.list.length) { if (newVal && !props.list.length) {
return emit('refresh') return emit('refresh')
} }
let t = newVal ? 0 : 200
// console.log('active', 'newVal', newVal, 'oldVal', oldVal) // console.log('active', 'newVal', newVal, 'oldVal', oldVal)
if (newVal) { if (newVal) {
bus.emit(EVENT_KEY.CURRENT_ITEM, props.list[state.localIndex]) bus.emit(EVENT_KEY.CURRENT_ITEM, props.list[state.localIndex])
} }
setTimeout(() => {
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, { bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
uniqueId: props.uniqueId, uniqueId: props.uniqueId,
index: state.localIndex, index: state.localIndex,
type: newVal === false ? EVENT_KEY.ITEM_STOP : EVENT_KEY.ITEM_PLAY type: newVal === false ? EVENT_KEY.ITEM_STOP : EVENT_KEY.ITEM_PLAY
}) })
}, t)
}, },
{ immediate: true } { immediate: true }
) )
@ -271,8 +274,9 @@ function touchEnd(e) {
slideTouchEnd(e, state, canNext, (isNext) => { slideTouchEnd(e, state, canNext, (isNext) => {
let half = (props.virtualTotal - 1) / 2 let half = (props.virtualTotal - 1) / 2
if (props.list.length > props.virtualTotal) { if (props.list.length > props.virtualTotal) {
// //()
if (isNext) { if (isNext) {
// `dom` `dom`
if (state.localIndex > props.list.length - props.virtualTotal && state.localIndex > half) { if (state.localIndex > props.list.length - props.virtualTotal && state.localIndex > half) {
emit('loadMore') emit('loadMore')
} }
@ -297,6 +301,7 @@ function touchEnd(e) {
}) })
} }
} else { } else {
// `dom` `dom`
if (state.localIndex >= half && state.localIndex < props.list.length - (half + 1)) { if (state.localIndex >= half && state.localIndex < props.list.length - (half + 1)) {
let addIndex = state.localIndex - half let addIndex = state.localIndex - half
if (addIndex >= 0) { if (addIndex >= 0) {
@ -321,7 +326,7 @@ function touchEnd(e) {
slideReset(e, slideListEl.value, state, emit) slideReset(e, slideListEl.value, state, emit)
} }
function canNext(state, isNext) { function canNext(state, isNext: boolean) {
return !( return !(
(state.localIndex === 0 && !isNext) || (state.localIndex === 0 && !isNext) ||
(state.localIndex === props.list.length - 1 && isNext) (state.localIndex === props.list.length - 1 && isNext)

View File

@ -13,6 +13,7 @@ const BASE_URL_MAP = {
} }
export const IS_SUB_DOMAIN = ['GITEE_PAGES', 'GP_PAGES'].includes(import.meta.env.VITE_ENV) export const IS_SUB_DOMAIN = ['GITEE_PAGES', 'GP_PAGES'].includes(import.meta.env.VITE_ENV)
export const IS_GITEE_PAGES = ['GITEE_PAGES'].includes(import.meta.env.VITE_ENV)
export const BASE_URL = BASE_URL_MAP[import.meta.env.VITE_ENV] export const BASE_URL = BASE_URL_MAP[import.meta.env.VITE_ENV]
export const IMG_URL = BASE_URL + '/images/' export const IMG_URL = BASE_URL + '/images/'
export const FILE_URL = BASE_URL + '/data/' export const FILE_URL = BASE_URL + '/data/'

View File

@ -1,6 +1,5 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import mitt from 'mitt'
import './assets/less/index.less' import './assets/less/index.less'
import { startMock } from '@/mock' import { startMock } from '@/mock'
import router from './router' import router from './router'
@ -8,8 +7,11 @@ import mixin from './utils/mixin'
import VueLazyload from '@jambonn/vue-lazyload' import VueLazyload from '@jambonn/vue-lazyload'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import { useClick } from '@/utils/hooks/useClick' import { useClick } from '@/utils/hooks/useClick'
import bus, { EVENT_KEY } from '@/utils/bus'
window.isMoved = false window.isMoved = false
window.isMuted = true
window.showMutedNotice = true
HTMLElement.prototype.addEventListener = new Proxy(HTMLElement.prototype.addEventListener, { HTMLElement.prototype.addEventListener = new Proxy(HTMLElement.prototype.addEventListener, {
apply(target, ctx, args) { apply(target, ctx, args) {
const eventName = args[0] const eventName = args[0]
@ -34,10 +36,7 @@ HTMLElement.prototype.addEventListener = new Proxy(HTMLElement.prototype.addEven
const vClick = useClick() const vClick = useClick()
const pinia = createPinia() const pinia = createPinia()
const emitter = mitt()
const app = createApp(App) const app = createApp(App)
app.config.globalProperties.emitter = emitter
app.provide('mitt', emitter)
app.mixin(mixin) app.mixin(mixin)
const loadImage = new URL('./assets/img/icon/img-loading.png', import.meta.url).href const loadImage = new URL('./assets/img/icon/img-loading.png', import.meta.url).href
app.use(VueLazyload, { app.use(VueLazyload, {
@ -52,3 +51,10 @@ app.directive('click', vClick)
//放到最后才可以使用pinia //放到最后才可以使用pinia
startMock() startMock()
setTimeout(() => {
bus.emit(EVENT_KEY.HIDE_MUTED_NOTICE)
window.showMutedNotice = false
}, 2000)
bus.on(EVENT_KEY.REMOVE_MUTED, () => {
window.isMuted = false
})

View File

@ -22,11 +22,11 @@
<img src="../../../assets/img/icon/components/follow/share.png" alt="" /> <img src="../../../assets/img/icon/components/follow/share.png" alt="" />
<span>分享主页</span> <span>分享主页</span>
</div> </div>
<div class="option" @click="cancel((e) => $nav('/message/chat'))"> <div class="option" @click="cancel((e) => $router.push('/message/chat'))">
<img src="../../../assets/img/icon/components/follow/private-chat.png" alt="" /> <img src="../../../assets/img/icon/components/follow/private-chat.png" alt="" />
<span>发私信</span> <span>发私信</span>
</div> </div>
<div class="option" @click="cancel((e) => $nav('/home/report', { mode: 'chat' }))"> <div class="option" @click="cancel((e) => $router.push('/home/report', { mode: 'chat' }))">
<img src="../../../assets/img/icon/components/follow/report.png" alt="" /> <img src="../../../assets/img/icon/components/follow/report.png" alt="" />
<span>举报</span> <span>举报</span>
</div> </div>

View File

@ -37,7 +37,12 @@
</div> </div>
<div class="indicator" ref="indicator"></div> <div class="indicator" ref="indicator"></div>
</div> </div>
<Icon v-hide="loading" icon="ion:search" class="search" @click="$nav('/home/search')" /> <Icon
v-hide="loading"
icon="ion:search"
class="search"
@click="$router.push('/home/search')"
/>
</div> </div>
<div class="toggle-type" :class="{ open }"> <div class="toggle-type" :class="{ open }">
<div class="l-button" :class="{ active: type === 0 }" @click="toggleType(0)"> <div class="l-button" :class="{ active: type === 0 }" @click="toggleType(0)">
@ -276,6 +281,7 @@ export default {
color: rgba(white, 0.7); color: rgba(white, 0.7);
position: relative; position: relative;
font-size: 17rem; font-size: 17rem;
cursor: pointer;
.tab1-img { .tab1-img {
position: absolute; position: absolute;

View File

@ -109,7 +109,7 @@
<div class="share-btn shared" v-else>已私信</div> <div class="share-btn shared" v-else>已私信</div>
</div> </div>
</div> </div>
<div class="more" @click="cancel($nav('/message/share-to-friend'))"> <div class="more" @click="cancel($router.push('/message/share-to-friend'))">
<img src="../../../assets/img/icon/components/video/more-dark.png" /> <img src="../../../assets/img/icon/components/video/more-dark.png" />
<div class="right"> <div class="right">
<span>更多好友</span> <span>更多好友</span>

View File

@ -38,7 +38,7 @@
:can-download="canDownload" :can-download="canDownload"
@click="closeShare()" @click="closeShare()"
/> />
<to-share item-type="report" @click="$nav('/home/report', { mode: this.mode })" /> <to-share item-type="report" @click="$router.push('/home/report', { mode: this.mode })" />
<to-share item-type="copyPassword" @click="copyLink" /> <to-share item-type="copyPassword" @click="copyLink" />
<to-share :item-type="isCollect ? 'collectYellow' : 'collect'" @click="toggleCollect" /> <to-share :item-type="isCollect ? 'collectYellow' : 'collect'" @click="toggleCollect" />
<to-share item-type="comeon" @click="_no" /> <to-share item-type="comeon" @click="_no" />
@ -67,7 +67,7 @@
</dy-button> </dy-button>
</div> </div>
</div> </div>
<div class="more" @click="closeShare($nav('/message/share-to-friend'))"> <div class="more" @click="closeShare($router.push('/message/share-to-friend'))">
<img class="left" src="../../../assets/img/icon/components/video/more-dark.png" /> <img class="left" src="../../../assets/img/icon/components/video/more-dark.png" />
<span>更多朋友</span> <span>更多朋友</span>
</div> </div>

View File

@ -320,10 +320,12 @@ onUnmounted(() => {
onActivated(() => { onActivated(() => {
state.active = true state.active = true
bus.emit(EVENT_KEY.TOGGLE_CURRENT_VIDEO)
}) })
onDeactivated(() => { onDeactivated(() => {
state.active = false state.active = false
bus.emit(EVENT_KEY.TOGGLE_CURRENT_VIDEO)
}) })
function closeComments() { function closeComments() {

View File

@ -47,7 +47,7 @@
</div> </div>
<SlideList <SlideList
:active="props.active" :active="props.active"
uniqueId="uniqueId3" uniqueId="hot"
:style="{ :style="{
background: 'black', background: 'black',
marginTop: state.subTypeVisible ? state.subTypeHeight : 0 marginTop: state.subTypeVisible ? state.subTypeHeight : 0

View File

@ -18,7 +18,7 @@
<SlideList <SlideList
:cbs="{ isLive: true }" :cbs="{ isLive: true }"
:active="props.active" :active="props.active"
uniqueId="uniqueId2" uniqueId="live"
:style="{ :style="{
background: 'black', background: 'black',
marginTop: state.subTypeVisible ? state.subTypeHeight : 0 marginTop: state.subTypeVisible ? state.subTypeHeight : 0

View File

@ -1,6 +1,11 @@
<template> <template>
<SlideItem> <SlideItem>
<SlideList style="background: #000" :active="props.active" :api="recommendedVideo" /> <SlideList
uniqueId="home"
style="background: #000"
:active="props.active"
:api="recommendedVideo"
/>
</SlideItem> </SlideItem>
</template> </template>

View File

@ -109,6 +109,7 @@ async function getData(refresh = false) {
// } // }
function click(uniqueId) { function click(uniqueId) {
if (!props.active) return
if (uniqueId !== props.uniqueId) return if (uniqueId !== props.uniqueId) return
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, { bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
uniqueId, uniqueId,
@ -123,12 +124,23 @@ function updateItem({ position, item }) {
} }
} }
function togglePlay() {
if (!props.active) return
bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
uniqueId: props.uniqueId,
index: state.index,
type: EVENT_KEY.ITEM_TOGGLE
})
}
onMounted(() => { onMounted(() => {
bus.on(EVENT_KEY.SINGLE_CLICK, click) bus.on(EVENT_KEY.SINGLE_CLICK, click)
bus.on(EVENT_KEY.UPDATE_ITEM, updateItem) bus.on(EVENT_KEY.UPDATE_ITEM, updateItem)
bus.on(EVENT_KEY.TOGGLE_CURRENT_VIDEO, togglePlay)
}) })
onUnmounted(() => { onUnmounted(() => {
bus.off(EVENT_KEY.SINGLE_CLICK, click) bus.off(EVENT_KEY.SINGLE_CLICK, click)
bus.on(EVENT_KEY.UPDATE_ITEM, updateItem) bus.off(EVENT_KEY.UPDATE_ITEM, updateItem)
bus.off(EVENT_KEY.TOGGLE_CURRENT_VIDEO, togglePlay)
}) })
</script> </script>

View File

@ -2,7 +2,7 @@
<div class="other-login" id="other-login"> <div class="other-login" id="other-login">
<BaseHeader mode="light" backMode="dark" backImg="back"> <BaseHeader mode="light" backMode="dark" backImg="back">
<template v-slot:right> <template v-slot:right>
<span class="f14" @click="$nav('/login/help')">帮助与设置</span> <span class="f14" @click="$router.push('/login/help')">帮助与设置</span>
</template> </template>
</BaseHeader> </BaseHeader>
<div class="content"> <div class="content">
@ -24,11 +24,13 @@
</div> </div>
<div class="right"> <div class="right">
已阅读并同意 已阅读并同意
<span class="link" @click="$nav('/service-protocol', { type: '“抖音”用户服务协议' })" <span
class="link"
@click="$router.push('/service-protocol', { type: '“抖音”用户服务协议' })"
>用户协议</span >用户协议</span
> >
<span class="link" @click="$nav('/service-protocol', { type: '“抖音”隐私政策' })" <span class="link" @click="$router.push('/service-protocol', { type: '“抖音”隐私政策' })"
>隐私政策</span >隐私政策</span
> >
同时登录并使用抖音火山版火山小视频和抖音 同时登录并使用抖音火山版火山小视频和抖音
@ -46,7 +48,7 @@
</dy-button> </dy-button>
<div class="options"> <div class="options">
<span class="link" @click="$nav('/login/password')">密码登录</span> <span class="link" @click="$router.push('/login/password')">密码登录</span>
<span class="link" @click="otherLogin">其他方式登录</span> <span class="link" @click="otherLogin">其他方式登录</span>
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="PasswordLogin"> <div class="PasswordLogin">
<BaseHeader mode="light" backMode="dark" backImg="back"> <BaseHeader mode="light" backMode="dark" backImg="back">
<template v-slot:right> <template v-slot:right>
<span class="f14" @click="$nav('/login/help')">帮助与设置</span> <span class="f14" @click="$router.push('/login/help')">帮助与设置</span>
</template> </template>
</BaseHeader> </BaseHeader>
<div class="content"> <div class="content">
@ -26,11 +26,13 @@
</div> </div>
<div class="right"> <div class="right">
已阅读并同意 已阅读并同意
<span class="link" @click="$nav('/service-protocol', { type: '“抖音”用户服务协议' })" <span
class="link"
@click="$router.push('/service-protocol', { type: '“抖音”用户服务协议' })"
>用户协议</span >用户协议</span
> >
<span class="link" @click="$nav('/service-protocol', { type: '“抖音”隐私政策' })" <span class="link" @click="$router.push('/service-protocol', { type: '“抖音”隐私政策' })"
>隐私政策</span >隐私政策</span
> >
同时登录并使用抖音火山版火山小视频和抖音 同时登录并使用抖音火山版火山小视频和抖音
@ -53,7 +55,9 @@
<div class="options"> <div class="options">
<span> <span>
忘记了<span class="link" @click="$nav('/login/retrieve-password')">找回密码</span> 忘记了<span class="link" @click="$router.push('/login/retrieve-password')"
>找回密码</span
>
</span> </span>
</div> </div>
</div> </div>

View File

@ -32,11 +32,13 @@
</div> </div>
<div class="right"> <div class="right">
已阅读并同意 已阅读并同意
<span class="link" @click="$nav('/service-protocol', { type: '“抖音”用户服务协议' })" <span
class="link"
@click="$router.push('/service-protocol', { type: '“抖音”用户服务协议' })"
>用户协议</span >用户协议</span
> >
<span class="link" @click="$nav('/service-protocol', { type: '“抖音”隐私政策' })" <span class="link" @click="$router.push('/service-protocol', { type: '“抖音”隐私政策' })"
>隐私政策</span >隐私政策</span
> >
同时登录并使用抖音火山版火山小视频和抖音 同时登录并使用抖音火山版火山小视频和抖音

View File

@ -19,7 +19,7 @@
<span class="notice">抖音扫一扫立即关注我</span> <span class="notice">抖音扫一扫立即关注我</span>
</div> </div>
<div class="footer"> <div class="footer">
<!-- <div class="btn" @click="$nav('/scan')">--> <!-- <div class="btn" @click="$router.push('/scan')">-->
<div class="btn" @click="_no"> <div class="btn" @click="_no">
<div class="wrapper"> <div class="wrapper">
<img src="../../assets/img/icon/scan.png" alt="" /> <img src="../../assets/img/icon/scan.png" alt="" />

View File

@ -11,7 +11,7 @@
<span class="belong">{{ store.userinfo.nickname }}的红包</span> <span class="belong">{{ store.userinfo.nickname }}的红包</span>
<div class="password">大吉大利</div> <div class="password">大吉大利</div>
<span class="money">0.01</span> <span class="money">0.01</span>
<!-- <span class="notice" @click="$nav('/me/money')">已存入我的零钱可直接使用></span>--> <!-- <span class="notice" @click="$router.push('/me/money')">已存入我的零钱可直接使用></span>-->
<span class="notice" @click="_no">已存入我的零钱可直接使用></span> <span class="notice" @click="_no">已存入我的零钱可直接使用></span>
</div> </div>
<img src="../../assets/img/icon/message/chat/money-detail-bg.png" alt="" class="bg" /> <img src="../../assets/img/icon/message/chat/money-detail-bg.png" alt="" class="bg" />

View File

@ -9,7 +9,7 @@
</div> </div>
<div class="right"> <div class="right">
<img <img
@click="mitt.emit('showAudioCall')" @click="bus.emit(EVENT_KEY.SHOW_AUDIO_CALL)"
src="../../../assets/img/icon/message/chat/call.png" src="../../../assets/img/icon/message/chat/call.png"
alt="" alt=""
/> />
@ -187,12 +187,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import ChatMessage from '../components/ChatMessage.vue' import ChatMessage from '../components/ChatMessage.vue'
import { computed, inject, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue' import { computed, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
import Loading from '@/components/Loading.vue' import Loading from '@/components/Loading.vue'
import { useBaseStore } from '@/store/pinia' import { useBaseStore } from '@/store/pinia'
import { _checkImgUrl, _no, _sleep } from '@/utils' import { _checkImgUrl, _no, _sleep } from '@/utils'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useNav } from '@/utils/hooks/useNav' import { useNav } from '@/utils/hooks/useNav'
import bus, { EVENT_KEY } from '@/utils/bus'
let CALL_STATE = { let CALL_STATE = {
REJECT: 0, REJECT: 0,
@ -233,7 +234,6 @@ defineOptions({
name: 'Chat' name: 'Chat'
}) })
const mitt = inject('mitt')
const router = useRouter() const router = useRouter()
const nav = useNav() const nav = useNav()
const store = useBaseStore() const store = useBaseStore()

View File

@ -62,5 +62,9 @@ export const EVENT_KEY = {
GO_USERINFO: 'GO_USERINFO', GO_USERINFO: 'GO_USERINFO',
SHOW_SHARE: 'SHOW_SHARE', SHOW_SHARE: 'SHOW_SHARE',
UPDATE_ITEM: 'UPDATE_ITEM', UPDATE_ITEM: 'UPDATE_ITEM',
CURRENT_ITEM: 'CURRENT_ITEM' CURRENT_ITEM: 'CURRENT_ITEM',
REMOVE_MUTED: 'REMOVE_MUTED',
HIDE_MUTED_NOTICE: 'HIDE_MUTED_NOTICE',
TOGGLE_CURRENT_VIDEO: 'TOGGLE_CURRENT_VIDEO',
SHOW_AUDIO_CALL: 'SHOW_AUDIO_CALL'
} }

View File

@ -8,10 +8,11 @@ export function useClick() {
el.addEventListener('pointerdown', (e) => _stopPropagation(e)) el.addEventListener('pointerdown', (e) => _stopPropagation(e))
el.addEventListener('pointerup', (e) => { el.addEventListener('pointerup', (e) => {
_stopPropagation(e) _stopPropagation(e)
binding.value?.() binding.value?.(e)
}) })
}, },
unmounted(el: HTMLDivElement) { unmounted(el: HTMLDivElement) {
// eslint-disable-next-line
el = null el = null
} }
} }

View File

@ -3,7 +3,7 @@ import SelectDialog from '../components/dialog/SelectDialog.vue'
import SimpleConfirmDialog from '../components/dialog/SimpleConfirmDialog.vue' import SimpleConfirmDialog from '../components/dialog/SimpleConfirmDialog.vue'
import ConfirmDialog from '../components/dialog/ConfirmDialog.vue' import ConfirmDialog from '../components/dialog/ConfirmDialog.vue'
import Loading from '../components/Loading.vue' import Loading from '../components/Loading.vue'
import { IMG_URL, IS_DEV } from '@/config' import { IMG_URL, IS_DEV, IS_GITEE_PAGES } from '@/config'
import NoticeDialog from '../components/dialog/NoticeDialog.vue' import NoticeDialog from '../components/dialog/NoticeDialog.vue'
import bus, { EVENT_KEY } from './bus' import bus, { EVENT_KEY } from './bus'
import { ArchiveReader, libarchiveWasm } from 'libarchive-wasm' import { ArchiveReader, libarchiveWasm } from 'libarchive-wasm'
@ -381,7 +381,7 @@ export function _no() {
* @privateF * @privateF
*/ */
export async function _fetch(url: string): Promise<{ json(): Promise<any> } | Response> { export async function _fetch(url: string): Promise<{ json(): Promise<any> } | Response> {
if (IS_DEV) { if (IS_DEV || !IS_GITEE_PAGES) {
url = url.replace('.md', '.json') url = url.replace('.md', '.json')
return fetch(url) return fetch(url)
} else { } else {

View File

@ -10,7 +10,7 @@ import BaseButton from '../components/BaseButton.vue'
import CONST_VAR from './const_var' import CONST_VAR from './const_var'
import Dom from './dom' import Dom from './dom'
import bus, { EVENT_KEY } from './bus' import bus, { EVENT_KEY } from './bus'
import { _stopPropagation, random } from '@/utils' import { random } from '@/utils'
import { Icon } from '@iconify/vue' import { Icon } from '@iconify/vue'
import SlideHorizontal from '@/components/slide/SlideHorizontal.vue' import SlideHorizontal from '@/components/slide/SlideHorizontal.vue'
@ -152,7 +152,7 @@ export default {
const up = (e) => { const up = (e) => {
if (!isDown) return if (!isDown) return
if (!isMove) check(e) if (!isMove && !window.isMoved) check(e)
isMove = isDown = false isMove = isDown = false
} }

View File

@ -22,8 +22,8 @@ axiosInstance.interceptors.request.use(
) )
/* /*
* { code: xxx, data: xxx }reject和抛error * { success: boolean, data: xxx }reject和抛error
* { code: Xxx, data:xxx }then里面总是会接收到 * then里面总是会接收到返回值
* */ * */
axiosInstance.interceptors.response.use( axiosInstance.interceptors.response.use(
(response: AxiosResponse) => { (response: AxiosResponse) => {

View File

@ -107,7 +107,7 @@ export function slideTouchMove(
notNextCb = null, notNextCb = null,
slideOtherDirectionCb = null slideOtherDirectionCb = null
) { ) {
console.log('move', state.name) // console.log('move', state.name)
if (!checkEvent(e)) return if (!checkEvent(e)) return
if (!state.isDown) return if (!state.isDown) return

View File

@ -18,6 +18,9 @@
"@/*": [ "@/*": [
"./src/*" "./src/*"
] ]
} },
"types": [
"unplugin-vue-macros/macros-global"
]
} }
} }

View File

@ -1,13 +1,11 @@
import { defineConfig, PluginOption } from 'vite' import { defineConfig, PluginOption } from 'vite'
import Vue from '@vitejs/plugin-vue' import Vue from '@vitejs/plugin-vue'
import VueJsx from '@vitejs/plugin-vue-jsx' import VueJsx from '@vitejs/plugin-vue-jsx'
import { resolve } from 'path'
import { visualizer } from 'rollup-plugin-visualizer' import { visualizer } from 'rollup-plugin-visualizer'
import DefineOptions from 'unplugin-vue-define-options/vite' // 引入插件
import { Plugin as importToCDN } from 'vite-plugin-cdn-import' import { Plugin as importToCDN } from 'vite-plugin-cdn-import'
import commonjs from 'vite-plugin-commonjs'
import { fileURLToPath, URL } from 'node:url' import { fileURLToPath, URL } from 'node:url'
import { getLastCommit } from 'git-last-commit' import { getLastCommit } from 'git-last-commit'
import VueMacros from 'unplugin-vue-macros/vite'
// import viteImagemin from 'vite-plugin-imagemin' // import viteImagemin from 'vite-plugin-imagemin'
// import viteCompression from 'vite-plugin-compression' // import viteCompression from 'vite-plugin-compression'
@ -28,20 +26,19 @@ export default defineConfig(async () => {
base: './', base: './',
envDir: 'env', envDir: 'env',
plugins: [ plugins: [
// VueMacros({ VueMacros({
// plugins: { plugins: {
// vue: Vue(), vue: Vue(),
// vueJsx: VueJsx(), // if needed vueJsx: VueJsx() // if needed
// }, }
// betterDefine: true, // betterDefine: true,
// // reactivityTransform: { // reactivityTransform: {
// // exclude: [/node_modules/, /jQuery\.js/] // exclude: [/node_modules/, /jQuery\.js/]
// // } // }
// }), }),
// Vue(),
// VueJsx(),
lifecycle === 'report' ? (visualizer({ open: false }) as any as PluginOption) : null, lifecycle === 'report' ? (visualizer({ open: false }) as any as PluginOption) : null,
DefineOptions(),
Vue(),
VueJsx(),
importToCDN({ importToCDN({
modules: [ modules: [
{ {