ElectronJS

一. 全局安装

1
npm install -g electron

二. 安装方式

1. electron-quick-start

1
2
3
4
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
npm start

2. 通过electron-forge创建项目

安装electron-forge脚手架

1
2
3
4
npm install -g electron-forge
electron-forge init my-new-app
cd my-new-app
npm start

3. 手动创建项目

1
2
3
1. 新建一个index.html main.js
2. npm init --yes 生成一个package.json
3.

js常用工具类库

一. momentJS日期处理

日期处理类库
http://momentjs.cn/

1
2
3
4
npm install moment
var moment = require('moment');
moment().format();
moment().format('MM/DD/YYYY hh:mm:ss a dddd MMMM Do')

二. validatorJS验证处理

表单数据验证
github地址

1
2
3
4
npm install validator
import validator from 'validator';
validator.isEmail('foo@bar.com'); //=> true
......

三. LodashJS数据处理

是一个一致性、模块化、高性能的 JavaScript 实用工具库。
https://www.lodashjs.com/

为什么选择 Lodash ?

Lodash 通过降低 array、number、objects、string 等等的使用难度从而让JavaScript 变得更简单。
Lodash 的模块化方法 非常适用于:

  1. 遍历 array、object 和 string
  2. 对值进行操作和检测
  3. 创建符合功能的函数
1
2
3
4
npm i --save lodash
var _ = require('lodash'); // 24Kb
var _ = require('lodash/core'); // 4Kb
......

四. 卡片|泳道拖拽

git地址

1
2
3
4
5
6
7
8
9
10
npm i -S vuedraggable
import draggable from 'vuedraggable'
......
<draggable v-model="myArray">
<transition-group>
<div v-for="element in myArray" :key="element.id">
{{element.name}}
</div>
</transition-group>
</draggable>

五. threeJS数据驱动的三维图形可视化

github地址
文档
该项目的目的是使用默认的WebGL渲染器创建一个易于使用,轻量级的3D库。该库还在示例中提供了Canvas 2D,SVG和CSS3D渲染器。

sketch设计软件安装及插件配置

sketch软件安装

  1. 下载地址
  2. 如果提示软件有损,请先运行:

    1
    sudo spctl --master-disable

汉化插件

  1. SketchI18N.sketchplugin

图标字体:

一、安装字体插件

  1. 下载并解压:sketch-iconfont-master.zip
  2. 双击 iconfont.sketchplugin 完成安装

二、安装 Font Bundle

安装好 Sketch Iconfont 之后,你会发现,这个 Plugin,还不能使用。既然是管理 IconFont 的 Plugin,第一件事情就是要先安装 IconFont,然后才能进行管理。Plugin 的作者为了方便使用,提供了一个 Font Bundle, 里面包括了多个比较热门的 IconFont,安装后就可以使用了。

  1. 下载并解压: font-bundles-master.zip
  2. 打开 ttf-files 文件夹,依次安装里面的字体
  3. 打开 Sketch,点击 Plugins -> Icon Font -> Install a Font-Bundle
  4. 在弹出的对话框中,选择 font-bundles-master 文件夹,然后点击 Open

输出html标注页面

  1. sketch-measure-master

vue动态指令

自定义定位的指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* 简写 l:left; r:rihgt; b:bottom; t:top; z:z-index; bg:background; w:widht; h:height;
* w、h的值根据top.left.right.bottom来进行设置
* <div v-pos:top.left="data"></div>
* data: {
t:0,
l:0,
w:50,
h:50,
bg:'red',
z:9
}
*/

Vue.directive('position', {
bind: function (el, binding, vnode) {
el.style.position = 'fixed'
var pos1 = ['left', 'right', 'bottom', 'top'].includes(binding.arg) ? binding.arg : 'left'
el.style[pos1] = (binding.value[pos1.substring(0,1)] || '0') + 'px'
el.style.background = binding.value.bg || 'red'
binding.value.w && (el.style.width = binding.value.w + 'px')
binding.value.h && (el.style.height = binding.value.h + 'px')
el.style.zIndex = binding.value.z || '0'
let pos2 = Object.keys(binding.modifiers)
pos2.map(p=>{
el.style[p] = (binding.value[p.substring(0, 1)] || '0') + 'px'
})
}
})

