雅戈尔OA系统

工号:

1
2
3
4



# npm&yarn 换源&命令删除node_modules

1.查看当前源
npm
yarn config get registry
2、切换为淘宝源
yarn
npm config set registry https://registry.npm.taobao.org
3、或者切换为自带的
npm
yarn config set registry https://registry.yarnpkg.com
4、删除 node_modules
安装 rimraf
npm install rimraf -g
使用命令删除
rimraf node_modules

1
2
3
4



#### 本地排程号-工厂

西服:2019-J502
时装:2020-TX

1
2
3
4

liantong_0518

```home.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
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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
<template>
<div class="container">
<div class="screen-container">
<van-swipe-cell
v-for="(item, index) in screenList"
:disabled="!item.hasEnter"
:key="index">
<van-row
:class="`screenItem ${Number(screenIndex) === index ? 'screenActive' : ''}`"
@click="screenChange(item, index)"
>
<van-col class="content">
<p>{{ item.scrname }}</p>
<p>编号:{{ item.scrid }}</p>
<p v-if="item.createtime">创建时间:{{ item.createtime.slice(0,10) }}</p>
</van-col>
<van-col class="content">
<img :src="require(`@/assets/${item.scrid}.png`)" alt="">
</van-col>
</van-row>
<template #right>
<van-button square text="进入控制台" type="info" class="to-ctrl" @click="toControl(item), screenChange(item, index)"/>
</template>
</van-swipe-cell>
<!-- <div class="btn" @touchstart.prevent="startTouch" @touchend.prevent="touchEnd">测试语音</div> -->
</div>
<van-row class="posSelect" @click="selectShow()">切换地点</van-row>
<van-dialog
v-model="selectDialogShow"
@confirm="dialogConfirmHandler"
closeOnClickOverlay
:showConfirmButton="false"
title="请选择"
>
<div class="optionsWrap">
<div
:class="`posOption ${deviceCode==index+1 ? 'isActive' : ''}`"
v-for="(item, index) in screenPosList"
:key="index"
@click="screenSelect(index)"
>
{{ item.name }}
</div>
</div>
</van-dialog>
<!-- <Loading ref="loading" :visable="true"/> -->
</div>
</template>

<script>
import { Button, Tabbar, TabbarItem, Swipe, SwipeCell, SwipeItem, Row, Col, Dialog } from 'vant'
import * as dd from 'dingtalk-jsapi'
import { getScreenList, changeScreen, getTokenByAuthCode } from '../api/dingdingApi'
// import Loading from 'components/Loading'

export default {
name: 'home',
data () {
return {
selectDialogShow: false,
deviceCode: localStorage.getItem('DEVICE_CODE') || '1',
screenIndex: localStorage.getItem('SCREEN_INDEX') || 0,
// 大屏物理地点
screenPosList: [
{
name: 'A座大屏',
deviceCode: '1',
isActive: true
},
{
name: 'B座博物馆',
deviceCode: '2',
isActive: false
},
{
name: 'B座拼接屏',
deviceCode: '3',
isActive: false
}, {
name: '进入测试',
deviceCode: 100,
isActive: false
}
],
screenList: [
{
screenId: 1,
scrid: 1,
name: '设备互联调度中心',
num: '20200429090807',
time: '2020/4/29'
},
{
screenId: 2,
scrid: 2,
name: '产前调度中心',
num: '20200429090807',
time: '2020/4/29'
},
{
screenId: 3,
scrid: 3,
name: '车间订单调度中心',
num: '20200429090807',
time: '2020/4/29'
},
{
screenId: 4,
scrid: 4,
name: '智能产线调度中心',
num: '20200429090807',
time: '2020/4/29'
},
{
screenId: 5,
scrid: 5,
name: '生产通知调度大屏',
num: '20200429090807',
time: '2020/4/29'
},
{
screenId: 6,
scrid: 6,
name: '精益中心调度大屏',
num: '20200429090807',
time: '2020/4/29'
}
]
}
},
components: {
[Button.name]: Button,
[Tabbar.name]: Tabbar,
[TabbarItem.name]: TabbarItem,
[Swipe.name]: Swipe,
[SwipeItem.name]: SwipeItem,
[Row.name]: Row,
[Col.name]: Col,
[Dialog.Component.name]: Dialog.Component,
// Loading: Loading,
[SwipeCell.name]: SwipeCell
},
mounted () {
console.log(' --- 进入Home ---')

if (localStorage.getItem('FIRST_ENTER') === 'true' && localStorage.getItem('DEVICE_CODE') === null) {
this.selectDialogShow = true
} else {
this.selectDialogShow = false
try {
document.title = this.screenPosList[localStorage.getItem('DEVICE_CODE') - 1].name + '-控制器'
} catch (e) { console.error(e) }
}
console.log('deviceCode created:', localStorage.getItem('DEVICE_CODE'))
if (process.env.NODE_ENV === 'development') {
getScreenList().then(res => {
this.screenList = res.data
for (let item of this.screenList) {
item.imgUrl = 'p' + item.scrid
item.hasEnter = ![20200521001, 20200521004, 20200521005].includes(item.scrid)
}
const scrLoading = document.querySelector('#scr-loading')
setTimeout(() => {
scrLoading.className = 'fade-hide'
}, 500)
setTimeout(() => {
scrLoading.className = ''
scrLoading.style.display = 'none'
}, 1000)
})
}
debugger
console.log('--- 正在添加token ---')
try {
dd.runtime.permission.requestAuthCode({
corpId: 'ding93d89be042ee6abd35c2f4657eb6378f',
// corpId: 'ding9bf7f88c8bc0ced3ffe93478753d9884',
onSuccess: result => {
console.log(result)
console.log('添加token成功', result)
getTokenByAuthCode({
requestAuthCode: result.code
}).then(res => {
console.log('getTokenByAuthCode 成功', res)

localStorage.setItem('TOKEN', res.data)
getScreenList().then(res => {
this.screenList = res.data
for (let item of this.screenList) {
item.imgUrl = 'p' + item.scrid
}
}).catch(err => {
alert(JSON.stringify(err))
console.log('=========================>')

console.error(err)
})
}).catch(err => {
alert('getTokenByAuthCode 出错')
console.log('getTokenByAuthCode 出错', err)
})
/* {
code: 'hYLK98jkf0m' //string authCode
} */
},
onFail: err => {
console.log('添加token失败-->', err)
}

})
} catch (error) {
alert('添加token中途崩溃')
console.error('添加token中途崩溃')
console.error(error)
}
},
beforeRouteEnter (to, from, next) {
if (!from.name) {
localStorage.setItem('FIRST_ENTER', true)
} else {
localStorage.setItem('FIRST_ENTER', false)
}
next()
},
methods: {
// 大屏地点选择
screenSelect (index) {
console.log(typeof (index))
if (index === 3) {
this.$router.push('/test')
return
}
this.screenPosList.forEach(item => {
item.isActive = false
})
this.screenPosList[index].isActive = true
this.deviceCode = this.screenPosList[index].deviceCode
localStorage.setItem('DEVICE_CODE', this.deviceCode)
document.title = this.screenPosList[index].name + '-控制器'
dd.biz.navigation.setTitle({
title: document.title, // 控制标题文本,空字符串表示显示默认文本
onSuccess: function (result) {
console.log('设置title成功', result)
},
onFail: function (err) {
console.error('设置title失败', err)
}
})
this.selectDialogShow = false
},
dialogConfirmHandler () {
console.log('deviceCode:', this.deviceCode)
localStorage.setItem('DEVICE_CODE', this.deviceCode)
// this.selectDialogShow = true
},
// 切换地点按钮
selectShow () {
this.selectDialogShow = true
},
screenChange (item, index) {
this.screenIndex = index
localStorage.setItem('SCREEN_INDEX', this.screenIndex)
changeScreen({
deviceCode: this.deviceCode,
scrid: item.scrid
}).then(res => {
console.log(res)
})
},
toControl (item) {
this.$router.push({
path: '/control',
name: 'control',
query: {
name: item.scrname,
scrid: item.scrid,
deviceCode: this.deviceCode,
respower: item.respower
}
})
}
}
}
</script>
<style lang="scss" scoped>
.container{
height: auto;
width: 100%;
padding-bottom: 50px;
.screen-container {
height: 100%;
// background: red;
overflow: scroll;
.screenItem {
width: 90%;
height: 120px;
margin: 10px auto;
border: 1px solid rgba(136, 136, 136, 0.1);
// box-shadow: 3px 3px 5px rgba(136, 136, 136, 0.2);
padding: 20px 15px;
box-sizing: border-box;
.content {
height: 100%;
width: 50%;
position: relative;
.title {
position: absolute;
width: 120px;
height: 30px;
text-align: center;
line-height: 30px;
right: 0;
top: 15px;
background: rgba(82, 79, 79, 0.8);
font-size: 16px;
color: #fff;
}
}
.content:nth-child(1) {
text-align: left;
p {
margin: 0;
}
p:nth-child(1) {
color: #000;
font-size: 16px;
line-height: 22px;
margin-bottom: 4px;
// white-space: nowrap;
// text-overflow: ellipsis;
// overflow: hidden;
}
p:nth-child(n + 2) {
color: #9199A9!important;
font-size: 14px;
line-height: 20px;
}
}
.content:nth-child(2) {
text-align: right;
img {
width: 120px;
height: 60px;
background: #000;
border-radius: 4px;
}
}
}
.to-ctrl {
width: 80px;
height: 3.2rem;
line-height: 1.5;
}
.screenActive {
border-color: #3DD6F6;
background: url('../assets/icon_selected.png') bottom right no-repeat;
background-size: 10%;
border-radius: 3px;
}
}
// .btn{
// width: 300px;
// background: red;
// height: 100px;
// }
.posSelect {
width: 90%;
height: 40px;
background: #1487fb;
// border: 1px solid #1487fb;
border-radius: 20px;
position: fixed;
bottom: 15px;
left: 50%;
transform: translateX(-50%);
text-align: center;
line-height: 40px;
font-size: 16px;
color: #fff;
}
.optionsWrap {
width: 100%;
box-sizing: border-box;
padding: 10px 20px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.posOption {
width: 80px;
padding: 5px 25px;
color: #9199A9;
text-align: center;
border-radius: 25px;
margin-bottom: 10px;
border: 1px solid transparent;
}
.isActive {
border-color: #1487fb;
color: #1487fb;
}
}
}
</style>
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

```javascript
const path = require('path')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
const port = process.env.port || process.env.npm_config_port || 8888
const cdnDomian = './' // cdn域名,如果有cdn修改成对应的cdn
const name = '大屏控制器' // page title
const IS_PRODUCTION = process.env.NODE_ENV === 'production'
// dev环境接口地址
let DEVE_MODE_REQUEST_URL = 'http://localhost:8080/'
if (process.argv[4] === 'test') {
// test环境接口地址
DEVE_MODE_REQUEST_URL = 'http://101.71.158.252:8888/'
}
const cdn = {
css: [],
js: [
'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',
'https://cdn.bootcss.com/vue-router/3.0.3/vue-router.min.js',
'https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js',
'https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js',
'https://cdn.bootcss.com/js-cookie/2.2.1/js.cookie.min.js'
]
}

const externals = {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios',
'js-cookie': 'Cookies'
}

function resolve (dir) {
return path.join(__dirname, dir)
}
console.log('process', process.argv[4])
module.exports = {
publicPath: IS_PRODUCTION ? cdnDomian : './',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
devServer: {
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
disableHostCheck: true,
proxy: {
'/sc_api': {
target: DEVE_MODE_REQUEST_URL,
changeOrigin: true
}
},
after: require('./mock/mock-server.js')
},
configureWebpack: {
// provide the app's title in webpack's name field, so that
// it can be accessed in index.html to inject the correct title.
name: name,
resolve: {
alias: {
'@': resolve('src'), // 主目录
'views': resolve('src/views'), // 页面
'components': resolve('src/components'), // 组件
'api': resolve('src/api'), // 接口
'utils': resolve('src/utils'), // 通用功能
'assets': resolve('src/assets'), // 静态资源
'style': resolve('src/style') // 通用样式
}
}
},
chainWebpack (config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test

// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()

// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
.end()

config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)

config
.when(process.env.NODE_ENV !== 'development',
config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single')
}
)
if (IS_PRODUCTION) {
config.plugin('html').tap(args => {
args[0].cdn = cdn
return args
})
config.externals(externals)
config.plugin('html').tap(args => {
args[0].minify.minifyCSS = true // 压缩html中的css
return args
})
// gzip需要nginx进行配合
config
.plugin('compression')
.use(CompressionWebpackPlugin)
.tap(() => [
{
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 超过10k进行压缩
deleteOriginalAssets: false // 是否删除源文件
}
])
config.optimization.minimizer([
new UglifyjsWebpackPlugin({
// 生产环境推荐关闭 sourcemap 防止源码泄漏
// 服务端通过前端发送的行列,根据 sourcemap 转为源文件位置
sourceMap: true,
uglifyOptions: {
warnings: false,
compress: {
drop_console: false,
drop_debugger: false
}
}
})
])
}
},
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: !!IS_PRODUCTION,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
// 启用 CSS modules for all css / pre-processor files.
modules: false,
loaderOptions: {
sass: {
data: '@import "style/_mixin.scss";@import "style/_variables.scss";@import "style/common.scss";' // 全局引入
}
}
}
}