正在显示
34 个修改的文件
包含
964 行增加
和
0 行删除
.gitignore
0 → 100644
.prettierrc.json
0 → 100644
README.md
0 → 100644
1 | +## 项目名称 | ||
2 | + | ||
3 | +> vue2-mo | ||
4 | + | ||
5 | +## 运行说明 | ||
6 | + | ||
7 | +- 安装依赖 | ||
8 | + | ||
9 | + ``` | ||
10 | + npm i | ||
11 | + ``` | ||
12 | + | ||
13 | +- 本地运行(测试接口) | ||
14 | + | ||
15 | + ``` | ||
16 | + npm start | ||
17 | + ``` | ||
18 | + | ||
19 | +- 本地运行(正式接口) | ||
20 | + | ||
21 | + ``` | ||
22 | + npm test | ||
23 | + ``` | ||
24 | + | ||
25 | +- 构建(测试接口) | ||
26 | + | ||
27 | + ``` | ||
28 | + npm run build:test | ||
29 | + ``` | ||
30 | + | ||
31 | +- 构建(正式接口) | ||
32 | + ``` | ||
33 | + npm run build | ||
34 | + ``` | ||
35 | + | ||
36 | +## 适配相关 | ||
37 | + | ||
38 | +开发使用 px 即可,自动转化为 rem | ||
39 | + | ||
40 | +### **modules/index.html** | ||
41 | + | ||
42 | +最大响应宽度设置 | ||
43 | + | ||
44 | +### **postcss.config** | ||
45 | + | ||
46 | +转化尺寸配置 | ||
47 | + | ||
48 | +## 配置相关 | ||
49 | + | ||
50 | +### **src/constants ** | ||
51 | + | ||
52 | +配置各个环境的常量,可自由添加 | ||
53 | + | ||
54 | +### **scripts/requests** | ||
55 | + | ||
56 | +axios 请求封装,包括公共方法,api,上报等 | ||
57 | + | ||
58 | +### **scripts/utils** | ||
59 | + | ||
60 | +工具函数 | ||
61 | + | ||
62 | +### **scripts/filters** | ||
63 | + | ||
64 | +过滤器 |
babel.config.js
0 → 100644
browserslist
0 → 100644
build/webpack.config.js
0 → 100644
1 | +/** | ||
2 | + * @file webpack 配置文件 | ||
3 | + */ | ||
4 | +const path = require('path') | ||
5 | + | ||
6 | +const CleanWebpackPlugin = require('clean-webpack-plugin') | ||
7 | +const HtmlWebpackPlugin = require('html-webpack-plugin') | ||
8 | +const MiniCssExtractPlugin = require('mini-css-extract-plugin') | ||
9 | +const { VueLoaderPlugin } = require('vue-loader') | ||
10 | +const hashDigestLength = 6 // 文件名末尾 hash 值长度 | ||
11 | +/** | ||
12 | + * webpack 配置项 | ||
13 | + * @param {Object} env - 环境对象 | ||
14 | + * @param {Object} argv - 命令行参数选项 | ||
15 | + * @param {String} argv.mode - 模式 | ||
16 | + */ | ||
17 | +module.exports = function (env = {}, argv) { | ||
18 | + let productionEnv = (!argv.host && argv.mode == 'production'); //生产环境下打包情况不一样,先清除旧的dist,部分文件的publicPath也不一样 | ||
19 | + let config = { | ||
20 | + devtool: productionEnv ? '' : 'source-map', | ||
21 | + | ||
22 | + resolve: { | ||
23 | + alias: { | ||
24 | + '@': path.resolve(__dirname, '../src'), | ||
25 | + components: path.resolve(__dirname, '../src/components'), | ||
26 | + images: path.resolve(__dirname, '../src/images'), | ||
27 | + modules: path.resolve(__dirname, '../src/modules'), | ||
28 | + scripts: path.resolve(__dirname, '../src/scripts'), | ||
29 | + styles: path.resolve(__dirname, '../src/styles'), | ||
30 | + } | ||
31 | + }, | ||
32 | + | ||
33 | + entry: { | ||
34 | + app: './src/scripts', | ||
35 | + }, | ||
36 | + | ||
37 | + output: { | ||
38 | + // filename: 'scripts/[name]_[chunkhash].js', | ||
39 | + filename: 'scripts/[name].js', | ||
40 | + hashDigestLength, | ||
41 | + // path: path.resolve(__dirname, productionEnv ? '../../dist/m/' : '../dist/'), | ||
42 | + path: path.resolve(__dirname, productionEnv ? '../dist/' : '../dist/'), | ||
43 | + }, | ||
44 | + | ||
45 | + module: { | ||
46 | + rules: [{ | ||
47 | + test: /\.(jpg|png|svg|gif)$/, | ||
48 | + use: [{ | ||
49 | + loader: 'file-loader', | ||
50 | + options: { | ||
51 | + // name: `[name]_[hash:${hashDigestLength}].[ext]`, | ||
52 | + name: `[name].[ext]`, | ||
53 | + outputPath: 'images', | ||
54 | + publicPath: productionEnv ? '/images/' : '/images/', | ||
55 | + //https://inside.wx.luckyxp.com.cn/webup/data/User/wxtest/home/project/lls-m/dist/images/ | ||
56 | + } | ||
57 | + }] | ||
58 | + }, { | ||
59 | + test: /\.(woff|ttf|woff2|eot)$/, | ||
60 | + use: [ | ||
61 | + { | ||
62 | + loader: 'file-loader', | ||
63 | + options: { | ||
64 | + outputPath: 'styles', | ||
65 | + publicPath: './' | ||
66 | + } | ||
67 | + } | ||
68 | + ] | ||
69 | + }, { | ||
70 | + test: /\.(css|postcss)$/, | ||
71 | + use: [{ | ||
72 | + loader: MiniCssExtractPlugin.loader | ||
73 | + }, { | ||
74 | + loader: 'css-loader', | ||
75 | + options: { | ||
76 | + importLoaders: 1 | ||
77 | + } | ||
78 | + }, { | ||
79 | + loader: 'postcss-loader', | ||
80 | + }] | ||
81 | + }, { | ||
82 | + test: /\.js$/, | ||
83 | + exclude: /node_modules/, | ||
84 | + use: [{ | ||
85 | + loader: 'babel-loader' | ||
86 | + }] | ||
87 | + }, { | ||
88 | + test: /\.vue$/, | ||
89 | + use: [{ | ||
90 | + loader: 'vue-loader', | ||
91 | + options: { | ||
92 | + compilerOptions: { | ||
93 | + preserveWhitespace: false | ||
94 | + } | ||
95 | + } | ||
96 | + }] | ||
97 | + }] | ||
98 | + }, | ||
99 | + | ||
100 | + plugins: [ | ||
101 | + new VueLoaderPlugin(), | ||
102 | + new MiniCssExtractPlugin({ | ||
103 | + filename: 'styles/[name]_[chunkhash].css' | ||
104 | + // filename: 'styles/[name].css' | ||
105 | + }), | ||
106 | + new HtmlWebpackPlugin({ | ||
107 | + title: 'AFK Journey', | ||
108 | + template: './src/index.html', | ||
109 | + }) | ||
110 | + ], | ||
111 | + | ||
112 | + optimization: { | ||
113 | + runtimeChunk: { | ||
114 | + name: 'manifest' | ||
115 | + }, | ||
116 | + splitChunks: { | ||
117 | + chunks: 'all', | ||
118 | + minChunks: 2 | ||
119 | + } | ||
120 | + }, | ||
121 | + | ||
122 | + performance: { | ||
123 | + hints: false | ||
124 | + }, | ||
125 | + | ||
126 | + devServer: { | ||
127 | + contentBase: path.join(__dirname, '../'), | ||
128 | + disableHostCheck: true, | ||
129 | + open: true, | ||
130 | + host: 'localhost', | ||
131 | + // host: '192.168.17.6', | ||
132 | + // host: 'inside.wx.luckyxp.com.cn', | ||
133 | + port: 8001, | ||
134 | + proxy: { | ||
135 | + } | ||
136 | + } | ||
137 | + } | ||
138 | + | ||
139 | + config.plugins = config.plugins.concat([ | ||
140 | + // new CleanWebpackPlugin([productionEnv ? 'm' : 'dist'], { | ||
141 | + // root: path.join(__dirname, productionEnv ? '../../dist/' : '../') | ||
142 | + // }), | ||
143 | + new CleanWebpackPlugin(['dist'], { | ||
144 | + root: path.join(__dirname, '../') | ||
145 | + }), | ||
146 | + ]) | ||
147 | + | ||
148 | + return config | ||
149 | +} |
package-lock.json
0 → 100644
此 diff 太大无法显示。
package.json
0 → 100644
1 | +{ | ||
2 | + "name": "igame", | ||
3 | + "version": "1.0.0", | ||
4 | + "description": "igame", | ||
5 | + "main": "index.js", | ||
6 | + "scripts": { | ||
7 | + "start": "webpack-dev-server --config build/webpack.config.js --mode=development --progress", | ||
8 | + "test": "webpack-dev-server --config build/webpack.config.js --mode=production --progress", | ||
9 | + "build:test": "webpack --config build/webpack.config.js --mode=development --progress", | ||
10 | + "build": "webpack --config build/webpack.config.js --mode=production --progress" | ||
11 | + }, | ||
12 | + "repository": { | ||
13 | + "type": "git", | ||
14 | + "url": "" | ||
15 | + }, | ||
16 | + "author": "taojixuan", | ||
17 | + "devDependencies": { | ||
18 | + "@babel/core": "^7.3.4", | ||
19 | + "@babel/plugin-syntax-dynamic-import": "^7.2.0", | ||
20 | + "@babel/preset-env": "^7.3.4", | ||
21 | + "autoprefixer": "^9.4.9", | ||
22 | + "axios": "^0.18.0", | ||
23 | + "babel-loader": "^8.0.5", | ||
24 | + "clean-webpack-plugin": "^1.0.1", | ||
25 | + "css-loader": "^2.1.0", | ||
26 | + "cssnano": "^4.1.10", | ||
27 | + "file-loader": "^3.0.1", | ||
28 | + "html-webpack-plugin": "^3.2.0", | ||
29 | + "mini-css-extract-plugin": "^0.5.0", | ||
30 | + "node-sass": "^7.0.1", | ||
31 | + "postcss-import": "^12.0.1", | ||
32 | + "postcss-loader": "^3.0.0", | ||
33 | + "postcss-nested": "^4.1.2", | ||
34 | + "sass-loader": "^13.0.2", | ||
35 | + "style-loader": "^3.3.1", | ||
36 | + "vue": "^2.6.10", | ||
37 | + "vue-color": "^2.7.0", | ||
38 | + "vue-loader": "^15.6.4", | ||
39 | + "vue-router": "^3.0.2", | ||
40 | + "vue-template-compiler": "^2.6.10", | ||
41 | + "vuex": "^3.1.0", | ||
42 | + "webpack": "^4.29.5", | ||
43 | + "webpack-cli": "^3.2.3", | ||
44 | + "webpack-dev-server": "^3.2.1" | ||
45 | + }, | ||
46 | + "dependencies": { | ||
47 | + "clipboard": "^2.0.11", | ||
48 | + "core-js": "^2.5.7", | ||
49 | + "postcss-px2rem": "^0.3.0", | ||
50 | + "vant": "^2.12.50" | ||
51 | + } | ||
52 | +} |
postcss.config.js
0 → 100644
src/images/bg.jpg
0 → 100644
213.8 KB
src/index.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html lang="zh-Hans"> | ||
3 | + | ||
4 | +<head> | ||
5 | + <meta charset="UTF-8"> | ||
6 | + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover"> | ||
7 | + <title> | ||
8 | + <%= htmlWebpackPlugin.options.title %> | ||
9 | + </title> | ||
10 | + <meta name="keywords" | ||
11 | + content="afk journey,AFK,AFK2,RPG,RPGGAMES,MMORPG,FREEGAME,FARLIGHT,IDLE RPG,Strategy RPG,Gacha,Journey,Open World" /> | ||
12 | + <link rel="icon" | ||
13 | + href="https://oss-resource.farlightgames.com/p/SDK/200000/0/100000/2023-04-23/D:/img/f92c62a9048640b522cdb0fd00eb379b.ico"> | ||
14 | +</head> | ||
15 | + | ||
16 | +<body> | ||
17 | + <div id="app"></div> | ||
18 | +</body> | ||
19 | +<style> | ||
20 | + .grecaptcha-badge { | ||
21 | + display: none !important; | ||
22 | + opacity: 0; | ||
23 | + } | ||
24 | +</style> | ||
25 | +<script> | ||
26 | + (function (win) { | ||
27 | + var doc = win.document; | ||
28 | + var docEl = doc.documentElement; | ||
29 | + var tid; | ||
30 | + function refreshRem () { | ||
31 | + var width = docEl.getBoundingClientRect().width; | ||
32 | + if (width > 600) { // 最大宽度 | ||
33 | + width = 600; | ||
34 | + } | ||
35 | + var rem = width / 10; | ||
36 | + docEl.style.fontSize = rem + 'px'; | ||
37 | + } | ||
38 | + | ||
39 | + win.addEventListener('resize', function () { | ||
40 | + clearTimeout(tid); | ||
41 | + tid = setTimeout(refreshRem, 300); | ||
42 | + }, false); | ||
43 | + win.addEventListener('pageshow', function (e) { | ||
44 | + if (e.persisted) { | ||
45 | + clearTimeout(tid); | ||
46 | + tid = setTimeout(refreshRem, 300); | ||
47 | + } | ||
48 | + }, false); | ||
49 | + | ||
50 | + refreshRem(); | ||
51 | + | ||
52 | + })(window); | ||
53 | +</script> | ||
54 | + | ||
55 | +</html> | ||
56 | + | ||
57 | +</html> |
src/modules/app/index.vue
0 → 100644
1 | +<template> | ||
2 | + <router-view></router-view> | ||
3 | +</template> | ||
4 | + | ||
5 | +<script> | ||
6 | +export default { | ||
7 | + data() { | ||
8 | + return { | ||
9 | + }; | ||
10 | + }, | ||
11 | + methods: { | ||
12 | + }, | ||
13 | + created() { | ||
14 | + }, | ||
15 | + mounted() { | ||
16 | + }, | ||
17 | + computed: {}, | ||
18 | +}; | ||
19 | +</script> | ||
20 | + | ||
21 | +<style lang="postcss"> | ||
22 | + | ||
23 | +</style> |
src/modules/errorPages/my404.vue
0 → 100644
src/modules/index/index.postcss
0 → 100644
src/modules/index/index.vue
0 → 100644
1 | +<template> | ||
2 | + <div class="container">首页</div> | ||
3 | +</template> | ||
4 | + | ||
5 | +<script> | ||
6 | +import Tracker from '@/scripts/tracker' | ||
7 | +import { reqPublic } from 'scripts/requests/index.js' | ||
8 | +import Clipboard from 'clipboard' | ||
9 | +import { ALink, getParameterByName, getUrlSearchJson } from 'scripts/util' | ||
10 | +import { URLS, ENV } from 'scripts/constants/index' | ||
11 | +export default { | ||
12 | + components: {}, | ||
13 | + data() { | ||
14 | + return {} | ||
15 | + }, | ||
16 | + computed: {}, | ||
17 | + methods: {}, | ||
18 | + created() {}, | ||
19 | + mounted() {}, | ||
20 | + watch: {}, | ||
21 | +} | ||
22 | +</script> | ||
23 | + | ||
24 | +<style lang="postcss" scoped> | ||
25 | +@import './index.postcss'; | ||
26 | +</style> |
src/modules/layout/index.vue
0 → 100644
1 | +<template> | ||
2 | + <div class="root"> | ||
3 | + <transition name="el-fade-in" mode="out-in"> | ||
4 | + <router-view></router-view> | ||
5 | + </transition> | ||
6 | + </div> | ||
7 | +</template> | ||
8 | + | ||
9 | +<script> | ||
10 | +export default { | ||
11 | + data() { | ||
12 | + return {} | ||
13 | + }, | ||
14 | + methods: { | ||
15 | + initMenu() {}, | ||
16 | + }, | ||
17 | + created() {}, | ||
18 | + mounted() {}, | ||
19 | + computed: {}, | ||
20 | +} | ||
21 | +</script> | ||
22 | + | ||
23 | +<style lang="postcss"></style> |
src/scripts/common.js
0 → 100644
src/scripts/constants/env.js
0 → 100644
1 | +/** | ||
2 | + * @file 常量 - 环境 | ||
3 | + */ | ||
4 | + const ENV = process.env.NODE_ENV === 'production' ? 'prod' : 'dev'; | ||
5 | + const HOSTNAME = process.env.NODE_ENV === 'production' ? 'https://game-reserve-api.farlightgames.com' : 'https://game-reserve-api-test.farlightgames.com'; | ||
6 | + const IOS_APPID = process.env.NODE_ENV === "production" ? "1628970855" : "1131944535"; | ||
7 | + const ANDROID_APPID = process.env.NODE_ENV === "production" ? "com.farlightgames.igame.gp" : "com.lilithgame.sgame.android.cn"; | ||
8 | + const IOS_LILITH_APPID = process.env.NODE_ENV === "production" ? "10013832" : "8876096"; | ||
9 | + const ANDROID_LILITH_APPID = process.env.NODE_ENV === "production" ? "10013832" : "5660453"; | ||
10 | + const FILTER_ID = process.env.NODE_ENV === "production" ? 85252 : 89032; | ||
11 | + export default { | ||
12 | + ENV, | ||
13 | + HOSTNAME, | ||
14 | + IOS_APPID, | ||
15 | + ANDROID_APPID, | ||
16 | + IOS_LILITH_APPID, | ||
17 | + ANDROID_LILITH_APPID, | ||
18 | + FILTER_ID | ||
19 | + } |
src/scripts/constants/index.js
0 → 100644
src/scripts/constants/urls.js
0 → 100644
1 | +const kvUrl = 'https://oss-resource.farlightgames.com/p/SDK/200000/0/100000/2023-04-23/D:/video/7f42f378ea8a098ede28586170c4c056.mp4' | ||
2 | +const videoUrl = 'https://oss-resource.farlightgames.com/p/SDK/200000/0/100000/2023-04-23/D:/video/b5f951cc9b914e98ea25dab668cfd1c6.mp4' | ||
3 | +const mLink = process.env.NODE_ENV === 'production' ? 'https://afkjourney.farlightgames.com/m/index.html' : 'https://inside.wx.luckyxp.com.cn/webup/data/User/wxtest/home/project/lls-m/dist/index.html' | ||
4 | +const pcLink = process.env.NODE_ENV === 'production' ? 'https://afkjourney.farlightgames.com/index.html' : 'https://inside.wx.luckyxp.com.cn/webup/data/User/wxtest/home/project/lls-pc/dist/index.html' | ||
5 | +export default { | ||
6 | + kvUrl, | ||
7 | + videoUrl, | ||
8 | + mLink, | ||
9 | + pcLink | ||
10 | +} |
src/scripts/filters.js
0 → 100644
1 | +/** | ||
2 | + * @file vue 全局过滤器 | ||
3 | + */ | ||
4 | +import Vue from 'vue' | ||
5 | + | ||
6 | +/** | ||
7 | + * 时间格式化 | ||
8 | + * @param {Number|String} time - 时间戳或字符串 | ||
9 | + * @param {String} format - 时间格式:'YYYY-MM-DD hh:mm:ss'(默认值) | ||
10 | + * @param {Boolean} simplify - 是否简化时间格式 | ||
11 | + */ | ||
12 | +Vue.filter('adFormatTime', function (time, format = 'YYYY-MM-DD hh:mm:ss', simplify) { | ||
13 | + if (typeof time == 'string' && time.indexOf('T') === -1) { //排除格林威治时间 | ||
14 | + time = time.replace(/-/g, '/') | ||
15 | + } | ||
16 | + if (String(time).length < 11) { | ||
17 | + time += '000'; | ||
18 | + } | ||
19 | + let date = new Date(Number(time)); | ||
20 | + | ||
21 | + // #region 简化时间格式,最多 7 天 | ||
22 | + if (simplify) { | ||
23 | + let result = '' | ||
24 | + let difference = Date.now() - date.getTime() | ||
25 | + if (difference < 60000) { | ||
26 | + result = '刚刚' | ||
27 | + } else if (difference < 3600000) { | ||
28 | + result = parseInt(difference / 60000) + ' 分钟前' | ||
29 | + } else if (difference < 86400000) { | ||
30 | + result = parseInt(difference / 3600000) + ' 小时前' | ||
31 | + } else if (difference < 604800000) { | ||
32 | + result = parseInt(difference / 86400000) + ' 天前' | ||
33 | + } | ||
34 | + if (result) { | ||
35 | + return result | ||
36 | + } | ||
37 | + } | ||
38 | + // #endregion | ||
39 | + | ||
40 | + const patterns = { | ||
41 | + 'M+': date.getMonth() + 1, | ||
42 | + 'D+': date.getDate(), | ||
43 | + 'h+': date.getHours(), | ||
44 | + 'm+': date.getMinutes(), | ||
45 | + 's+': date.getSeconds() | ||
46 | + } | ||
47 | + if (/Y+/.test(format)) { | ||
48 | + format = format.replace(RegExp.lastMatch, (date.getFullYear() + '').slice(4 - RegExp.lastMatch.length)) | ||
49 | + } | ||
50 | + for (let p in patterns) { | ||
51 | + if (new RegExp('(' + p + ')').test(format)) { | ||
52 | + format = format.replace(RegExp.lastMatch, RegExp.lastMatch.length == 1 ? patterns[p] : String(patterns[p]).padStart(2, '0')) | ||
53 | + } | ||
54 | + } | ||
55 | + return format | ||
56 | +}) | ||
57 | + | ||
58 | +/** | ||
59 | + * 数字格式化 | ||
60 | + * @param {Number} num - 待格式化的数字 | ||
61 | + */ | ||
62 | +Vue.filter('adFormatNumber', function (num) { | ||
63 | + if (typeof num == 'undefined') { | ||
64 | + return '' | ||
65 | + } | ||
66 | + let result = num.toString() | ||
67 | + if (num > 100000000) { | ||
68 | + result = (num / 100000000).toFixed(1) + '亿' | ||
69 | + } else if (num > 10000) { | ||
70 | + result = (num / 10000).toFixed(1) + '万' | ||
71 | + } | ||
72 | + return result | ||
73 | +}) |
src/scripts/index.js
0 → 100644
1 | +/** | ||
2 | + * @file 项目入口文件 | ||
3 | + */ | ||
4 | +import Vue from 'vue' | ||
5 | +import VueRouter from 'vue-router' | ||
6 | +import Vuex from 'vuex' | ||
7 | +import routes from './routes' | ||
8 | +import store from './store' | ||
9 | +import App from 'modules/app/index.vue' | ||
10 | +import './landscape.js' | ||
11 | +import './ipadLandscape.js' | ||
12 | +import './common' | ||
13 | +import './filters' | ||
14 | +import 'styles/common.css' | ||
15 | +import 'styles/commonStyle.css' | ||
16 | + | ||
17 | +Vue.use(VueRouter) | ||
18 | +Vue.use(Vuex) | ||
19 | +import 'vant/es/toast/style'; | ||
20 | +import { Toast, Popup } from "vant"; | ||
21 | +Vue.use(Toast); | ||
22 | +Vue.use(Popup); | ||
23 | + | ||
24 | +// 配置发送请求拦截器,实现路由切换后取消之前的请求 | ||
25 | +let axiosPromiseArr = []; | ||
26 | +import axios from 'axios' | ||
27 | +axios.interceptors.request.use(config => { | ||
28 | + config.cancelToken = new axios.CancelToken(cancel => { | ||
29 | + axiosPromiseArr.push({ cancel }); | ||
30 | + }) | ||
31 | + return config; | ||
32 | +}, err => { | ||
33 | + var error = { message: '网络异常,请刷新重试', err: err, type: 'requestError' }; | ||
34 | + console.log(error); | ||
35 | + return Promise.reject(error); | ||
36 | +}) | ||
37 | + | ||
38 | +var Router = new VueRouter({ routes }); | ||
39 | + | ||
40 | +Router.beforeEach((to, from, next) => { | ||
41 | + axiosPromiseArr.forEach((ele, index) => { | ||
42 | + ele.cancel(); | ||
43 | + delete axiosPromiseArr[index]; | ||
44 | + }) | ||
45 | + next() | ||
46 | +}) | ||
47 | + | ||
48 | +new Vue({ | ||
49 | + el: '#app', | ||
50 | + render: h => h(App), | ||
51 | + router: Router, | ||
52 | + store: new Vuex.Store(store), | ||
53 | +}) | ||
54 | + |
src/scripts/ipadLandscape.js
0 → 100644
1 | +var supportsOrientationChange = "onorientationchange" in window, | ||
2 | + orientationEvent = supportsOrientationChange ? "orientationchange" : "resize"; | ||
3 | +// 监听事件 | ||
4 | +window.addEventListener(orientationEvent, function () { | ||
5 | + var ua = navigator.userAgent; | ||
6 | + var deviceType = ""; | ||
7 | + //判断设备类型 | ||
8 | + if (ua.indexOf("iPad") > 0) { | ||
9 | + deviceType = "isIpad"; | ||
10 | + } else if (ua.indexOf("Android") > 0) { | ||
11 | + deviceType = "isAndroid"; | ||
12 | + } else { | ||
13 | + // console.log("既不是ipad,也不是安卓!"); | ||
14 | + return; | ||
15 | + } | ||
16 | + let ipadId = document.getElementById('orientLayer') | ||
17 | + // 判断横竖屏 | ||
18 | + if ("isIpad" == deviceType) { | ||
19 | + if (Math.abs(window.orientation) == 90) { | ||
20 | + ipadId.style.display = 'block' | ||
21 | + // console.log("我是ipad的横屏",ipadId.style.display = 'block'); | ||
22 | + } else { | ||
23 | + // console.log("我是ipad的竖屏"); | ||
24 | + ipadId.style.display = 'none' | ||
25 | + } | ||
26 | + } | ||
27 | +}, false); |
src/scripts/landscape.js
0 → 100644
1 | +/* 横竖提示处理 | ||
2 | + * isVertical:不传默认为false,即显示竖屏提示,(false: 提示用户横屏, true:提示用户竖屏) | ||
3 | + */ | ||
4 | +(function landscape(config) { | ||
5 | + var isVertical =true; | ||
6 | + var showWay = isVertical ? "@media screen and (min-aspect-ratio: 12/7){#orientLayer{display:block;} }" : | ||
7 | + "@media all and (orientation : portrait){#orientLayer{display: block;} }"; | ||
8 | + var color = config && config.color ? config.color : "#000", | ||
9 | + txt = isVertical ? "Screen Auto-Rotate" : " ", | ||
10 | + images = config && config.images ? config.images : | ||
11 | + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIYAAADaCAMAAABU68ovAAAAXVBMVEUAAAD29vb////x8fH////////x8fH5+fn29vby8vL////5+fn39/f6+vr////x8fH////////+/v7////09PT////x8fH39/f////////////////////x8fH///+WLTLGAAAAHXRSTlMAIpML+gb4ZhHWn1c2gvHBvq1uKJcC6k8b187lQ9yhhboAAAQYSURBVHja7d3blpowFIDhTUIAOchZDkre/zE7ycySrbUUpsRN2/1fzO18KzEqxEVgTiZNfgmmtxRc8iaR8HNe8x4BtjQePKayYCIoyBSgvNNE1AkNSHqZyLqk97EgUCCHBzZ5mkg7ScvIJuIyOyXBRFxgpqWZyGsAZLB1KjsJi8nutHU4JCRbFRH8tmirI9k8Jx2sqNs8K/m0LQkrktO2crgcgXGB4AiTEsB0hJfo9MGgX7CGcYiYwQxmMOOvZwRhBG8tCoMXjBDeXvWCEcHbi14wgCBmMIMZzGAGM5jxETNwzMAxA8cMHDNwzMAxA8cMHDNwzMAxA8cMHDNwzMAxY6E2rUQxnH2tz9cirlJFwFBJedaPnUv0M7++egPDE8iAJcIDmxwH5wwv9vUviw2kLbVO3TJU5uul/EyB0FoLp4x60PdGUd3qPurrWyjGGTc05u+1dcgI7/+tCCPARWGhH7o5Y7RCf+bH9ctXLp6v2BVDxfqz0oPXeSVaNtINo/1SXDv4dck8IIkbhtC2ol+iouEonTBCbYvVMnXOjxww6s/RFrBUpXHh/gw1rHj5d/qhYn9Gpk2FWh6xRBRX5Oj3Znh2Sq49/L6+y8pB26q9GbE2dbA2mVbx6I+7MfBglLCttm73ZQi7AD3iL4HqjFYJHSPRppqaUaJ3ATpGa+ckpGak2hRRMyqjGMkvl+xyFeSMwjAqcsZgGDdyhl0oNTnDN4yenJGZFGxNChP5/Y3efh6SM2rDOJMzboYxkDMqwyjIGcIw6F+io2FU1IxIm1JqRmgXSkvNKNCXeTpGrU0JNSO2c6LIGPgCS8AuDHz9ta0SXWDtxoDRH+MqlbC2Dt2G2JFRadtQZt2qq/orGowdGb2euxYiqWEpVWhTBnszoNAPdStuQwxqf0aocdWKW4Z+DfszIh8pxJqbuCE4YAC+4bm0evtipjpgJHeFnyyt1Ku2xa0bhjxr27p75rECNwyI9ZwvXkHq+7aTaMEV44YYy/spfgjgjNHaWW+GeUhGEX7tLlVinIFDDSgnOwhi1V6bU0b6tVS9eAERe863g4dRrtiHdc6o+nn5vtyVVgR79Cqt4uL6gfHPQyGqtP2vf7HADGbcYwaOGThm4JiBYwaOGThm4JiBYwaOGThm4JiBYwaOGThm4JiBYwaOGThm4JjhtOM+J/AgT008yDMkN/dPP9hzS8zAMQN3OEYeekp5YU7KOKXwVXqiY+QS7smcinGKABWdiBgpPJTSMHJ4KidhhPBUSMLw4CmPhKHgKUXCkHsygum71ftNSgCX6bsl8FQyfbcL5EdYsDk0R3j7aiA5wpt5AjKg/2gLJEBD/0Hf2OOf/vRrj6z/7GtP4B3nMKyjHA12kIPSjnJs3FEO0TvKkYJHOWCR+rjJH0Vn6fI5PjNbAAAAAElFTkSuQmCC"; | ||
12 | + // style | ||
13 | + var nodeStyle = document.createElement('style'); | ||
14 | + nodeStyle.setAttribute('type', 'text/css'); | ||
15 | + nodeStyle.innerHTML = | ||
16 | + '@-webkit-keyframes rotation{10%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} 50%, 60%{transform: rotate(0deg); -webkit-transform: rotate(0deg)} 90%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} 100%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} } @keyframes rotation{10%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} 50%, 60%{transform: rotate(0deg); -webkit-transform: rotate(0deg)} 90%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} 100%{transform: rotate(90deg); -webkit-transform: rotate(90deg)} } #orientLayer{display: none; z-index: 999999;} ' + | ||
17 | + showWay + | ||
18 | + ' .mod-orient-layer{display: none; position: fixed; height: 100%; width: 100%; left: 0; top: 0; right: 0; bottom: 0; background: ' + | ||
19 | + color + | ||
20 | + '; z-index: 9997} .mod-orient-layer__content{position: absolute; width: 100%; top: 45%; margin-top: -75px; text-align: center} .mod-orient-layer__icon-orient{background-image: url(' + | ||
21 | + images + | ||
22 | + '); display: inline-block; width: 67px; height: 109px; transform: rotate(90deg); -webkit-transform: rotate(90deg); -webkit-animation: rotation infinite 1.5s ease-in-out; animation: rotation infinite 1.5s ease-in-out; -webkit-background-size: 67px; background-size: 67px} .mod-orient-layer__desc{margin-top: 20px; font-size: 15px; color: #fff}' | ||
23 | + document.getElementsByTagName('body')[0].appendChild(nodeStyle); | ||
24 | + // dom | ||
25 | + var nodeDom = document.createElement('div'); | ||
26 | + nodeDom.setAttribute('id', 'orientLayer'); | ||
27 | + nodeDom.setAttribute('class', 'mod-orient-layer'); | ||
28 | + nodeDom.innerHTML = | ||
29 | + '<div class="mod-orient-layer__content"> <i class="icon mod-orient-layer__icon-orient"></i> <div class="mod-orient-layer__desc">' + | ||
30 | + txt + '</div> </div>'; | ||
31 | + document.getElementsByTagName('body')[0].appendChild(nodeDom); | ||
32 | +}()) |
src/scripts/requests/api/public.js
0 → 100644
1 | +import axios from '../axios' | ||
2 | +import { ENV } from 'scripts/constants/index' | ||
3 | +// import { Message } from 'element-ui'; | ||
4 | + | ||
5 | +export default { | ||
6 | + // 新增预约 | ||
7 | + appointment(data){ | ||
8 | + let params = { | ||
9 | + ...data | ||
10 | + } | ||
11 | + return axios | ||
12 | + .post(`/gear/reserve/v2/nocode-add`, { ...params }) | ||
13 | + .then((res) => { | ||
14 | + return res.data | ||
15 | + }) | ||
16 | + .catch((err) => { | ||
17 | + // Message.error(err, 2) | ||
18 | + }) | ||
19 | + } | ||
20 | +} |
src/scripts/requests/axios.js
0 → 100644
1 | +/** | ||
2 | + * @file Axios 全局配置 | ||
3 | + */ | ||
4 | +import axios from 'axios' | ||
5 | +import { ENV } from '../constants/index' | ||
6 | + | ||
7 | + | ||
8 | +const myAxios = axios.create({ | ||
9 | + baseURL: ENV.HOSTNAME, | ||
10 | + // withCredentials: true | ||
11 | +}) | ||
12 | + | ||
13 | +myAxios.defaults.timeout = 10000; | ||
14 | +myAxios.interceptors.response.use((res) => { | ||
15 | + if (res.status >= 200 && res.status < 300) { | ||
16 | + return res; | ||
17 | + } | ||
18 | + return Promise.reject(res); | ||
19 | +}, (error) => { | ||
20 | + // 网络异常 | ||
21 | + if (axios.isCancel(error)) { | ||
22 | + var err = { message: '路由切换,网络请求已取消', err: error, type: 'cancel' }; | ||
23 | + console.log(err); | ||
24 | + return Promise.reject(err); | ||
25 | + } else { | ||
26 | + var err = { message: '网络异常,请刷新重试', err: error, type: 'responseError' }; | ||
27 | + console.log(err); | ||
28 | + return Promise.reject(err); | ||
29 | + } | ||
30 | +}); | ||
31 | + | ||
32 | +export default myAxios |
src/scripts/requests/index.js
0 → 100644
src/scripts/routes.js
0 → 100644
1 | +/** | ||
2 | + * @file 路由信息 | ||
3 | + */ | ||
4 | + | ||
5 | +export default [{ | ||
6 | + path: '/', | ||
7 | + redirect: '/index', | ||
8 | + component: () => import(/* webpackChunkName: 'entry' */ '../modules/app/index.vue') | ||
9 | +}, { | ||
10 | + path: '/index', | ||
11 | + component: () => import(/* webpackChunkName: 'index' */ '../modules/layout/index.vue'), | ||
12 | + children: [ | ||
13 | + { | ||
14 | + path: '/index', | ||
15 | + component: () => import(/* webpackChunkName: 'index' */ '../modules/index/index.vue'), | ||
16 | + meta: { | ||
17 | + name: '首页' | ||
18 | + } | ||
19 | + } | ||
20 | + ] | ||
21 | +}, { | ||
22 | + path: '*', | ||
23 | + name: '404', | ||
24 | + component: () => import(/* webpackChunkName: '404' */ '../modules/errorPages/my404.vue'), | ||
25 | + meta: { | ||
26 | + name: '404' | ||
27 | + } | ||
28 | +}] |
src/scripts/store.js
0 → 100644
src/scripts/tracker.js
0 → 100644
1 | +/** | ||
2 | + * 发送自定义上报时间 | ||
3 | + * @param {*} eventName 事件名称 | ||
4 | + * @param {*} eventParams 自定义参数 | ||
5 | + */ | ||
6 | +let send = function (eventName, eventParams = {}) { | ||
7 | + gtag('event', eventName, { | ||
8 | + ...eventParams | ||
9 | + }) | ||
10 | +} | ||
11 | +const Tracker = { | ||
12 | + /** | ||
13 | + * 点击预约按钮 | ||
14 | + */ | ||
15 | + start_index: function () { | ||
16 | + send('start_appointment_index') | ||
17 | + }, | ||
18 | +} | ||
19 | + | ||
20 | + | ||
21 | +export default Tracker |
src/scripts/util.js
0 → 100644
1 | +/** | ||
2 | + * @file 工具函数 | ||
3 | + * 常用方法,公共方法 | ||
4 | + */ | ||
5 | + | ||
6 | +/** | ||
7 | + * @name GetLabelFormValue 对象数组中根据一个字段获取对象 | ||
8 | + * @param {Array[Object]} array - 对象数组 | ||
9 | + * @param {String} key - 字段名 | ||
10 | + * @param {any} value - 该字段的预设值 | ||
11 | + * @param {String} label - 可选,无匹配对象的空值字段 | ||
12 | + */ | ||
13 | + const GetObjFormKey = function (array, key = 'value', value = '', label) { | ||
14 | + if (!array) return {} | ||
15 | + | ||
16 | + for (var item of array) { | ||
17 | + if (String(item[key]) === String(value)) { | ||
18 | + return item | ||
19 | + } | ||
20 | + } | ||
21 | + if (label) { | ||
22 | + var result = {} | ||
23 | + result[label] = '' | ||
24 | + return result | ||
25 | + } else { | ||
26 | + return {} | ||
27 | + } | ||
28 | +} | ||
29 | + | ||
30 | +/** | ||
31 | + * 模拟a标签跳转 | ||
32 | + * @param url | ||
33 | + * @param target | ||
34 | + * @return {*} | ||
35 | + */ | ||
36 | + const ALink = function(url, target = '_blank') { | ||
37 | + const a = document.createElement('a'); | ||
38 | + a.href = url; | ||
39 | + a.target = target; | ||
40 | + document.body.appendChild(a); | ||
41 | + a.click(); | ||
42 | + document.body.removeChild(a); | ||
43 | +} | ||
44 | +/** | ||
45 | + * 获取url参数 | ||
46 | + * @param {*} name 参数名 | ||
47 | + * @param {*} url | ||
48 | + * @returns | ||
49 | + */ | ||
50 | + const getParameterByName = function (name, url) { | ||
51 | + if (!url) url = window.location.href; | ||
52 | + name = name.replace(/[[]]/g, '$&'); | ||
53 | + var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), | ||
54 | + results = regex.exec(url); | ||
55 | + if (!results) return null; | ||
56 | + if (!results[2]) return ''; | ||
57 | + return decodeURIComponent(results[2].replace(/\\+/g, ' ')); | ||
58 | +} | ||
59 | + | ||
60 | +function getUrlSearchJson() { | ||
61 | + var url = location.search; | ||
62 | + if(!url) { | ||
63 | + return null; | ||
64 | + } | ||
65 | + var newObj = new Object(); | ||
66 | + if (url.indexOf("?") != -1) { | ||
67 | + var strs = url.split('?')[1].split("&"); | ||
68 | + for (var i = 0; i < strs.length; i++) { | ||
69 | + newObj[strs[i].split("=")[0]] = (strs[i].split("=")[1]) || ''; | ||
70 | + } | ||
71 | + } | ||
72 | + return newObj; | ||
73 | +} | ||
74 | + | ||
75 | +export { GetObjFormKey, ALink, getParameterByName, getUrlSearchJson } |
src/styles/common.css
0 → 100644
1 | + |
src/styles/commonStyle.css
0 → 100644
1 | +/** | ||
2 | + * @file 公共样式 | ||
3 | + */ | ||
4 | +html,body{ | ||
5 | +/* we don't want to allow users to select text everywhere, | ||
6 | + you can enable it on the places you think appropriate */ | ||
7 | + user-select: none; | ||
8 | + -webkit-overflow-scrolling: touch; | ||
9 | + font-family: -apple-system, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Source Han Sans", "Microsoft YaHei", sans-serif; | ||
10 | + height: 100%; | ||
11 | + scroll-behavior: smooth; | ||
12 | +} | ||
13 | +*, *:before, *:after { | ||
14 | + /* suppressing the tap highlight */ | ||
15 | + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); | ||
16 | + box-sizing: border-box; | ||
17 | + vertical-align: top; | ||
18 | + padding: 0; | ||
19 | + margin: 0; | ||
20 | + -webkit-font-smoothing: antialiased; | ||
21 | +} | ||
22 | + | ||
23 | +*:focus { | ||
24 | + /* the default outline doesn't play well with a mobile application, | ||
25 | + I usually start without it, | ||
26 | + but don't forget to research further to make your mobile app accessible. */ | ||
27 | + outline: 0; | ||
28 | +} | ||
29 | + | ||
30 | +a { | ||
31 | + background: transparent; | ||
32 | + text-decoration: none; | ||
33 | + outline: none; | ||
34 | + transition: all .1s linear; | ||
35 | +} | ||
36 | + | ||
37 | +a:active { | ||
38 | + filter: brightness(1.1); | ||
39 | +} | ||
40 | + | ||
41 | +.clickBtn:active { | ||
42 | + filter: brightness(1.1); | ||
43 | + transform: scale(0.98); | ||
44 | +} | ||
45 | + | ||
46 | + | ||
47 | +*[contenteditable] { | ||
48 | + user-select: auto !important; | ||
49 | + -webkit-user-select: auto !important; | ||
50 | +} | ||
51 | +/** | ||
52 | + * 有强迫症的同学总会觉得输入框文本位置整体偏上,感觉未居中心里就痒痒的。桌面端浏览器里声明line-height等于height就能解决,但移动端浏览器里还是未能解决,需将line-height声明为normal才行。 | ||
53 | + */ | ||
54 | +input { | ||
55 | + line-height: normal; | ||
56 | +} | ||
57 | + | ||
58 | +::-webkit-scrollbar { | ||
59 | + width: 8px; | ||
60 | + height: 8px; | ||
61 | + background-color: transparent; | ||
62 | +} | ||
63 | + | ||
64 | +::-webkit-scrollbar-track { | ||
65 | + background-color: transparent; | ||
66 | +} | ||
67 | + | ||
68 | +::-webkit-scrollbar-thumb { | ||
69 | + border-radius: 3px; | ||
70 | + background-color: #5d5d5d; | ||
71 | +} | ||
72 | + | ||
73 | +.van-toast { | ||
74 | + min-width: 1.6rem!important; | ||
75 | + border-radius: 0.08rem!important; | ||
76 | + font-size: 0.38rem!important; | ||
77 | + padding: 0.24rem 0.4rem!important; | ||
78 | + line-height: 1.5!important; | ||
79 | +} | ||
80 | + | ||
81 | +.van-popup { | ||
82 | + background-color: transparent!important; | ||
83 | + width: 100%; | ||
84 | + height: 100%; | ||
85 | +} | ||
86 | + | ||
87 | +.van-overlay{ | ||
88 | + background-color: rgba(0,0,0,.4)!important; | ||
89 | +} | ||
90 | + | ||
91 | +.van-overflow-hidden{ | ||
92 | + overflow: auto!important; | ||
93 | +} | ||
94 | + | ||
95 | +button { | ||
96 | + border: none; | ||
97 | +} | ||
98 | + | ||
99 | + | ||
100 | + |
-
请 注册 或 登录 后发表评论