前端开发思考

目录

一、前端演化进程
二、跨端演化进程
三、未来走向思考

保持一颗好奇心:对知识、对时代的一种敬畏之心!

一、前端演化进程

  1. js诞生
    解决提交页面上表单的数据,开始有了javaScript
  2. cms时代
    后端人员模板界面套用 织梦\phpCms\帝国Cms….
  3. 网页三剑客时代
    html + css + js
  4. DOM操作时代
    jQuery + bootstrap
  5. 模块化操作时代
    CommonJS\CMD\AMD requireJS seaJS backboneJS
  6. 工程化时代
    vueJS reactJS angularJS

二、跨端演化进程

  1. web端
    pc: c端界面 中后台系统界面
  2. 响应式
    h5手机端界面
  3. hybrid混合式
    phoneGapJS\cordovaJS
  4. Native原生式
    reactNative、weex
  5. 小程序
    微信小程序
  6. 桌面端
    electronJS、nwJS

三、未来走向思考

技术的发展跟时代的发展是紧密相连的,前端的演化进程是在互联网时代、移动互联时代,诞生的进化的过程。

下一个时代:人工智能时代、大数据、云计算
前端开发会向桌面端转移?手机端会被什么替代?web浏览器只在电脑上出现?……

职业猜想:

  1. 数据可视化方向 d3JS thre中eJS …
  2. 桌面端开发 electronJS
  3. 中台系统、微服务的开发,代替以前的前端开发与后端开发
  4. 可视化拖拽代替以前工程化进程

js常见数据校验

1.输入字符必须为中文

1
2
3
4
String.prototype.checkChinese(str){
var reg = new RegExp('^[\\u4E00-\\u9FFF]+$','g')
return reg.test(str);
}

2.去除字符两边的空格

1
2
3
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/gm, '')
}

3.邮箱验证

1
2
3
4
String.prototype.checkEmaila = function(){
var reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
return reg.test(this);
}

4.手机号码验证

1
2
3
String.prototype.checkPhone = function(){
return /^1[345789]\d{9}$/.test(this);
}

5.身价证号码验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
String.prototype.checkIdentityCode = function(){
var city = {11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外 "};
var tip = "";
var pass= true;

if(!this || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(this)){
tip = "身份证号格式错误";
pass = false;
}else if(!city[this.substr(0,2)]){
tip = "地址编码错误";
pass = false;
}else{
//18位身份证需要验证最后一位校验位
if(this.length == 18){
var code = this.split('');
//∑(ai×Wi)(mod 11)
//加权因子
var factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
//校验位
var parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ];
var sum = 0;
var ai = 0;
var wi = 0;
for (var i = 0; i < 17; i++)
{
ai = code[i];
wi = factor[i];
sum += ai * wi;
}
var last = parity[sum % 11];
if(parity[sum % 11] != code[17]){
tip = "校验位错误";
pass =false;
}
}
}
return pass || tip;
}

