commit ef8081b838ba553c114ce4a102b7820fa1aa5ad2 Author: dengtongyu Date: Tue Apr 18 20:02:38 2023 +0800 feat: 初始化 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..44e83e2 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +build +dist +node_modules +.vscode \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..40c2966 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,67 @@ +module.exports = { + root: true, + env: { + "browser": true, + "es2021": true, + "node": true, + "vue/setup-compiler-macros": true + }, + extends: ["eslint:recommended", "plugin:vue/vue3-recommended", "@vue/typescript/recommended", "prettier"], + parser: "vue-eslint-parser", + parserOptions: { + ecmaVersion: "latest", + parser: "@typescript-eslint/parser", + sourceType: "module" + }, + plugins: ["vue", "html", "@typescript-eslint"], + rules: { + "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", + "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", + "semi": [2, "always"], + "comma-dangle": [2, "never"], + "eqeqeq": "warn", + "quotes": ["warn", "double"], + "@typescript-eslint/ban-types": [ + "warn", + { + types: { + "{}": false + } + } + ], + "@typescript-eslint/no-explicit-any": "off", + "vue/no-unused-vars": "warn", + "vue/multi-word-component-names": "off", + "vue/no-mutating-props": "off", + "@typescript-eslint/ban-ts-comment": "off", + "vue/html-closing-bracket-newline": [ + "error", + { + singleline: "never", + multiline: "always" + } + ], + "vue/html-indent": [ + "error", + 2, + { + attribute: 1, + baseIndent: 1, + closeBracket: 0, + alignAttributesVertically: true, + ignores: [] + } + ], + "vue/max-attributes-per-line": [ + "error", + { + singleline: { + max: 2 + }, + multiline: { + max: 1 + } + } + ] + } +}; \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6238331 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +.DS_Store +node_modules +/dist +package-lock.json + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..5a3baee --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,11 @@ +module.exports = { + semi: false, + singleQuote: false, + tabWidth: 2, + useTabs: false, + printWidth: 120, + proseWrap: 'preserve', + trailingComma: 'es5', + bracketSpacing: true, + quoteProps: "consistent", +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f127a15 --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +# wechat + +一个h5项目 + +## 安装 + +``` +npm install +``` + +## 运行 + +``` +npm run serve:dev //本地运行,并且代理到开发环境 +npm run serve:test //本地运行,并且代理到测试环境 +npm run serve:uat //本地运行,并且代理到预发布环境 +npm run serve:prod //本地运行,并且代理到生产环境 +``` + +## 打包 + +``` +// 测试环境 +npm run build:test + +// 预发布环境 +npm run build:uat + +// 生产环境 +npm run build:prod +``` + +## 说明 + +项目采用vue3.0 + vite搭建,组件库默认引入了vant,状态管理使用pinia。 +使用vw适配方案,默认375宽度,可在vite.config.ts里配置更改默认宽度。 + +## 常见问题 + +### 按需引入组件 + +项目使用 unplugin-vue-components 插件,它可以自动引入组件,并按需引入组件的样式,无需手动引入样式。 + +```JS +import { + Button +} from 'vant'; +``` + +### 引入函数组件的样式 + +Vant 中有个别组件是以函数的形式提供的,包括 Toast,Dialog,Notify 和 ImagePreview 组件。在使用函数组件时,unplugin-vue-components 无法自动引入对应的样式,因此需要手动引入样式。 + +```JS +// Toast +import { + Toast +} from 'vant'; +import 'vant/es/toast/style'; + +// Dialog +import { + Dialog +} from 'vant'; +import 'vant/es/dialog/style'; + +// Notify +import { + Notify +} from 'vant'; +import 'vant/es/notify/style'; + +// ImagePreview +import { + ImagePreview +} from 'vant'; +import 'vant/es/image-preview/style'; +``` + +### 本地代理 + +运行项目时的接口代理,可在 proxy.config.ts 中配置。 + +## 相关文档 + +[vue3.0 文档](https://cn.vuejs.org/guide/quick-start.html). +[vite 文档](https://vitejs.cn/). +[vant 文档](https://vant-contrib.gitee.io/vant/#/zh-CN/). diff --git a/components.d.ts b/components.d.ts new file mode 100644 index 0000000..676560d --- /dev/null +++ b/components.d.ts @@ -0,0 +1,17 @@ +// generated by unplugin-vue-components +// We suggest you to commit this file into source control +// Read more: https://github.com/vuejs/core/pull/3399 +import '@vue/runtime-core' + +export {} + +declare module '@vue/runtime-core' { + export interface GlobalComponents { + Abnormal: typeof import('./src/components/abnormal/index.vue')['default'] + HelloWorld: typeof import('./src/components/HelloWorld.vue')['default'] + IconAndText: typeof import('./src/components/abnormal/iconAndText.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + VanButton: typeof import('vant/es')['Button'] + } +} diff --git a/config/index.d.ts b/config/index.d.ts new file mode 100644 index 0000000..1d478b8 --- /dev/null +++ b/config/index.d.ts @@ -0,0 +1,15 @@ +export declare const appName: string; + +export declare const passid: string; + +export declare const VITE_APP_ENV: string; + +export declare let proxyTarget: string; + +export declare const vconsoleDebug: boolean; + +export declare const scriptSrcStr: string; + +export declare let temp: string; + +export declare const injectScriptStr: string; \ No newline at end of file diff --git a/config/index.ts b/config/index.ts new file mode 100644 index 0000000..de6ef18 --- /dev/null +++ b/config/index.ts @@ -0,0 +1,33 @@ +const appName = "金币充值"; + +const ENV: any = import.meta.env || process.env; +const VITE_APP_ENV: string = ENV.VITE_APP_ENV; + +let proxyTarget = ""; +switch (VITE_APP_ENV) { + case "test": + proxyTarget = "http://apibeta.haloapp.vip"; + break; + case "prod": + proxyTarget = "http://apibeta.haloapp.vip"; + break; + default: + proxyTarget = "http://apibeta.haloapp.vip"; + break; +} + +const vconsoleDebug = true; +const scriptSrcStr = "var src = '/midjs/mjs/vconsole/v3.14.6/vconsole.min.js';document.write('');document.write('new window.VConsole();');"; +let temp = ""; +if (vconsoleDebug && (VITE_APP_ENV === "test" || VITE_APP_ENV === "uat")) { + temp = scriptSrcStr; +} else { + temp = `if (/vconsole=true/.test(window.location)) {${scriptSrcStr}};`; +} +const injectScriptStr = ``; + +export { + appName, + proxyTarget, + injectScriptStr +}; \ No newline at end of file diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..2c9212d --- /dev/null +++ b/env.d.ts @@ -0,0 +1,17 @@ +/// +declare interface ImportMetaEnv { + readonly VITE_APP_ENV: string + // 更多环境变量... +} + +declare interface ImportMeta { + readonly env: ImportMetaEnv +} + +declare interface Window { + wx: any; + WeixinJSBridge: any; + info: any; + webkit: any; + androidJsObj: any; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..b5d777f --- /dev/null +++ b/index.html @@ -0,0 +1,22 @@ + + + + + + + + <%- title %> + + + + +
+ <%- injectScript %> + + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..3d9011f --- /dev/null +++ b/package.json @@ -0,0 +1,46 @@ +{ + "name": "wechat", + "description": "一个h5项目", + "author": "dengtongyu", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "serve:test": "cross-env VITE_APP_ENV=test vite", + "serve:prod": "cross-env VITE_APP_ENV=prod vite", + "build:test": "vue-tsc --noEmit && cross-env VITE_APP_ENV=test vite build", + "build:prod": "vue-tsc --noEmit && cross-env VITE_APP_ENV=prod vite build", + "preview": "vite preview", + "lint": "eslint --fix config/*.{ts} && eslint --fix src/*.{ts,vue} && eslint --fix src/**/*.{ts,vue}" + }, + "dependencies": { + "axios": "^0.27.2", + "pinia": "^2.0.19", + "vant": "^4.2.0", + "vue": "^3.2.37", + "vue-router": "^4.1.3" + }, + "devDependencies": { + "@types/node": "^18.11.18", + "@typescript-eslint/eslint-plugin": "^5.40.1", + "@typescript-eslint/parser": "^5.40.1", + "@vitejs/plugin-legacy": "^2.0.1", + "@vitejs/plugin-vue": "^3.0.0", + "@vue/eslint-config-prettier": "^7.0.0", + "@vue/eslint-config-typescript": "^11.0.2", + "cross-env": "^7.0.3", + "eslint": "^8.25.0", + "eslint-plugin-html": "^7.1.0", + "eslint-plugin-vue": "^9.6.0", + "less": "^4.1.3", + "postcss-px-to-viewport": "^1.1.1", + "prettier": "^2.7.1", + "typescript": "^4.6.4", + "unplugin-vue-components": "^0.22.4", + "vite": "^3.0.9", + "vite-plugin-html": "^3.2.0", + "vite-plugin-vue-setup-extend": "^0.4.0", + "vue-tsc": "^0.38.4" + } +} diff --git a/proxy.config.ts b/proxy.config.ts new file mode 100644 index 0000000..cb80ce9 --- /dev/null +++ b/proxy.config.ts @@ -0,0 +1,26 @@ +import { proxyTarget } from "./config" + +let proxyTable = { + "/zuul": { + target: proxyTarget, + changeOrigin: true + }, + "/media/": { + target: proxyTarget, + changeOrigin: true + }, + "/zwwxgzt": { + target: proxyTarget, + changeOrigin: true + }, + "/midjs": { + target: proxyTarget, + changeOrigin: true + }, + "/irc": { + target: proxyTarget, + changeOrigin: true + }, +}; + +export default proxyTable; diff --git a/public/IMG_5350.PNG b/public/IMG_5350.PNG new file mode 100644 index 0000000..04b46da Binary files /dev/null and b/public/IMG_5350.PNG differ diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..f960131 Binary files /dev/null and b/public/logo.png differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..27c46ae --- /dev/null +++ b/src/App.vue @@ -0,0 +1,6 @@ + + + diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..79cac8b --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,21 @@ +import ajax from "../lib/ajax"; +// import { passid } from "../../config"; + +const chargeprodList = function (param?: any) { + const params = Object.assign({channelType: 2}, param || {}); + return ajax.get("/chargeprod/list", { params }); +}; + +const chargeUser = function (param: any) { + return ajax.get("/user/getChargeUser", { params: param }); +}; + +const submitPay = function (param: any) { + return ajax.post("/wx/submitPay", param); +}; + +export { + chargeprodList, + chargeUser, + submitPay +}; \ No newline at end of file diff --git a/src/assets/images/download_andriod.png b/src/assets/images/download_andriod.png new file mode 100644 index 0000000..2935e52 Binary files /dev/null and b/src/assets/images/download_andriod.png differ diff --git a/src/assets/images/download_ios.png b/src/assets/images/download_ios.png new file mode 100644 index 0000000..71cbdac Binary files /dev/null and b/src/assets/images/download_ios.png differ diff --git a/src/assets/images/h5_bg.png b/src/assets/images/h5_bg.png new file mode 100644 index 0000000..8feba16 Binary files /dev/null and b/src/assets/images/h5_bg.png differ diff --git a/src/assets/images/h5_mask.png b/src/assets/images/h5_mask.png new file mode 100644 index 0000000..23bd662 Binary files /dev/null and b/src/assets/images/h5_mask.png differ diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png new file mode 100644 index 0000000..b1fbdb2 Binary files /dev/null and b/src/assets/images/logo.png differ diff --git a/src/assets/images/no_power.png b/src/assets/images/no_power.png new file mode 100644 index 0000000..1f32e7f Binary files /dev/null and b/src/assets/images/no_power.png differ diff --git a/src/assets/images/web_bg.png b/src/assets/images/web_bg.png new file mode 100644 index 0000000..19bfbc6 Binary files /dev/null and b/src/assets/images/web_bg.png differ diff --git a/src/assets/svg/404.svg b/src/assets/svg/404.svg new file mode 100644 index 0000000..1ffc6c5 --- /dev/null +++ b/src/assets/svg/404.svg @@ -0,0 +1,33 @@ + + + 404 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/svg/500.svg b/src/assets/svg/500.svg new file mode 100644 index 0000000..1f4a786 --- /dev/null +++ b/src/assets/svg/500.svg @@ -0,0 +1,50 @@ + + + + 服务器异常 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/svg/device_abnormal.svg b/src/assets/svg/device_abnormal.svg new file mode 100644 index 0000000..042d263 --- /dev/null +++ b/src/assets/svg/device_abnormal.svg @@ -0,0 +1,57 @@ + + + + 设备异常 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/svg/failed.svg b/src/assets/svg/failed.svg new file mode 100644 index 0000000..6b15e39 --- /dev/null +++ b/src/assets/svg/failed.svg @@ -0,0 +1,50 @@ + + + + 加载失败 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/svg/logo.svg b/src/assets/svg/logo.svg new file mode 100644 index 0000000..81737e1 --- /dev/null +++ b/src/assets/svg/logo.svg @@ -0,0 +1,89 @@ + + + + diff --git a/src/assets/svg/no_data.svg b/src/assets/svg/no_data.svg new file mode 100644 index 0000000..3e73b53 --- /dev/null +++ b/src/assets/svg/no_data.svg @@ -0,0 +1,43 @@ + + + + 暂无数据 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/svg/no_network.svg b/src/assets/svg/no_network.svg new file mode 100644 index 0000000..3ee7609 --- /dev/null +++ b/src/assets/svg/no_network.svg @@ -0,0 +1,48 @@ + + + + 暂无网络 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/svg/no_permission.svg b/src/assets/svg/no_permission.svg new file mode 100644 index 0000000..aad52a4 --- /dev/null +++ b/src/assets/svg/no_permission.svg @@ -0,0 +1,47 @@ + + + + 暂无权限 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue new file mode 100644 index 0000000..89e0d3f --- /dev/null +++ b/src/components/HelloWorld.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/abnormal/iconAndText.vue b/src/components/abnormal/iconAndText.vue new file mode 100644 index 0000000..f81dc5d --- /dev/null +++ b/src/components/abnormal/iconAndText.vue @@ -0,0 +1,39 @@ + + + \ No newline at end of file diff --git a/src/components/abnormal/index.vue b/src/components/abnormal/index.vue new file mode 100644 index 0000000..8765c48 --- /dev/null +++ b/src/components/abnormal/index.vue @@ -0,0 +1,107 @@ + + + \ No newline at end of file diff --git a/src/installComponents.ts b/src/installComponents.ts new file mode 100644 index 0000000..0240d54 --- /dev/null +++ b/src/installComponents.ts @@ -0,0 +1,10 @@ +import { Button, Search } from "vant"; + +const install = function (app: any) { + app.use(Button); + app.use(Search); +}; + +export { + install +}; diff --git a/src/lib/ajax.ts b/src/lib/ajax.ts new file mode 100644 index 0000000..6b3699b --- /dev/null +++ b/src/lib/ajax.ts @@ -0,0 +1,3 @@ +import axios from "./request"; + +export default axios; \ No newline at end of file diff --git a/src/lib/request.ts b/src/lib/request.ts new file mode 100644 index 0000000..e707174 --- /dev/null +++ b/src/lib/request.ts @@ -0,0 +1,34 @@ +import axios from "axios"; + +axios.defaults.headers.common["Request-Type"] = "ajax"; + +axios.interceptors.response.use( + function (response) { + // 对响应数据做点什么 + const { errcode } = response.data || {}; + if (errcode === 401) { + const { + data: { authorizeURI } + } = response.data; + let currentURI = location.href; + currentURI = encodeURIComponent(currentURI); + currentURI = encodeURIComponent(currentURI); + let redirectURI = authorizeURI; + redirectURI = redirectURI.replace("REDIRECT_URI", currentURI); + const hostNames = ["127.0.0.1", "localhost"]; + if (hostNames.includes(location.hostname)) { + console.log("当前cookie失效"); + } else { + location.replace(redirectURI); + } + } + + const data = response.data || JSON.parse(response.request.responseText); + return data; + }, + function (error) { + return Promise.reject(error); + } +); + +export default axios; diff --git a/src/lib/util.ts b/src/lib/util.ts new file mode 100644 index 0000000..4c6ceaa --- /dev/null +++ b/src/lib/util.ts @@ -0,0 +1,239 @@ +// 随机长度字符串 +const randomString = (len: number) => { + len = len || 10; + const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const maxPos = chars.length; + let str = ""; + for (let i = 0; i < len; i++) { + str += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return str; +}; + +const checkVersion = function() { + const u = navigator.userAgent; + return { + trident: u.indexOf("Trident") > -1, // IE内核 + presto: u.indexOf("Presto") > -1, // opera内核 + webKit: u.indexOf("AppleWebKit") > -1, // 苹果、谷歌内核 + gecko: u.indexOf("Gecko") > -1 && u.indexOf("KHTML") === -1, // 火狐内核 + mobile: !!u.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端 + ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端 + android: u.indexOf("Android") > -1 || u.indexOf("Adr") > -1, // android终端 + iPhone: u.indexOf("iPhone") > -1, // 是否为iPhone或者QQHD浏览器 + iPad: u.indexOf("iPad") > -1, // 是否iPad + webApp: u.indexOf("Safari") > -1, // 是否web应该程序,没有头部与底部 + weixin: u.indexOf("MicroMessenger") > -1, // 是否微信 + qq: u.indexOf("QQ") > -1, // 是否QQ + tutuApp: u.match("toupaiApp"), + app: u.match("toupaiApp") // 是否在app内 + }; +}; + +// 获取当前链接参数 +const getQueryString = function() { + const url = window.location.href; + const paramArr = url.slice(url.indexOf("?") + 1).split("&"); + const params: any = {}; + paramArr.map(param => { + const [key, val] = param.split("="); + params[key] = decodeURIComponent(val); + }); + return params; +}; + +const routeTypeConstant = { + ROOM_PAGE: 1, //跳转房间页 传参(routerType): uid + H5_PAGE: 2, // 跳转h5 + PURSE_PAGE: 3, //跳转钱包页 + RED_PAGE: 4, //xcRedColor + RECHARGE_PAGE: 5, //跳转充值页 + PERSON_PAGE: 6, //跳转个人页 传参(routerType) : uid + CAR_PAGE: 7, //跳转座驾 传参(routerType) : 0 (装扮商城) 或者 1 (车库) // 1是跳到我的座驾 + HEADWEAR_PAGE: 8, //跳转到头饰 传参(routerType) : 0 (装扮商城) 或者 1 (头饰库) // 1是跳到我的头饰 + SYSTEMMESSAGE_PAGE: 9, //系统消息 + FAMILY_PAGE: 10, //跳转到家族页面 + GROUP_PAGE: 11, //跳转到群组 + BACKGROUND_PAGE: 12, //跳转到背景设置 传参(routerType): 0 (装扮商城) 或者 1 (背景库) + NEW_USER_PAGE: 13, //新秀玩友 + INVITE_FRIEND_PAGE: 14, //邀请好友 + PUBLICCHAT_PAGE: 15, //公聊大厅 + XCZ_ACCOUNT_PAGE: 16, //绑定 xcz 账号 + PHONE_NUM_PAGE: 17, //绑定手机号 + PAY_PWD_PAGE: 18, //设置支付密码 + WITHDRAW_RECORD_PAGE: 19, //提现记录页面 + RECOMMEND_CARD_PAGE: 20, //跳转到推荐卡仓库 + TASK_CENTER_PAGE: 27, // 跳转到任务中心就是萝卜不足也是跳那里 + TEACHER_PUPIL_PAGE: 28, //跳转到师徒页面入口 + SQUARE_PUBLISH: 51, // 发布动态 + FEEDPACK_PAGE: 52 //跳转反馈页面入口 +}; + +// 客户端方法 +const tools = { + cookieUtils: { + set: function(key:string|number, val:string|number, time:number) { + const date = new Date(); + const expiresDays = time; + date.setTime(date.getTime() + expiresDays * 24 * 3600 * 1000); + document.cookie = key + "=" + val + ";expires=" + date.toUTCString(); + }, + + get: function(key:string) { + const getCookie = document.cookie.replace(/[ ]/g, ""); + const arrCookie = getCookie.split(";"); + let val; + for (let i = 0; i < arrCookie.length; i++) { + const arr = arrCookie[i].split("="); + if (key === arr[0]) { + val = arr[1]; + break; + } + } + return val; + }, + + delete: function(key:string) { + const date = new Date(); + date.setTime(date.getTime() - 10000); + document.cookie = key + "+v; expires =" + date.toUTCString(); + } + }, + nativeUtils: { + jumpAppointPage: function(type: string, val: string) { + // routerType 跳转名称 + // routerVal 跳转需要传的参数 + const browser = checkVersion(); + const jumpObj:any = {}; + jumpObj.routerType = routeTypeConstant[type as keyof typeof routeTypeConstant]; + if (val) jumpObj.routerVal = val; + + if (browser.app) { + if (browser.ios) { + if (type.indexOf("_") > -1) { + window.webkit.messageHandlers.jumpAppointPage.postMessage(jumpObj); + } else { + if (val) { + window.webkit.messageHandlers.type.postMessage(val); + } else { + window.webkit.messageHandlers.type.postMessage(null); + } + } + } else if (browser.android) { + // eslint-disable-next-line no-undef + if (window.androidJsObj && typeof window.androidJsObj === "object") { + if (type.indexOf("_") > -1) { + window.androidJsObj.jumpAppointPage(JSON.stringify(jumpObj)); + } else { + window.androidJsObj.jumpAppointPage(type); + } + } + } + } + }, + + getUid: function() { + const browser = checkVersion(); + let val; + if (browser.app) { + if (browser.ios) { + val = tools.cookieUtils.get("uid"); + } else if (browser.android) { + // eslint-disable-next-line no-undef + if (window.androidJsObj && typeof window.androidJsObj === "object") { + val = parseInt(window.androidJsObj.getUid()); + } + } + } else { + const locate = getQueryString(); + if (!locate.uid && !locate.shareUid) { + val = 901189; + } else { + if (locate.shareUid) { + val = locate.shareUid; + } else { + val = locate.uid; + } + } + } + return val; + }, + + getTicket: function() { + const browser = checkVersion(); + let val; + if (browser.app) { + if (browser.ios) { + val = window.webkit.messageHandlers.getTicket.postMessage(null); + } else if (browser.android) { + // eslint-disable-next-line no-undef + if (window.androidJsObj && typeof window.androidJsObj === "object") { + val = window.androidJsObj.getTicket(); + } + } + } else { + val = "app外"; + } + return val; + }, + getAppVersion: function() { + const browser = checkVersion(); + let val; + if (browser.app) { + if (browser.ios) { + val = window.webkit.messageHandlers.getAppVersion.postMessage(null); + } else { + val = window.androidJsObj.getAppVersion(); + } + } + return val; + } + } +}; + +const getMsgFromDevice = function() { + const browser = checkVersion(); + let info = {}; + if (browser.app) { + if (browser.ios) { + window.webkit.messageHandlers.getDeviceId.postMessage(null); + window.webkit.messageHandlers.getRoomUid.postMessage(null); + } else if (browser.android) { + // eslint-disable-next-line no-undef + if (window.androidJsObj && typeof window.androidJsObj === "object") { + window.info.deviceId = window.androidJsObj.getDeviceId(); + window.info.roomUid = window.androidJsObj.getRoomUid(); + } + + window.info.appVersion = tools.nativeUtils.getAppVersion(); + } + + window.info.uid = tools.nativeUtils.getUid(); + window.info.ticket = tools.nativeUtils.getTicket(); + window.info.appVersion = tools.nativeUtils.getAppVersion(); + } else { + const params = getQueryString(); + if ( + params.debug === true || + params.debug === "true" || + location.hostname === "localhost" + ) { + window.info.roomUid = 904860; + window.info.uid = 1000009; + window.info.deviceId = "afhksafhksajhfs1kjahsfkjsf0000aaaaaaaacaa"; + window.info.ticket = + "eyJhbGciOiJIUzI1NiJ9.eyJ0aWNrZXRfdHlwZSI6bnVsbCwidWlkIjo5MTMzOSwidGlja2V0X2lkIjoiOGJmMTdlYmQtMTY4ZC00NTliLWI0NzUtMDU3M2Y1ZmM4MDQzIiwiZXhwIjozNjAwLCJjbGllbnRfaWQiOiJlcmJhbi1jbGllbnQifQ.MnKGEc6bSkyOkCbx26lib6J0koFDA2uiKnbwkhdk3MU"; + } + } + info = window.info; + return info; +}; + +export { + randomString, + checkVersion, + tools, + getQueryString, + getMsgFromDevice, + routeTypeConstant +}; diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..bb3ca69 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,15 @@ +import { createApp } from "vue"; +import routes from "./routes"; +import App from "./App.vue"; +import pinia from "./store/pinia"; +import { install } from "./installComponents"; +import "./styles/index.less"; + +const app = createApp(App); +app.use(pinia); +app.use(routes); +install(app); +app.mount("#app"); + + + diff --git a/src/pages/Home.vue b/src/pages/Home.vue new file mode 100644 index 0000000..5e67e1f --- /dev/null +++ b/src/pages/Home.vue @@ -0,0 +1,39 @@ + + + + + \ No newline at end of file diff --git a/src/pages/Login.vue b/src/pages/Login.vue new file mode 100644 index 0000000..83344a1 --- /dev/null +++ b/src/pages/Login.vue @@ -0,0 +1,56 @@ + + + + + \ No newline at end of file diff --git a/src/pages/error/404.vue b/src/pages/error/404.vue new file mode 100644 index 0000000..9239fa0 --- /dev/null +++ b/src/pages/error/404.vue @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/src/pages/error/500.vue b/src/pages/error/500.vue new file mode 100644 index 0000000..9ce1d7d --- /dev/null +++ b/src/pages/error/500.vue @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/src/pages/error/DeviceAbnormal.vue b/src/pages/error/DeviceAbnormal.vue new file mode 100644 index 0000000..b5c0c9c --- /dev/null +++ b/src/pages/error/DeviceAbnormal.vue @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/src/pages/error/Failed.vue b/src/pages/error/Failed.vue new file mode 100644 index 0000000..1fc4019 --- /dev/null +++ b/src/pages/error/Failed.vue @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/src/pages/error/NoAccess.vue b/src/pages/error/NoAccess.vue new file mode 100644 index 0000000..a22c46c --- /dev/null +++ b/src/pages/error/NoAccess.vue @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/src/pages/error/NoData.vue b/src/pages/error/NoData.vue new file mode 100644 index 0000000..26b64f8 --- /dev/null +++ b/src/pages/error/NoData.vue @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/src/pages/error/NoNetwork.vue b/src/pages/error/NoNetwork.vue new file mode 100644 index 0000000..32c010b --- /dev/null +++ b/src/pages/error/NoNetwork.vue @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/src/pages/h5.vue b/src/pages/h5.vue new file mode 100644 index 0000000..d070fde --- /dev/null +++ b/src/pages/h5.vue @@ -0,0 +1,75 @@ + + + + + \ No newline at end of file diff --git a/src/pages/web.vue b/src/pages/web.vue new file mode 100644 index 0000000..ac10ebe --- /dev/null +++ b/src/pages/web.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/src/routes/index.ts b/src/routes/index.ts new file mode 100644 index 0000000..1474eed --- /dev/null +++ b/src/routes/index.ts @@ -0,0 +1,33 @@ +import { createWebHashHistory, createRouter } from "vue-router"; +import routes from "./routes"; +// import pinia from "../store/pinia"; +// import { baseInfo } from "../store"; + +// const baseInfoStore = baseInfo(pinia); +const history = createWebHashHistory(); + + +const router = createRouter({ + history, + routes: routes +}); + +// router.beforeEach((to, from, next) => { +// if (to.meta && to.meta.power) { +// const user = baseInfoStore.userInfo.value; +// if (user.uin) { +// next(); +// } else { +// next({ +// path: "/loginfo", +// query: { +// rediret: to.fullPath +// } +// }); +// } +// } else { +// next(); +// } +// }); + +export default router; \ No newline at end of file diff --git a/src/routes/routes.ts b/src/routes/routes.ts new file mode 100644 index 0000000..4be2947 --- /dev/null +++ b/src/routes/routes.ts @@ -0,0 +1,15 @@ +const routes = [ + { path: "/", name: "root", redirect: "/home" }, + { path: "/home", name: "home", meta: { power: true }, component: () => import("../pages/Home.vue") }, + { path: "/loginfo", name: "loginfo", component: () => import("../pages/Login.vue") }, + { path: "/nonetwork:text?", name: "nonetwork", props: true, component: () => import("../pages/error/NoNetwork.vue") }, + { path: "/noaccess/:text?", name: "noaccess", props: true, component: () => import("../pages/error/NoAccess.vue") }, + { path: "/empty/:text?", name: "empty", props: true, component: () => import("../pages/error/NoData.vue") }, + { path: "/deviceabnormal/:text?", name: "deviceabnormal", props: true, component: () => import("../pages/error/DeviceAbnormal.vue") }, + { path: "/failed/:text?", name: "failed", props: true, component: () => import("../pages/error/Failed.vue") }, + { path: "/500/:text?", name: "500", props: true, component: () => import("../pages/error/500.vue") }, + { path: "/404", name: "404", component: () => import("../pages/error/404.vue") }, + { path: "/:catchAll(.*)", redirect: "/404", hidden: true } +]; + +export default routes; \ No newline at end of file diff --git a/src/store/baseInfo.ts b/src/store/baseInfo.ts new file mode 100644 index 0000000..b7a6728 --- /dev/null +++ b/src/store/baseInfo.ts @@ -0,0 +1,30 @@ +import { defineStore } from "pinia"; +import { ref, computed } from "vue"; +import { getUserInfo } from "../api"; + +const baseInfo = defineStore("baseInfo", () => { + const user = ref({}); + const loginUserInfo = () => { + return new Promise((resolve, reject) => { + getUserInfo({}) + .then((res: any) => { + const { errcode, data } = res; + if (errcode === 0) { + const info = data.data; + user.value = info; + } + resolve(res); + }) + .catch((err: any) => { + reject(err); + }); + }); + }; + const userInfo = computed(() => { + return user; + }); + + return { loginUserInfo, userInfo }; +}); + +export default baseInfo; \ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..74fa0bc --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,6 @@ +// import baseInfo from "./baseInfo"; +import pay from "./pay"; + +export { + pay +}; \ No newline at end of file diff --git a/src/store/pay.ts b/src/store/pay.ts new file mode 100644 index 0000000..485de1b --- /dev/null +++ b/src/store/pay.ts @@ -0,0 +1,56 @@ +import { ref } from "vue"; +import { defineStore } from "pinia"; +import { showFailToast } from "vant"; +import { chargeprodList, chargeUser } from "@/api/index"; + + +const pay = defineStore("pay", () => { + const openId = ref(""); + const dataId = ref(""); + const channel = ref(""); + + const payLsit = ref>([]); + + const receiveUser = ref({}); + + const getChargeprod = () => { + return new Promise((resolve, reject) => { + chargeprodList() + .then((res: any) => { + const { code, data } = res; + if (code === 200) { + payLsit.value = data; + } + resolve(res); + }) + .catch((err: any) => { + reject(err); + }); + }); + }; + + const getChargeUser = (erbanNo: string | number) => { + return new Promise((resolve, reject) => { + chargeUser({erbanNo: erbanNo}) + .then((res: any) => { + const { code, data, message } = res; + if (code === 200) { + receiveUser.value = data; + }else if(code === 1404) { + showFailToast(message || "您输入的账号不存在"); + } + else{ + showFailToast(message); + } + resolve(res); + }) + .catch((err: any) => { + reject(err); + }); + }); + }; + + return { openId, dataId, channel, getChargeprod, getChargeUser }; +}); + +export default pay; \ No newline at end of file diff --git a/src/store/pinia.ts b/src/store/pinia.ts new file mode 100644 index 0000000..23d5e61 --- /dev/null +++ b/src/store/pinia.ts @@ -0,0 +1,5 @@ +import { createPinia } from "pinia"; + +const pinia = createPinia(); + +export default pinia; \ No newline at end of file diff --git a/src/styles/cover.less b/src/styles/cover.less new file mode 100644 index 0000000..b58e734 --- /dev/null +++ b/src/styles/cover.less @@ -0,0 +1 @@ +// --van-button-default-color:var(--van-text-color); \ No newline at end of file diff --git a/src/styles/global.less b/src/styles/global.less new file mode 100644 index 0000000..c7ae967 --- /dev/null +++ b/src/styles/global.less @@ -0,0 +1,48 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; + } + + html, + body, + #app { + width: 100%; + height: 100%; + margin: 0; + } + + ul, + li, + p, + h1, + h2, + h3, + h4, + h5, + h6 { + margin: 0; + } + + #app { + color: #000; + font-size: 14px; + font-family: "Helvetica", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif; + } + + a { + -webkit-tap-highlight-color:rgba(255,0,0,0); + -moz-tap-highlight-color:rgba(255,0,0,0); + tap-highlight-color:rgba(255,0,0,0); + } \ No newline at end of file diff --git a/src/styles/index.less b/src/styles/index.less new file mode 100644 index 0000000..bb307c4 --- /dev/null +++ b/src/styles/index.less @@ -0,0 +1,2 @@ +@import './cover.less'; +@import './global.less'; \ No newline at end of file diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..fc81239 --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1,7 @@ +/// + +declare module "*.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent<{}, {}, any>; + export default component; +} diff --git a/src/wx/index.ts b/src/wx/index.ts new file mode 100644 index 0000000..96b777d --- /dev/null +++ b/src/wx/index.ts @@ -0,0 +1,39 @@ +import { useRouter } from "vue-router"; + +const router = useRouter(); + +const onBridgeReady = function (data: any) { + const { appid, timeStamp, nonceStr, signType, paySign } = data; + window.WeixinJSBridge.invoke( + "getBrandWCPayRequest", { + "appId": appid, + "timeStamp": timeStamp, + "nonceStr": nonceStr, + "package": data, + "signType": signType, + "paySign": paySign + }, + function (res: any) { + if (res.err_msg === "get_brand_wcpay_request:ok") {// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 + window.location.reload(); + } else if (res.err_msg === "get_brand_wcpay_request:fail") { + router.replace({ + path: "/payfailed" + }); + } else { + router.replace({ + path: "/payfailed" + }); + } + } + ); +}; +// if (typeof window.WeixinJSBridge === "undefined") { +// document.addEventListener("WeixinJSBridgeReady", onBridgeReady, false); +// } else { +// onBridgeReady(); +// } + +export { + onBridgeReady +}; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3007e06 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": [ + "ESNext", + "DOM" + ], + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + "baseUrl": "./", + "paths": { + "@/*": [ + "src/*" + ] + }, + "types": [ + "vite/client", + "node" + ], + }, + "include": [ + "./*.d.ts", + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue", + "config/**/*.ts" + ], + "references": [ + { + "path": "./tsconfig.node.json" + } + ] +} \ No newline at end of file diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..1eb706a --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts", "proxy.config.ts", "config/**/*.ts", "./*.d.ts",] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..3666f74 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,102 @@ +import { defineConfig, loadEnv } from "vite"; +import vue from "@vitejs/plugin-vue"; +import Components from "unplugin-vue-components/vite"; +import { VantResolver } from "unplugin-vue-components/resolvers"; +import postcsspxtoviewport from "postcss-px-to-viewport"; +import { createHtmlPlugin } from "vite-plugin-html"; +import VueSetupExtend from "vite-plugin-vue-setup-extend"; +import legacy from "@vitejs/plugin-legacy"; +import proxyConfig from "./proxy.config"; +import { appName, injectScriptStr } from "./config"; +import path from "path"; + +type enforceType = "post" | "pre"; +const enforceValue:enforceType = "post"; +const setCrossoriginUseCredentials = () => { + return { + name: "set-crossorigin", + enforce: enforceValue, + transformIndexHtml(html) { + return html.replace(/crossorigin/g, "crossorigin=\"use-credentials\""); + } + }; +}; + + +// https://vitejs.dev/config/ +export default (opt: any) => { + const { mode } = opt; + const env: any = loadEnv(mode, process.cwd()); + + return defineConfig({ + base: "./", + envDir: "./env", + build: { + target: "es2015" + }, + plugins: [ + createHtmlPlugin({ + inject: { + data: { + title: appName, + injectScript: injectScriptStr + } + } + }), + vue(), + VueSetupExtend(), + Components({ + resolvers: [VantResolver()] + }), + legacy({ + // targets: ['defaults', 'not IE 11'], + targets: ["chrome 52"], + additionalLegacyPolyfills: ["regenerator-runtime/runtime"], + renderLegacyChunks: true, + polyfills: [ + "es.symbol", + "es.array.filter", + "es.promise", + "es.promise.finally", + "es/map", + "es/set", + "es.array.for-each", + "es.object.define-properties", + "es.object.define-property", + "es.object.get-own-property-descriptor", + "es.object.get-own-property-descriptors", + "es.object.keys", + "es.object.to-string", + "web.dom-collections.for-each", + "esnext.global-this", + "esnext.string.match-all" + ] + }), + setCrossoriginUseCredentials() + ], + css: { + preprocessorOptions: { + less: { + javascriptEnabled: true + } + }, + postcss: { + plugins: [ + postcsspxtoviewport({ + viewportWidth: 375, + selectorBlackList: [""] + }) + ] + } + }, + server: { + proxy: proxyConfig + }, + resolve: { + alias: { + "@": path.resolve(__dirname, "src") + } + } + }); + +}; \ No newline at end of file