first commit

This commit is contained in:
Your Name
2026-01-19 14:19:22 +08:00
commit fe2d9c1868
4777 changed files with 665503 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
import path from 'path'
import versions from './versions'
const latest = versions[0]
const nav = [
{
text: '首页',
link: '/'
},
{
text: '文档',
activeMatch: `^/([0-9]\.x)/`,
items: versions.map((version) => ({
text: version,
link: `/${version}/`
}))
},
{
text: '视频',
link: 'https://wiki.w7.cc/college/collectiondetail/3'
},
{
text: '讨论',
link: 'https://github.com/w7corp/easywechat/discussions'
},
{
text: '赞助',
link: 'https://github.com/sponsors/overtrue'
}
]
export const sidebar = versions.reduce(
(sidebars, version) => ({
...sidebars,
[`/${version}/`]: require(path.join(
__dirname,
`../src/${version}/sidebar`
))
}),
{}
)
export default {
lang: 'zh-CN',
title: 'EasyWeChat',
description: '一个 PHP 微信开发 SDK',
srcDir: 'src',
srcExclude: [],
scrollOffset: 'header',
head: [
['link', { rel: 'icon', href: '/favicon.svg' }],
['meta', { name: 'twitter:site', content: '@easywechat' }],
['meta', { name: 'twitter:card', content: 'summary' }],
[
'meta',
{
name: 'twitter:image',
content: 'https://easywechat/logo.png'
}
]
],
themeConfig: {
nav,
sidebar,
logo: '/logo-icon.svg',
algolia: {
indexName: 'easywechat',
appId: 'X3KJL5SQXD',
apiKey: '5c5ba71b35c48411f245bef4c695fc36'
// searchParameters: {
// facetFilters: ['version:v3']
// }
},
// carbonAds: {
// code: '',
// placement: ''
// },
socialLinks: [
{ icon: 'github', link: 'https://github.com/w7corp/easywechat' },
{ icon: 'twitter', link: 'https://twitter.com/overtrue' }
],
editLink: {
pattern:
'https://github.com/w7corp/EasyWeChat/edit/6.x/docs/src/:path',
text: '帮助我们改善此页面!'
},
license: {
text: 'MIT License',
link: 'https://opensource.org/licenses/MIT'
},
copyright: `Copyright © 2013-${new Date().getFullYear()} 微擎 <a class="ml-4" href="https://beian.miit.gov.cn/" target="_blank">皖ICP备19002904号-6</a>`
},
vite: {
define: {
__VUE_OPTIONS_API__: false
},
optimizeDeps: {
include: ['gsap', 'dynamics.js'],
exclude: []
},
// @ts-ignore
ssr: {
external: []
},
server: {
host: true,
fs: {
// for when developing with locally linked theme
allow: ['../..']
}
},
build: {
minify: 'terser',
chunkSizeWarningLimit: Infinity
},
json: {
stringify: true
}
},
vue: {
reactivityTransform: true
}
}

View File

@@ -0,0 +1,55 @@
<script setup>
/**
* Adding a new banner:
* 1. uncomment the banner slot in ../index.ts
* 2. uncomment and update BANNER_ID in ../../inlined-scripts/restorePreferences.ts
* 3. update --vt-banner-height if necessary
*/
let open = $ref(true)
/**
* Call this if the banner is dismissible
*/
function dismiss() {
open = false
document.documentElement.classList.add('banner-dismissed')
localStorage.setItem(`vue-docs-banner-${__VUE_BANNER_ID__}`, 'true')
}
</script>
<template>
<div class="banner" v-if="open"></div>
</template>
<style>
html:not(.banner-dismissed) {
--vt-banner-height: 24px;
}
</style>
<style scoped>
.banner {
position: fixed;
z-index: var(--vp-z-index-banner);
box-sizing: border-box;
top: 0;
left: 0;
right: 0;
height: var(--vt-banner-height);
line-height: var(--vt-banner-height);
text-align: center;
font-size: 12px;
font-weight: 600;
color: #fff;
background-color: var(--vt-c-green);
}
.banner-dismissed .banner {
display: none;
}
a {
text-decoration: underline;
}
</style>

