Showing
80 changed files
with
2454 additions
and
0 deletions
.env
0 → 100644
.env.development
0 → 100644
| 1 | +# 资源公共路径 | ||
| 2 | +VITE_BASE = / | ||
| 3 | + | ||
| 4 | +# 测试open-id | ||
| 5 | +VITE_OPENID = api-test-openid | ||
| 6 | +# VITE_OPENID = o8BRf1gLDWieH3Y3JvbrI_4IjaME | ||
| 7 | +# VITE_OPENID = oJLZq5t9PIKLW9tm1oSUNAuPwssA | ||
| 8 | +# VITE_OPENID = oJLZq5uT_6GwIh2tQWh1F9IoHZ3U | ||
| 9 | +# VITE_OPENID = | ||
| 10 | + | ||
| 11 | +# B端账号 | ||
| 12 | +VITE_ID = 13761653761 | ||
| 13 | + | ||
| 14 | +# 验证码 | ||
| 15 | +VITE_PIN = | ||
| 16 | + | ||
| 17 | +# 反向代理服务器地址 | ||
| 18 | +VITE_PROXY_TARGET = https://oa-dev.onwall.cn | ||
| 19 | +# VITE_PROXY_TARGET = http://oa.onwall.cn | ||
| 20 | + | ||
| 21 | +# PC端地址 | ||
| 22 | +VITE_MOBILE_URL = http://localhost:5173/ |
.env.production
0 → 100644
| 1 | +### | ||
| 2 | + # @Date: 2023-08-24 15:30:45 | ||
| 3 | + # @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + # @LastEditTime: 2023-08-24 16:02:52 | ||
| 5 | + # @FilePath: /xysBooking/.env.production | ||
| 6 | + # @Description: 文件描述 | ||
| 7 | +### | ||
| 8 | +# 资源公共路径 | ||
| 9 | +VITE_BASE = /f/xysBooking/ | ||
| 10 | + | ||
| 11 | +# 测试open-id | ||
| 12 | +VITE_APP_OPENID = | ||
| 13 | + | ||
| 14 | +# B端账号 | ||
| 15 | +VITE_APP_ID = | ||
| 16 | + | ||
| 17 | +# 验证码 | ||
| 18 | +VITE_APP_PIN = | ||
| 19 | + | ||
| 20 | +# 反向代理服务器地址 | ||
| 21 | +VITE_PROXY_TARGET = https://oa.onwall.cn | ||
| 22 | + | ||
| 23 | +# PC端地址 | ||
| 24 | +# VITE_MOBILE_URL = http://oa.onwall.cn/f/guanzong/web/ | ||
| 25 | +# VITE_MOBILE_URL = http://guanzong.onwall.cn/f/guanzong/web/ |
.eslintrc-auto-import.json
0 → 100644
| 1 | +{ | ||
| 2 | + "globals": { | ||
| 3 | + "EffectScope": true, | ||
| 4 | + "computed": true, | ||
| 5 | + "createApp": true, | ||
| 6 | + "customRef": true, | ||
| 7 | + "defineAsyncComponent": true, | ||
| 8 | + "defineComponent": true, | ||
| 9 | + "effectScope": true, | ||
| 10 | + "getCurrentInstance": true, | ||
| 11 | + "getCurrentScope": true, | ||
| 12 | + "h": true, | ||
| 13 | + "inject": true, | ||
| 14 | + "isProxy": true, | ||
| 15 | + "isReactive": true, | ||
| 16 | + "isReadonly": true, | ||
| 17 | + "isRef": true, | ||
| 18 | + "markRaw": true, | ||
| 19 | + "nextTick": true, | ||
| 20 | + "onActivated": true, | ||
| 21 | + "onBeforeMount": true, | ||
| 22 | + "onBeforeUnmount": true, | ||
| 23 | + "onBeforeUpdate": true, | ||
| 24 | + "onDeactivated": true, | ||
| 25 | + "onErrorCaptured": true, | ||
| 26 | + "onMounted": true, | ||
| 27 | + "onRenderTracked": true, | ||
| 28 | + "onRenderTriggered": true, | ||
| 29 | + "onScopeDispose": true, | ||
| 30 | + "onServerPrefetch": true, | ||
| 31 | + "onUnmounted": true, | ||
| 32 | + "onUpdated": true, | ||
| 33 | + "provide": true, | ||
| 34 | + "reactive": true, | ||
| 35 | + "readonly": true, | ||
| 36 | + "ref": true, | ||
| 37 | + "resolveComponent": true, | ||
| 38 | + "shallowReactive": true, | ||
| 39 | + "shallowReadonly": true, | ||
| 40 | + "shallowRef": true, | ||
| 41 | + "toRaw": true, | ||
| 42 | + "toRef": true, | ||
| 43 | + "toRefs": true, | ||
| 44 | + "triggerRef": true, | ||
| 45 | + "unref": true, | ||
| 46 | + "useAttrs": true, | ||
| 47 | + "useCssModule": true, | ||
| 48 | + "useCssVars": true, | ||
| 49 | + "useRoute": true, | ||
| 50 | + "useRouter": true, | ||
| 51 | + "useSlots": true, | ||
| 52 | + "watch": true, | ||
| 53 | + "watchEffect": true, | ||
| 54 | + "watchPostEffect": true, | ||
| 55 | + "watchSyncEffect": true | ||
| 56 | + } | ||
| 57 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
.gitignore
0 → 100644
.jshintrc
0 → 100644
build/proxy.js
0 → 100644
components.d.ts
0 → 100644
| 1 | +// generated by unplugin-vue-components | ||
| 2 | +// We suggest you to commit this file into source control | ||
| 3 | +// Read more: https://github.com/vuejs/core/pull/3399 | ||
| 4 | +import '@vue/runtime-core' | ||
| 5 | + | ||
| 6 | +export {} | ||
| 7 | + | ||
| 8 | +declare module '@vue/runtime-core' { | ||
| 9 | + export interface GlobalComponents { | ||
| 10 | + RouterLink: typeof import('vue-router')['RouterLink'] | ||
| 11 | + RouterView: typeof import('vue-router')['RouterView'] | ||
| 12 | + VanButton: typeof import('vant/es')['Button'] | ||
| 13 | + VanCalendar: typeof import('vant/es')['Calendar'] | ||
| 14 | + VanCol: typeof import('vant/es')['Col'] | ||
| 15 | + VanDialog: typeof import('vant/es')['Dialog'] | ||
| 16 | + VanField: typeof import('vant/es')['Field'] | ||
| 17 | + VanForm: typeof import('vant/es')['Form'] | ||
| 18 | + VanIcon: typeof import('vant/es')['Icon'] | ||
| 19 | + VanRadio: typeof import('vant/es')['Radio'] | ||
| 20 | + VanRadioGroup: typeof import('vant/es')['RadioGroup'] | ||
| 21 | + VanRow: typeof import('vant/es')['Row'] | ||
| 22 | + } | ||
| 23 | +} |
index.html
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2023-06-13 13:26:46 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-10-25 17:30:49 | ||
| 5 | + * @FilePath: /xysBooking/index.html | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | +--> | ||
| 8 | +<!DOCTYPE html> | ||
| 9 | +<html lang='zh'> | ||
| 10 | +<head> | ||
| 11 | + <meta charset="UTF-8"> | ||
| 12 | + <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" /> | ||
| 13 | + <!-- <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"> --> | ||
| 14 | + <title></title> | ||
| 15 | + <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.compat.css" /> --> | ||
| 16 | +</head> | ||
| 17 | +<body> | ||
| 18 | + <div id="app"></div> | ||
| 19 | + <script type="module" src="/src/main.js"></script> | ||
| 20 | +</body> | ||
| 21 | +</html> |
package-lock.json
0 → 100644
This diff could not be displayed because it is too large.
package.json
0 → 100644
| 1 | +{ | ||
| 2 | + "name": "xysBooking", | ||
| 3 | + "description": "项目, 编译上传直接执行publish, 不需要其他额外操作。", | ||
| 4 | + "version": "1.0.0", | ||
| 5 | + "scripts": { | ||
| 6 | + "dev": "vite", | ||
| 7 | + "start": "vite --host 0.0.0.0", | ||
| 8 | + "build": "vite build", | ||
| 9 | + "build-watch": "vite build --watch", | ||
| 10 | + "build-ts": "vue-tsc --noEmit && vite build", | ||
| 11 | + "serve": "vite preview", | ||
| 12 | + "cypress:open": "cypress open" | ||
| 13 | + }, | ||
| 14 | + "dependencies": { | ||
| 15 | + "@vant/area-data": "^1.3.1", | ||
| 16 | + "@vant/touch-emulator": "^1.4.0", | ||
| 17 | + "@vitejs/plugin-legacy": "^1.8.2", | ||
| 18 | + "@vueuse/core": "^8.5.0", | ||
| 19 | + "animate.css": "^4.1.1", | ||
| 20 | + "browser-md5-file": "^1.1.1", | ||
| 21 | + "dayjs": "^1.11.3", | ||
| 22 | + "default-passive-events": "^2.0.0", | ||
| 23 | + "global": "^4.4.0", | ||
| 24 | + "html2canvas": "^1.4.1", | ||
| 25 | + "jquery": "^3.6.0", | ||
| 26 | + "js-cookie": "^3.0.1", | ||
| 27 | + "js-sha1": "^0.6.0", | ||
| 28 | + "lodash": "^4.17.21", | ||
| 29 | + "moment": "^2.29.3", | ||
| 30 | + "mui-player": "^1.7.0", | ||
| 31 | + "sha1": "^1.1.1", | ||
| 32 | + "typescript": "^4.7.3", | ||
| 33 | + "uuid": "^8.3.2", | ||
| 34 | + "vant": "^4.8.2", | ||
| 35 | + "vconsole": "^3.14.6", | ||
| 36 | + "vite-plugin-dynamic-import": "^0.9.6", | ||
| 37 | + "vite-plugin-mp": "^1.6.1", | ||
| 38 | + "vue": "^3.2.36", | ||
| 39 | + "weixin-js-sdk": "^1.6.0", | ||
| 40 | + "xijs": "^1.2.6" | ||
| 41 | + }, | ||
| 42 | + "devDependencies": { | ||
| 43 | + "@types/jquery": "^3.5.14", | ||
| 44 | + "@types/lodash": "^4.14.182", | ||
| 45 | + "@types/moment": "^2.13.0", | ||
| 46 | + "@typescript-eslint/parser": "^5.27.1", | ||
| 47 | + "@vitejs/plugin-vue": "^2.3.3", | ||
| 48 | + "@vue/compiler-sfc": "^3.2.36", | ||
| 49 | + "axios": "^0.27.2", | ||
| 50 | + "chai": "^4.3.6", | ||
| 51 | + "cypress": "^9.7.0", | ||
| 52 | + "eslint-plugin-vue": "^9.0.1", | ||
| 53 | + "less": "^4.1.2", | ||
| 54 | + "mocha": "^10.0.0", | ||
| 55 | + "pinia": "^2.0.14", | ||
| 56 | + "postcss-px-to-viewport": "^1.1.1", | ||
| 57 | + "qs": "^6.10.3", | ||
| 58 | + "tslint": "^6.1.3", | ||
| 59 | + "unplugin-auto-import": "^0.8.8", | ||
| 60 | + "unplugin-vue-components": "^0.23.0", | ||
| 61 | + "unplugin-vue-define-options": "^0.6.1", | ||
| 62 | + "vite": "^2.9.9", | ||
| 63 | + "vite-plugin-style-import": "1.4.1", | ||
| 64 | + "vue-esign": "^1.1.4", | ||
| 65 | + "vue-router": "^4.0.15" | ||
| 66 | + } | ||
| 67 | +} |
prettier.config.js
0 → 100644
| 1 | +module.exports = { | ||
| 2 | + printWidth: 100, // 代码行的宽度,通用建议每行最大长度建议为100/120,但最好不超过这两个数。 | ||
| 3 | + tabWidth: 2, // 指定每次缩进的空格数。 | ||
| 4 | + semi: true, // 是否在代码语句结尾添加分号。 | ||
| 5 | + vueIndentScriptAndStyle: true, | ||
| 6 | + singleQuote: true, // 是否使用单引号,JSX单独设置。 | ||
| 7 | + trailingComma: 'all', // 在多行以逗号分割的句法中尽可能补充尾行逗号。 | ||
| 8 | + bracketSpacing: true, // 是否在对象属性与大括号之间填充空格。 | ||
| 9 | + bracketSameLine: false, // 开始标签的右尖括号是否跟随在最后一行属性末尾。 | ||
| 10 | + proseWrap: 'never', | ||
| 11 | + htmlWhitespaceSensitivity: 'strict', | ||
| 12 | + endOfLine: 'auto', // 设置换行风格,避免不同操作系统造成的大量代码diff。 | ||
| 13 | + singleAttributePerLine: false // 在Html,Vue,JSX中是否强制每条属性占用一行。 | ||
| 14 | +}; |
publish.sh
0 → 100644
| 1 | +#!/usr/bin/env sh | ||
| 2 | +# ----------------------------------------------- | ||
| 3 | +# Filename: publish.sh | ||
| 4 | +# Revision: 1.0 | ||
| 5 | +# Date: 2022年5月20日 | ||
| 6 | +# Author: Hooke | ||
| 7 | +# Description: **** 根据php项目相应特征书写项目发布流程 | ||
| 8 | +# ----------------------------------------------- | ||
| 9 | + | ||
| 10 | +# 当发生错误时中止脚本 | ||
| 11 | +set -e | ||
| 12 | + | ||
| 13 | +# 本地Git服务器目录路径 | ||
| 14 | +path=/Users/huyirui/program/itomix/git/isp/f | ||
| 15 | + | ||
| 16 | +# 编译输出文件夹 | ||
| 17 | +output=xysBooking | ||
| 18 | + | ||
| 19 | +# 打包 | ||
| 20 | +npm run build | ||
| 21 | + | ||
| 22 | +# 移除Git服务器目录下项目文件夹 | ||
| 23 | +rm -r $path"/${output:?}/images" | ||
| 24 | +rm -r $path"/${output:?}/index.html" | ||
| 25 | +rm -r $path"/${output:?}/static" | ||
| 26 | + | ||
| 27 | +# 把本地编译输出文件夹添加到服务器目录 | ||
| 28 | +mv "${output:?}/images" $path"/${output:?}" | ||
| 29 | +mv "${output:?}/index.html" $path"/${output:?}" | ||
| 30 | +mv "${output:?}/static" $path"/${output:?}" | ||
| 31 | + | ||
| 32 | +# 提交到Git服务器 | ||
| 33 | +cd $path"/${output:?}" | ||
| 34 | +git pull | ||
| 35 | +git add -A | ||
| 36 | +git commit -m '别院预约前端网页更新' | ||
| 37 | +git push | ||
| 38 | + | ||
| 39 | +# 更新SSH服务器上文件 | ||
| 40 | +ssh -p 22 itomix@ipadbiz.cn 'cd /opt/space-dev/ && git pull origin develop' |
src/@types/message/interface.ts
0 → 100644
| 1 | +export interface commentListType { | ||
| 2 | + id: string; | ||
| 3 | + avatar: string; | ||
| 4 | + name: string; | ||
| 5 | + kg_name: string; | ||
| 6 | + comment_time: string; | ||
| 7 | + note: string; | ||
| 8 | + c_action: string; | ||
| 9 | + c_name: string; | ||
| 10 | + cover: string; | ||
| 11 | + prod_id: string; | ||
| 12 | + perf_id: string; | ||
| 13 | + book_id: string; | ||
| 14 | + perf_name: string; | ||
| 15 | + book_name: string; | ||
| 16 | + localism_type: string; | ||
| 17 | + is_new: number; | ||
| 18 | +} |
src/App.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2023-06-13 13:26:46 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2024-01-15 10:04:45 | ||
| 5 | + * @FilePath: /xysBooking/src/App.vue | ||
| 6 | + * @Description: 启动页 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <div class="bg-wrapper"> | ||
| 10 | + <div class="box-wrapper"> | ||
| 11 | + <div class="box-top"></div> | ||
| 12 | + <router-view></router-view> | ||
| 13 | + </div> | ||
| 14 | + </div> | ||
| 15 | +</template> | ||
| 16 | + | ||
| 17 | +<script setup> | ||
| 18 | +import { mainStore, useTitle } from '@/utils/generatePackage' | ||
| 19 | +import { computed, watchEffect, onMounted } from 'vue'; | ||
| 20 | +import { useRoute, useRouter } from 'vue-router' | ||
| 21 | +import { setToastDefaultOptions } from 'vant'; | ||
| 22 | +// 会根据配置判断是否显示调试控件 | ||
| 23 | +// eslint-disable-next-line no-unused-vars | ||
| 24 | +import vConsole from '@/utils/vconsole' | ||
| 25 | +/*// 初始化WX环境 | ||
| 26 | +import wx from 'weixin-js-sdk' | ||
| 27 | +import { wxJsAPI } from '@/api/wx/config' | ||
| 28 | +import { apiList } from '@/api/wx/jsApiList.js'*/ | ||
| 29 | + | ||
| 30 | +import { orderInfoAPI } from '@/api/index' | ||
| 31 | + | ||
| 32 | +// 使用 include + pinia 状态管理动态缓存页面 | ||
| 33 | +const store = mainStore() | ||
| 34 | +const keepPages = computed(() => store.getKeepPages) | ||
| 35 | + | ||
| 36 | +// TAG: 全局设置页面标题 | ||
| 37 | +const $route = useRoute(); | ||
| 38 | +const $router = useRouter(); | ||
| 39 | +watchEffect( | ||
| 40 | + () => useTitle($route.meta.title) | ||
| 41 | +) | ||
| 42 | + | ||
| 43 | +// TAG: 全局配置Toast | ||
| 44 | +setToastDefaultOptions({ | ||
| 45 | + duration: 2000, | ||
| 46 | + className: 'zIndex' | ||
| 47 | +}); | ||
| 48 | + | ||
| 49 | +onMounted(async () => { | ||
| 50 | + /*const { data } = await wxJsAPI(); | ||
| 51 | + data.jsApiList = apiList; | ||
| 52 | + wx.config(data); | ||
| 53 | + wx.ready(() => { | ||
| 54 | + wx.showAllNonBaseMenuItem(); | ||
| 55 | + }); | ||
| 56 | + wx.error((err) => { | ||
| 57 | + console.warn(err); | ||
| 58 | + });*/ | ||
| 59 | + // 进入后先查询有没有订单,有订单直接跳转最终页面 | ||
| 60 | + const { data } = await orderInfoAPI(); | ||
| 61 | + if (data?.id) { | ||
| 62 | + $router.replace({ | ||
| 63 | + path: '/result', | ||
| 64 | + query: { | ||
| 65 | + id: data.id | ||
| 66 | + } | ||
| 67 | + }) | ||
| 68 | + } | ||
| 69 | +}) | ||
| 70 | +</script> | ||
| 71 | + | ||
| 72 | +<style lang="less"> | ||
| 73 | +@prefix: ~'@{namespace}-x'; | ||
| 74 | + | ||
| 75 | +// html, | ||
| 76 | +// body { | ||
| 77 | +// width: 100%; | ||
| 78 | +// height: 100%; | ||
| 79 | +// } | ||
| 80 | + | ||
| 81 | +body { | ||
| 82 | + position: relative; | ||
| 83 | + // --van-white: #fff; | ||
| 84 | + // --van-blue: #1989fa; | ||
| 85 | + // --van-button-primary-color: var(--van-white); | ||
| 86 | + // --van-button-primary-background: var(--van-primary-color); | ||
| 87 | + /* 全局修改主色调 */ | ||
| 88 | + // --van-blue: #F9D95C; | ||
| 89 | + | ||
| 90 | + background-color: #F7EFEB; | ||
| 91 | + | ||
| 92 | + p { | ||
| 93 | + margin: 0; | ||
| 94 | + padding: 0; | ||
| 95 | + } | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +.@{prefix} { | ||
| 99 | + color: red; | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +.global-center { | ||
| 103 | + position: relative; | ||
| 104 | + top: 50%; | ||
| 105 | + transform: translateY(-50%); | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +.zIndex { | ||
| 109 | + z-index: 4500 !important; | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +.bg-wrapper { | ||
| 113 | + padding: 1rem; | ||
| 114 | + padding-bottom: 0; | ||
| 115 | + background-image: url('https://cdn.ipadbiz.cn/bieyuan/bg@2x~1.png'); | ||
| 116 | + background-repeat: no-repeat; | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +.box-wrapper { | ||
| 120 | + background: #FFFFFF; | ||
| 121 | + box-shadow: 0px 0px 13px 0px rgba(95, 69, 54, 0.25); | ||
| 122 | + border-radius: 10px; | ||
| 123 | + border-bottom-right-radius: 0; | ||
| 124 | + border-bottom-left-radius: 0; | ||
| 125 | + min-height: calc(100vh - 1rem); | ||
| 126 | + | ||
| 127 | + .box-top { | ||
| 128 | + padding: 0 1rem 1rem; | ||
| 129 | + height: 1rem; | ||
| 130 | + background-image: url('https://cdn.ipadbiz.cn/bieyuan/top@2x~1.png'); | ||
| 131 | + background-repeat: no-repeat; | ||
| 132 | + background-size: calc(100% - 2rem); | ||
| 133 | + background-position: 1rem 0; | ||
| 134 | + /* 向右位移 1rem */ | ||
| 135 | + } | ||
| 136 | +} | ||
| 137 | +</style> |
src/api/common.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-06-17 14:54:29 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-06-25 09:33:28 | ||
| 5 | + * @FilePath: /huizhu/src/api/common.js | ||
| 6 | + * @Description: 通用接口 | ||
| 7 | + */ | ||
| 8 | +import { fn, fetch, uploadFn } from '@/api/fn'; | ||
| 9 | + | ||
| 10 | +const Api = { | ||
| 11 | + SMS: '/srv/?a=sms', | ||
| 12 | + TOKEN: '/srv/?a=upload', | ||
| 13 | + SAVE_FILE: '/srv/?a=upload&t=save_file', | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * @description: 发送验证码 | ||
| 18 | + * @param {*} phone 手机号码 | ||
| 19 | + * @returns | ||
| 20 | + */ | ||
| 21 | +export const smsAPI = (params) => fn(fetch.post(Api.SMS, params)); | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * @description: 获取七牛token | ||
| 25 | + * @param {*} filename 文件名 | ||
| 26 | + * @param {*} file 图片base64 | ||
| 27 | + * @returns | ||
| 28 | + */ | ||
| 29 | +export const qiniuTokenAPI = (params) => fn(fetch.stringifyPost(Api.TOKEN, params)); | ||
| 30 | + | ||
| 31 | +/** | ||
| 32 | + * @description: 上传七牛 | ||
| 33 | + * @param {*} | ||
| 34 | + * @returns | ||
| 35 | + */ | ||
| 36 | +export const qiniuUploadAPI = (url, data, config) => uploadFn(fetch.basePost(url, data, config)); | ||
| 37 | + | ||
| 38 | +/** | ||
| 39 | + * @description: 保存图片 | ||
| 40 | + * @param {*} format | ||
| 41 | + * @param {*} hash | ||
| 42 | + * @param {*} height | ||
| 43 | + * @param {*} width | ||
| 44 | + * @param {*} filekey | ||
| 45 | + * @returns | ||
| 46 | + */ | ||
| 47 | +export const saveFileAPI = (params) => fn(fetch.stringifyPost(Api.SAVE_FILE, params)); |
src/api/fn.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-05-18 22:56:08 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-08-24 10:56:44 | ||
| 5 | + * @FilePath: /front/src/api/fn.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import axios from '@/utils/axios'; | ||
| 9 | +import { showSuccessToast, showFailToast } from 'vant'; | ||
| 10 | +import qs from 'Qs' | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 网络请求功能函数 | ||
| 14 | + * @param {*} api 请求axios接口 | ||
| 15 | + * @returns 请求成功后,获取数据 | ||
| 16 | + */ | ||
| 17 | +export const fn = (api) => { | ||
| 18 | + return api | ||
| 19 | + .then(res => { | ||
| 20 | + if (res.data.code === 1) { | ||
| 21 | + return res.data || true; | ||
| 22 | + } else { | ||
| 23 | + // tslint:disable-next-line: no-console | ||
| 24 | + console.warn(res); | ||
| 25 | + if (!res.data.show) return false; | ||
| 26 | + showFailToast(res.data.msg); | ||
| 27 | + return false; | ||
| 28 | + } | ||
| 29 | + }) | ||
| 30 | + .catch(err => { | ||
| 31 | + // tslint:disable-next-line: no-console | ||
| 32 | + console.error(err); | ||
| 33 | + return false; | ||
| 34 | + }) | ||
| 35 | + .finally(() => { // 最终执行 | ||
| 36 | + }) | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +/** | ||
| 40 | + * 七牛返回格式 | ||
| 41 | + * @param {*} api | ||
| 42 | + * @returns | ||
| 43 | + */ | ||
| 44 | +export const uploadFn = (api) => { | ||
| 45 | + return api | ||
| 46 | + .then(res => { | ||
| 47 | + if (res.statusText === 'OK') { | ||
| 48 | + return res.data || true; | ||
| 49 | + } else { | ||
| 50 | + // tslint:disable-next-line: no-console | ||
| 51 | + console.warn(res); | ||
| 52 | + if (!res.data.show) return false; | ||
| 53 | + showFailToast(res.data.msg); | ||
| 54 | + return false; | ||
| 55 | + } | ||
| 56 | + }) | ||
| 57 | + .catch(err => { | ||
| 58 | + // tslint:disable-next-line: no-console | ||
| 59 | + console.error(err); | ||
| 60 | + return false; | ||
| 61 | + }) | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +/** | ||
| 65 | + * 统一 GET/POST 不同传参形式 | ||
| 66 | + */ | ||
| 67 | +export const fetch = { | ||
| 68 | + get: function (api, params) { | ||
| 69 | + return axios.get(api, { params }) | ||
| 70 | + }, | ||
| 71 | + post: function (api, params) { | ||
| 72 | + return axios.post(api, params) | ||
| 73 | + }, | ||
| 74 | + stringifyPost: function (api, params) { | ||
| 75 | + return axios.post(api, qs.stringify(params)) | ||
| 76 | + }, | ||
| 77 | + basePost: function (url, data, config) { | ||
| 78 | + return axios.post(url, data, config) | ||
| 79 | + } | ||
| 80 | +} |
src/api/index.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2023-08-24 09:42:27 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-08-24 12:52:26 | ||
| 5 | + * @FilePath: /front/src/api/index.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import { fn, fetch } from '@/api/fn'; | ||
| 9 | + | ||
| 10 | +const Api = { | ||
| 11 | + ORDER_REST_COUNT: '/srv/?a=order_rest_count', | ||
| 12 | + ORDER_INFO: '/srv/?a=order_info', | ||
| 13 | + ORDER_DETAIL_MY_LAST: '/srv/?a=order_detail_my_last', | ||
| 14 | + ORDER_ADD: '/srv/?a=order_add', | ||
| 15 | + ORDER_CANCEL: '/srv/?a=order_cancel', | ||
| 16 | +}; | ||
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * @description: 剩余预约数量列表 | ||
| 20 | + * @param {Array} dates 查询日期 | ||
| 21 | + * @returns | ||
| 22 | + */ | ||
| 23 | +export const orderRestCountAPI = (params) => fn(fetch.get(Api.ORDER_REST_COUNT, params)); | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * @description: 查询预约信息 | ||
| 27 | + * @param {String} id 预约订单ID | ||
| 28 | + * @returns | ||
| 29 | + */ | ||
| 30 | +export const orderInfoAPI = (params) => fn(fetch.get(Api.ORDER_INFO, params)); | ||
| 31 | + | ||
| 32 | +/** | ||
| 33 | + * @description: 我的预约信息 | ||
| 34 | + * @returns | ||
| 35 | + */ | ||
| 36 | +export const orderDetailMyLastAPI = (params) => fn(fetch.get(Api.ORDER_DETAIL_MY_LAST, params)); | ||
| 37 | + | ||
| 38 | +/** | ||
| 39 | + * @description: 保存预约信息 | ||
| 40 | + * @param {Array} dates 日期列表 | ||
| 41 | + * @param {Array} details | ||
| 42 | + * @returns | ||
| 43 | + */ | ||
| 44 | +export const orderAddAPI = (params) => fn(fetch.post(Api.ORDER_ADD, params)); | ||
| 45 | + | ||
| 46 | +/** | ||
| 47 | + * @description: 取消预约 | ||
| 48 | + * @param {String} id 预约订单的ID | ||
| 49 | + * @returns | ||
| 50 | + */ | ||
| 51 | +export const orderCancelAPI = (params) => fn(fetch.post(Api.ORDER_CANCEL, params)); |
src/api/wx/config.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-06-09 13:32:44 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2022-06-14 14:47:01 | ||
| 6 | + * @FilePath: /tswj/src/api/wx/config.js | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | +import { fn, fetch } from '@/api/fn'; | ||
| 10 | + | ||
| 11 | +const Api = { | ||
| 12 | + WX_JSAPI: '/srv/?a=wx_share', | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * @description 获取微信CONFIG配置文件 | ||
| 17 | + * @param {*} url | ||
| 18 | + * @returns {*} cfg | ||
| 19 | + */ | ||
| 20 | +export const wxJsAPI = (params) => fn(fetch.get(Api.WX_JSAPI, params)); |
src/api/wx/jsApiList.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-06-13 14:18:57 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-06-13 14:27:21 | ||
| 5 | + * @FilePath: /tswj/src/api/wx/jsApiList.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +export const apiList = [ | ||
| 9 | + "updateAppMessageShareData", | ||
| 10 | + "updateTimelineShareData", | ||
| 11 | + "onMenuShareTimeline", | ||
| 12 | + "onMenuShareAppMessage", | ||
| 13 | + "onMenuShareQQ", | ||
| 14 | + "onMenuShareWeibo", | ||
| 15 | + "onMenuShareQZone", | ||
| 16 | + "startRecord", | ||
| 17 | + "stopRecord", | ||
| 18 | + "onVoiceRecordEnd", | ||
| 19 | + "playVoice", | ||
| 20 | + "pauseVoice", | ||
| 21 | + "stopVoice", | ||
| 22 | + "onVoicePlayEnd", | ||
| 23 | + "uploadVoice", | ||
| 24 | + "downloadVoice", | ||
| 25 | + "chooseImage", | ||
| 26 | + "previewImage", | ||
| 27 | + "uploadImage", | ||
| 28 | + "downloadImage", | ||
| 29 | + "translateVoice", | ||
| 30 | + "getNetworkType", | ||
| 31 | + "openLocation", | ||
| 32 | + "getLocation", | ||
| 33 | + "hideOptionMenu", | ||
| 34 | + "showOptionMenu", | ||
| 35 | + "hideMenuItems", | ||
| 36 | + "showMenuItems", | ||
| 37 | + "hideAllNonBaseMenuItem", | ||
| 38 | + "showAllNonBaseMenuItem", | ||
| 39 | + "closeWindow", | ||
| 40 | + "scanQRCode", | ||
| 41 | + "chooseWXPay", | ||
| 42 | + "openProductSpecificView", | ||
| 43 | + "addCard", | ||
| 44 | + "chooseCard", | ||
| 45 | + "openCard" | ||
| 46 | +] |
src/api/wx/pay.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-06-09 13:32:44 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2022-06-09 13:42:06 | ||
| 6 | + * @FilePath: /tswj/src/api/wx/config.js | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | +import { fn, fetch } from '@/api/fn'; | ||
| 10 | + | ||
| 11 | +const Api = { | ||
| 12 | + WX_PAY: 'c/bill_paymentForBill.do', | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * @description 微信支付接口 | ||
| 17 | + * @param {*} | ||
| 18 | + * @returns {*} | ||
| 19 | + */ | ||
| 20 | +export const wxPayAPI = (params) => fn(fetch.get(Api.WX_PAY, params)); |
src/assets/css/content-bg.less
0 → 100644
| 1 | + | ||
| 2 | +.modify-top { | ||
| 3 | + z-index: 36; | ||
| 4 | + position: absolute; | ||
| 5 | + left: 0; | ||
| 6 | + top: 0; | ||
| 7 | + width: 100%; | ||
| 8 | + height: 10px; | ||
| 9 | + background-image: url('http://gyzs.onwall.cn/top-xian%402x.png'); | ||
| 10 | + background-size: contain; | ||
| 11 | +} | ||
| 12 | +.content-bg { | ||
| 13 | + /** | ||
| 14 | + * background-color and background-image 共存,不能使用渐变色 | ||
| 15 | + * 图片铺平当时精度提高看看效果 | ||
| 16 | + * 直接用渐变色 | ||
| 17 | + * 不使用渐变色背景 | ||
| 18 | + */ | ||
| 19 | + height: 100%; | ||
| 20 | + min-height: 100vh; | ||
| 21 | + // background-image: url('@images/bg-yellow-duan@2x.png'); | ||
| 22 | + background-image: url('http://gyzs.onwall.cn/bg-yellow-duan%402x.png'); | ||
| 23 | + // background-size: cover; | ||
| 24 | + // background: linear-gradient(360deg, #FDD347 0%, #FFED6D 100%) ; | ||
| 25 | +} |
src/assets/images/+@2x.png
0 → 100644
247 Bytes
src/assets/images/-@2x.png
0 → 100644
129 Bytes
src/assets/images/bg@2x~1.png
0 → 100644
580 KB
src/assets/images/dui@2x.png
0 → 100644
1.31 KB
src/assets/images/error.png
0 → 100644
4.42 KB
src/assets/images/hua01@2x.png
0 → 100644
3.57 KB
src/assets/images/hua02@2x.png
0 → 100644
2.82 KB
src/assets/images/hua03@2x.png
0 → 100644
2.02 KB
src/assets/images/hua04@2x.png
0 → 100644
1.38 KB
src/assets/images/huizhu.png
0 → 100644
5.41 KB
src/assets/images/left001@2x.png
0 → 100644
4.6 KB
src/assets/images/left002@2x.png
0 → 100644
4.4 KB
src/assets/images/right001@2x.png
0 → 100644
4.79 KB
src/assets/images/right002@2x.png
0 → 100644
4.65 KB
src/assets/images/rili@2x.png
0 → 100644
1.15 KB
src/assets/images/success.png
0 → 100644
4.71 KB
src/assets/images/top@2x~1.png
0 → 100644
25.7 KB
src/assets/images/二维码@2x.png
0 → 100644
186 KB
src/assets/styles/base.less
0 → 100644
| 1 | +@namespace: 'tswj'; | ||
| 2 | + | ||
| 3 | +/* ============ 颜色 ============ */ | ||
| 4 | + | ||
| 5 | +// 主色调 | ||
| 6 | +@base-color: #11D2B1; | ||
| 7 | +// 文字颜色 | ||
| 8 | +@base-font-color: #FFFFFF; | ||
| 9 | + | ||
| 10 | +// 定义一个映射 | ||
| 11 | +#colors() { | ||
| 12 | + base-color: @base-color; | ||
| 13 | + base-font-color: @base-font-color; | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +// 混合 | ||
| 17 | +.width100 { | ||
| 18 | + width: 100%; | ||
| 19 | +} |
src/auto-imports.d.ts
0 → 100644
| 1 | +// Generated by 'unplugin-auto-import' | ||
| 2 | +export {} | ||
| 3 | +declare global { | ||
| 4 | + const EffectScope: typeof import('vue')['EffectScope'] | ||
| 5 | + const computed: typeof import('vue')['computed'] | ||
| 6 | + const createApp: typeof import('vue')['createApp'] | ||
| 7 | + const customRef: typeof import('vue')['customRef'] | ||
| 8 | + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] | ||
| 9 | + const defineComponent: typeof import('vue')['defineComponent'] | ||
| 10 | + const effectScope: typeof import('vue')['effectScope'] | ||
| 11 | + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] | ||
| 12 | + const getCurrentScope: typeof import('vue')['getCurrentScope'] | ||
| 13 | + const h: typeof import('vue')['h'] | ||
| 14 | + const inject: typeof import('vue')['inject'] | ||
| 15 | + const isProxy: typeof import('vue')['isProxy'] | ||
| 16 | + const isReactive: typeof import('vue')['isReactive'] | ||
| 17 | + const isReadonly: typeof import('vue')['isReadonly'] | ||
| 18 | + const isRef: typeof import('vue')['isRef'] | ||
| 19 | + const markRaw: typeof import('vue')['markRaw'] | ||
| 20 | + const nextTick: typeof import('vue')['nextTick'] | ||
| 21 | + const onActivated: typeof import('vue')['onActivated'] | ||
| 22 | + const onBeforeMount: typeof import('vue')['onBeforeMount'] | ||
| 23 | + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] | ||
| 24 | + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] | ||
| 25 | + const onDeactivated: typeof import('vue')['onDeactivated'] | ||
| 26 | + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] | ||
| 27 | + const onMounted: typeof import('vue')['onMounted'] | ||
| 28 | + const onRenderTracked: typeof import('vue')['onRenderTracked'] | ||
| 29 | + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] | ||
| 30 | + const onScopeDispose: typeof import('vue')['onScopeDispose'] | ||
| 31 | + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] | ||
| 32 | + const onUnmounted: typeof import('vue')['onUnmounted'] | ||
| 33 | + const onUpdated: typeof import('vue')['onUpdated'] | ||
| 34 | + const provide: typeof import('vue')['provide'] | ||
| 35 | + const reactive: typeof import('vue')['reactive'] | ||
| 36 | + const readonly: typeof import('vue')['readonly'] | ||
| 37 | + const ref: typeof import('vue')['ref'] | ||
| 38 | + const resolveComponent: typeof import('vue')['resolveComponent'] | ||
| 39 | + const shallowReactive: typeof import('vue')['shallowReactive'] | ||
| 40 | + const shallowReadonly: typeof import('vue')['shallowReadonly'] | ||
| 41 | + const shallowRef: typeof import('vue')['shallowRef'] | ||
| 42 | + const toRaw: typeof import('vue')['toRaw'] | ||
| 43 | + const toRef: typeof import('vue')['toRef'] | ||
| 44 | + const toRefs: typeof import('vue')['toRefs'] | ||
| 45 | + const triggerRef: typeof import('vue')['triggerRef'] | ||
| 46 | + const unref: typeof import('vue')['unref'] | ||
| 47 | + const useAttrs: typeof import('vue')['useAttrs'] | ||
| 48 | + const useCssModule: typeof import('vue')['useCssModule'] | ||
| 49 | + const useCssVars: typeof import('vue')['useCssVars'] | ||
| 50 | + const useRoute: typeof import('vue-router')['useRoute'] | ||
| 51 | + const useRouter: typeof import('vue-router')['useRouter'] | ||
| 52 | + const useSlots: typeof import('vue')['useSlots'] | ||
| 53 | + const watch: typeof import('vue')['watch'] | ||
| 54 | + const watchEffect: typeof import('vue')['watchEffect'] | ||
| 55 | + const watchPostEffect: typeof import('vue')['watchPostEffect'] | ||
| 56 | + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] | ||
| 57 | +} |
src/common/mixin.js
0 → 100644
| 1 | +import axios from 'axios'; | ||
| 2 | +import { Toast } from 'vant'; | ||
| 3 | + | ||
| 4 | +export default { | ||
| 5 | + // 初始化设置 | ||
| 6 | + init: { | ||
| 7 | + mounted () { | ||
| 8 | + document.title = this.$route.meta.title; | ||
| 9 | + } | ||
| 10 | + }, | ||
| 11 | + likeFn: { | ||
| 12 | + methods: { | ||
| 13 | + /** | ||
| 14 | + * 用户相关操作 | ||
| 15 | + * @param {String} type 动作类型:like, favor, play | ||
| 16 | + * @param {String} id 作品 ID | ||
| 17 | + */ | ||
| 18 | + handleAction (type, id) { // 用户操作 | ||
| 19 | + axios.post('/srv/?a=prod_action', { | ||
| 20 | + action_type: type, | ||
| 21 | + prod_id: id | ||
| 22 | + }) | ||
| 23 | + .then(res => { | ||
| 24 | + if (res.data.code === 1) { | ||
| 25 | + if (res.data.msg === `${type}-add-OK`) { // 动作操作成功 | ||
| 26 | + this.getProductDetail(type, id); | ||
| 27 | + if (type === 'favor') { | ||
| 28 | + Toast('收藏成功'); | ||
| 29 | + } | ||
| 30 | + if (type === 'like') { | ||
| 31 | + Toast('点赞成功'); | ||
| 32 | + } | ||
| 33 | + } else { // 取消操作 | ||
| 34 | + this.getProductDetail(type, id); | ||
| 35 | + if (type !== 'play') { | ||
| 36 | + Toast('取消成功'); | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + } else { | ||
| 40 | + // tslint:disable-next-line: no-console | ||
| 41 | + console.warn(res); | ||
| 42 | + if (!res.data.show) return false; | ||
| 43 | + Toast({ | ||
| 44 | + icon: 'close', | ||
| 45 | + message: res.data.msg | ||
| 46 | + }); | ||
| 47 | + } | ||
| 48 | + }) | ||
| 49 | + .catch(err => { | ||
| 50 | + // tslint:disable-next-line: no-console | ||
| 51 | + console.error(err); | ||
| 52 | + }); | ||
| 53 | + }, | ||
| 54 | + getProductDetail (type, id) { // 查询更新作品详情 | ||
| 55 | + axios.get('/srv/?a=prod_info', { | ||
| 56 | + params: { | ||
| 57 | + prod_id: id | ||
| 58 | + } | ||
| 59 | + }) | ||
| 60 | + .then(res => { | ||
| 61 | + if (res.data.code === 1) { | ||
| 62 | + this.detail[`is_${type}`] = res.data.data[`is_${type}`]; | ||
| 63 | + this.detail[`${type}_num`] = res.data.data[`${type}_num`]; | ||
| 64 | + } else { | ||
| 65 | + // tslint:disable-next-line: no-console | ||
| 66 | + console.warn(res); | ||
| 67 | + if (!res.data.show) return false; | ||
| 68 | + Toast({ | ||
| 69 | + icon: 'close', | ||
| 70 | + message: res.data.msg | ||
| 71 | + }); | ||
| 72 | + } | ||
| 73 | + }) | ||
| 74 | + .catch(err => { | ||
| 75 | + // tslint:disable-next-line: no-console | ||
| 76 | + console.error(err); | ||
| 77 | + }); | ||
| 78 | + } | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | +}; |
src/common/tool.js
0 → 100644
| 1 | +/** | ||
| 2 | + * 判断多行省略文本 | ||
| 3 | + * @param {*} id 目标dom标签 | ||
| 4 | + * @returns | ||
| 5 | + */ | ||
| 6 | +const hasEllipsis = (id) => { | ||
| 7 | + let oDiv = document.getElementById(id); | ||
| 8 | + let flag = false | ||
| 9 | + if (oDiv.scrollHeight > oDiv.clientHeight) { | ||
| 10 | + flag = true | ||
| 11 | + } | ||
| 12 | + return flag | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +export default { | ||
| 16 | + hasEllipsis | ||
| 17 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/common/vueuse.js
0 → 100644
| 1 | +import { ref } from 'vue' | ||
| 2 | +import { useBrowserLocation, useEventListener, useTitle, useUrlSearchParams, useWindowScroll, logicAnd } from '@vueuse/core' | ||
| 3 | +export const fn = () => { | ||
| 4 | + // const location = useBrowserLocation() | ||
| 5 | + // console.warn(location.value); | ||
| 6 | + | ||
| 7 | + // useEventListener(window, 'scroll', (evt) => { | ||
| 8 | + // const { x, y } = useWindowScroll() | ||
| 9 | + // // console.warn(x.value); | ||
| 10 | + // console.warn(y.value); | ||
| 11 | + // }) | ||
| 12 | + | ||
| 13 | + // useTitle('New Title') | ||
| 14 | + | ||
| 15 | + const a = ref(true) | ||
| 16 | + const b = ref(true) | ||
| 17 | + const flag = a.value && b.value | ||
| 18 | + console.warn(flag); | ||
| 19 | + | ||
| 20 | +} |
src/composables/useLogin.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-06-22 00:07:42 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-06-21 15:58:52 | ||
| 5 | + * @FilePath: /huizhu/src/composables/useLogin.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import { bLoginAPI } from '@/api/B/login' | ||
| 9 | +import { useRouter } from 'vue-router' | ||
| 10 | +import { wxInfo } from '@/utils/tools'; | ||
| 11 | +import { ref } from 'vue' | ||
| 12 | +import { useCountDown } from '@vant/use'; | ||
| 13 | +import { smsAPI } from '@/api/common' | ||
| 14 | +import { showSuccessToast, showFailToast } from 'vant'; | ||
| 15 | + | ||
| 16 | +export const useLogin = () => { | ||
| 17 | + const phone = ref(''); | ||
| 18 | + const code = ref('') | ||
| 19 | + | ||
| 20 | + const refForm = ref(null); | ||
| 21 | + const validateForm = () => { | ||
| 22 | + const valid = refForm.value.validate(); | ||
| 23 | + valid | ||
| 24 | + .then(() => { | ||
| 25 | + refForm.value.submit(); | ||
| 26 | + }) | ||
| 27 | + .catch(error => { | ||
| 28 | + console.error(error); | ||
| 29 | + showFailToast('请检查后再次提交'); | ||
| 30 | + }) | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 判断微信环境看是否弹出控件框 | ||
| 35 | + * 桌面微信直接输入 | ||
| 36 | + * 其他环境弹出输入框 | ||
| 37 | + */ | ||
| 38 | + let use_widget = ref(true); | ||
| 39 | + use_widget.value = !!(wxInfo().isiOS || wxInfo().isAndroid); | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * 手机号码校验 | ||
| 43 | + * 函数返回 true 表示校验通过,false 表示不通过 | ||
| 44 | + * @param {*} val | ||
| 45 | + */ | ||
| 46 | + const sms_disabled = ref(false); | ||
| 47 | + const phoneValidator = (val) => { | ||
| 48 | + let flag = false; | ||
| 49 | + // 简单判断手机号位数 | ||
| 50 | + if (/1\d{10}/.test(val) && phone.value.length === 11) { | ||
| 51 | + sms_disabled.value = false; | ||
| 52 | + flag = true; | ||
| 53 | + } else { | ||
| 54 | + sms_disabled.value = true; | ||
| 55 | + flag = false; | ||
| 56 | + } | ||
| 57 | + return flag | ||
| 58 | + }; | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 手机号数字弹框 | ||
| 62 | + */ | ||
| 63 | + const keyboard_show = ref(false); | ||
| 64 | + const refPhone = ref(null) | ||
| 65 | + const showKeyboard = () => { // 弹出数字弹框 | ||
| 66 | + keyboard_show.value = true; | ||
| 67 | + }; | ||
| 68 | + const keyboardBlur = () => { // 数字键盘失焦回调 | ||
| 69 | + keyboard_show.value = false; | ||
| 70 | + refPhone.value.validate(); | ||
| 71 | + }; | ||
| 72 | + | ||
| 73 | + // 设置发送短信倒计时 | ||
| 74 | + // TAG: vant 自带倒计时函数 | ||
| 75 | + const limitSeconds = ref(60000); // 配置倒计时秒数 | ||
| 76 | + const countDown = useCountDown({ // 配置倒计时 | ||
| 77 | + time: limitSeconds.value, | ||
| 78 | + onFinish: () => { | ||
| 79 | + countDown.reset(); | ||
| 80 | + } | ||
| 81 | + }); | ||
| 82 | + | ||
| 83 | + const sendCode = async () => { // 发送验证码 | ||
| 84 | + countDown.start(); | ||
| 85 | + // 验证码接口 | ||
| 86 | + const { code } = await smsAPI({ phone: phone.value }); | ||
| 87 | + if (code) { | ||
| 88 | + showSuccessToast('发送成功'); | ||
| 89 | + } | ||
| 90 | + }; | ||
| 91 | + | ||
| 92 | + // 过滤输入的数字 只能四位 | ||
| 93 | + const smsFormatter = (value) => value.substring(0, 4); | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * 用户登录 | ||
| 97 | + * @param {*} phone | ||
| 98 | + * @param {*} pin | ||
| 99 | + */ | ||
| 100 | + const $router = useRouter(); | ||
| 101 | + const onSubmit = async (values) => { | ||
| 102 | + const { code } = await bLoginAPI({ phone: values.phone, pin: values.code }) | ||
| 103 | + if (code) { | ||
| 104 | + $router.push({ | ||
| 105 | + path: '/business/index' | ||
| 106 | + }); | ||
| 107 | + } | ||
| 108 | + }; | ||
| 109 | + | ||
| 110 | + return { | ||
| 111 | + phone, | ||
| 112 | + code, | ||
| 113 | + onSubmit, | ||
| 114 | + use_widget, | ||
| 115 | + sms_disabled, | ||
| 116 | + phoneValidator, | ||
| 117 | + keyboardBlur, | ||
| 118 | + keyboard_show, | ||
| 119 | + showKeyboard, | ||
| 120 | + refPhone, | ||
| 121 | + refForm, | ||
| 122 | + validateForm, | ||
| 123 | + smsFormatter, | ||
| 124 | + limitSeconds, | ||
| 125 | + countDown, | ||
| 126 | + sendCode, | ||
| 127 | + } | ||
| 128 | +} |
src/constant.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-05-25 18:34:17 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2023-06-14 09:55:42 | ||
| 6 | + * @FilePath: /huizhu/src/constant.js | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +// 颜色变量 | ||
| 11 | +export const styleColor = { | ||
| 12 | + baseColor: '#11D2B1', | ||
| 13 | + baseFontColor: '#FFFFFF' | ||
| 14 | +} |
src/env.d.ts
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-05-14 23:28:39 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2022-06-07 22:49:56 | ||
| 6 | + * @FilePath: /tswj/src/env.d.ts | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | +interface ImportMetaEnv extends Readonly<Record<string, string>> { | ||
| 10 | + readonly VITE_OPENID: string; | ||
| 11 | + readonly VITE_ID: string; | ||
| 12 | + readonly VITE_PIN: string; | ||
| 13 | + readonly VITE_APPID: string; | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +interface ImportMeta { | ||
| 17 | + readonly env: ImportMetaEnv | ||
| 18 | +} |
src/hooks/injectionSymbols.js
0 → 100644
src/hooks/useContext.js
0 → 100644
| 1 | +import { provide, inject } from "vue"; | ||
| 2 | + | ||
| 3 | +// const key = Symbol(); | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 创建全局变量 | ||
| 7 | + * @param {*} context | ||
| 8 | + * @param {*} key | ||
| 9 | + */ | ||
| 10 | +export function createContext(context, key) { | ||
| 11 | + provide(key, context) | ||
| 12 | +} | ||
| 13 | +/** | ||
| 14 | + * 使用全局变量 | ||
| 15 | + * @param {*} key | ||
| 16 | + * @returns | ||
| 17 | + */ | ||
| 18 | +export function useContext(key) { | ||
| 19 | + return inject(key) | ||
| 20 | +} |
src/hooks/useDebounce.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-05-28 22:31:25 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2022-05-30 10:18:09 | ||
| 6 | + * @FilePath: /tswj/src/hooks/useDebounce.js | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | +import _ from 'lodash'; | ||
| 10 | +/** | ||
| 11 | + * 封装lodash防抖 | ||
| 12 | + * @param {*} fn 执行函数 | ||
| 13 | + * @param {*} timestamp 执行间隔 | ||
| 14 | + * @param {*} options 函数配置 - 在延迟开始前调用,在延迟结束后不调用 | ||
| 15 | + * @returns 返回新的 debounced(防抖动)函数。 | ||
| 16 | + */ | ||
| 17 | +export const useDebounce = (fn, timestamp = 500, options = { leading: true, trailing: false }) => { | ||
| 18 | + return _.debounce(fn, timestamp, options); | ||
| 19 | +} |
src/hooks/useFlowFn.js
0 → 100644
| 1 | + | ||
| 2 | +/** | ||
| 3 | + * @description 封装简化滚动查询列表执行流程 | ||
| 4 | + * @param {*} data 接口返回列表数据 | ||
| 5 | + * @param {*} list 自定义列表 | ||
| 6 | + * @param {*} offset | ||
| 7 | + * @param {*} loading | ||
| 8 | + * @param {*} finished | ||
| 9 | + * @param {*} finishedTextStatus | ||
| 10 | + * @param {*} emptyStatus | ||
| 11 | + */ | ||
| 12 | +import _ from 'lodash' | ||
| 13 | + | ||
| 14 | +export const flowFn = (data, list, offset, loading, finished, finishedTextStatus, emptyStatus) => { | ||
| 15 | + list.value = _.concat(list.value, data); | ||
| 16 | + list.value = _.uniqBy(list.value, 'id'); | ||
| 17 | + offset.value = list.value.length; | ||
| 18 | + loading.value = false; | ||
| 19 | + // 数据全部加载完成 | ||
| 20 | + if (!data.length) { | ||
| 21 | + // 加载状态结束 | ||
| 22 | + finished.value = true; | ||
| 23 | + } | ||
| 24 | + // 空数据提示 | ||
| 25 | + if (!list.value.length) { | ||
| 26 | + finishedTextStatus.value = false; | ||
| 27 | + } | ||
| 28 | + emptyStatus.value = Object.is(list.value.length, 0); | ||
| 29 | +} |
src/hooks/useGo.js
0 → 100644
| 1 | +import { useRouter } from 'vue-router'; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 封装路由跳转方便行内调用 | ||
| 5 | + * @returns | ||
| 6 | + */ | ||
| 7 | +export function useGo () { | ||
| 8 | + let router = useRouter() | ||
| 9 | + function go (path, query) { | ||
| 10 | + router.push({ | ||
| 11 | + path: path, | ||
| 12 | + query: query | ||
| 13 | + }) | ||
| 14 | + } | ||
| 15 | + return go | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +export function useReplace () { | ||
| 19 | + let router = useRouter() | ||
| 20 | + function replace (path, query) { | ||
| 21 | + router.replace({ | ||
| 22 | + path: path, | ||
| 23 | + query: query | ||
| 24 | + }) | ||
| 25 | + } | ||
| 26 | + return replace | ||
| 27 | +} |
src/hooks/useKeepAlive.js
0 → 100644
src/main.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-05-31 12:06:19 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2023-08-22 10:42:53 | ||
| 6 | + * @FilePath: /front/src/main.js | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | +import { createApp } from 'vue'; | ||
| 10 | +import { | ||
| 11 | + Button, | ||
| 12 | + Image as VanImage, | ||
| 13 | + Col, | ||
| 14 | + Row, | ||
| 15 | + Icon, | ||
| 16 | + Form, | ||
| 17 | + Field, | ||
| 18 | + CellGroup, | ||
| 19 | + ConfigProvider, | ||
| 20 | + Toast, | ||
| 21 | + Uploader, | ||
| 22 | + Empty, | ||
| 23 | + Tab, | ||
| 24 | + Tabs, | ||
| 25 | + Overlay, | ||
| 26 | + NumberKeyboard, | ||
| 27 | + Lazyload, | ||
| 28 | + List, | ||
| 29 | + PullRefresh, | ||
| 30 | + Popup, | ||
| 31 | + Picker, | ||
| 32 | + Sticky, | ||
| 33 | + Stepper, | ||
| 34 | + Tag, | ||
| 35 | + Swipe, | ||
| 36 | + SwipeItem, | ||
| 37 | + Dialog, | ||
| 38 | + ActionSheet, | ||
| 39 | + Loading, | ||
| 40 | + Checkbox, | ||
| 41 | + CheckboxGroup, | ||
| 42 | + Search, | ||
| 43 | + Signature, | ||
| 44 | + Calendar, | ||
| 45 | +} from 'vant'; | ||
| 46 | +import router from './router'; | ||
| 47 | +import App from './App.vue'; | ||
| 48 | +// import axios from './utils/axios'; | ||
| 49 | +import axios from '@/utils/axios'; | ||
| 50 | +// import 'default-passive-events'; // 解决Chrome控制台non-passive event listener输出问题 | ||
| 51 | +import { createPinia } from 'pinia'; | ||
| 52 | +import 'vant/lib/index.css'; | ||
| 53 | +import vueEsign from 'vue-esign'; | ||
| 54 | + | ||
| 55 | +const pinia = createPinia(); | ||
| 56 | +const app = createApp(App); | ||
| 57 | + | ||
| 58 | +app.config.globalProperties.$http = axios; // 关键语句 | ||
| 59 | + | ||
| 60 | +app | ||
| 61 | + .use(pinia) | ||
| 62 | + .use(router) | ||
| 63 | + .use(Button) | ||
| 64 | + .use(VanImage) | ||
| 65 | + .use(Col) | ||
| 66 | + .use(Row) | ||
| 67 | + .use(Icon) | ||
| 68 | + .use(Form) | ||
| 69 | + .use(Field) | ||
| 70 | + .use(CellGroup) | ||
| 71 | + .use(Toast) | ||
| 72 | + .use(Uploader) | ||
| 73 | + .use(Empty) | ||
| 74 | + .use(Tab) | ||
| 75 | + .use(Tabs) | ||
| 76 | + .use(Overlay) | ||
| 77 | + .use(NumberKeyboard) | ||
| 78 | + .use(Lazyload) | ||
| 79 | + .use(List) | ||
| 80 | + .use(PullRefresh) | ||
| 81 | + .use(Popup) | ||
| 82 | + .use(Picker) | ||
| 83 | + .use(Sticky) | ||
| 84 | + .use(Stepper) | ||
| 85 | + .use(Tag) | ||
| 86 | + .use(Swipe) | ||
| 87 | + .use(SwipeItem) | ||
| 88 | + .use(Dialog) | ||
| 89 | + .use(ActionSheet) | ||
| 90 | + .use(Loading) | ||
| 91 | + .use(Checkbox) | ||
| 92 | + .use(CheckboxGroup) | ||
| 93 | + .use(Search) | ||
| 94 | + .use(ConfigProvider) | ||
| 95 | + .use(Signature) | ||
| 96 | + .use(Calendar); | ||
| 97 | + | ||
| 98 | +app.use(vueEsign); | ||
| 99 | + | ||
| 100 | +app.mount('#app'); |
src/mock/routes.js
0 → 100644
| 1 | +const routes = [{ | ||
| 2 | + path: '/image', | ||
| 3 | + redirect: '', | ||
| 4 | + name: 'html转图片', | ||
| 5 | + component: 'html2canvas', | ||
| 6 | + keepAlive: '', | ||
| 7 | + meta: { | ||
| 8 | + title: 'html转图片', | ||
| 9 | + name: '' | ||
| 10 | + }, | ||
| 11 | + children: [{ | ||
| 12 | + path: 'children', | ||
| 13 | + redirect: '', | ||
| 14 | + name: 'html转图片', | ||
| 15 | + component: 'children-test', | ||
| 16 | + keepAlive: '', | ||
| 17 | + meta: { | ||
| 18 | + title: 'html转图片', | ||
| 19 | + name: '' | ||
| 20 | + } | ||
| 21 | + }] | ||
| 22 | +}] | ||
| 23 | +// const routes = [] | ||
| 24 | + | ||
| 25 | +export default routes |
src/route.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2023-06-13 13:26:46 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-08-23 14:47:37 | ||
| 5 | + * @FilePath: /front/src/route.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +export default [ | ||
| 9 | + { | ||
| 10 | + path: '/', | ||
| 11 | + component: () => import('@/views/index.vue'), | ||
| 12 | + meta: { | ||
| 13 | + title: '别院预约', | ||
| 14 | + }, | ||
| 15 | + }, | ||
| 16 | + { | ||
| 17 | + path: '/auth', | ||
| 18 | + component: () => import('@/views/auth.vue'), | ||
| 19 | + meta: { | ||
| 20 | + title: '授权页面', | ||
| 21 | + }, | ||
| 22 | + }, | ||
| 23 | +]; |
src/router.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-05-26 13:57:28 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-06-29 21:36:59 | ||
| 5 | + * @FilePath: /tswj/src/router.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import { createRouter, createWebHashHistory } from 'vue-router'; | ||
| 9 | +import RootRoute from './route.js'; | ||
| 10 | +import asyncRoutesArr from "./mock/routes" | ||
| 11 | +import generateRoutes from './utils/generateRoute' | ||
| 12 | + | ||
| 13 | +// TAG: 路由配置表 | ||
| 14 | +/** | ||
| 15 | + * 把项目独有的路由配置到相应的路径,默认路由文件只放公用部分 | ||
| 16 | + * 但是 vue 文件内容还是要事先准备好 | ||
| 17 | + */ | ||
| 18 | +const modules = import.meta.globEager('@/router/routes/modules/**/*.js'); // Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块 | ||
| 19 | +const routeModuleList = []; | ||
| 20 | + | ||
| 21 | +Object.keys(modules).forEach((key) => { | ||
| 22 | + const mod = modules[key].default || {}; | ||
| 23 | + const modList = Array.isArray(mod) ? [...mod] : [mod]; | ||
| 24 | + routeModuleList.push(...modList); | ||
| 25 | +}); | ||
| 26 | + | ||
| 27 | +// 创建路由实例并传递 `routes` 配置 | ||
| 28 | +const router = createRouter({ | ||
| 29 | + history: createWebHashHistory('/index.html'), | ||
| 30 | + routes: [...RootRoute, ...routeModuleList] | ||
| 31 | +}); | ||
| 32 | + | ||
| 33 | +// TAG: 动态生成路由 | ||
| 34 | +/** | ||
| 35 | + * generateRoute 负责把后台返回数据拼接成项目需要的路由结构,动态添加到路由表里面 | ||
| 36 | + */ | ||
| 37 | +router.beforeEach((to, from, next) => { | ||
| 38 | + // 使用404为中转页面,避免动态路由没有渲染出来,控制台报警告问题 | ||
| 39 | + if (to.path == '/404' && to.redirectedFrom != undefined) { | ||
| 40 | + // 模拟异步操作 | ||
| 41 | + setTimeout(() => { | ||
| 42 | + if (!asyncRoutesArr.length) return; // 没有动态路由避免报错 | ||
| 43 | + const arr = generateRoutes(asyncRoutesArr); // 在路由守卫处生成,避免有子路由时刷新白屏问题。 | ||
| 44 | + arr.forEach(item => { | ||
| 45 | + router.addRoute(item) // 新增路由 | ||
| 46 | + }) | ||
| 47 | + // 重写被404覆盖路由信息 | ||
| 48 | + next({ ...to.redirectedFrom, replace: true }); | ||
| 49 | + }, 1000); | ||
| 50 | + } else { | ||
| 51 | + next() | ||
| 52 | + } | ||
| 53 | +}) | ||
| 54 | + | ||
| 55 | +router.afterEach(() => { | ||
| 56 | + // console.warn(to); | ||
| 57 | + // console.warn(wx); | ||
| 58 | + // share(to) | ||
| 59 | +}) | ||
| 60 | + | ||
| 61 | +export default router; |
src/shims-vue.d.ts
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-06-07 22:46:46 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2022-06-08 05:34:56 | ||
| 6 | + * @FilePath: /tswj/src/shims-vue.d.ts | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | +declare module '*.vue' { | ||
| 10 | + import type { DefineComponent } from 'vue'; | ||
| 11 | + const component: DefineComponent; | ||
| 12 | + export default component; | ||
| 13 | +} |
src/store/index.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-04-18 15:59:42 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-08-22 17:36:03 | ||
| 5 | + * @FilePath: /front/src/store/index.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import { defineStore } from 'pinia'; | ||
| 9 | +// import { testStore } from './test'; // 另一个store | ||
| 10 | +import _ from 'lodash'; | ||
| 11 | +import { useRouter } from 'vue-router' | ||
| 12 | + | ||
| 13 | +export const mainStore = defineStore('main', { | ||
| 14 | + state: () => { | ||
| 15 | + return { | ||
| 16 | + msg: 'Hello world', | ||
| 17 | + count: 0, | ||
| 18 | + auth: false, | ||
| 19 | + keepPages: ['default'], // 很坑爹,空值全部都缓存 | ||
| 20 | + appUserInfo: [], // 缓存预约人信息 | ||
| 21 | + }; | ||
| 22 | + }, | ||
| 23 | + getters: { | ||
| 24 | + getKeepPages () { | ||
| 25 | + return this.keepPages | ||
| 26 | + }, | ||
| 27 | + // getTestStoreList () { | ||
| 28 | + // return testStore().list // 返回另一个store的值 | ||
| 29 | + // } | ||
| 30 | + }, | ||
| 31 | + actions: { | ||
| 32 | + changeState (state) { | ||
| 33 | + this.auth = state; | ||
| 34 | + }, | ||
| 35 | + changeKeepPages () { // 清空所有缓存,用一个不存在的值覆盖 | ||
| 36 | + this.keepPages = ['default']; | ||
| 37 | + }, | ||
| 38 | + keepThisPage () { // 新增缓存页 | ||
| 39 | + const $router = useRouter(); | ||
| 40 | + const page = $router.currentRoute.value.meta.name; | ||
| 41 | + this.keepPages.push(page); | ||
| 42 | + }, | ||
| 43 | + removeThisPage () { // 删除缓存页 | ||
| 44 | + const $router = useRouter(); | ||
| 45 | + const page = $router.currentRoute.value.meta.name; | ||
| 46 | + _.remove(this.keepPages, item => item === page) | ||
| 47 | + }, | ||
| 48 | + changeUserInfo (info) { | ||
| 49 | + this.appUserInfo = info; | ||
| 50 | + } | ||
| 51 | + }, | ||
| 52 | +}); |
src/theme-vars.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-05-25 18:34:17 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2022-06-22 01:35:44 | ||
| 6 | + * @FilePath: /tswj/src/theme-vars.js | ||
| 7 | + * @Description: 修改vant默认表单样式 | ||
| 8 | + */ | ||
| 9 | +import { styleColor } from '@/constant.js'; | ||
| 10 | + | ||
| 11 | +export const loginTheme = { | ||
| 12 | + buttonPrimaryBackground: styleColor.baseColor, | ||
| 13 | + buttonPrimaryBorderColor: styleColor.baseColor, | ||
| 14 | + buttonPrimaryColor: styleColor.baseFontColor, | ||
| 15 | + CellVerticalPadding: '14px' | ||
| 16 | +}; |
src/utils/MonitorKeyboard.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-06-20 01:22:50 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-06-20 01:23:18 | ||
| 5 | + * @FilePath: /tswj/src/composables/useMonitorKeyboard.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +/** | ||
| 9 | + * @class 监听虚拟键盘 | ||
| 10 | + * @classdesc 监听虚拟键盘弹出隐藏 | ||
| 11 | + * @public onEnd 结束监听虚拟键盘 | ||
| 12 | + * @public onShow 传递一个回调 监听虚拟键盘弹出 | ||
| 13 | + * @public onHidden 传递一个回调 监听虚拟键盘隐藏 | ||
| 14 | + */ | ||
| 15 | +class MonitorKeyboard { | ||
| 16 | + constructor() { | ||
| 17 | + this.type = this.IsIA(); | ||
| 18 | + this.originalHeight = window.innerHeight; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * @function IsIA 获取设备类型 | ||
| 23 | + * @param 1 Android 2 iOS | ||
| 24 | + */ | ||
| 25 | + IsIA = () => { | ||
| 26 | + const userAgent = typeof window === 'object' ? window.navigator.userAgent : ''; | ||
| 27 | + if (/android/i.test(userAgent)) { | ||
| 28 | + return 1; | ||
| 29 | + } else if (/iPhone|iPod|iPad/i.test(userAgent)) { | ||
| 30 | + return 2; | ||
| 31 | + } | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + // Android系统 | ||
| 35 | + onResize = () => { | ||
| 36 | + //键盘弹起与隐藏都会引起窗口的高度发生变化 | ||
| 37 | + const resizeHeight = window.innerHeight; | ||
| 38 | + | ||
| 39 | + if (this.originalHeight - resizeHeight > 50) { | ||
| 40 | + this.show('Android系统: 软键盘弹出'); | ||
| 41 | + } else { | ||
| 42 | + this.hidden('Android系统: 软键盘收起'); | ||
| 43 | + } | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + // iOS获取焦点 | ||
| 47 | + onFocusin = () => { | ||
| 48 | + this.show('iOS系统:软键盘弹出'); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + // iOS失去焦点 | ||
| 52 | + onFocusout = () => { | ||
| 53 | + this.hidden('iOS系统:软键盘收起'); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * @function onStart 开始监听虚拟键盘 | ||
| 58 | + */ | ||
| 59 | + onStart = () => { | ||
| 60 | + if (this.type == 1) { | ||
| 61 | + // 获取窗口的高度 | ||
| 62 | + window.addEventListener('resize', this.onResize); | ||
| 63 | + } | ||
| 64 | + if (this.type == 2) { | ||
| 65 | + // iOS系统 | ||
| 66 | + window.addEventListener('focusin', this.onFocusin); | ||
| 67 | + window.addEventListener('focusout', this.onFocusout); | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * @function onEnd 结束监听虚拟键盘 | ||
| 73 | + */ | ||
| 74 | + onEnd = () => { | ||
| 75 | + if (this.type == 1) { | ||
| 76 | + //获取窗口的高度 | ||
| 77 | + window.removeEventListener('resize', this.onResize); | ||
| 78 | + } | ||
| 79 | + if (this.type == 2) { | ||
| 80 | + window.removeEventListener('focusin', this.onFocusin); | ||
| 81 | + window.removeEventListener('focusout', this.onFocusout); | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * @function onShow 传递一个回调函数 | ||
| 87 | + * @param 虚拟键盘弹出时触发 | ||
| 88 | + */ | ||
| 89 | + onShow = (fn) => { | ||
| 90 | + this.show = fn; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + /** | ||
| 94 | + * @function onHidden 传递一个回调函数 | ||
| 95 | + * @param 虚拟键盘隐藏时触发 | ||
| 96 | + */ | ||
| 97 | + onHidden = (fn) => { | ||
| 98 | + this.hidden = fn; | ||
| 99 | + } | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +export default MonitorKeyboard |
src/utils/axios.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-05-28 10:17:40 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2023-08-24 10:56:20 | ||
| 6 | + * @FilePath: /front/src/utils/axios.js | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | +import axios from 'axios'; | ||
| 10 | +import router from '@/router'; | ||
| 11 | +import qs from 'Qs' | ||
| 12 | +import { strExist } from '@/utils/tools' | ||
| 13 | +// import { parseQueryString } from '@/utils/tools' | ||
| 14 | + | ||
| 15 | +axios.defaults.params = { | ||
| 16 | + f: 'xysBooking', | ||
| 17 | +}; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * @description 请求拦截器 | ||
| 21 | + */ | ||
| 22 | +axios.interceptors.request.use( | ||
| 23 | + config => { | ||
| 24 | + // const url_params = parseQueryString(location.href); | ||
| 25 | + // GET请求默认打上时间戳,避免从缓存中拿数据。 | ||
| 26 | + const timestamp = config.method === 'get' ? (new Date()).valueOf() : ''; | ||
| 27 | + /** | ||
| 28 | + * POST PHP需要修改数据格式 | ||
| 29 | + * 序列化POST请求时需要屏蔽上传相关接口,上传相关接口序列化后报错 | ||
| 30 | + */ | ||
| 31 | + // config.data = config.method === 'post' && !strExist(['a=upload', 'upload.qiniup.com'], config.url) ? qs.stringify(config.data) : config.data; | ||
| 32 | + // 绑定默认请求头 | ||
| 33 | + config.params = { ...config.params, timestamp } | ||
| 34 | + return config; | ||
| 35 | + }, | ||
| 36 | + error => { | ||
| 37 | + // 请求错误处理 | ||
| 38 | + return Promise.reject(error); | ||
| 39 | + }); | ||
| 40 | + | ||
| 41 | +/** | ||
| 42 | + * @description 响应拦截器 | ||
| 43 | + */ | ||
| 44 | +axios.interceptors.response.use( | ||
| 45 | + response => { | ||
| 46 | + // // 默认显示错误提示 | ||
| 47 | + // response.data.show = true; | ||
| 48 | + // // 判断微信授权状态,进入页面时未授权需要授权跳转 | ||
| 49 | + // // C/B 授权拼接头特殊标识,openid_x | ||
| 50 | + // let prefixAPI = router?.currentRoute.value.href?.indexOf('business') > 0 ? 'b' : 'c'; | ||
| 51 | + if (response.data.code === 401) { | ||
| 52 | + // 特殊标识-带此标识报错不显示 | ||
| 53 | + response.data.show = false; | ||
| 54 | + /** | ||
| 55 | + * 未授权跳转登录页 | ||
| 56 | + * 带着上一个页面的信息, 授权完成后 返回当前页面 | ||
| 57 | + */ | ||
| 58 | + router.replace({ path: '/auth', query: { href: location.hash } }); | ||
| 59 | + } | ||
| 60 | + if (['预约ID不存在'].includes(response.data.msg)) { | ||
| 61 | + response.data.show = false; | ||
| 62 | + } | ||
| 63 | + // // 拦截B端未登录情况 | ||
| 64 | + // if (['老师请先登录!', '老师不存在!'].includes(response.data.msg)) { router.replace({ path: '/business/login' }); } | ||
| 65 | + return response; | ||
| 66 | + }, | ||
| 67 | + error => { | ||
| 68 | + return Promise.reject(error); | ||
| 69 | + }); | ||
| 70 | + | ||
| 71 | +export default axios; |
src/utils/generateIcons.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-05-17 11:34:35 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2022-06-20 16:31:28 | ||
| 6 | + * @FilePath: /tswj/src/utils/generateIcons.js | ||
| 7 | + * @Description: 图标集合 | ||
| 8 | + */ | ||
| 9 | +import icon_video from '@images/video.png' | ||
| 10 | +import icon_up from '@images/icon-guanbi@2x.png' | ||
| 11 | +import icon_down from '@images/icon-zhankai@2x.png' | ||
| 12 | +import icon_subscribed from '@images/icon-dingyue01@2x.png' | ||
| 13 | +import icon_unsubscribe from '@images/icon-dingyue02@2x.png' | ||
| 14 | +import no_image from '@images/que-shuju@2x.png' | ||
| 15 | +import icon_avatar from '@images/que-touxiang@2x.png' | ||
| 16 | +import icon_logo from '@images/que-logo@2x.png' | ||
| 17 | +import icon_dianzan1 from '@images/icon-dianzan01@2x.png' | ||
| 18 | +import icon_dianzan2 from '@images/icon-dianzan02@2x.png' | ||
| 19 | +import icon_shoucang1 from '@images/icon-shoucang01@2x.png' | ||
| 20 | +import icon_shoucang2 from '@images/icon-shoucang02@2x.png' | ||
| 21 | +import icon_liuyan from '@images/icon-liuyan@2x.png' | ||
| 22 | +import icon_book from '@images/shu@2x.png' | ||
| 23 | +import icon_me from '@images/icon-my@2x.png' | ||
| 24 | +import icon_home from '@images/icon-home@2x.png' | ||
| 25 | +import icon_rank from '@images/icon-paihang@2x.png' | ||
| 26 | +import icon_ranking1 from '@images/1@2x.png' | ||
| 27 | +import icon_ranking2 from '@images/2@2x.png' | ||
| 28 | +import icon_ranking3 from '@images/3@2x.png' | ||
| 29 | +import icon_flower from '@images/xiaohua@2x.png' | ||
| 30 | +import icon_refuse from '@images/icon-jujue@2x.png' | ||
| 31 | +import icon_apply from '@images/icon-shenhe@2x.png' | ||
| 32 | +import icon_enable from '@images/icon-tongguo@2x.png' | ||
| 33 | + | ||
| 34 | +export { | ||
| 35 | + icon_video, | ||
| 36 | + icon_up, | ||
| 37 | + icon_down, | ||
| 38 | + icon_subscribed, | ||
| 39 | + icon_unsubscribe, | ||
| 40 | + no_image, | ||
| 41 | + icon_avatar, | ||
| 42 | + icon_logo, | ||
| 43 | + icon_dianzan1, | ||
| 44 | + icon_dianzan2, | ||
| 45 | + icon_liuyan, | ||
| 46 | + icon_shoucang1, | ||
| 47 | + icon_shoucang2, | ||
| 48 | + icon_book, | ||
| 49 | + icon_me, | ||
| 50 | + icon_home, | ||
| 51 | + icon_rank, | ||
| 52 | + icon_ranking1, | ||
| 53 | + icon_ranking2, | ||
| 54 | + icon_ranking3, | ||
| 55 | + icon_flower, | ||
| 56 | + icon_refuse, | ||
| 57 | + icon_apply, | ||
| 58 | + icon_enable, | ||
| 59 | +} |
src/utils/generateModules.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Author: hookehuyr hookehuyr@gmail.com | ||
| 3 | + * @Date: 2022-05-17 11:17:58 | ||
| 4 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 5 | + * @LastEditTime: 2022-07-01 14:55:12 | ||
| 6 | + * @FilePath: /tswj/src/utils/generateModules.js | ||
| 7 | + * @Description: | ||
| 8 | + */ | ||
| 9 | +import MyButton from '@/components/MyButton/index.vue' | ||
| 10 | +import VideoCard from '@/components/VideoCard/index.vue' | ||
| 11 | +import NoticeOverlay from '@/components/NoticeOverlay/index.vue' | ||
| 12 | +import NoticeOverlayModule from '@/components/NoticeOverlayModule/index.vue' | ||
| 13 | +import DonateBook from '@/components/DonateBook/index.vue' | ||
| 14 | +import ShortcutFixed from '@/components/ShortcutFixed/index.vue' | ||
| 15 | +import BookCard from '@/components/BookCard/index.vue' | ||
| 16 | +import VideoDetail from '@/components/VideoDetail/index.vue' | ||
| 17 | +import DonateBar from '@/components/DonateBar/index.vue' | ||
| 18 | +import DonateFlower from '@/components/DonateFlower/index.vue' | ||
| 19 | + | ||
| 20 | +export { | ||
| 21 | + MyButton, | ||
| 22 | + VideoCard, | ||
| 23 | + NoticeOverlay, | ||
| 24 | + NoticeOverlayModule, | ||
| 25 | + DonateBook, | ||
| 26 | + ShortcutFixed, | ||
| 27 | + BookCard, | ||
| 28 | + VideoDetail, | ||
| 29 | + DonateBar, | ||
| 30 | + DonateFlower, | ||
| 31 | +} |
src/utils/generatePackage.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-05-17 11:26:03 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-06-20 14:00:13 | ||
| 5 | + * @FilePath: /tswj/src/utils/generatePackage.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import Cookies from 'js-cookie' | ||
| 9 | +import $ from 'jquery' | ||
| 10 | +import _ from 'lodash' | ||
| 11 | +import axios from '@/utils/axios'; | ||
| 12 | +import { storeToRefs } from 'pinia' | ||
| 13 | +import { mainStore } from '@/store' | ||
| 14 | +import { Toast, Dialog } from 'vant'; | ||
| 15 | +import { wxInfo, hasEllipsis } from '@/utils/tools'; | ||
| 16 | +import { useTitle } from '@vueuse/core' | ||
| 17 | + | ||
| 18 | +export { | ||
| 19 | + Cookies, | ||
| 20 | + $, | ||
| 21 | + _, | ||
| 22 | + axios, | ||
| 23 | + storeToRefs, | ||
| 24 | + mainStore, | ||
| 25 | + Toast, | ||
| 26 | + Dialog, | ||
| 27 | + wxInfo, | ||
| 28 | + hasEllipsis, | ||
| 29 | + useTitle | ||
| 30 | +} |
src/utils/generateRoute.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-05-16 17:21:45 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-06-29 17:00:15 | ||
| 5 | + * @FilePath: /tswj/src/utils/generateRoute.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 根据后台返回的路径,生成页面的组件模版 | ||
| 11 | + * @param {*} component | ||
| 12 | + * @returns 模版地址 | ||
| 13 | + */ | ||
| 14 | +function loadView(component) { | ||
| 15 | + return () => import(`../views/${component}.vue`) | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * 生成路由结构 | ||
| 20 | + * @param {*} routes | ||
| 21 | + */ | ||
| 22 | +const generateRoutes = (routes) => { | ||
| 23 | + const arr = [] | ||
| 24 | + routes.forEach(route => { | ||
| 25 | + const router = {} | ||
| 26 | + const { | ||
| 27 | + path, | ||
| 28 | + redirect, | ||
| 29 | + name, | ||
| 30 | + component, | ||
| 31 | + keepAlive, | ||
| 32 | + meta, | ||
| 33 | + children | ||
| 34 | + } = route | ||
| 35 | + | ||
| 36 | + router.path = path | ||
| 37 | + redirect && (router.redirect = redirect) | ||
| 38 | + name && (router.name = name) | ||
| 39 | + router.component = loadView(component) | ||
| 40 | + keepAlive && (router.keepAlive = keepAlive) | ||
| 41 | + meta && (router.meta = meta) | ||
| 42 | + router.children = !Array.isArray(children) || generateRoutes(children); | ||
| 43 | + arr.push(router) | ||
| 44 | + }) | ||
| 45 | + return arr | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +export default generateRoutes; |
src/utils/qetag.js
0 → 100644
| 1 | +import sha1 from "js-sha1"; | ||
| 2 | + | ||
| 3 | +function getEtag(buffer, callback) { | ||
| 4 | + // sha1算法 | ||
| 5 | + var shA1 = sha1.digest; | ||
| 6 | + | ||
| 7 | + // 以4M为单位分割 | ||
| 8 | + var blockSize = 4 * 1024 * 1024; | ||
| 9 | + var sha1String = []; | ||
| 10 | + var prefix = 0x16; | ||
| 11 | + var blockCount = 0; | ||
| 12 | + | ||
| 13 | + var bufferSize = buffer.size || buffer.length || buffer.byteLength; | ||
| 14 | + blockCount = Math.ceil(bufferSize / blockSize); | ||
| 15 | + | ||
| 16 | + for (var i = 0; i < blockCount; i++) { | ||
| 17 | + sha1String.push(shA1(buffer.slice(i * blockSize, (i + 1) * blockSize))); | ||
| 18 | + } | ||
| 19 | + function concatArr2Uint8(s) {//Array 2 Uint8Array | ||
| 20 | + var tmp = []; | ||
| 21 | + for (var i of s) tmp = tmp.concat(i); | ||
| 22 | + return new Uint8Array(tmp); | ||
| 23 | + } | ||
| 24 | + function Uint8ToBase64(u8Arr, urisafe) {//Uint8Array 2 Base64 | ||
| 25 | + var CHUNK_SIZE = 0x8000; //arbitrary number | ||
| 26 | + var index = 0; | ||
| 27 | + var length = u8Arr.length; | ||
| 28 | + var result = ''; | ||
| 29 | + var slice; | ||
| 30 | + while (index < length) { | ||
| 31 | + slice = u8Arr.subarray(index, Math.min(index + CHUNK_SIZE, length)); | ||
| 32 | + result += String.fromCharCode.apply(null, slice); | ||
| 33 | + index += CHUNK_SIZE; | ||
| 34 | + } | ||
| 35 | + return urisafe ? btoa(result).replace(/\//g, '_').replace(/\+/g, '-') : btoa(result); | ||
| 36 | + } | ||
| 37 | + function calcEtag() { | ||
| 38 | + if (!sha1String.length) return 'Fto5o-5ea0sNMlW_75VgGJCv2AcJ'; | ||
| 39 | + var sha1Buffer = concatArr2Uint8(sha1String); | ||
| 40 | + // 如果大于4M,则对各个块的sha1结果再次sha1 | ||
| 41 | + if (blockCount > 1) { | ||
| 42 | + prefix = 0x96; | ||
| 43 | + sha1Buffer = shA1(sha1Buffer.buffer); | ||
| 44 | + } else { | ||
| 45 | + sha1Buffer = Array.apply([], sha1Buffer); | ||
| 46 | + } | ||
| 47 | + sha1Buffer = concatArr2Uint8([[prefix], sha1Buffer]); | ||
| 48 | + return Uint8ToBase64(sha1Buffer, true); | ||
| 49 | + } | ||
| 50 | + return (calcEtag()); | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +export { getEtag } |
src/utils/share.js
0 → 100644
| 1 | +import wx from 'weixin-js-sdk' | ||
| 2 | +import axios from '@/utils/axios'; | ||
| 3 | + | ||
| 4 | +const fn = (to) => { | ||
| 5 | + // 路由名 | ||
| 6 | + let ruleName = location.href.split('#/')[1].split('?')[0]; | ||
| 7 | + | ||
| 8 | + const icon = 'https://cdn.lifeat.cn/webappgroup/betterLifelogo.png' | ||
| 9 | + | ||
| 10 | + const shareInfoMap = { | ||
| 11 | + 'client/index': { | ||
| 12 | + title: '童声无界', | ||
| 13 | + desc: '引导页', | ||
| 14 | + icon | ||
| 15 | + }, | ||
| 16 | + 'client/chooseSchool': { | ||
| 17 | + title: '选择幼儿园', | ||
| 18 | + desc: '引导页', | ||
| 19 | + icon | ||
| 20 | + }, | ||
| 21 | + default: { | ||
| 22 | + title: to.name, | ||
| 23 | + desc: window.location.href, | ||
| 24 | + icon | ||
| 25 | + }, | ||
| 26 | + } | ||
| 27 | + let infoMap = shareInfoMap[ruleName] ? shareInfoMap[ruleName] : shareInfoMap['default']; | ||
| 28 | + // console.warn(ruleName); | ||
| 29 | + console.warn(infoMap); | ||
| 30 | + console.warn(wx); | ||
| 31 | + console.warn(axios); | ||
| 32 | +} | ||
| 33 | +export default fn | ||
| 34 | +// 这个判断后加的为了减少请求次数,据后端说有次数限制,当需要分享的页面才去请求接口。 | ||
| 35 | +// if (shareInfoMap[ruleName]) { | ||
| 36 | +// // request 是封装的请求 | ||
| 37 | +// request.post('/wxmp/sign/jsSdk', { | ||
| 38 | +// url: location.href, | ||
| 39 | +// }).then(res => { | ||
| 40 | +// let { timestamp, nonceStr, signature, appId } = res; | ||
| 41 | +// wx.config({ | ||
| 42 | +// debug: false, | ||
| 43 | +// appId, | ||
| 44 | +// timestamp, | ||
| 45 | +// nonceStr, | ||
| 46 | +// signature, | ||
| 47 | +// jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'] | ||
| 48 | +// }); | ||
| 49 | +// wx.error(function (errres) { | ||
| 50 | +// console.info(errres) | ||
| 51 | +// }) | ||
| 52 | +// wx.ready(() => { //需在用户可能点击分享按钮前就先调用 | ||
| 53 | +// console.info('ready') | ||
| 54 | +// //分享朋友 | ||
| 55 | +// wx.updateAppMessageShareData({ | ||
| 56 | +// title: infoMap.title, // 分享标题 | ||
| 57 | +// desc: infoMap.desc, // 分享描述 | ||
| 58 | +// link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 | ||
| 59 | +// imgUrl: infoMap.icon, // 分享图标 | ||
| 60 | +// success: function () { | ||
| 61 | +// console.info("成功") | ||
| 62 | +// // 设置成功 | ||
| 63 | +// }, | ||
| 64 | +// fail: function (erres) { | ||
| 65 | +// console.info('失败:', erres) | ||
| 66 | +// } | ||
| 67 | +// }) | ||
| 68 | +// //分享到 朋友圈 | ||
| 69 | +// wx.updateTimelineShareData({ | ||
| 70 | +// title: infoMap.title, // 分享标题 | ||
| 71 | +// link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 | ||
| 72 | +// imgUrl: infoMap.icon, // 分享图标 | ||
| 73 | +// success: function () { | ||
| 74 | +// console.info("成功") | ||
| 75 | +// // 设置成功 | ||
| 76 | +// }, | ||
| 77 | +// fail: function (erres) { | ||
| 78 | +// console.info('失败:', erres) | ||
| 79 | +// } | ||
| 80 | +// }) | ||
| 81 | +// }); | ||
| 82 | +// }).catch(err => { | ||
| 83 | +// console.info('err:', err) | ||
| 84 | +// }) | ||
| 85 | +// } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/utils/tools.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-04-18 15:59:42 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-06-30 13:54:32 | ||
| 5 | + * @FilePath: /tswj/src/utils/tools.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import dayjs from 'dayjs'; | ||
| 9 | + | ||
| 10 | +// 格式化时间 | ||
| 11 | +const formatDate = (date) => { | ||
| 12 | + return dayjs(date).format('YYYY-MM-DD HH:mm'); | ||
| 13 | +}; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * @description 判断浏览器属于平台 | ||
| 17 | + * @returns | ||
| 18 | + */ | ||
| 19 | +const wxInfo = () => { | ||
| 20 | + let u = navigator.userAgent; | ||
| 21 | + let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器 | ||
| 22 | + let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 | ||
| 23 | + let uAgent = navigator.userAgent.toLowerCase(); | ||
| 24 | + let isTable = (uAgent.match(/MicroMessenger/i) == 'micromessenger') ? true : false; | ||
| 25 | + return { | ||
| 26 | + isAndroid, | ||
| 27 | + isiOS, | ||
| 28 | + isTable | ||
| 29 | + }; | ||
| 30 | +}; | ||
| 31 | + | ||
| 32 | +/** | ||
| 33 | + * @description 判断多行省略文本 | ||
| 34 | + * @param {*} id 目标dom标签 | ||
| 35 | + * @returns | ||
| 36 | + */ | ||
| 37 | +const hasEllipsis = (id) => { | ||
| 38 | + let oDiv = document.getElementById(id); | ||
| 39 | + let flag = false; | ||
| 40 | + if (oDiv.scrollHeight > oDiv.clientHeight) { | ||
| 41 | + flag = true | ||
| 42 | + } | ||
| 43 | + return flag | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +/** | ||
| 47 | + * @description 解析URL参数 | ||
| 48 | + * @param {*} url | ||
| 49 | + * @returns | ||
| 50 | + */ | ||
| 51 | +const parseQueryString = url => { | ||
| 52 | + var json = {}; | ||
| 53 | + var arr = url.indexOf('?') >= 0 ? url.substr(url.indexOf('?') + 1).split('&') : []; | ||
| 54 | + arr.forEach(item => { | ||
| 55 | + var tmp = item.split('='); | ||
| 56 | + json[tmp[0]] = tmp[1]; | ||
| 57 | + }); | ||
| 58 | + return json; | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +/** | ||
| 62 | + * 字符串包含字符数组中字符的状态 | ||
| 63 | + * @param {*} array 字符数组 | ||
| 64 | + * @param {*} str 字符串 | ||
| 65 | + * @returns 包含状态 | ||
| 66 | + */ | ||
| 67 | +const strExist = (array, str) => { | ||
| 68 | + const exist = array.filter(arr => { | ||
| 69 | + if (str.indexOf(arr) >= 0) return str; | ||
| 70 | + }) | ||
| 71 | + return exist.length > 0 | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +export { formatDate, wxInfo, hasEllipsis, parseQueryString, strExist }; |
src/utils/vconsole.js
0 → 100644
src/views/auth.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2022-08-29 13:55:31 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-08-24 10:52:35 | ||
| 5 | + * @FilePath: /front/src/views/auth.vue | ||
| 6 | + * @Description: 授权模块 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <div /> | ||
| 10 | +</template> | ||
| 11 | + | ||
| 12 | +<script setup> | ||
| 13 | +import { onMounted } from 'vue' | ||
| 14 | +import { useRoute } from 'vue-router' | ||
| 15 | + | ||
| 16 | +const $route = useRoute(); | ||
| 17 | + | ||
| 18 | +onMounted(() => { | ||
| 19 | + // php需要先跳转链接获取openid | ||
| 20 | + /** | ||
| 21 | + * encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。 | ||
| 22 | + * 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。 | ||
| 23 | + * 其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。 | ||
| 24 | + */ | ||
| 25 | + let raw_url = encodeURIComponent(location.origin + location.pathname + $route.query.href); // 未授权的地址 | ||
| 26 | + // TAG: 开发环境测试数据 | ||
| 27 | + const short_url = `/srv/?a=openid&res=${raw_url}`; | ||
| 28 | + location.href = import.meta.env.DEV | ||
| 29 | + ? `${short_url}&test_openid=${import.meta.env.VITE_OPENID}` | ||
| 30 | + : `${short_url}`; | ||
| 31 | +}) | ||
| 32 | +</script> |
src/views/index.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2023-06-21 10:23:09 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2024-01-15 10:07:06 | ||
| 5 | + * @FilePath: /xysBooking/src/views/index.vue | ||
| 6 | + * @Description: 预约页首页 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <div class="index-page"> | ||
| 10 | + </div> | ||
| 11 | +</template> | ||
| 12 | + | ||
| 13 | +<script setup> | ||
| 14 | +import { ref } from 'vue' | ||
| 15 | +import { useRoute, useRouter } from 'vue-router' | ||
| 16 | +import dayjs from 'dayjs' | ||
| 17 | +import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js' | ||
| 18 | +//import { } from '@/utils/generateModules.js' | ||
| 19 | +//import { } from '@/utils/generateIcons.js' | ||
| 20 | +//import { } from '@/composables' | ||
| 21 | +import { showSuccessToast, showFailToast } from 'vant'; | ||
| 22 | +import { orderRestCountAPI } from '@/api/index' | ||
| 23 | +const $route = useRoute(); | ||
| 24 | +const $router = useRouter(); | ||
| 25 | +useTitle($route.meta.title); | ||
| 26 | + | ||
| 27 | +onMounted(async () => { | ||
| 28 | +}); | ||
| 29 | + | ||
| 30 | +</script> | ||
| 31 | + | ||
| 32 | +<style lang="less" scoped> | ||
| 33 | +.index-page { | ||
| 34 | + padding: 1rem 1rem 0; | ||
| 35 | +} | ||
| 36 | +</style> |
tsconfig.json
0 → 100644
| 1 | +{ | ||
| 2 | + "compilerOptions": { | ||
| 3 | + /* 基本选项 */ | ||
| 4 | + "target": "esnext", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' | ||
| 5 | + "module": "CommonJS", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015' | ||
| 6 | + "lib": [ // 指定要包含在编译中的库文件 | ||
| 7 | + "esnext", | ||
| 8 | + "dom", | ||
| 9 | + "dom.iterable", | ||
| 10 | + "scripthost" | ||
| 11 | + ], | ||
| 12 | + "allowJs": true, // 允许编译 javascript 文件 | ||
| 13 | + // "checkJs": true, // 报告 javascript 文件中的错误 | ||
| 14 | + "jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react' | ||
| 15 | + // "declaration": true, // 生成相应的 '.d.ts' 文件 | ||
| 16 | + // "sourceMap": true, // 生成相应的 '.map' 文件 | ||
| 17 | + // "outFile": "./", // 将输出文件合并为一个文件 | ||
| 18 | + "outDir": "./", // 指定输出目录 | ||
| 19 | + // "rootDir": "./", // 用来控制输出目录结构 --outDir. | ||
| 20 | + "removeComments": true, // 删除编译后的所有的注释 | ||
| 21 | + // "noEmit": true, // 不生成输出文件 | ||
| 22 | + "importHelpers": true, // 从 tslib 导入辅助工具函数 | ||
| 23 | + "isolatedModules": false, // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似) | ||
| 24 | + | ||
| 25 | + /* 严格的类型检查选项 */ | ||
| 26 | + "strict": true, // 启用所有严格类型检查选项 | ||
| 27 | + // "noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错 | ||
| 28 | + // "strictNullChecks": true, // 启用严格的 null 检查 | ||
| 29 | + // "noImplicitThis": true, // 当 this 表达式值为 any 类型的时候,生成一个错误 | ||
| 30 | + // "alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict' | ||
| 31 | + | ||
| 32 | + /* 额外的检查 */ | ||
| 33 | + "noUnusedLocals": true, // 有未使用的变量时,抛出错误 | ||
| 34 | + "noUnusedParameters": true, // 有未使用的参数时,抛出错误 | ||
| 35 | + "noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误 | ||
| 36 | + "noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿) | ||
| 37 | + | ||
| 38 | + /* 模块解析选项 */ | ||
| 39 | + "moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6) | ||
| 40 | + "baseUrl": ".", // 用于解析非相对模块名称的基目录 | ||
| 41 | + "paths": { // 模块名到基于 baseUrl 的路径映射的列表 | ||
| 42 | + "@/*": [ | ||
| 43 | + "src/*" | ||
| 44 | + ] | ||
| 45 | + }, | ||
| 46 | + // "rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容 | ||
| 47 | + // "typeRoots": [], // 包含类型声明的文件列表 | ||
| 48 | + "types": [ // 需要包含的类型声明文件名列表 | ||
| 49 | + // "webpack-env", | ||
| 50 | + "vite/client", | ||
| 51 | + "lodash", | ||
| 52 | + "moment", | ||
| 53 | + "node", | ||
| 54 | + "jquery", | ||
| 55 | + ], | ||
| 56 | + "allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。 | ||
| 57 | + | ||
| 58 | + /* Source Map Options */ | ||
| 59 | + // "sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置 | ||
| 60 | + // "mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置 | ||
| 61 | + // "inlineSourceMap": true, // 生成单个 sourcemaps 文件,而不是将 sourcemaps 生成不同的文件 | ||
| 62 | + // "inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性 | ||
| 63 | + | ||
| 64 | + /* 其他选项 */ | ||
| 65 | + // "experimentalDecorators": true, // 启用装饰器 | ||
| 66 | + // "emitDecoratorMetadata": true, // 为装饰器提供元数据的支持 | ||
| 67 | + | ||
| 68 | + "esModuleInterop": true, // 可以在es6中导入commonjs | ||
| 69 | + }, | ||
| 70 | + "include": [ | ||
| 71 | + "src/**/*" | ||
| 72 | + ], | ||
| 73 | + "exclude": [ | ||
| 74 | + "node_modules", | ||
| 75 | + "dist" | ||
| 76 | + ], | ||
| 77 | + "vueCompilerOptions": { | ||
| 78 | + "target": 2, | ||
| 79 | + "experimentalSuppressInvalidJsxElementTypeErrors": true | ||
| 80 | + } | ||
| 81 | +} |
tslint.json
0 → 100644
| 1 | +{ | ||
| 2 | + "defaultSeverity": "warning", | ||
| 3 | + "extends": [ | ||
| 4 | + "tslint:recommended" | ||
| 5 | + ], | ||
| 6 | + "linterOptions": { | ||
| 7 | + "exclude": [ | ||
| 8 | + "node_modules/**" | ||
| 9 | + ] | ||
| 10 | + }, | ||
| 11 | + "rules": { | ||
| 12 | + "quotemark": [ | ||
| 13 | + true, | ||
| 14 | + "single" | ||
| 15 | + ], | ||
| 16 | + "indent": [ | ||
| 17 | + true, | ||
| 18 | + "spaces", | ||
| 19 | + 2 | ||
| 20 | + ], | ||
| 21 | + "interface-name": false, | ||
| 22 | + "ordered-imports": false, | ||
| 23 | + "object-literal-sort-keys": false, | ||
| 24 | + "no-consecutive-blank-lines": false, | ||
| 25 | + "no-console": true | ||
| 26 | + } | ||
| 27 | +} |
typings/index.d.ts
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2022-06-13 10:39:44 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-06-13 10:41:43 | ||
| 5 | + * @FilePath: /tswj/typings/index.d.ts | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +export {}; | ||
| 9 | + | ||
| 10 | +// => 全局类型声明 | ||
| 11 | +declare global { | ||
| 12 | + interface Window { | ||
| 13 | + _hmt: any; | ||
| 14 | + wx: any; | ||
| 15 | + AlipayJSBridge: any; | ||
| 16 | + } | ||
| 17 | + namespace GD { | ||
| 18 | + interface BaseResponse<T = any> { | ||
| 19 | + code: number; | ||
| 20 | + data: T; | ||
| 21 | + msg: string; | ||
| 22 | + page: { | ||
| 23 | + pageNo: number; | ||
| 24 | + pageSize: number; | ||
| 25 | + pages: number; | ||
| 26 | + total: number; | ||
| 27 | + }; | ||
| 28 | + } | ||
| 29 | + } | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +// const response = GD.BaseResponse<{name: string}> |
vite.config.js
0 → 100644
| 1 | +/* | ||
| 2 | + * @Date: 2023-06-13 13:26:46 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2023-08-25 14:14:26 | ||
| 5 | + * @FilePath: /xysBooking/vite.config.js | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | + */ | ||
| 8 | +import vue from '@vitejs/plugin-vue'; | ||
| 9 | +import dynamicImport from 'vite-plugin-dynamic-import'; | ||
| 10 | +// import legacy from '@vitejs/plugin-legacy'; | ||
| 11 | +// import styleImport, { VantResolve } from 'vite-plugin-style-import'; | ||
| 12 | +import Components from 'unplugin-vue-components/vite'; | ||
| 13 | +import { VantResolver } from 'unplugin-vue-components/resolvers'; | ||
| 14 | +import { defineConfig, loadEnv } from 'vite'; | ||
| 15 | +import { createProxy } from './build/proxy' | ||
| 16 | +import DefineOptions from 'unplugin-vue-define-options/vite'; | ||
| 17 | +import AutoImport from 'unplugin-auto-import/vite'; | ||
| 18 | +import postcsspxtoviewport from 'postcss-px-to-viewport' | ||
| 19 | + | ||
| 20 | +var path = require('path'); | ||
| 21 | + | ||
| 22 | +export default ({ command, mode }) => { | ||
| 23 | + const root = process.cwd(); | ||
| 24 | + | ||
| 25 | + const viteEnv = loadEnv(mode, root); | ||
| 26 | + // let isProd = (command === 'serve'); // 情景配置是否为开发模式 serve 或 build | ||
| 27 | + | ||
| 28 | + return defineConfig({ | ||
| 29 | + // root: '', | ||
| 30 | + // root: './src/packages', // 多页面应用配置入口根目录 | ||
| 31 | + base: viteEnv.VITE_BASE, // 开发或生产环境服务的公共基础路径。 | ||
| 32 | + // base: isProd ? '/' : '/f/voice/', // 开发或生产环境服务的公共基础路径。 | ||
| 33 | + // mode: '', // 在配置中指明将会把 serve 和 build 时的模式 都 覆盖掉。也可以通过命令行 --mode 选项来重写。 | ||
| 34 | + // define: '', // 定义全局常量替换方式。其中每项在开发环境下会被定义在全局,而在构建时被静态替换。 | ||
| 35 | + plugins: [ // 将要用到的插件数组。Falsy 虚值的插件将被忽略,插件数组将被扁平化(flatten)。查看 插件 API 获取 Vite 插件的更多细节。 | ||
| 36 | + vue(), | ||
| 37 | + Components({ | ||
| 38 | + resolvers: [VantResolver()], | ||
| 39 | + }), | ||
| 40 | + // styleImport({ | ||
| 41 | + // resolves: [VantResolve()], | ||
| 42 | + // libs: [ | ||
| 43 | + // { | ||
| 44 | + // libraryName: 'vant', | ||
| 45 | + // esModule: true, | ||
| 46 | + // resolveStyle: name => `../es/${name}/style` | ||
| 47 | + // } | ||
| 48 | + // ] | ||
| 49 | + // }), // 按需引入 vant 位置报错问题 | ||
| 50 | + dynamicImport(), // 增强 Vite 内置的 dynamic import, 支持在 import() 中使用别名 | ||
| 51 | + // legacy({ | ||
| 52 | + // targets: ['defaults', 'not IE 11'] | ||
| 53 | + // }), // Vite 的默认旧版浏览器支持时提供此插件本机ESM的支持。 | ||
| 54 | + DefineOptions(), // TAG: 插件来对组件名进行注册的, 解决setup没法写name的问题 | ||
| 55 | + AutoImport({ // API 自动导入 | ||
| 56 | + // 可以自定义文件生成的位置,默认是根目录下,使用ts的建议放src目录下 | ||
| 57 | + dts: 'src/auto-imports.d.ts', | ||
| 58 | + imports: ['vue', 'vue-router'], | ||
| 59 | + // 解决eslint报错问题 | ||
| 60 | + eslintrc: { | ||
| 61 | + enabled: true | ||
| 62 | + } | ||
| 63 | + }), | ||
| 64 | + ], | ||
| 65 | + publicDir: 'public', // 作为静态资源服务的文件夹。这个目录中的文件会在开发中被服务于 /,在开发模式时,会被拷贝到 outDir 的根目录,并没有转换,永远只是复制到这里。该值可以是文件系统的绝对路径,也可以是相对于项目的根目录路径。 | ||
| 66 | + // cacheDir: '', // 存储缓存文件的目录。此目录下会存储预打包的依赖项或 vite 生成的某些缓存文件,使用缓存可以提高性能。如需重新生成缓存文件,你可以使用 --force 命令行选项或手动删除目录。此选项的值可以是文件的绝对路径,也可以是以项目根目录为基准的相对路径。 | ||
| 67 | + resolve: { | ||
| 68 | + alias: { // 将会被传递到 @rollup/plugin-alias 作为 entries 的选项。也可以是一个对象,或一个 { find, replacement } 的数组. 当使用文件系统路径的别名时,请始终使用绝对路径。相对路径的别名值会被原封不动地使用,因此无法被正常解析。 更高级的自定义解析方法可以通过 插件 实现。 | ||
| 69 | + "@": path.resolve(__dirname, "src"), | ||
| 70 | + "@components": path.resolve(__dirname, "src/components"), | ||
| 71 | + "@composables": path.resolve(__dirname, "src/composables"), | ||
| 72 | + "@utils": path.resolve(__dirname, "src/utils"), | ||
| 73 | + "@images": path.resolve(__dirname, "src/assets/images"), | ||
| 74 | + "@css": path.resolve(__dirname, "src/assets/css"), | ||
| 75 | + "@mock": path.resolve(__dirname, "src/assets/mock"), | ||
| 76 | + "common": path.resolve(__dirname, "src/common"), | ||
| 77 | + }, | ||
| 78 | + dedupe: ['vue'], // 如果你在你的应用程序中有相同依赖的副本(比如 monorepos),使用这个选项来强制 Vite 总是将列出的依赖关系解析到相同的副本(从项目根目录)。 | ||
| 79 | + // conditions: [''], // 在解析包的 情景导出 时允许的附加条件。 | ||
| 80 | + // mainFields: [''], // package.json 中,在解析包的入口点时尝试的字段列表。注意,这比从 exports 字段解析的情景导出优先级低:如果一个入口点从 exports 成功解析,主字段将被忽略。 | ||
| 81 | + extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], // 导入时想要省略的扩展名列表。注意,不 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会干扰 IDE 和类型支持。 | ||
| 82 | + }, | ||
| 83 | + css: { | ||
| 84 | + modules: '', // 配置 CSS modules 的行为。选项将被传递给 postcss-modules。 | ||
| 85 | + postcss: { // 内联的 PostCSS 配置(格式同 postcss.config.js),或者一个(默认基于项目根目录的)自定义的 PostCSS 配置路径。其路径搜索是通过 postcss-load-config 实现的。 注意,如果提供了该内联配置,Vite 将不会搜索其他 PostCSS 配置源。 | ||
| 86 | + plugins: [ | ||
| 87 | + // postcsspxtoviewport({ | ||
| 88 | + // unitToConvert: 'px', // 要转化的单位 | ||
| 89 | + // viewportWidth: 375, // UI设计稿的宽度 | ||
| 90 | + // unitPrecision: 6, // 转换后的精度,即小数点位数 | ||
| 91 | + // propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换 | ||
| 92 | + // viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw | ||
| 93 | + // fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw | ||
| 94 | + // selectorBlackList: ['ignore-'], // 指定不转换为视窗单位的类名, | ||
| 95 | + // minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换 | ||
| 96 | + // mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false | ||
| 97 | + // replace: true, // 是否转换后直接更换属性值 | ||
| 98 | + // // exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配 | ||
| 99 | + // exclude: [], | ||
| 100 | + // landscape: false // 是否处理横屏情况 | ||
| 101 | + // }) | ||
| 102 | + ] | ||
| 103 | + }, | ||
| 104 | + preprocessorOptions: { | ||
| 105 | + less: { | ||
| 106 | + javascriptEnabled: true, | ||
| 107 | + additionalData: `@import "${path.resolve(__dirname, 'src/assets/styles/base.less')}";` | ||
| 108 | + } | ||
| 109 | + } // 指定传递给 CSS 预处理器的选项。 | ||
| 110 | + }, | ||
| 111 | + // json: { | ||
| 112 | + // namedExports: true, // 是否支持从 .json 文件中进行按名导入。 | ||
| 113 | + // stringify: false, // 若设置为 true,导入的 JSON 会被转换为 export default JSON.parse("...") 会比转译成对象字面量性能更好,尤其是当 JSON 文件较大的时候。 开启此项,则会禁用按名导入。 | ||
| 114 | + // }, | ||
| 115 | + // esbuild: false, // | ||
| 116 | + // assetsInclude: '', // 指定其他文件类型作为静态资源处理 | ||
| 117 | + logLevel: 'info', // 调整控制台输出的级别,默认为 'info'。 | ||
| 118 | + // clearScreen: true, // 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息。命令行模式下请通过 --clearScreen false 设置。 | ||
| 119 | + server: { | ||
| 120 | + host: '0.0.0.0', | ||
| 121 | + port: viteEnv.VITE_PORT, // 本地服务端口 | ||
| 122 | + // strictPort: true, // 设为true时若端口已被占用则会直接退出, 而不是尝试下一个可用端口 | ||
| 123 | + // https: '', | ||
| 124 | + // open: false, // 在服务器启动时自动在浏览器中打开应用程序. 当此值为字符串时, 会被当作URL的路径名. | ||
| 125 | + // proxy: { // 代理 | ||
| 126 | + // '/srv/': { | ||
| 127 | + // // target: 'http://voice.onwall.cn', | ||
| 128 | + // target: viteEnv.VITE_PROXY_TARGET, | ||
| 129 | + // changeOrigin: true, | ||
| 130 | + // // rewrite: (path) => path.replace(/^\/api/, '') | ||
| 131 | + // }, | ||
| 132 | + // }, | ||
| 133 | + proxy: createProxy(viteEnv.VITE_PROXY_PREFIX, viteEnv.VITE_PROXY_TARGET), | ||
| 134 | + // cors: '', // 为开发服务器配置 CORS。默认启用并允许任何源,传递一个 选项对象 来调整行为或设为 false 表示禁用。 | ||
| 135 | + // force: '', // 设置为 true 强制使依赖预构建。 | ||
| 136 | + // hmr: '', // 禁用或配置 HMR 连接(用于 HMR websocket 必须使用不同的 http 服务器地址的情况)。 设置 server.hmr.overlay 为 false 可以禁用服务器错误遮罩层。 | ||
| 137 | + // watch: '', // 传递给 chokidar 的文件系统监视器选项。 | ||
| 138 | + }, | ||
| 139 | + build: { | ||
| 140 | + // outDir: 'voice', // 指定输出路径(相对于项目根目录). | ||
| 141 | + outDir: viteEnv.VITE_OUTDIR, // 指定输出路径(相对于项目根目录). | ||
| 142 | + assetsDir: 'static', | ||
| 143 | + rollupOptions: { | ||
| 144 | + output: { | ||
| 145 | + chunkFileNames: 'static/js/[name]-[hash].js', | ||
| 146 | + entryFileNames: 'static/js/[name]-[hash].js', | ||
| 147 | + assetFileNames: 'static/[ext]/[name]-[hash].[ext]', | ||
| 148 | + }, | ||
| 149 | + input: { // 多页面应用模式, 打包时配置,运行配置要处理root | ||
| 150 | + main: path.resolve(__dirname, 'index.html'), | ||
| 151 | + // mono1: path.resolve(__dirname, 'src/packages/mono1/index.html'), | ||
| 152 | + // mono2: path.resolve(__dirname, 'src/packages/mono2/index.html'), | ||
| 153 | + } | ||
| 154 | + }, | ||
| 155 | + }, | ||
| 156 | + optimizeDeps: { | ||
| 157 | + // entries: '', | ||
| 158 | + // exclude: [], | ||
| 159 | + include: ['jquery', 'lodash', 'moment', 'axios', 'pinia', 'vue-router', 'vant'], // 默认情况下,不在 node_modules 中的,链接的包不会被预构建。使用此选项可强制预构建链接的包。 | ||
| 160 | + // keepNames: false, // 打包器有时需要重命名符号以避免冲突。 设置此项为 true 可以在函数和类上保留 name 属性。 若想获取更多详情,请参阅 keepNames | ||
| 161 | + } | ||
| 162 | + }); | ||
| 163 | +}; |
yarn-error.log
0 → 100644
This diff is collapsed. Click to expand it.
yarn.lock
0 → 100644
This diff could not be displayed because it is too large.
-
Please register or login to post a comment