Skip to content

Commit

Permalink
docs: ✏️ 优化演示demo支持在顶部显示对应页面微信小程序的二维码
Browse files Browse the repository at this point in the history
  • Loading branch information
Moonofweisheng committed Dec 14, 2024
1 parent 7ed7dd3 commit b1f42af
Show file tree
Hide file tree
Showing 83 changed files with 253 additions and 16 deletions.
119 changes: 119 additions & 0 deletions build/qrcode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// 调用微信api生成每个页面的小程序码,使用axios发起请求

const fs = require('fs')
const path = require('path')
const axios = require('axios')
const JSON5 = require('json5') // 引入 json5 库

const appID = process.argv[process.argv.indexOf('--APP_ID') + 1] // 在 --APP_ID 后面
const appSecret = process.argv[process.argv.indexOf('--APP_SECRET') + 1] // --APP_SECRET 后面

// 获取 access_token 的函数
async function getAccessToken() {
const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appID}&secret=${appSecret}`

try {
const response = await axios.get(url)
return response.data.access_token
} catch (error) {
console.error(`获取 access_token 失败: ${error.response ? error.response.data : error.message}`)
throw error // 抛出错误以便后续处理
}
}

// 读取 pages.json 文件
const pagesJsonPath = path.join(__dirname, '../src/pages.json') // 计算 pages.json 的路径
let pagesJson

try {
const jsonData = fs.readFileSync(pagesJsonPath, 'utf8')
pagesJson = JSON5.parse(jsonData) // 使用 json5 解析带注释的 JSON
} catch (error) {
console.error(`读取或解析 pages.json 失败: ${error.message}`)
process.exit(1) // 退出程序
}

const pages = pagesJson.pages.filter((page) => page.path.endsWith('Index'))

// 将驼峰命名法转换为小写短横线连接的函数
function camelToKebabCase(str) {
return str
.replace(/([a-z])([A-Z])/g, '$1-$2') // 在小写字母和大写字母之间插入短横线
.replace(/([A-Z])/g, '-$1') // 在大写字母前插入短横线
.replace(/--+/g, '-') // 替换多个短横线为一个短横线
.replace(/^-|-$/g, '') // 去掉开头和结尾的短横线
.toLowerCase() // 转换为小写
}

// 删除 wxqrcode 目录及其内容
function clearWxqrcodeDirectory(outputDir) {
if (fs.existsSync(outputDir)) {
fs.rmSync(outputDir, { recursive: true, force: true }) // 递归删除目录及其内容
console.log(`已删除目录: ${outputDir}`)
}
}

// 生成小程序码的函数
async function generateMiniProgramCode(accessToken, pagePath, retries = 3) {
const url = `https://api.weixin.qq.com/wxa/getwxacode?access_token=${accessToken}`
const data = {
path: pagePath,
width: 430 // 小程序码的宽度,可以根据需要调整
}

for (let attempt = 1; attempt <= retries; attempt++) {
try {
const response = await axios.post(url, data, {
responseType: 'arraybuffer' // 以二进制形式接收图片数据
})

// 确保输出目录存在
const outputDir = path.join(__dirname, '../docs/public/wxqrcode')
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true }) // 创建目录及其父目录
}

// 提取组件名并转换格式
const componentName = pagePath.split('/')[1] // 假设路径格式为 pages/组件名/Index
const formattedName = camelToKebabCase(componentName) // 转换为小写短横线连接

// 将返回的图片数据保存为文件
const fileName = path.join(outputDir, `${formattedName}.png`) // 生成文件名
fs.writeFileSync(fileName, response.data)
console.log(`小程序码已生成并保存为 ${fileName}`)
return // 成功后退出函数
} catch (error) {
console.error(`生成小程序码失败: ${error.response ? error.response.data : error.message}`)
if (attempt < retries) {
console.log(`重试 ${attempt}/${retries}...`)
} else {
console.error(`所有重试均失败,无法生成小程序码: ${pagePath}`)
}
}
}
}

// 遍历每个页面并生成小程序码
async function generateCodesForAllPages(accessToken) {
for (const page of pages) {
await generateMiniProgramCode(accessToken, page.path)
}
}

// 生成二维码图片
async function genrateQRCodeImage() {
const outputDir = path.join(__dirname, '../docs/public/wxqrcode')

// 在开始生成小程序码之前清空 wxqrcode 目录
clearWxqrcodeDirectory(outputDir)

try {
const accessToken = await getAccessToken()
await generateCodesForAllPages(accessToken)
} catch (error) {
console.error('程序执行失败:', error.message)
}
}