View File

@@ -0,0 +1,24 @@
<script lang="ts" setup>
import { useData } from 'vitepress'
const { theme } = useData()
</script>
<template>
<div
class="text-center border-t dark:border-black leading-loose py-6 text-xs"
>
<p v-if="theme.license" class="license">
Released under the
<a class="link" :href="theme.license.link" no-icon>
{{ theme.license.text }} </a
>.
</p>
<p
v-if="theme.copyright"
class="copyright"
v-html="theme.copyright"
></p>
</div>
</template>

View File

@@ -0,0 +1,25 @@
<script setup lang="ts">
import SponsorsGroup from './SponsorsGroup.vue'
import { useData } from 'vitepress'
const { frontmatter } = useData()
</script>
<template>
<div v-if="frontmatter.sponsors !== false">
<a class="sponsors-aside-text">Sponsors</a>
<SponsorsGroup tier="special" />
<SponsorsGroup tier="platinum" />
</div>
</template>
<style>
a.sponsors-aside-text {
color: var(--vt-c-text-3);
display: block;
margin: 3em 0 1em;
font-weight: 700;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.4px;
}
</style>

View File

@@ -0,0 +1,201 @@
<script lang="ts">
interface Sponsor {
url: string
img: string
name: string
}
interface SponsorData {
special: Sponsor[]
platinum: Sponsor[]
platinum_china: Sponsor[]
gold: Sponsor[]
silver: Sponsor[]
bronze: Sponsor[]
}
// shared data across instances so we load only once
let data = $ref<SponsorData>()
let pending = false
</script>
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'
const { tier, placement = 'aside' } = defineProps<{
tier: keyof SponsorData
placement?: 'aside' | 'page' | 'landing'
}>()
let container = $ref<HTMLElement>()
let visible = $ref(false)
onMounted(async () => {
// only render when entering view
const observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting) {
visible = true
observer.disconnect()
}
},
{ rootMargin: '0px 0px 300px 0px' }
)
observer.observe(container)
onUnmounted(() => observer.disconnect())
// load data
if (!pending) {
pending = true
// data = await (await fetch(`${base}/data.json`)).json()
}
})
</script>
<template>
<div
ref="container"
class="sponsor-container"
:class="[tier.startsWith('plat') ? 'platinum' : tier, placement]"
>
<template v-if="data && visible">
<a
v-for="{ url, img, name } of data[tier]"
class="sponsor-item"
:href="url"
target="_blank"
rel="sponsored noopener"
>
<picture v-if="img.endsWith('png')">
<source
type="image/avif"
:srcset="`${base}/images/${img.replace(/\.png$/, '.avif')}`"
/>
<img :src="`${base}/images/${img}`" :alt="name" />
</picture>
<img v-else :src="`${base}/images/${img}`" :alt="name" />
</a>
</template>
<a
v-if="placement !== 'page' && tier !== 'special'"
href="https://github.com/sponsors/overtrue"
class="sponsor-item action"
>Your logo</a
>
</div>
</template>
<style scoped>
.sponsor-container {
--max-width: 100%;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(var(--max-width), 1fr));
column-gap: 4px;
}
.sponsor-container.platinum {
--max-width: 240px;
}
.sponsor-container.gold {
--max-width: 180px;
}
.sponsor-container.silver {
--max-width: 140px;
}
.sponsor-item {
margin: 2px 0;
background-color: var(--vt-c-white-soft);
display: flex;
justify-content: space-around;
align-items: center;
border-radius: 2px;
transition: background-color 0.2s ease;
height: calc(var(--max-width) / 2 - 6px);
}
.sponsor-item.action {
font-size: 11px;
color: var(--vt-c-text-3);
}
.sponsor-item img {
max-width: calc(var(--max-width) - 30px);
max-height: calc(var(--max-width) / 2 - 20px);
}
.special .sponsor-item {
height: 160px;
}
.special .sponsor-item img {
max-width: 300px;
max-height: 150px;
}
/* dark mode */
.dark .aside .sponsor-item,
.dark .landing .sponsor-item {
background-color: var(--vt-c-bg-soft);
}
.aside .sponsor-item img,
.landing .sponsor-item img {
transition: filter 0.2s ease;
}
.dark .aside .sponsor-item img,
.dark .landing .sponsor-item img {
filter: grayscale(1) invert(1);
}
.dark .aside .sponsor-item:hover,
.dark .landing .sponsor-item:hover {
color: var(--vt-c-indigo);
background-color: var(--vt-c-white-mute);
}
.dark .sponsor-item:hover img {
filter: none;
}
/* aside mode (on content pages) */
.sponsor-container.platinum.aside {
--max-width: 110px;
column-gap: 1px;
}
.aside .sponsor-item {
margin: 1px 0;
}
.aside .special .sponsor-item {
width: 100%;
height: 60px;
}
.aside .special .sponsor-item img {
width: 120px;
}
.aside .platinum .sponsor-item {
width: 111px;
height: 50px;
}
.aside .platinum .sponsor-item img {
max-width: 88px;
}
/* narrow, aside will be hidden under this state so it's mutually exclusive */
@media (max-width: 720px) {
.sponsor-container.platinum {
--max-width: 180px;
}
.sponsor-container.gold {
--max-width: 140px;
}
.sponsor-container.silver {
--max-width: 120px;
}
}
@media (max-width: 480px) {
.sponsor-container.platinum {
--max-width: 150px;
}
.sponsor-container.gold {
--max-width: 120px;
}
.sponsor-container.silver {
--max-width: 100px;
}
}
</style>