6.日期格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Date.prototype.formatDate = function(fmt) { //author: meizz
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"H+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt))
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)
if(new RegExp("("+ k +")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
return fmt;
}

String.prototype.formatDate = function(fmt) {
if(/^(\d{13}|\d{10})$/.test(this)){
return new Date(Number(this)).formatDate(fmt)
}
return new Date(this).formatDate(fmt)
}

// new Date().formatDate('yyyy年MM月dd日 HH:mm:ss')
// new Date().formatDate('HH:mm:ss')

// new Date(1554373056366).formatDate('yyyy/MM/dd')
// new Date('2019-08-02').formatDate('yyyy/MM/dd')

// '2018-09-23 12:23:10'.formatDate('yyyy年MM月dd日 HH时mm分ss秒')
// '1537676590000'.formatDate('yyyy/MM/dd HH:mm:ss')

7.合法IP

1
2
3
4
String.prototype.checkIP = function(){
var reg = /^(?=(\b|\D))(((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))(?=(\b|\D))$/;
return reg.test(this);
}

8.输入字符类型为数字,且长度不能越过n值

1
2
3
4
5
6
7
8
9
10
11
12
// symbols: > || < || >= || <= || != || == || len
String.prototype.numJudge = function(symbols, value){
if(/^\d+\.?\d+$/.test(this)){
if (symbols == 'len' && !/\./.test(this) && this.length == value){
return true
}
if(symbols != 'len' && eval(this + ' '+ symbols +' ' + value)){
return true
}
}
return false
}

9.滚动到窗口底部时加载数据

1
2
3
4
5
6
7
8
9
10
11
handleScroll(){
if(this.reloading){ // 是否可能加载数据
var wScrollY = window.scrollY; // 当前滚动条位置
var wInnerH = window.innerHeight; // 设备窗口的高度(不会变)
var bScrollH = document.body.scrollHeight; // 滚动条总高度
if (wScrollY + wInnerH >= bScrollH) {
this.reloading = false
this.reloadCount++ // 监听加载的次数时开始请求,请求成功后设置reloading:true,实现再次滚动到底部时加载
}
}
}

10.验证字符串是否为json格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
isJSON(value, callback, str) {
if (typeof value == 'string') {
try {
value = value.replace(/'/g, '"');
var obj= str ? JSON.parse("{"+value+"}") : JSON.parse(value);
if(typeof obj === 'object'){
callback()
return true
}else{
return false;
}
} catch(e) {
callback(new Error('数据格式不正确'))
return false;
}
}
callback(new Error('数据格式不正确'))
}

Hexo + github 搭建个人博客

一. 安装nginx

  1. yun install -y nginx
  2. whereis nginx 默认目录
  3. nginx 启动
  4. nginx -t 测试Nginx配置是否正确
  5. nginx -s reload 重启
  6. ps -ef |grep nginx 查看nginx的进程号
  7. nginx -s stop nginx 或 kill -9 pid 服务停止

二. 安装git

  1. git tag -l 查看tag list
  2. git checkout v6.2.4

安装grafana

  1. liunx安装

    1
    2
    3
    4
    wget https://dl.grafana.com/wwwww/release/grafana-6.2.4-1.x86_64.rpm 
    sudo yum localinstall grafana-6.2.4-1.x86_64.rpm

    sudo yum install grafana
  2. mac安装

    1
    2
    brew update 
    brew install grafana
  3. 配置变量

    1
    2
    3
    4
    5
    6
    7
    8
    vim ~/.bashrc
    export GOROOT=/Users/apple/workshop/go
    export GOPATH=/Users/apple/go
    export PATH=${PATH}:$GOPATH/bin
    export PATH=${PATH}:$GOROOT/bin

    bin/darwin-amd64/grafana-server &
    yarn start

Hexo + github 搭建个人博客

一. 在github上先创建2个库

  1. 存储frontEnd_blog项目 - hexo编译后的资源存储在这里 – 参考
  2. 存储hexo_blog项目 参考文档参考

二. 设置frontEnd_blog项目

  1. 点击Settings
  2. 在GitHub Pages 下,点击 Choose a theme,随便选择一个主题
  3. 然后在GitHub Pages 下会看到:
    Your site is published at https://sww1230.github.io/frontEnd_blog/
    设置完毕后你就可以通过 username.github.io(username为你的用户名访问你的博客了)

三. 上传并配置hexo_blog

  1. 安装hexo

    1
    2
    3
    4
    5
    6
    7
    8
    npm install hexo-cli -g
    hexo init hexo_blog
    cd hexo_blog
    npm install
    hexo g #生成或 hexo generate
    hexo s #启动本地服务器 或者 hexo server,这一步之后就可以通过http://localhost:4000 查看了
    hexo new "文章名" #新建文章
    hexo new page "页面名" #新建页面
  2. 修改_config.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    title: frontEnd_blog
    subtitle: 前端技术积累沉淀
    author: wenwu.shang
    url: https://sww1230.github.io/
    root: /frontEnd_blog/

    deploy:
    type: git
    repo: https://github.com/sww1230/frontEnd_blog.git
    branch: master
  3. 编译hexo_blog部署至frontEnd_blog

    1
    hexo d
  4. 上传代码至hexo_blog库

    1
    2
    3
    4
    5
    git init
    git remote add origin https://github.com/sww1230/hexo_blog.git
    git add .
    git commit -m 'update'
    git push

typeScript

什么是 TypeScript?
TypeScript 是一种由微软开发的自由和开源的编程语言,它是 JavaScript 的一个超集,扩展了 JavaScript 的语法。
TypeScript的设计目的应该是解决JavaScript的“痛点”:弱类型和没有命名空间,导致很难模块化

1.声明变量类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var foo: string;
foo = true; //error: Cannot convert 'boolean' to string
interface Phone {
model: string
readonly price: number // readonly 标记某个属性是只读的
producer?: string // ?标记 表示这个属性是可选的
[propName: string]: any // any 任意属性 包括 string 和 number 类
}
let newPhone: Phone = {
model: 'iPhone XS',
price: 8599, // OK
}
let phoneB: Phone = {
model: 'iPhone XS',
price: 8599,
producer: 'Apple', // OK
}

2.类型批注

对于基本类型的批注是number, bool和string。而弱或动态类型的结构则是any类型。

1
2
3
4
5
function area(shape: string, width?: number, height: number):string {
var area = width * height;
return "I'm a " + shape + " with an area of " + area + " cm squared.";
}
console.log(area("rectangle", 30, 15));

3.接口

接口可以作为一个类型批注。

1
2
3
4
5
6
7
8
9
10
11
12
  interface Shape {
name: string;
width: number;
height: number;
color?: string;
}
function area(shape : Shape) {
var area = shape.width * shape.height;
return "I'm " + shape.name + " with area " + area + " cm squared";
}
console.log( area( {name: "rectangle", width: 30, height: 15} ) );
console.log( area( {name: "square", width: 30, height: 30, color: "blue"} ) );

4.类

TypeScript支持集成了可选的类型批注支持的ECMAScript 6的类
类中有两个属性 area 和 color,一个构造器 (constructor()), 一个方法是 shoutout()
可以使用三种修饰符:public、private、protected

1
2
3
4
5
6
7
8
9
10
11
12
class Shape {
area: number;
private color: string;
constructor ( public name: string, width: number, height: number ) {
this.area = width * height;
this.color = "pink";
};
shoutout() {
return "I'm " + this.color + " " + this.name + " with an area of " + this.area + " cm squared.";
}
}
var square = new Shape("square", 30, 30);

5.继承

继承使用关键字 extends;
super( name, width, height )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Shape3D extends Shape {
volume: number;
constructor ( public name: string, width: number, height: number, length: number ) {
super( name, width, height );
this.volume = length * this.area;
};
shoutout() {
return "I'm " + this.name + " with a volume of " + this.volume + " cm cube.";
}
superShout() {
return super.shoutout();
}
}
var cube = new Shape3D("cube", 30, 30, 30);
console.log( cube.shoutout() );
console.log( cube.superShout() );

6.抽象类

抽象类是某个类具体实现的抽象表述,作为其他类的基类使用。
TypeScript 中使用 abstract 关键字表示抽象类以及其内部的抽象方法

它具有两个特点:

  1. 不能被实例化
  2. 其抽象方法必须被子类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
abstract class Animal {
public abstract makeSound(): void
public move() {
console.log('Roaming...')
}
}
class Cat extends Animal {
makeSound() {
console.log('Meow~')
}
}
let tom = new Cat()
tom.makeSound() // => 'Meow~'
tom.move() // => 'Roaming...'

上述例子中,我们创建了一个抽象类 Animal,它定义了一个抽象方法 makeSound。然后,我们定义了一个 Cat 类,继承自 Animal。因为 Animal 定义了 makeSound 抽象类,所以我们必须在 Cat 类里面实现它。不然的话,TS 会报错。

7.类与接口

类可以实现(implement)接口。通过接口,你可以强制地指明类遵守某个契约。你可以在接口中声明一个方法,然后要求类去具体实现它。

1
2
3
4
5
6
7
8
9
10
interface ClockInterface {
currentTime: Date
setTime(d: Date)
}
class Clock implements ClockInterface {
currentTime: Date
setTime(d: Date) {
this.currentTime = d
}
}

接口与抽象类的区别

  1. 类可以实现(implement)多个接口,但只能扩展(extends)自一个抽象类。
  2. 抽象类中可以包含具体实现,接口不能。
  3. 抽象类在运行时是可见的,可以通过 instanceof 判断。接口则只在编译时起作用。
  4. 接口只能描述类的公共(public)部分,不会检查私有成员,而抽象类没有这样的限制。

axios 水印 埋点

axios统一请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

-----------------
ajax.js
import API from './base.js'
export default {
load(apiJSON){
window._api = {...API}
let apiGroups = Object.keys(apiJSON)
apiGroups.forEach(group=>{
let apiConfig = apiJSON[group]
let allApis = {}
if(apiConfig){
if(apiConfig['get']){
API.makeApiMethod(apiConfig['get'], allApis)
}
if(apiConfig['post']){
API.makeApiMethod(apiConfig['post'], allApis, 'post')
}
}
_api[group] = allApis
})
}
}
-----------------




-----------------
base.js
import axios from 'axios'
import siteOptions from '@/config/index'

const serverBasePath = siteOptions['serverBasePath'] || '';
const $http = axios.create({
headers: {'X-Requested-With': 'XMLHttpRequest'}
})

// http 响应拦截.
$http.interceptors.response.use(
siteOptions['ajaxResponseFilter'] || (response=>response.data)
)

export default{
axios,
$http,
customizeHttp(options){
return this.$http = this.axios.create(options)
},
get (url, params, callback) {
return this.$http.get(url, {
params: params
})
},
post (url, params, callback) {
return this.$http.post(url, params)
},
makeApiMethod(source, target, method) {
let getApiNames = Object.keys(source)
getApiNames.forEach(apiName=>{
target[apiName] = (params)=>{
return this[method || 'get'](serverBasePath + source[apiName], params)
}
})
}
}
-----------------




1. 所有的 ajax api 在此文件夹下配置
2. 根据业务模块,将 ajax api 划分成不同的 modules,放在各自的文件内,单独维护
3. 这里提供两个示例模块 - site 与 biz1,项目中根据业务功能命名。
4. 新加的业务模块,需要在 index.js 中注册才能生效,详见:index.js。

import site from './modules/site'
import biz1 from './modules/biz1'

/**
* 当前目录下的 modules 文件夹中,存放所有的业务模块所相关的 ajax api 路径。
* site 与 biz1 为两个示例业务模块。
*
* ajax 调用示例:
* _api.site.getUserInfo({
* // params...
* }).then(result=>{
* // 回调
* })
*
* 注意:
* 1. 导出的模块名字必须与文件名一致。
* 2. _api 为全局变量,直接使用,不需要显式引入。
*/
export default {
site,
biz1
}


export default {
get: {
getUserInfo: "/user/get"
},
post: {
getUserPerm: "/user/perm"
}
}



--------------
const isUseDevServerProxy = true
const isUseRapMockerTarget = false
const apiProxyTarget = 'http://dbms.dev.www.com:8081'
const apiProxyMatches = [
'/user',
'/api'
]

function addProxyOptions(options){
if(!isUseDevServerProxy) return;
let devProxyOptions = {
}
apiProxyMatches.forEach(api=>{
devProxyOptions[api] = {
target: apiProxyTarget,
changeOrigin: true,
bypass: function(req, res, proxyOpt){
res.set('RAD-PROXY', 'on');
res.set('RAD-PROXY-BY', apiProxyTarget);
}
}
if(isUseRapMockerTarget){
devProxyOptions[api]['pathRewrite'] = (path, req) => '/' + req.method + '/' + path
}
})
options['devServer'] = options['devServer'] || {}
options['devServer']['proxy'] = devProxyOptions
}

module.exports = addProxyOptions
------------------



import axios from 'axios';
import queryString from 'query-string';
import { Message } from 'element-ui';

if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = '/api';
}

let get = (url, params = {}) => {
return new Promise((resolve) => {
axios.get(url, params).then((response) => {
resolve(response.data);
});
});
};

let post = (url, params = {}) => {
return new Promise((resolve) => {
axios.post(url, queryString.stringify(params), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).then((response) => {
resolve(response.data);
});
});
};

let put = (url, params = {}) => {
return new Promise((resolve) => {
axios.put(url, queryString.stringify(params), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).then((response) => {
resolve(response.data);
});
});
};

let putJSON = (url, params = {}) => {
return new Promise((resolve) => {
axios.put(url, JSON.stringify(params), {
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
}).then((response) => {
resolve(response.data);
});
});
};

let postJSON = (url, params = {}) => {
return new Promise((resolve) => {
axios.post(url, JSON.stringify(params), {
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
}).then((response) => {
resolve(response.data);
});
});
};

let del = (url, params = {}) => {
return new Promise((resolve) => {
axios.delete(url, params).then((response) => {
resolve(response.data);
});
});
};

let upload = (url, params = {}, option = {}) => {
let formData = new FormData();
for (let _key in params) {
formData.append(_key, params[_key]);
}
return new Promise((resolve) => {
axios.post(url, formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: function (event) {
if (typeof option.onUploadProgress === 'function') {
option.onUploadProgress(event);
}
}
}).then((response) => {
resolve(response.data);
});
});
};

// axios.interceptors.request.use((config) => {
// return config;
// }, function (err) {
// return Promise.reject(err);
// });

axios.interceptors.response.use((response) => {
return response;
}, (error) => {
if (!error.response) {
if (
location.hostname ==
'ops.www.com'
) {
location.href =
'https://sso.www.com/user/login?system_key=v2';
} else {
location.href =
'https://sso.test.www.com/user/login?redirect_url=' +
location.href;
}
} else {
Message.error(error.message);
}
});

export default {
get,
post,
put,
del,
upload,
putJSON,
postJSON
};


import ajax from '@/util/ajax';
let batchAdd = params => {
return ajax.postJSON('/agent_conf_app/batch', params);
};
export default {
batchAdd
};

水印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  #watermark{
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
// 水印 mask, 盖在最上层.
z-index: 2147483647;
pointer-events: none;
}