// 生成小程序二维码图片 pnpm qrcode -- --APP_ID xxx --APP_SECRET xxx
genrateQRCodeImage()
48 changes: 48 additions & 0 deletions docs/.vitepress/theme/components/QrCode.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<div @mouseenter="showQRCode = true" @mouseleave="showQRCode = false">
<el-tooltip
placement="bottom"
effect="light"
:visible="showQRCode"
:popper-options="{ modifiers: [{ name: 'offset', options: { offset: [0, 20] } }] }"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
>
<path fill="currentColor" d="M2 2h9v9H2zm2 2v5h5V4zm9-2h9v9h-9zm2 2v5h5V4zM5.5 5.5h2.004v2.004H5.5zm11 0h2.004v2.004H16.5zm-3.504 7.496H15V15h-2.004zm7 0H22V15h-2.004zM2 13h9v9H2zm2 2v5h5v-5zm11.996.996H18v2h2v2h2V22h-2.004v-2h-2v-2h-2zM5.5 16.5h2.004v2.004H5.5zm7.496 3.496H15V22h-2.004z"></path>
</svg>
<template #content>
<div class="qr-code">
<img :src="src" alt="二维码" />
</div>
</template>
</el-tooltip>
</div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import { ElTooltip } from 'element-plus';
interface Props {
/** 二维码资源 */
src: string
}
const props = withDefaults(defineProps<Props>(), {
src: ''
})
const showQRCode = ref(false);
</script>