View File

@@ -0,0 +1,7 @@
<template>
<sup
class="bg-green-500 text-xs text-white px-2 py-1 rounded-lg align-top rounded-bl-none"
title="该特性需要更新到此版本可用"
><slot
/></sup>
</template>

View File

@@ -0,0 +1,21 @@
import './styles/index.css'
import { h, App } from 'vue'
import SponsorsAside from './components/SponsorsAside.vue'
import VersionTag from './components/VersionTag.vue'
import Footer from './components/Footer.vue'
import DefaultTheme from 'vitepress/theme'
export default Object.assign({
...DefaultTheme,
Layout: () => {
// @ts-ignore
return h(DefaultTheme.Layout, null, {
// banner: () => h(Banner),
'aside-mid': () => h(SponsorsAside),
'layout-bottom': () => h(Footer)
})
},
enhanceApp({ app }: { app: App }) {
app.component('version-tag', VersionTag)
}
})

View File

@@ -0,0 +1,28 @@
.vt-badge.wip:before {
content: 'WIP';
}
.vt-badge.ts {
background-color: #3178c6;
}
.vt-badge.ts:before {
content: 'TS';
}
.vt-badge.dev-only,
.vt-badge.experimental {
color: var(--vt-c-text-light-1);
background-color: var(--vt-c-yellow);
}
.vt-badge.dev-only:before {
content: 'Dev only';
}
.vt-badge.experimental:before {
content: 'Experimental';
}
.vt-badge[data-text]:before {
content: attr(data-text);
}

View File