引入 __punch.js 水印
-----
export default {
isShowWatermark: true,
getWatermark(){
return new Promise(function(resolve, reject) {
resolve({
name: '用户名',
id: 'ID'
});
}).then((user)=>{
return {
name: user['name'],
id: user['id']
}
});
//return _api.site.getUserInfo()
}
}
-----

export function renderWatermark(watermarkStr){
if(siteOptions['isShowWatermark'] === true) {
siteOptions['getWatermark']().then(user=>{
watermarkStr = user['name'] + '-' + user['id']
let $watermark = document.querySelector('#watermark')
if(watermarkStr && $watermark && window['__punch']){
__punch.to($watermark, watermarkStr, {
width: 250, //水印单元宽度
height: 80, //水印单元高度
bg: 'transparent', //水印背景
bgAlpha: 0, //水印背景透明度
color: '#AAA', //水印字体颜色
alpha: 0.20, //水印字体颜色透明度
font: '14px Arial' //水印字体
})
}
})
}
}

埋点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function enableTracker(){
let tickerSDK = 'https://img-wwwww.wwwww.com/weixin/mall/cdn/ticker/ticker.min.2.0.6.js'
let script = document.createElement("script");
script.type = "text/javascript";
script.src = tickerSDK;
script.onload = function(){
mxticker.init({
// 是否启用埋点.
isTrackUser: true,
// 若启用埋点,则需要配置初始化选项.
trackerOptions: {
av: 1,
as: 3,
bu_id: 2,
api: '//loganalytics.wwwww.com/log'
}
})
}
document.head.appendChild(script);
}