<style scoped>
.qr-code {
width: 130px; /* 设置二维码的宽度 */
height: auto; /* 高度自适应 */
transition: opacity 0.3s ease; /* 添加过渡效果 */
}
</style>
34 changes: 25 additions & 9 deletions docs/.vitepress/theme/components/VPIframe.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
<div class="demo-header">
<ExternalLink :href="href" class="demo-link" :style="`${expanded ? '' : 'height:0;width:0;opacity:0'}`">
</ExternalLink>
<QrCode class="demo-qrcode" :src="qrcode" v-if="expanded&&qrcode"></QrCode>
<el-icon class="expand-icon" style="cursor: pointer;" @click="toggleExpand">
<component :is="expanded ? Fold : Expand" />
</el-icon>
</div>
<!-- iframe 容器 -->
<div class="iframe-container">
<iframe v-if="expanded" ref="iframe" id="demo" class="iframe" scrolling="auto" frameborder="0" :src="href" />
<iframe v-if="expanded&&transitionEnd" ref="iframe" id="demo" class="iframe" scrolling="auto" frameborder="0" :src="href" />
</div>
</div>
</template>
Expand All @@ -23,6 +24,8 @@
import { Expand, Fold } from '@element-plus/icons-vue'
import { useRoute, useData } from 'vitepress'
import { computed, onMounted, ref, watch } from 'vue'
import QrCode from './QrCode.vue'
interface Props {
/** 是否展开状态 */
expanded?: boolean
Expand All @@ -35,7 +38,7 @@ const props = withDefaults(defineProps<Props>(), {
// 状态管理
const baseUrl = ref('')
const iframe = ref<HTMLIFrameElement | null>(null)
const transitionEnd = ref(false)
const transitionEnd = ref(true)
const emit = defineEmits<{
'update:expanded': [boolean] // 更新展开状态
Expand All @@ -54,6 +57,13 @@ const href = computed(() => {
return baseUrl.value + `pages/${kebabToCamel(paths[paths.length - 1])}/Index`
})
const qrcode = computed(() => {
const path = route.path
const paths = path ? path.split('.')[0].split('/') : []
if (!paths.length) return ''
return `/wxqrcode/${kebabToCamel(paths[paths.length - 1])}.png`
})
// 工具函数:转换 kebab-case 为 camelCase
function kebabToCamel(input: string): string {
return input.replace(/-([a-z])/g, (match, group) => group.toUpperCase())
Expand All @@ -74,17 +84,13 @@ function toggleExpand() {
// 触发事件通知父组件
emit('update:expanded', !props.expanded)
emit('state-change', !props.expanded)
if (props.expanded) {
transitionEnd.value = false
}
transitionEnd.value = false
}
// 过渡结束处理
function onTransitionEnd() {
if (!props.expanded) {
transitionEnd.value = true
}
transitionEnd.value = true
}
// iframe 消息通信
Expand Down Expand Up @@ -180,6 +186,16 @@ watch(
color: var(--color);
}
.demo-qrcode{
font-size: 28px !important;
transition: all 0.3s ease-in-out;
position: absolute;
left: calc(50% - 14px);
--color: inherit;
fill: currentColor;
color: var(--color);
}
.expand-icon {
position: absolute;
right: 8px;
Expand Down
Binary file added docs/public/wxqrcode/action-sheet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/backtop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/badge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/calendar-view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/calendar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/card.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/cell.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/checkbox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/circle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/col-picker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/collapse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/config-provider.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/count-down.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/count-to.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/curtain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/datetime-picker-view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/datetime-picker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/divider.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/drop-menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/fab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/floating-panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/form.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/gap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/grid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/wxqrcode/icon.png
Binary file added docs/public/wxqrcode/img-cropper.png
Binary file added docs/public/wxqrcode/img.png
Binary file added docs/public/wxqrcode/index-bar.png
Binary file added docs/public/wxqrcode/index.png
Binary file added docs/public/wxqrcode/input-number.png
Binary file added docs/public/wxqrcode/input.png
Binary file added docs/public/wxqrcode/keyboard.png
Binary file added docs/public/wxqrcode/layout.png
Binary file added docs/public/wxqrcode/loading.png
Binary file added docs/public/wxqrcode/loadmore.png
Binary file added docs/public/wxqrcode/message-box.png
Binary file added docs/public/wxqrcode/navbar.png
Binary file added docs/public/wxqrcode/notice-bar.png
Binary file added docs/public/wxqrcode/notify.png
Binary file added docs/public/wxqrcode/number-keyboard.png
Binary file added docs/public/wxqrcode/overlay.png
Binary file added docs/public/wxqrcode/pagination.png
Binary file added docs/public/wxqrcode/password-input.png
Binary file added docs/public/wxqrcode/picker-view.png
Binary file added docs/public/wxqrcode/picker.png
Binary file added docs/public/wxqrcode/popover.png
Binary file added docs/public/wxqrcode/popup.png
Binary file added docs/public/wxqrcode/progress.png
Binary file added docs/public/wxqrcode/radio.png
Binary file added docs/public/wxqrcode/rate.png
Binary file added docs/public/wxqrcode/resize.png
Binary file added docs/public/wxqrcode/search.png
Binary file added docs/public/wxqrcode/segmented.png
Binary file added docs/public/wxqrcode/select-picker.png
Binary file added docs/public/wxqrcode/sidebar.png
Binary file added docs/public/wxqrcode/skeleton.png
Binary file added docs/public/wxqrcode/slider.png
Binary file added docs/public/wxqrcode/sort-button.png
Binary file added docs/public/wxqrcode/status-tip.png
Binary file added docs/public/wxqrcode/steps.png
Binary file added docs/public/wxqrcode/sticky.png
Binary file added docs/public/wxqrcode/swipe-action.png
Binary file added docs/public/wxqrcode/swiper.png
Binary file added docs/public/wxqrcode/switch.png
Binary file added docs/public/wxqrcode/tabbar.png
Binary file added docs/public/wxqrcode/table.png
Binary file added docs/public/wxqrcode/tabs.png
Binary file added docs/public/wxqrcode/tag.png
Binary file added docs/public/wxqrcode/text.png
Binary file added docs/public/wxqrcode/textarea.png
Binary file added docs/public/wxqrcode/toast.png
Binary file added docs/public/wxqrcode/tooltip.png
Binary file added docs/public/wxqrcode/transition.png
Binary file added docs/public/wxqrcode/upload.png
Binary file added docs/public/wxqrcode/watermark.png
Binary file added docs/public/wxqrcode/wx-reward-ad.png
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
"compiler": "npm run clean:lib && node build/compiler.js",
"upload:mp-weixin": "uni build -p mp-weixin && minici --platform weixin",
"upload:mp-alipay": "uni build -p mp-alipay && minici --platform alipay",
"upload:mp-dingtalk": "uni build -p mp-dingtalk && minici --platform dd"
"upload:mp-dingtalk": "uni build -p mp-dingtalk && minici --platform dd",
"qrcode": "node build/qrcode.js"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-4020420240722002",
Expand Down Expand Up @@ -97,13 +98,15 @@
"@vue/runtime-core": "^3.4.38",
"@vue/tsconfig": "^0.1.3",
"@vueuse/core": "^12.0.0",
"axios": "^1.7.9",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.7.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.9.0",
"git-cz": "^4.9.0",
"husky": "^8.0.3",
"inquirer": "8.0.0",
"json5": "^2.2.3",
"lint-staged": "^13.2.0",
"mini-types": "^0.1.7",
"miniprogram-api-typings": "^3.12.3",
Expand Down
Loading

0 comments on commit b1f42af

Please sign in to comment.