@@ -0,0 +1,11 @@
@import './layout.css';
@import './pages.css';
@import './badges.css';
@import './options-boxes.css';
@import './inline-demo.css';
@import './utilities.css';
@import './style-guide.css';
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -0,0 +1,90 @@
.vt-doc a[href^="https://sfc.vuejs.org"]:before
{
content: '▶';
width: 20px;
height: 20px;
display: inline-block;
border-radius: 10px;
vertical-align: middle;
position: relative;
top: -2px;
color: var(--vt-c-green);
border: 2px solid var(--vt-c-green);
margin-right: 8px;
margin-left: 4px;
line-height: 15px;
padding-left: 4.5px;
font-size: 11px;
}
.demo {
padding: 22px 24px;
border-radius: 8px;
box-shadow: var(--vt-shadow-2);
margin-bottom: 1.2em;
transition: background-color 0.5s ease;
}
.dark .demo {
background-color: var(--vt-c-bg-soft);
}
.demo p {
margin: 0;
}
.demo button {
background-color: var(--vt-c-bg-mute);
transition: background-color 0.5s;
padding: 5px 12px;
border: 1px solid var(--vt-c-divider);
border-radius: 8px;
font-size: 0.9em;
font-weight: 600;
}
.demo button + button {
margin-left: 1em;
}
.demo input,
.demo textarea,
.demo select {
border: 1px solid var(--vt-c-divider);
border-radius: 4px;
padding: 0.2em 0.6em;
margin-top: 10px;
background: transparent;
transition: background-color 0.5s;
}
.dark .demo select {
background: var(--vt-c-bg-soft);
}
.dark .demo select option {
background: transparent;
}
.demo input:not([type]):focus,
.demo textarea:focus,
.demo select:focus {
outline: 1px solid blue;
}
.demo select {
/* this was set by normalize.css */
-webkit-appearance: listbox;
}
.demo label {
margin: 0 1em 0 0.4em;
}
.demo select[multiple] {
width: 100px;
}
.demo h1 {
margin: 10px 0 0;
}

View File

@@ -0,0 +1,7 @@
.VPContent,
.VPContent .VPContentPage,
.VPContent .VPContentPage main,
.VPContent .VPContentPage main > div,
.VPContent .VPContentPage main > div > div {
@apply flex-1 flex flex-col;
}

View File

@@ -0,0 +1,27 @@
.next-steps {
margin-top: 3rem;
}
.next-steps .vt-box {
border: 1px solid var(--vt-c-bg-soft);
}
.next-steps .vt-box:hover {
border-color: var(--vt-c-green-light);
transition: border-color 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}
.vt-doc .next-steps-link {
font-size: 20px;
line-height: 1.4;
letter-spacing: -0.02em;
margin-bottom: 0.75em;
display: block;
color: var(--vt-c-green);
}
.vt-doc .next-steps-caption {
margin-bottom: 0;
color: var(--vt-c-text-2);
transition: color 0.5s;
}

View File

@@ -0,0 +1,15 @@
/* always show anchors on /api/ and /style-guide/ pages */
.vt-doc.api h2 .header-anchor,
.vt-doc.style-guide h2 .header-anchor {
opacity: 1;
}
.vt-doc.sponsor h3 {
text-align: center;
padding-bottom: 1em;
border-bottom: 1px solid var(--vt-c-divider-light);
}
.vt-doc.sponsor h3 .header-anchor {
display: none;
}

View File

@@ -0,0 +1,61 @@
.style-example {
border-radius: 8px 8px 12px 12px;
margin: 1.6em 0;
padding: 1.6em 1.6em 0.1px;
position: relative;
border: 1px solid transparent;
transition: background-color 0.25s ease, border-color 0.25s ease;
}
.vt-doc .style-example h3 {
margin: 0;
font-size: 1.1em;
}
.style-example-bad {
background: #f7e8e8;
}
.dark .style-example-bad {
background: transparent;
border-color: var(--vt-c-red);
}
.style-example-bad h3 {
color: var(--vt-c-red);
}
.style-example-good {
background: #ecfaf7;
}
.dark .style-example-good {
background: transparent;
border-color: var(--vt-c-green);
}
.style-example-good h3 {
color: var(--vt-c-green);
}
.details summary {
font-weight: bold !important;
}
.style-verb {
font-size: 0.6em;
display: inline-block;
border-radius: 6px;
font-size: 0.65em;
line-height: 1;
font-weight: 600;
padding: 0.35em 0.4em 0.3em;
position: relative;
top: -0.15em;
margin-right: 0.5em;
color: var(--vt-c-bg);
transition: color 0.5s;
background-color: var(--vt-c-brand);
}
.style-verb.avoid {
background-color: var(--vt-c-red);
}

View File

@@ -0,0 +1,14 @@
.nowrap {
white-space: nowrap;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}

View File

@@ -0,0 +1 @@
export default ["6.x", "5.x", "4.x", "3.x"];