Commit c9aa1ee3 by chenweisong

init

parents
> 1%
last 2 versions
module.exports = {
root: true,
env: {
node: true
},
extends: ["plugin:vue/essential", "@vue/prettier"],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
},
parserOptions: {
parser: "babel-eslint"
}
};
.DS_Store
node_modules
/dist
/kpi
# 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?
# mobile-h5
# 1. main.js 中的常用封装引用
- 引入 echarts 全局引用太大了,要按需引用
```
// import echarts from 'echarts'
// Vue.prototype.$echarts = echarts
```
# 2. 目录结构
```
├── mobile-h5 # 总项目目录
├── build # webpack 配置文件目录
├── config # webpack 配置文件引用的目录
├── kpi # webpack 打包正式生成的目录
├── src # 主开发文件的目录
│ ├── assets # 图片资源
│ ├── components # 组件模块
| │ ├── app # 组件模块
| | | ├── add # 本项目 指标新增 的组件的模块
| | | ├── common # 通用组件的模块
| | | ├── index # 本项目 首页 组件通用的模块
| | | ├── setMeal # 本项目 套餐 组件通用的模块
| | | ├── appUsage # 本项目 app使用情况 组件通用的模块
| | | ├── callCustomerNumber # 本项目 当月通话客户数 组件通用的模块
| | | ├── lowRentCustomers # 本项目 入网低凭客户点比 组件通用的模块
│ ├── common # 通用组件模块
│ ├── filters # 过滤器模块
│ ├── less # less 的公共样式模块
│ ├── libs # 封装的公共 js 文件模块
│ ├── mixins # mixins 文件模块
│ ├── router # 路由模块
│ ├── store # vuex 的 store 模块
│ ├── views # 主要开发的 vue 模块
│ ├── App.vue # 路由视图切换文件
│ ├── main.js # 初始化 vue 项目的文件
├── static # webpack 打包依赖的目录
├── index.html # 主页面入口,也是生成打包生产环境代码要依赖的文件
|-- package.json 依赖包
|-- README.md 项目说明文档(非常重要,必看)
|-- 当前打包版本2.4.52
```
# 3. 注意事项
- 因为版本升级时,不能影响旧版的使用,所以有些模块的文件命名后面加了个数字加以区分,如果旧版的不用了,就把旧文件删除,减少打包文件的体积。
```js
比如 add.vue => add2.vuereportForm.vue => reportForm2.vue
```
- token 值的获取都写在 store 里面了,触发方法在 App.vue 的 created 里面触发,如果是本地开发环境,就用固定的 token 值,不过 30 天后也会过期,如果是生产环境就用要每次都会获取新的 token。
- 收藏相关的接口是都要在 header 传 xid 给后台的。
- 移动端 iOS 与 android 阻止橡皮筋效果,添加这个代码会阻止屏幕的滚动,所以要在页面最大的盒子添加 css 代码(项目里面暂时没用到)。
```css
overflow-y: scrol;
```
```js
// 移动端iOS阻止橡皮筋效果
document.body.addEventListener('touchmove', function (e) {
e.preventDefault() // 阻止默认的处理方式(阻止下拉滑动的效果)
}, {passive: false}) // passive 参数不能省略,用来兼容ios和android
```
- 项目最完善的说明与讲解请看博客: [基于vue+mint-ui的mobile-h5的项目说明](https://segmentfault.com/a/1190000015798772)
- vue 单页面,多路由,前进刷新,后退不刷新,参考这个 https://segmentfault.com/a/1190000012083511。
# 4. 本地开发与本地测试链接
因为一般开发的页面要传很多参数,这里提供链接与参数,方便他人查看。
> 线上链接开头:https://emm.cmccbigdata.com:8443/
> 本地开发链接开头: http://localhost:8080/
> 本地测试链接开头:http://192.168.0.107/ ;配合 nginx 来配合使用
> 注意: 其中 192.168.0.107 是自己  电脑的 ip 地址,链接中的 token 是一个月后会过期的,过期需要找安卓或者 ios 开发者重新提供。
> token: 76d99bf768f8fab7e342dcf5bac06829
> 链接后面的参数都是 app 端传过来的,比如用户的身份信息:phone=13873110056&level=1&areaId=731
- 线上参考地址:
```
https://emm.cmccbigdata.com:8443/file/kpi/#/reportForm?qid=426&id=OCxusheng1&level=0&aid=0&area=%E5%85%A8%E7%9C%81&xid=c44b154cb578831270a3cc3fe3e4a6d3&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
https://emm.cmccbigdata.com:8443/file/kpi/#/specialArea?id=OCxusheng1&phone=13873110056&level=1&areaId=731&aid=18411&area=A_%E9%95%BF%E6%B2%99&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 首页指标
```
http://localhost:8080/#/index?id=OCxusheng1&phone=13873110056&level=0&areaId=0&aid=0&area=全省&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 工作台
```
// 路径: https://emm.cmccbigdata.com:8443/work/文件名
http://localhost:8080/#/workbench?id=OCxusheng1&phone=13873110056&level=0&areaId=0&aid=0&area=全省&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 网格营销情况跟踪 :
```
http://192.168.0.107/index.html#/gridMarketing?id=OCxusheng1&phone=13873110056&level=1&areaId=731&aid=18411&area=A_%E9%95%BF%E6%B2%99&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 全省渠道明细 / 渠道全景视图 :
```
http://192.168.0.107/index.html#/ChannelMonthlyReport?id=OCxusheng1&phone=13873110056&level=1&areaId=731&aid=18411&area=A_%E9%95%BF%E6%B2%99&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 专区:
安卓 与 ios 传的用户信息里面,除了 username、account、pid,其他的信息都传了 。
```
http://192.168.0.107/index.html#/specialArea?id=OCxusheng1&phone=13873110056&level=0&areaId=0&aid=0&area=全省&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 地市专区:
```
http://192.168.0.107/index.html#/specialAreaCity?id=OCxusheng1&phone=13873110056&level=0&areaId=0&aid=0&area=全省&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 网格营销情况跟踪
```
http://localhost:8080/#/gridMarketing?id=OCxusheng1&phone=13873110056&level=1&areaId=731&aid=18411&area=A_%E9%95%BF%E6%B2%99&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 报表确认
```
http://localhost:8080/#/reportForm?qid=591&id=OCxusheng1&level=0&aid=0&area=%E5%85%A8%E7%9C%81&xid=c44b154cb578831270a3cc3fe3e4a6d3&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 关键指标:
```
http://192.168.0.126/index.html#/add?type=BXL_M_ADD&code=1231&xid=633f47589186780e4d534ef743915005&ua=pc
http://192.168.0.126/index.html#/add2?type=BXL_M_ADD&id=OCxusheng1&level=0&aid=0&area=%E5%85%A8%E7%9C%81&xid=c44b154cb578831270a3cc3fe3e4a6d3&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- app 使用情况
```
http://192.168.0.107/index.html#/appUsage??id=OCxusheng1&phone=13873110056&level=1&areaId=731&aid=18411&area=A_%E9%95%BF%E6%B2%99&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
http://192.168.0.107/index.html#/appUsage2??id=OCxusheng1&phone=13873110056&level=1&areaId=731&aid=18411&area=A_%E9%95%BF%E6%B2%99&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 客户质量与预测
```
http://192.168.0.107/index.html#/customerQualityAndForecast?id=OCxusheng1&phone=13873110056&level=1&areaId=731&aid=18411&area=A_%E9%95%BF%E6%B2%99&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 复杂报表
```
http://192.168.0.107/index.html#/reportForm?qid=422&id=OCxusheng1&level=0&aid=0&area=全省&xid=c44b154cb578831270a3cc3fe3e4a6d3&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 指标 更多
```
http://192.168.0.107/index.html#/kpiMore
```
- 实时数据内页
```
http://192.168.0.107/index.html#/setMeal
http://192.168.0.107/index.html#/setMeal2?id=OCxusheng1&level=0&aid=0&area=%E5%85%A8%E7%9C%81&xid=c44b154cb578831270a3cc3fe3e4a6d3&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 收入预测
```
http://localhost:8080/#/revenueForecastModel?id=OCxusheng1&phone=13873110056&level=1&areaId=731&aid=18411&area=A_%E9%95%BF%E6%B2%99&xid=633f47589186780e4d534ef743915005&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
- 文字版报表
```
http://localhost:8080/#/reportForm?qid=622&id=OCxusheng1&level=0&aid=0&area=%E5%85%A8%E7%9C%81&xid=c44b154cb578831270a3cc3fe3e4a6d3&token=54cbcce6ef19bba57b5d656d34f1aabf&ua=pc
```
# 5. 报表页面常用接口的 qid:
一般报表:
- 404、405
多 tab 报表:
- 426
确认报表接口:
- 988
- 851
- 849
异常审核报表:
正式版: 2019年测试 表 1133 文 1109
检验版: 2019年检验测试 1156
文字版报表接口 qid :
- 文字版 1021 ,表格版 1056
- 932 908
- 592 717
- 接口 615 620 ,对比接口 591
- 783 表格版 786 文字版
- 426 表格版 622 文字版
- 489 表格版 621 文字版
- 630 表格版: 629 文字版
> 没有 type 的是普通报表,有 type 的是彩信通报;
> 根据 type === 'report_table' 来判断的是不是彩信通报文字版或者表格版;
> 有没有 audit 这个字段, 区分彩信通报正式版和检验版的
## 权限
手机经分的用户职能分了 4 种:
1.普通员工
2.经分管理员
3.领导
4.经分管理员+领导
其中 3 和 4 的用户如果没做特殊处理的话,权限是自动上升一级的,也就是用户信息传的 aid = pid
# end. Build Setup
## install dependencies
> npm install
## serve with hot reload at localhost:8080
> npm start
## build for production with minification
> npm run build
## build for production and view the bundle analyzer report
> npm run build --report
module.exports = {
presets: ["@vue/app"]
};
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "mobile-h5-new",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^2.6.5",
"iscroll": "^5.2.0",
"vue": "^2.6.10",
"vue-pdf": "^4.0.7",
"vue-router": "^3.0.3",
"vuex": "^3.0.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.11.0",
"@vue/cli-plugin-eslint": "^3.11.0",
"@vue/cli-service": "^3.11.0",
"@vue/eslint-config-prettier": "^5.0.0",
"axios": "^0.19.0",
"babel-eslint": "^10.0.1",
"babel-runtime": "^6.26.0",
"echarts": "^4.3.0",
"eslint": "^5.16.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-vue": "^5.0.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"mint-ui": "^2.2.13",
"mockjs": "^1.0.1-beta3",
"prettier": "^1.18.2",
"vue-template-compiler": "^2.6.10"
}
}
module.exports = {
plugins: {
autoprefixer: {}
}
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta id="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=yes" /> -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>...</title>
</head>
<body>
<noscript>
<strong>We're sorry but mobile-h5-new doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script>
var width = window.screen.width
document.getElementsByTagName('html')[0].style.fontSize = width / 7.5 + 'px';
// 如上:通过查询屏幕宽度,动态的设置 html 的 font-size 值,设计稿大多以 750*1334 设置的,通过上述换算后,在设计图上一张 150*150 的图,在css中对应的 rem 值则为:1.5*1.5 rem
</script>
<!-- <script src="http://mozilla.github.io/pdf.js/build/pdf.js"></script> -->
<!-- <script src="./static/pdf.js"></script> -->
</body>
</html>
/*! iNoBounce - v0.1.0
* https://github.com/lazd/iNoBounce/
* Copyright (c) 2013 Larry Davis <lazdnet@gmail.com>; Licensed BSD */
(function (global) {
// Stores the Y position where the touch started
var startY = 0
// Store enabled status
var enabled = false
var handleTouchmove = function (evt) {
// Get the element that was scrolled upon
var el = evt.target
// Check all parent elements for scrollability
while (el !== document.body && el !== document) {
// Get some style properties
var style = window.getComputedStyle(el)
if (!style) {
// If we've encountered an element we can't compute the style for, get out
break
}
// Ignore range input element
if (el.nodeName === 'INPUT' && el.getAttribute('type') === 'range') {
return
}
var scrolling = style.getPropertyValue('-webkit-overflow-scrolling')
var overflowY = style.getPropertyValue('overflow-y')
var height = parseInt(style.getPropertyValue('height'), 10)
// Determine if the element should scroll
var isScrollable = scrolling === 'touch' && (overflowY === 'auto' || overflowY === 'scroll')
var canScroll = el.scrollHeight > el.offsetHeight
if (isScrollable && canScroll) {
// Get the current Y position of the touch
var curY = evt.touches ? evt.touches[0].screenY : evt.screenY
// Determine if the user is trying to scroll past the top or bottom
// In this case, the window will bounce, so we have to prevent scrolling completely
var isAtTop = (startY <= curY && el.scrollTop === 0)
var isAtBottom = (startY >= curY && el.scrollHeight - el.scrollTop === height)
// Stop a bounce bug when at the bottom or top of the scrollable element
if (isAtTop || isAtBottom) {
evt.preventDefault()
}
// No need to continue up the DOM, we've done our job
return
}
// Test the next parent
el = el.parentNode
}
// Stop the bouncing -- no parents are scrollable
evt.preventDefault()
}
var handleTouchstart = function (evt) {
// Store the first Y position of the touch
startY = evt.touches ? evt.touches[0].screenY : evt.screenY
}
var enable = function () {
// Listen to a couple key touch events
window.addEventListener('touchstart', handleTouchstart, false)
window.addEventListener('touchmove', handleTouchmove, false)
enabled = true
}
var disable = function () {
// Stop listening
window.removeEventListener('touchstart', handleTouchstart, false)
window.removeEventListener('touchmove', handleTouchmove, false)
enabled = false
}
var isEnabled = function () {
return enabled
}
// Enable by default if the browser supports -webkit-overflow-scrolling
// Test this by setting the property with JavaScript on an element that exists in the DOM
// Then, see if the property is reflected in the computed style
var testDiv = document.createElement('div')
document.documentElement.appendChild(testDiv)
testDiv.style.WebkitOverflowScrolling = 'touch'
var scrollSupport = 'getComputedStyle' in window && window.getComputedStyle(testDiv)['-webkit-overflow-scrolling'] === 'touch'
document.documentElement.removeChild(testDiv)
if (scrollSupport) {
enable()
}
// A module to support enabling/disabling iNoBounce
var iNoBounce = {
enable: enable,
disable: disable,
isEnabled: isEnabled
}
if (typeof module !== 'undefined' && module.exports) {
// Node.js Support
module.exports = iNoBounce
}
if (typeof global.define === 'function') {
// AMD Support
(function (define) {
define('iNoBounce', [], function () { return iNoBounce })
}(global.define))
}
else {
// Browser support
global.iNoBounce = iNoBounce
}
}(this))
This source diff could not be displayed because it is too large. You can view the blob instead.
<template>
<div id="app">
<div v-show="showWaterMask"
class="waterMask"
id="waterMark"></div>
<!-- keep-alive可以使被包含的组件状态维持不变,即便是组件切换了,其内的状态依旧维持在内存之中。在下一次显示时,也不会重现渲染。 -->
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
<!-- 这里是会被缓存的视图组件,比如 page1,page2 -->
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
<!-- 这里是不被缓存的视图组件,比如 page3 -->
</router-view>
<!-- <Tab/> -->
</div>
</template>
<script>
// import Tab from "com/app/common/tab.vue";
import { addWaterMarker, formatDateTime } from "@/libs/common/common";
export default {
name: "App",
// components: {
// // Tab: Tab
// },
data() {
return {
showWaterMask: false
};
},
// created() { },
watch: {
$route(to, from) {
let date = formatDateTime(new Date(), "YYYY-MM-DD hh:mm:ss")
let message = ''
// 获取到用户信息才停止
let timer = setInterval(() => {
const route = this.$route
if (route.query.id && route.meta.waterMask) {
this.showWaterMask = true
clearInterval(timer)
message = `${date} ${route.query.id}`
addWaterMarker(document.getElementById('waterMark'), message, 700, 250)
} else {
this.showWaterMask = false;
if (route.meta.waterMask !== undefined) {
clearInterval(timer);
}
}
}, 10);
}
},
mounted() { },
};
</script>
<style lang="less" scoped>
.waterMask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999999;
pointer-events: none;
}
</style>
<style lang="less">
// 引入公共的样式
@import url("./less/index.less");
.mint-indicator-wrapper {
padding: 10px 25px !important;
}
::-webkit-scrollbar {
display: none;
}
.mint-indicator-wrapper {
z-index: 999999;
}
.l-footer__page {
width: 25%;
}
.mint-toast {
z-index: 10000000;
}
.mint-indicator-wrapper {
z-index: 1000000000;
}
</style>
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment