From ac0d3b2f7d6fb0a8d5a0b49f08a28d7ae72b98e5 Mon Sep 17 00:00:00 2001 From: dengtongyu Date: Thu, 13 Apr 2023 19:49:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 4 + .eslintrc.cjs | 67 +++++++++++++++ .gitignore | 22 +++++ .prettierrc.cjs | 11 +++ README.md | 88 +++++++++++++++++++ components.d.ts | 18 ++++ config/index.d.ts | 15 ++++ config/index.ts | 39 +++++++++ env.d.ts | 13 +++ index.html | 20 +++++ package.json | 48 +++++++++++ proxy.config.ts | 26 ++++++ public/favicon.svg | 89 ++++++++++++++++++++ src/App.vue | 6 ++ src/api/index.ts | 14 ++++ src/assets/images/no_power.png | Bin 0 -> 14506 bytes src/assets/svg/404.svg | 33 ++++++++ src/assets/svg/500.svg | 50 +++++++++++ src/assets/svg/device_abnormal.svg | 57 +++++++++++++ src/assets/svg/failed.svg | 50 +++++++++++ src/assets/svg/logo.svg | 89 ++++++++++++++++++++ src/assets/svg/no_data.svg | 43 ++++++++++ src/assets/svg/no_network.svg | 48 +++++++++++ src/assets/svg/no_permission.svg | 47 +++++++++++ src/components/HelloWorld.vue | 35 ++++++++ src/components/abnormal/iconAndText.vue | 39 +++++++++ src/components/abnormal/index.vue | 107 ++++++++++++++++++++++++ src/installComponents.ts | 10 +++ src/lib/ajax.ts | 3 + src/lib/request.ts | 34 ++++++++ src/lib/util.ts | 35 ++++++++ src/main.ts | 15 ++++ src/pages/Home.vue | 28 +++++++ src/pages/Login.vue | 56 +++++++++++++ src/pages/error/404.vue | 26 ++++++ src/pages/error/500.vue | 21 +++++ src/pages/error/DeviceAbnormal.vue | 25 ++++++ src/pages/error/Failed.vue | 25 ++++++ src/pages/error/NoAccess.vue | 25 ++++++ src/pages/error/NoData.vue | 26 ++++++ src/pages/error/NoNetwork.vue | 25 ++++++ src/routes/index.ts | 33 ++++++++ src/routes/routes.ts | 15 ++++ src/store/baseInfo.ts | 30 +++++++ src/store/index.ts | 5 ++ src/store/pinia.ts | 5 ++ src/styles/cover.less | 1 + src/styles/global.less | 77 +++++++++++++++++ src/styles/index.less | 2 + src/vite-env.d.ts | 7 ++ src/wx/index.ts | 48 +++++++++++ tsconfig.json | 43 ++++++++++ tsconfig.node.json | 9 ++ vite.config.ts | 101 ++++++++++++++++++++++ 54 files changed, 1808 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc.cjs create mode 100644 .gitignore create mode 100644 .prettierrc.cjs create mode 100644 README.md create mode 100644 components.d.ts create mode 100644 config/index.d.ts create mode 100644 config/index.ts create mode 100644 env.d.ts create mode 100644 index.html create mode 100644 package.json create mode 100644 proxy.config.ts create mode 100644 public/favicon.svg create mode 100644 src/App.vue create mode 100644 src/api/index.ts create mode 100644 src/assets/images/no_power.png create mode 100644 src/assets/svg/404.svg create mode 100644 src/assets/svg/500.svg create mode 100644 src/assets/svg/device_abnormal.svg create mode 100644 src/assets/svg/failed.svg create mode 100644 src/assets/svg/logo.svg create mode 100644 src/assets/svg/no_data.svg create mode 100644 src/assets/svg/no_network.svg create mode 100644 src/assets/svg/no_permission.svg create mode 100644 src/components/HelloWorld.vue create mode 100644 src/components/abnormal/iconAndText.vue create mode 100644 src/components/abnormal/index.vue create mode 100644 src/installComponents.ts create mode 100644 src/lib/ajax.ts create mode 100644 src/lib/request.ts create mode 100644 src/lib/util.ts create mode 100644 src/main.ts create mode 100644 src/pages/Home.vue create mode 100644 src/pages/Login.vue create mode 100644 src/pages/error/404.vue create mode 100644 src/pages/error/500.vue create mode 100644 src/pages/error/DeviceAbnormal.vue create mode 100644 src/pages/error/Failed.vue create mode 100644 src/pages/error/NoAccess.vue create mode 100644 src/pages/error/NoData.vue create mode 100644 src/pages/error/NoNetwork.vue create mode 100644 src/routes/index.ts create mode 100644 src/routes/routes.ts create mode 100644 src/store/baseInfo.ts create mode 100644 src/store/index.ts create mode 100644 src/store/pinia.ts create mode 100644 src/styles/cover.less create mode 100644 src/styles/global.less create mode 100644 src/styles/index.less create mode 100644 src/vite-env.d.ts create mode 100644 src/wx/index.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts 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..93ff15c --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +# vue3-template-h5 + +一个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..aaa6be2 --- /dev/null +++ b/components.d.ts @@ -0,0 +1,18 @@ +// 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 { + _index: typeof import('./src/components/abnormal/_index.vue')['default'] + 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..a73bc9f --- /dev/null +++ b/config/index.ts @@ -0,0 +1,39 @@ +const appName = "协同办公XX管理后台"; + +const passid = "paasid"; + +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 = "https://xxxxxx.com"; + break; + case "uat": + proxyTarget = "https://xxxxxx.com"; + break; + case "prod": + proxyTarget = "https://xxxxxx.com"; + break; + default: + proxyTarget = "https://xxxxxx.com"; + 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, + passid, + injectScriptStr +}; \ No newline at end of file diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..5b51319 --- /dev/null +++ b/env.d.ts @@ -0,0 +1,13 @@ +/// +declare interface ImportMetaEnv { + readonly VITE_APP_ENV: string + // 更多环境变量... +} + +declare interface ImportMeta { + readonly env: ImportMetaEnv +} + +declare interface Window { + wx: any; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..810bb30 --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ + + + + + + + + <%- title %> + + + +
+ <%- injectScript %> + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..937fdd2 --- /dev/null +++ b/package.json @@ -0,0 +1,48 @@ +{ + "name": "vue3-template-h5", + "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:uat": "cross-env VITE_APP_ENV=uat vite", + "serve:prod": "cross-env VITE_APP_ENV=prod vite", + "build:test": "vue-tsc --noEmit && cross-env VITE_APP_ENV=test vite build", + "build:uat": "vue-tsc --noEmit && cross-env VITE_APP_ENV=uat 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": "^3.5.4", + "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/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..81737e1 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,89 @@ + + + + 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..c9a33af --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,14 @@ +import ajax from "../lib/ajax"; +// import { passid } from "../../config"; + + +const HOST = "/zwwxgzt/workstation"; + +// 获取用户信息 +const getUserInfo = function (param: any) { + return ajax.post(`${HOST}/LoginUserInfo`, param); +}; + +export { + getUserInfo +}; \ No newline at end of file diff --git a/src/assets/images/no_power.png b/src/assets/images/no_power.png new file mode 100644 index 0000000000000000000000000000000000000000..1f32e7f07da7cc118e3f537d082b711fa80073b6 GIT binary patch literal 14506 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%0A>dA^1kr|#`b&I$Vre+*TI>T}dTiWmaj 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

s-VYu$)07 zPuIdsX)@2w-@#1TomMNVy`I;662{Y3G`>tc4)s6Lf0@t5{}Q@$94E*lI@YC!2n(}8Yxjk-Cafe_na;~vMi!P77kHrD~USdU|YtuE;sFO{6f*-;7kz)h4At`4n5;3W;fD)Ygu zmvG%Mae&B{`X3!+zZq4Jbsat%Ho*e3ylAN~OF0g_w#Q4W%f ziWB92d4vds8}H`E`xSko5j6*69%T=Yl#rwmGLut2aL|=T7KO@Zz=PoMyaT}X0*Mb| zk=ywxo{J#vtR_@f940PSsELC0l{VYD3Bo&}d zx|kq@0EaN&ZG`|YXb_l8I|E*Zs)M_wh!^9yl&I2x9_{aP535ctOi45rpcg4e04j=x z`DJ59U|R3fyG?@}U9sGnPeruG6F)7Vht z)1HS&hID^Vx+ObBk;bWe7~n!@K_orl_@Kvaj;xRh-vfksM3?|aLy!)im<6(?6hA}q z0YP>68DZ=9GaU3Ir1wYq2$Xa@N!EBnXjqk4!`1@Z2zSd|BDohKU)y6V`3F=Lo z2=QFXJK$^hQgpl9-8PO1Rd(AGv>ps+s|v4t4QApTq0X%2#{1D6+h#bbQi=7#$p5m+ zr4G!Pc8w~2D@^k-!CPV5CA@*BC65+*6--ws5`l&?`xfKcUl@LUY_2s@X*08EO`?K4 zBD1N literal 0 HcmV?d00001 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..a1b015b --- /dev/null +++ b/src/installComponents.ts @@ -0,0 +1,10 @@ +import { Button, Empty } from "vant"; + +const install = function (app: any) { + app.use(Button); + app.use(Empty); +}; + +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..21e359d --- /dev/null +++ b/src/lib/util.ts @@ -0,0 +1,35 @@ +// 设备信息 +const browser = { + versions: (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终端 + iPad: u.indexOf("iPad") > -1, //是否iPad + webApp: u.indexOf("Safari") === -1, //是否web应该程序,没有头部与底部 + zwwx: u.indexOf("zwwx-customized") > -1 //是否政务微信 + }; + })() +}; + +// 随机长度字符串 +const randomString = function (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; +}; + +export { + browser, + randomString +}; \ No newline at end of file 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..7b8de34 --- /dev/null +++ b/src/pages/Home.vue @@ -0,0 +1,28 @@ + + + + + \ 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/routes/index.ts b/src/routes/index.ts new file mode 100644 index 0000000..2688c88 --- /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..0fcd99b --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,5 @@ +import baseInfo from "./baseInfo"; + +export { + baseInfo +}; \ 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..fdbce38 --- /dev/null +++ b/src/styles/global.less @@ -0,0 +1,77 @@ +: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 { + background-color: #fff; + color: #000; + font-size: 14px; + font-family: "Helvetica", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif; + } + + .xtbg-tips-page { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + &-image { + width: 200px; + height: 200px; + & > img { + width: 100%; + height: 100%; + object-fit: cover; + } + } + &-text { + margin-top: 10px; + padding: 0 16px; + line-height: 26px; + color: #888; + font-size: 16px; + } + &-btn { + margin-top: 20px; + width: 100%; + display: flex; + justify-content: center; + &-class { + min-width: 100px; + margin: 0 8px !important; + } + } + } \ 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..635723e --- /dev/null +++ b/src/wx/index.ts @@ -0,0 +1,48 @@ +import axios from "axios"; + +// 初始化微信js-sdk配置 +const initConfig = (config: any) => { + function jsdkCB(data: any) { + let jsApiList = ["showWatermark"]; + if (typeof window.wx !== "object") { + return; + } + if (!config) { + config = {}; + } + jsApiList = jsApiList.concat(config.jsApiList || []); + const wxError = { + status: "", + errmsg: "配置失败,请退出重试" + }; + if (data.appid) { + window.wx.config({ + beta: true, + debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 + appId: data.appid, // 必填,政务微信的cropID + timestamp: data.timestamp, // 必填,生成签名的时间戳 + nonceStr: data.nonce, // 必填,生成签名的随机串 + signature: data.signature, // 必填,签名,见附录1 + jsApiList: jsApiList // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 + }); + window.wx.ready(function (e: any) { + console.log("config注册成功"); + // window['_initSuccess'] = true; + // 注册政务微信权限API,需要AgentId + // wxApi.registerAgentConfig(data, config); + typeof config.sucesscb === "function" && config.sucesscb(e); + }); + window.wx.error(function (e: any) { + console.log("initConfig wx error:", e); + typeof config.errorcb === "function" && config.errorcb(wxError); + }); + } + } + axios.get("/zwwxgzt/jsapi").then((res) => { + res && jsdkCB(res); + }); +}; + +export { + initConfig +}; \ 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..15848be --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,101 @@ +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 + }) + ] + } + }, + server: { + proxy: proxyConfig + }, + resolve: { + alias: { + "@": path.resolve(__dirname, "src") + } + } + }); + +}; \ No newline at end of file