Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master' into master

laoyao před 3 roky
rodič
revize
3faf8f865b

+ 151 - 141
imcs-ui/src/api/resourceProductMgr/areaMgr.js

@@ -1,141 +1,151 @@
-import axiosApi from '../AxiosApi.js'
-
-const apiList = {
-	getList: {
-    method: 'GET',
-    url: `/authority/zZone/all`
-  },
-  page: {
-    method: 'POST',
-    url: `/authority/zZone/page`
-  },
-  update: {
-    method: 'POST',
-    url: `/authority/zZone/update`
-  },
-  save: {
-    method: 'POST',
-    url: `/authority/zZone`
-  },
-  updateStatus: {
-    method: 'POST',
-    url: `/authority/zZone/status`
-  },
-  remove: {
-    method: 'DELETE',
-    url: `/authority/zZone`
-  },
-  delete: {
-    method: 'POST',
-    url: `/authority/zZone/delete`
-  },
-  iconGroupList: {
-    method: 'POST',
-    url: `/authority/zZone/iconGroupList/v1`
-  },
-  list: {
-    method: 'POST',
-    url: `/authority/zZone/query`
-  },
-  preview: {
-    method: 'POST',
-    url: `/authority/zZone/preview`
-  },
-  export: {
-    method: 'POST',
-    url: `/authority/zZone/export`
-  },
-  import: {
-    method: 'POST',
-    url: `/authority/zZone/import`
-  }
-}
-
-export default {
-	getList (data) {
-    return axiosApi({
-      ...apiList.getList,
-      data
-    })
-  },
-  page (data) {
-    return axiosApi({
-      ...apiList.page,
-      data
-    })
-  },
-  save (data) {
-    return axiosApi({
-      ...apiList.save,
-      data
-    })
-  },
-  update (data) {
-    return axiosApi({
-      ...apiList.update,
-      data
-    })
-  },
-  updateStatus (data) {
-    return axiosApi({
-      ...apiList.updateStatus,
-      data
-    })
-  },
-  remove (data) {
-    return axiosApi({
-      ...apiList.remove,
-      data
-    })
-  },
-  delete (data) {
-    return axiosApi({
-      ...apiList.delete,
-      data
-    })
-  },
-  iconGroupList (data) {
-    return axiosApi({
-      ...apiList.iconGroupList,
-      data
-    })
-  },
-  list (data) {
-    return axiosApi({
-      ...apiList.list,
-      data
-    })
-  },
-  check (code) {
-    return axiosApi({
-      method: 'GET',
-      url: `/authority/zZone/check/${code}`
-    })
-  },
-  checkField (data) {
-    return axiosApi({
-      method: 'POST',
-      url: `/authority/zZone/check`,
-      data
-    })
-  },
-  preview (data) {
-    return axiosApi({
-      ...apiList.preview,
-      data
-    })
-  },
-  export (data) {
-    return axiosApi({
-      ...apiList.export,
-      responseType: "blob",
-      data
-    })
-  },
-  import (data) {
-    return axiosApi({
-      ...apiList.import,
-      data
-    })
-  }
-}
+import axiosApi from '../AxiosApi.js'
+
+const apiList = {
+	getList: {
+    method: 'GET',
+    url: `/authority/zZone/all`
+  },
+  page: {
+    method: 'POST',
+    url: `/authority/zZone/page`
+  },
+  update: {
+    method: 'POST',
+    url: `/authority/zZone/update`
+  },
+  save: {
+    method: 'POST',
+    url: `/authority/zZone`
+  },
+  updateStatus: {
+    method: 'POST',
+    url: `/authority/zZone/status`
+  },
+  remove: {
+    method: 'DELETE',
+    url: `/authority/zZone`
+  },
+  delete: {
+    method: 'POST',
+    url: `/authority/zZone/delete`
+  },
+  iconGroupList: {
+    method: 'POST',
+    url: `/authority/zZone/iconGroupList/v1`
+  },
+  list: {
+    method: 'POST',
+    url: `/authority/zZone/query`
+  },
+  preview: {
+    method: 'POST',
+    url: `/authority/zZone/preview`
+  },
+  export: {
+    method: 'POST',
+    url: `/authority/zZone/export`
+  },
+  import: {
+    method: 'POST',
+    url: `/authority/zZone/import`
+  },
+  allSelect: {
+    method: 'GET',
+    url: `/authority/zZone/allSelect`
+  },
+}
+
+export default {
+	getList (data) {
+    return axiosApi({
+      ...apiList.getList,
+      data
+    })
+  },
+  page (data) {
+    return axiosApi({
+      ...apiList.page,
+      data
+    })
+  },
+  save (data) {
+    return axiosApi({
+      ...apiList.save,
+      data
+    })
+  },
+  update (data) {
+    return axiosApi({
+      ...apiList.update,
+      data
+    })
+  },
+  updateStatus (data) {
+    return axiosApi({
+      ...apiList.updateStatus,
+      data
+    })
+  },
+  remove (data) {
+    return axiosApi({
+      ...apiList.remove,
+      data
+    })
+  },
+  delete (data) {
+    return axiosApi({
+      ...apiList.delete,
+      data
+    })
+  },
+  iconGroupList (data) {
+    return axiosApi({
+      ...apiList.iconGroupList,
+      data
+    })
+  },
+  list (data) {
+    return axiosApi({
+      ...apiList.list,
+      data
+    })
+  },
+  check (code) {
+    return axiosApi({
+      method: 'GET',
+      url: `/authority/zZone/check/${code}`
+    })
+  },
+  checkField (data) {
+    return axiosApi({
+      method: 'POST',
+      url: `/authority/zZone/check`,
+      data
+    })
+  },
+  preview (data) {
+    return axiosApi({
+      ...apiList.preview,
+      data
+    })
+  },
+  export (data) {
+    return axiosApi({
+      ...apiList.export,
+      responseType: "blob",
+      data
+    })
+  },
+  import (data) {
+    return axiosApi({
+      ...apiList.import,
+      data
+    })
+  },
+  allSelect (data) {
+    return axiosApi({
+      ...apiList.allSelect,
+      data
+    })
+  }
+}

+ 308 - 307
imcs-ui/src/lang/zh/resource.js

@@ -1,307 +1,308 @@
-/**************** 【生产資源中心】菜单  **************/
-export default {
-	resource: {
-		// 本模型下的共通
-		common: {
-			aduio: '审核产品',
-			selectAdd: '选择设备',
-			peizhi: '生产资源配置',
-			toolList: '刀具列表',
-			programList: '程序列表',
-			jiankong: '监控方式',
-			setJiankong: '设置监控',
-			jiankongRecord: '监控记录',
-			noJiank: '无监控',
-			jiankongTime: '监控使用寿命',
-			jiankongNums: '监控使用次数',
-			seconds: '分钟',
-			nums: '次',
-			mimm: 'm/s',
-			jichuang: '机床',
-			jxsbi: '机械手臂',
-			agv: 'AGV',
-			tuoban: '托板',
-			users: '使用',
-			history: '历史',
-			eqDelete: '从设备删除',
-			zhixingPg: '执行程序',
-			maxWorkHours: '小时',
-			displayStatus: '是否显示',
-			stopTaskHours: '小时(不派任务)',
-			eqCenter: {
-				allCount: '设备总数',
-				supervisionCount: '系统监管',
-				independentCount: '独立运行',
-				onlineCount: '在线',
-				offlineCount: '离线',
-				workCount: '生产中',
-				freeCount: '空闲',
-				waitCount: '等待配送资源',
-				exceptionCount: '异常',
-				anArea: '按产线',
-				anType: '按分类',
-				waitTask: '待完成任务',
-				detail: '详情',
-				geKuwei: '个库位'
-			}
-		},
-		// 列表搜索表单名称
-		searchForm: {
-			programName: '产品名称',
-			startEndTime: '时间',
-			guige: '规格',
-			xinghao: '型号',
-			jichuang: '所在机床',
-			resourceName: '资源名称',
-			linkStatus: '在线状态',
-			eqName: '设备名称',
-			name: '名称',
-			no: '编号',
-			isCNC: '包含CNC程序',
-			isDao: '包含刀具库',
-			idJindu: '具备进度条',
-			isStatus: '具备状态',
-			isProStaus: '产线控制状态',
-			maxTime: '每日最多加工',
-			baoyang: '临近保养',
-			isAutoCode: '是否工序设备'
-		},
-		// 按钮的名称
-	  	buttons: {
-	  		equipment: '设备管理',
-	  		position: '设备位置管理',
-	  		setBtn: '设置控制状态',
-	  		work: '工作位置管理',
-	  		setting: '配置',
-	  		hardware: '硬件配置',
-	  		linkLine: '关联边线库',
-	  		tongbu: '同步刀具',
-	  		tongbEq: '同步到设备',
-	  		tongbSk: '同步数控程序',
-        upload: '上传程序',
-			mode:  '模式',
-			autoCode: '设备业务自动化节点',
-			detailConf: '详情配置'
-	  	},
-	  	// 列表的cell名称
-		table: {
-			// 【生产单元管理】列表table字段名称
-			area: {
-				no: '编号',
-				name: '产线名称',
-				nums: '资源数量',
-				layoutMap: '布局图',
-				resources: '包含生产资源',
-				mode: '产线模式',
-				remark: '备注',
-				status: '启用状态',
-				createUser: '操作人',
-				updateTime: '修改时间'
-			},
-			// 【设备管理】列表table字段名称
-			equipment: {
-				no: '编号',
-				pic: '主图',
-				name: '设备名称',
-				brand: '品牌',
-				specification: '规格',
-				model: '型号',
-			},
-			// 【选择设备】列表table字段名称
-			selectQm: {
-				no: '编号',
-				pic: '主图',
-				name: '设备名称',
-				brand: '品牌',
-				specification: '规格',
-				model: '型号',
-				zoneName: '已被选的生产单元',
-			},
-			// 【生产资源管理】列表table字段名称
-			resours: {
-				no: '编号',
-				pic: '主图',
-				name: '设备名称',
-				brand: '品牌',
-				specification: '规格',
-				resourceBusinessId: '设备业务',
-				capitalNo: '资产编号',
-			    capitalName: '资产名称',
-				capitalType: '资产类别',
-			    modeSpecification: '型号规格',
-				capitalPrice: '资产原值',
-				productionDate: '出厂年月',
-				productionNo: '出厂编号',
-				manufacturer: '制造厂家',
-				zoneName: '所属产线',
-				model: '型号',
-				category: '设备分类',
-				zoneName: '所属产线',
-        		programSynTime: '同步时间',
-        		programNum: '程序数量',
-				nums: '工作位置数量',
-				isProgram: '是否需要程序',
-				linkStatus: "连接状态",
-				controlStatus: '控制状态',
-				productionStatus: '生产状态'
-			},
-      		//【维保计划管理】列表table字段名称
-      repair:{
-				select:'选择设备',
-				code: '设备编号',
-        productionresourceName: '设备名称',
-        lineDesc: '所在产线',
-        countdown: '维修倒计时进度',
-        repairStartTime: '维保开始时间',
-        repairEndTime: '下次维保时间',
-        repairStatus: '维修状态',
-        status: '启用状态',
-        createUserDesc: '操作人',
-        weight:'排序',
-        createTime: '创建时间',
-        updateTime: '更新时间',
-        remark: '备注',
-        maintenanceTime: '维保日期',
-        maintenanceContent: '维保内容',
-        maintenanceStatus: '维保后设备状态',
-        maintenanceUser: '维保人',
-        maintenanceCreateTime: '提交日期',
-      },
-			// 【设备位置管理】列表table字段名称
-			eqPosition: {
-				no: '位置编号',
-				name: '名称',
-				pointId: '点位ID',
-				status: '锁定状态'
-			},
-			// 【设备刀具管理-设备列表】列表table字段名称
-			eqList: {
-				name: '设备名称',
-				name2: '设备编号',
-				name3: '设备类似',
-				name4: '所属生产单元',
-				name5: '设备连接状态',
-				name6: '同步时间',
-				name7: '刀库刀具数量'
-			},
-			// 【设备刀具管理-刀具列表】列表table字段名称
-			toolList: {
-				specification: '刀具规格',
-				model: '型号',
-				brand: '品牌',
-				no: '刀库刀具编号',
-				stopBits: '停止位',
-				useStatus: '使用状态',
-				monitorWay: '监控方式',
-				rateUseLife: '额定使用寿命/次',
-				leftUseLife: '剩余使用次数/次',
-				warnLimit: '预警极限',
-				synTime: '同步时间'
-			},
-			// 【设备刀具管理-监控记录】列表table字段名称
-			jkRecord: {
-				rateUseLife: '额定使用寿命/次',
-				leftUseLife: '剩余使用寿命/次',
-				warnLimit: '预警极限',
-				synTime: '同步时间'
-			},
-			// 【程序中心-本地库】列表table字段名称
-			program: {
-				no: '程序编号',
-				name: '程序名称',
-				runTime: '运行时间',
-				size: '大小',
-				toolNums: '刀具数量',
-				version: '版本',
-				status: '状态',
-        		synTime: '同步时间'
-			},
-			// 【程序中心-新增-刀具】列表table字段名称
-			programTool: {
-				specification: '刀具规格',
-				toolName: '刀具名称',
-				useTime: '使用时间(分钟)',
-				count: '数量',
-				model: '型号',
-				brand: '品牌',
-				usageTime: '使用时间',
-				duration: '持续时间'
-			},
-			// 【程序管理】列表table字段名称
-			pgMgr: {
-				bomName: '产品',
-				version: '工艺版本号',
-				procedureNo: '工序号',
-				resourceName: '设备名称',
-				programName: '程序名称',
-				runTime: '运行时长',
-				createTime: '新增时间',
-				updateTime: '更新时间',
-				createUserDesc: '操作'
-			},
-			// 【程序执行任务】列表table字段名称
-			pgTask: {
-				programNo: '程序编号',
-				programName: '程序名称',
-				version: '版本号',
-				resourceName: '设备名称',
-				resourceCode: '设备编号',
-				runStatus: '状态',
-				actualRunTime: '额定运行时间',
-				startTime: '开始时间',
-				runTime: '运行时间',
-				endTime: '结束时间',
-				createUserDesc: '操作人'
-			}
-		},
-		// 表单数据名称
-		form: {
-			positionName: '位置名称',
-			relationStorage: '关联库位',
-			isLock: '是否锁定',
-			pointId: '点位ID',
-			selectLink: '选择线边库货架',
-			userTime: '额定使用寿命',
-			warninhTime: '报警寿命',
-			userNums: '额定使用次数',
-			warninhNums: '报警次数',
-			prority: '优先级',
-			workTime: '加工时间',
-			pg: '程序',
-			pgNo: '程序编号',
-			pgName: '程序名称',
-			pgVision: '版本号',
-			pgEq: '适合设备',
-			pgUpload: '上传程序',
-			pgTime: '运行时间',
-			pgSize: '程序大小',
-			pgContent: '程序内容',
-			pgTool: '刀具',
-			workbench_num: '工作台数量',
-			hand_num: '手臂数量',
-			cache_storge_num: '缓存库数量',
-			max_speed: '最大移动速度',
-			tray_num: '可放子盘数量',
-			tuoban: '关联托板分类',
-			arm: '手抓',
-			armName: '手抓名称',
-      target_resource: '目标设备',
-			rouJiagong: '产线类型'
-		},
-		// 表单验证规则提示信息
-		rules: {
-		},
-		// 提示或者显示信息
-		tips:{
-			tongbTips: '同步成功!',
-			zhixingTips: '执行程序成功!',
-			areaTips: '删除区域管理数据后,会将区域管理数据全部删除,确认删除?',
-			fileTips: '只能上传TEXT文件!',
-			deletePg: '是否【从设备删除】数据,确认删除?',
-			zxTips: '是否【执行程序】数据,确认执行?',
-			taskTips: '删除程序执行任务数据后,会将程序执行任务数据全部删除,确认删除?',
-			resourTips: '删除生产资源数据后,会将生产资源数据全部删除,确认删除?',
-			hardware: '该硬件不需要配置!'
-		}
-	}
-}
+/**************** 【生产資源中心】菜单  **************/
+export default {
+	resource: {
+		// 本模型下的共通
+		common: {
+			aduio: '审核产品',
+			selectAdd: '选择设备',
+			peizhi: '生产资源配置',
+			toolList: '刀具列表',
+			programList: '程序列表',
+			jiankong: '监控方式',
+			setJiankong: '设置监控',
+			jiankongRecord: '监控记录',
+			noJiank: '无监控',
+			jiankongTime: '监控使用寿命',
+			jiankongNums: '监控使用次数',
+			seconds: '分钟',
+			nums: '次',
+			mimm: 'm/s',
+			jichuang: '机床',
+			jxsbi: '机械手臂',
+			agv: 'AGV',
+			tuoban: '托板',
+			users: '使用',
+			history: '历史',
+			eqDelete: '从设备删除',
+			zhixingPg: '执行程序',
+			maxWorkHours: '小时',
+			displayStatus: '是否显示',
+			stopTaskHours: '小时(不派任务)',
+			eqCenter: {
+				allCount: '设备总数',
+				supervisionCount: '系统监管',
+				independentCount: '独立运行',
+				onlineCount: '在线',
+				offlineCount: '离线',
+				workCount: '生产中',
+				freeCount: '空闲',
+				waitCount: '等待配送资源',
+				exceptionCount: '异常',
+				anArea: '按产线',
+				anType: '按分类',
+				waitTask: '待完成任务',
+				detail: '详情',
+				geKuwei: '个库位'
+			}
+		},
+		// 列表搜索表单名称
+		searchForm: {
+			programName: '产品名称',
+			startEndTime: '时间',
+			guige: '规格',
+			xinghao: '型号',
+			jichuang: '所在机床',
+			resourceName: '资源名称',
+			linkStatus: '在线状态',
+			eqName: '设备名称',
+			name: '名称',
+			no: '编号',
+			isCNC: '包含CNC程序',
+			isDao: '包含刀具库',
+			idJindu: '具备进度条',
+			isStatus: '具备状态',
+			isProStaus: '产线控制状态',
+			maxTime: '每日最多加工',
+			baoyang: '临近保养',
+			isAutoCode: '是否工序设备'
+		},
+		// 按钮的名称
+	  	buttons: {
+	  		equipment: '设备管理',
+	  		position: '设备位置管理',
+	  		setBtn: '设置控制状态',
+	  		work: '工作位置管理',
+	  		setting: '配置',
+	  		hardware: '硬件配置',
+	  		linkLine: '关联边线库',
+	  		tongbu: '同步刀具',
+	  		tongbEq: '同步到设备',
+	  		tongbSk: '同步数控程序',
+        upload: '上传程序',
+			mode:  '模式',
+			autoCode: '设备业务自动化节点',
+			detailConf: '详情配置'
+	  	},
+	  	// 列表的cell名称
+		table: {
+			// 【生产单元管理】列表table字段名称
+			area: {
+				no: '编号',
+				name: '产线名称',
+				nums: '资源数量',
+				layoutMap: '布局图',
+				resources: '包含生产资源',
+				mode: '产线模式',
+				remark: '备注',
+				status: '启用状态',
+				orgId: '产线部门',
+				createUser: '操作人',
+				updateTime: '修改时间'
+			},
+			// 【设备管理】列表table字段名称
+			equipment: {
+				no: '编号',
+				pic: '主图',
+				name: '设备名称',
+				brand: '品牌',
+				specification: '规格',
+				model: '型号',
+			},
+			// 【选择设备】列表table字段名称
+			selectQm: {
+				no: '编号',
+				pic: '主图',
+				name: '设备名称',
+				brand: '品牌',
+				specification: '规格',
+				model: '型号',
+				zoneName: '已被选的生产单元',
+			},
+			// 【生产资源管理】列表table字段名称
+			resours: {
+				no: '编号',
+				pic: '主图',
+				name: '设备名称',
+				brand: '品牌',
+				specification: '规格',
+				resourceBusinessId: '设备业务',
+				capitalNo: '资产编号',
+			    capitalName: '资产名称',
+				capitalType: '资产类别',
+			    modeSpecification: '型号规格',
+				capitalPrice: '资产原值',
+				productionDate: '出厂年月',
+				productionNo: '出厂编号',
+				manufacturer: '制造厂家',
+				zoneName: '所属产线',
+				model: '型号',
+				category: '设备分类',
+				zoneName: '所属产线',
+        		programSynTime: '同步时间',
+        		programNum: '程序数量',
+				nums: '工作位置数量',
+				isProgram: '是否需要程序',
+				linkStatus: "连接状态",
+				controlStatus: '控制状态',
+				productionStatus: '生产状态'
+			},
+      		//【维保计划管理】列表table字段名称
+      		repair: {
+				select:'选择设备',
+				code: '设备编号',
+		        productionresourceName: '设备名称',
+		        lineDesc: '所在产线',
+		        countdown: '维修倒计时进度',
+		        repairStartTime: '维保开始时间',
+		        repairEndTime: '下次维保时间',
+		        repairStatus: '维修状态',
+		        status: '启用状态',
+		        createUserDesc: '操作人',
+		        weight:'排序',
+		        createTime: '创建时间',
+		        updateTime: '更新时间',
+		        remark: '备注',
+		        maintenanceTime: '维保日期',
+		        maintenanceContent: '维保内容',
+		        maintenanceStatus: '维保后设备状态',
+		        maintenanceUser: '维保人',
+		        maintenanceCreateTime: '提交日期',
+		    },
+			// 【设备位置管理】列表table字段名称
+			eqPosition: {
+				no: '位置编号',
+				name: '名称',
+				pointId: '点位ID',
+				status: '锁定状态'
+			},
+			// 【设备刀具管理-设备列表】列表table字段名称
+			eqList: {
+				name: '设备名称',
+				name2: '设备编号',
+				name3: '设备类似',
+				name4: '所属生产单元',
+				name5: '设备连接状态',
+				name6: '同步时间',
+				name7: '刀库刀具数量'
+			},
+			// 【设备刀具管理-刀具列表】列表table字段名称
+			toolList: {
+				specification: '刀具规格',
+				model: '型号',
+				brand: '品牌',
+				no: '刀库刀具编号',
+				stopBits: '停止位',
+				useStatus: '使用状态',
+				monitorWay: '监控方式',
+				rateUseLife: '额定使用寿命/次',
+				leftUseLife: '剩余使用次数/次',
+				warnLimit: '预警极限',
+				synTime: '同步时间'
+			},
+			// 【设备刀具管理-监控记录】列表table字段名称
+			jkRecord: {
+				rateUseLife: '额定使用寿命/次',
+				leftUseLife: '剩余使用寿命/次',
+				warnLimit: '预警极限',
+				synTime: '同步时间'
+			},
+			// 【程序中心-本地库】列表table字段名称
+			program: {
+				no: '程序编号',
+				name: '程序名称',
+				runTime: '运行时间',
+				size: '大小',
+				toolNums: '刀具数量',
+				version: '版本',
+				status: '状态',
+        		synTime: '同步时间'
+			},
+			// 【程序中心-新增-刀具】列表table字段名称
+			programTool: {
+				specification: '刀具规格',
+				toolName: '刀具名称',
+				useTime: '使用时间(分钟)',
+				count: '数量',
+				model: '型号',
+				brand: '品牌',
+				usageTime: '使用时间',
+				duration: '持续时间'
+			},
+			// 【程序管理】列表table字段名称
+			pgMgr: {
+				bomName: '产品',
+				version: '工艺版本号',
+				procedureNo: '工序号',
+				resourceName: '设备名称',
+				programName: '程序名称',
+				runTime: '运行时长',
+				createTime: '新增时间',
+				updateTime: '更新时间',
+				createUserDesc: '操作'
+			},
+			// 【程序执行任务】列表table字段名称
+			pgTask: {
+				programNo: '程序编号',
+				programName: '程序名称',
+				version: '版本号',
+				resourceName: '设备名称',
+				resourceCode: '设备编号',
+				runStatus: '状态',
+				actualRunTime: '额定运行时间',
+				startTime: '开始时间',
+				runTime: '运行时间',
+				endTime: '结束时间',
+				createUserDesc: '操作人'
+			}
+		},
+		// 表单数据名称
+		form: {
+			positionName: '位置名称',
+			relationStorage: '关联库位',
+			isLock: '是否锁定',
+			pointId: '点位ID',
+			selectLink: '选择线边库货架',
+			userTime: '额定使用寿命',
+			warninhTime: '报警寿命',
+			userNums: '额定使用次数',
+			warninhNums: '报警次数',
+			prority: '优先级',
+			workTime: '加工时间',
+			pg: '程序',
+			pgNo: '程序编号',
+			pgName: '程序名称',
+			pgVision: '版本号',
+			pgEq: '适合设备',
+			pgUpload: '上传程序',
+			pgTime: '运行时间',
+			pgSize: '程序大小',
+			pgContent: '程序内容',
+			pgTool: '刀具',
+			workbench_num: '工作台数量',
+			hand_num: '手臂数量',
+			cache_storge_num: '缓存库数量',
+			max_speed: '最大移动速度',
+			tray_num: '可放子盘数量',
+			tuoban: '关联托板分类',
+			arm: '手抓',
+			armName: '手抓名称',
+      		target_resource: '目标设备',
+			rouJiagong: '产线类型'
+		},
+		// 表单验证规则提示信息
+		rules: {
+		},
+		// 提示或者显示信息
+		tips:{
+			tongbTips: '同步成功!',
+			zhixingTips: '执行程序成功!',
+			areaTips: '删除区域管理数据后,会将区域管理数据全部删除,确认删除?',
+			fileTips: '只能上传TEXT文件!',
+			deletePg: '是否【从设备删除】数据,确认删除?',
+			zxTips: '是否【执行程序】数据,确认执行?',
+			taskTips: '删除程序执行任务数据后,会将程序执行任务数据全部删除,确认删除?',
+			resourTips: '删除生产资源数据后,会将生产资源数据全部删除,确认删除?',
+			hardware: '该硬件不需要配置!'
+		}
+	}
+}

+ 786 - 787
imcs-ui/src/views/login/index.vue

@@ -1,787 +1,786 @@
-<template>
-  <div class="login-container">
-    <div class="login-info">
-    	<img :src="require(`@/assets/logo/logo1.png`)"/>
-    	<div>
-	    	<div class="title">{{$t('login.shuoming.title')}}</div>
-	      <div class="title">{{$t('login.shuoming.tips')}}</div>
-      </div>
-    </div>
-    <el-form
-      :model="loginForm"
-      :rules="rules"
-      autocomplete="off"
-      class="login-form"
-      label-position="left"
-      ref="loginForm"
-    >
-	    <el-tabs v-model="activeName" @tab-click="handleClick">
-		    <el-tab-pane label="扫码登录" name="first">
-		    	<div class="saomaDom">
-		    		<img :src="require(`@/assets/logo/saoma.png`)"/>
-		    		<div>请扫码登录</div>
-		    	</div>
-		    </el-tab-pane>
-		    <el-tab-pane label="密码登录" name="second">
-		      <div class="title-container">
-		        <h3 class="title">{{$t('login.title')}}</h3>
-		        <lang-select class="set-language"/>
-		      </div>
-		      <span v-if="login.type === 'up'">
-		        <el-form-item prop="tenant" v-show="isMultiTenant">
-		          <el-input
-		            :placeholder="$t('login.tenant')"
-		            @keyup.enter.native="handleLogin"
-		            autocomplete="off"
-		            name="tenantView"
-		            prefix-icon="el-icon-user"
-		            ref="tenant"
-		            type="text"
-		            v-model="loginForm.tenantView"
-		          />
-		        </el-form-item>
-		        <el-form-item prop="account">
-		          <el-input
-		            :placeholder="$t('login.username')"
-		            @keyup.enter.native="handleLogin"
-		            autocomplete="off"
-		            name="account"
-		            prefix-icon="el-icon-user"
-		            ref="account"
-		            type="text"
-		            v-model="loginForm.account"
-		          />
-		        </el-form-item>
-		        <el-form-item prop="password">
-		          <el-input
-		            :placeholder="$t('login.password')"
-		            :show-password="true"
-		            @keyup.enter.native="handleLogin"
-		            autocomplete="off"
-		            name="password"
-		            prefix-icon="el-icon-key"
-		            ref="password"
-		            type="password"
-		            v-model="loginForm.password"
-		          />
-		        </el-form-item>
-		        <el-form-item class="code-input" prop="code" v-show="isCaptcha">
-		          <el-input
-		            :placeholder="$t('login.code')"
-		            @keyup.enter.native="handleLogin"
-		            autocomplete="off"
-		            name="code"
-		            prefix-icon="el-icon-lock"
-		            ref="code"
-		            style="width: 70%"
-		            type="text"
-		            v-model="loginForm.code"
-		          />
-		        </el-form-item>
-		        <img
-		          v-show="isCaptcha"
-		          :src="imageCode"
-		          @click="getCodeImage"
-		          alt="codeImage"
-		          class="code-image"
-		        />
-		        <el-button
-		          :loading="loading"
-		          @click.native.prevent="handleLogin"
-		          style="width:100%;margin-bottom:14px;"
-		          type="primary"
-		        >{{ $t("login.logIn") }}</el-button
-		        >
-		      </span>
-		      <span v-if="login.type === 'social'">
-		        {{ $t("login.chooseToSignIn") }}
-		        <div>
-		          <template v-for="(l, index) in logo">
-		            <div :key="index" class="logo-wrapper">
-		              <img
-		                :class="{ radius: l.radius }"
-		                :src="resolveLogo(l.img)"
-		                @click="socialLogin(l.name)"
-		                alt
-		              />
-		            </div>
-		          </template>
-		        </div>
-		      </span>
-		      <span style="margin-top: -1rem" v-if="login.type === 'bind'">
-		        <el-tabs @tab-click="handleTabClick" v-model="tabActiveName">
-		          <el-tab-pane :label="$t('common.bindLogin')" name="bindLogin">
-		            <el-form-item prop="bindAccount">
-		              <el-input
-		                :placeholder="$t('login.account')"
-		                autocomplete="off"
-		                name="bindAccount"
-		                prefix-icon="el-icon-user"
-		                ref="bindAccount"
-		                type="text"
-		                v-model="loginForm.bindAccount"
-		              />
-		            </el-form-item>
-		            <el-form-item prop="bindPassword">
-		              <el-input
-		                :placeholder="$t('login.password')"
-		                :show-password="true"
-		                autocomplete="off"
-		                name="bindPassword"
-		                prefix-icon="el-icon-key"
-		                ref="bindPassword"
-		                type="password"
-		                v-model="loginForm.bindPassword"
-		              />
-		            </el-form-item>
-		            <el-button
-		              :loading="loading"
-		              @click.native.prevent="bindLogin"
-		              style="width:100%;margin-bottom:14px;"
-		              type="primary"
-		            >{{ $t("common.bindLogin") }}</el-button
-		            >
-		          </el-tab-pane>
-		          <el-tab-pane :label="$t('common.signLogin')" name="signLogin">
-		            <el-form-item prop="signAccount">
-		              <el-input
-		                :placeholder="$t('login.account')"
-		                autocomplete="off"
-		                name="signAccount"
-		                prefix-icon="el-icon-user"
-		                ref="signAccount"
-		                type="text"
-		                v-model="loginForm.signAccount"
-		              />
-		            </el-form-item>
-		            <el-form-item prop="signPassword">
-		              <el-input
-		                :placeholder="$t('login.password')"
-		                :show-password="true"
-		                autocomplete="off"
-		                name="signPassword"
-		                prefix-icon="el-icon-key"
-		                ref="signPassword"
-		                type="password"
-		                v-model="loginForm.signPassword"
-		              />
-		            </el-form-item>
-		            <el-button
-		              :loading="loading"
-		              @click.native.prevent="signLogin"
-		              style="width:100%;margin-bottom:14px;"
-		              type="primary"
-		            >{{ $t("common.signLogin") }}</el-button
-		            >
-		          </el-tab-pane>
-		        </el-tabs>
-		      </span>
-		      <!--<el-dropdown class="login-type" placement="top-end">
-		        <span class="el-dropdown-link">
-		          <el-link type="primary">{{ $t("login.ortherLoginType") }}</el-link>
-		        </span>
-		        <el-dropdown-menu slot="dropdown">
-		          <el-dropdown-item
-		            :disabled="login.type === 'up'"
-		            @click.native="login.type = 'up'"
-		          >{{ $t("login.type.up") }}
-		          </el-dropdown-item
-		          >
-		          <el-dropdown-item
-		            :disabled="login.type === 'social'"
-		            @click.native="login.type = 'social'"
-		          >{{ $t("login.type.social") }}
-		          </el-dropdown-item
-		          >
-		        </el-dropdown-menu>
-		      </el-dropdown>-->
-		      <el-input id="qcodeUser" name="qcodeUser" v-model="loginForm.qcodeUser" type="hidden" onfocus=""  @input="showQcodeUser()"/>
-		    </el-tab-pane>
-		  </el-tabs>
-    </el-form>
-    <span class="login-footer">
-      © 2019 - 2020
-      <span>{{$t('login.shuoming.tips')}}</span>
-    </span>
-  </div>
-</template>
-
-<script>
-  import LangSelect from "@/components/LangSelect";
-  import db from "@/utils/localstorage";
-  import {randomNum} from "@/utils";
-  import {socialLoginUrl} from "@/settings";
-  import loginApi from "@/api/Login.js";
-  import oauthApi from '@/api/Oauth'
-  import {Base64} from 'js-base64';
-
-  export default {
-    name: "Login",
-    components: {LangSelect},
-    data() {
-      return {
-      	activeName: 'first',
-        //是否启用多租户
-        isMultiTenant:
-          process.env.VUE_APP_IS_MULTI_TENANT === "true" ? true : false,
-        isCaptcha:
-          process.env.VUE_APP_IS_CAPTCHA === "true" ? true : false,
-        tabActiveName: "bindLogin",
-        login: {
-          type: "up"
-        },
-        logo: [
-          {img: "gitee.png", name: "gitee", radius: true},
-          {img: "github.png", name: "github", radius: true},
-          {img: "tencent_cloud.png", name: "tencent_cloud", radius: true},
-          {img: "qq.png", name: "qq", radius: false},
-          {img: "dingtalk.png", name: "dingtalk", radius: true},
-          {img: "microsoft.png", name: "microsoft", radius: false}
-        ],
-        loginForm: {
-          account: "zuihou",
-          password: "",   // zuihou
-          tenantView: "0000", //显示用的
-          tenant: "", //传递给后端的
-          key: randomNum(24, 16),
-          code: "",
-          grantType: process.env.VUE_APP_IS_CAPTCHA === "true" ? "captcha" : "password",
-          bindAccount: "",
-          bindPassword: "",
-          signAccount: "",
-          signPassword: "",
-          qcodeUser: ""
-        },
-        rules: {
-          account: {
-            required: true,
-            message: this.$t("rules.require"),
-            trigger: "blur"
-          },
-          tenantView: {
-            required: true,
-            message: this.$t("rules.require"),
-            trigger: "blur"
-          },
-          password: {
-            required: true,
-            message: this.$t("rules.require"),
-            trigger: "blur"
-          },
-          code: {
-            validator: (rule, value, callback) => {
-              if (this.isCaptcha && value === '') {
-                callback(this.$t("rules.require"))
-              } else {
-                callback()
-              }
-              callback()
-            }, trigger: 'blur'
-          },
-          bindAccount: {
-            required: true,
-            message: this.$t("rules.require"),
-            trigger: "blur"
-          },
-          bindPassword: {
-            required: true,
-            message: this.$t("rules.require"),
-            trigger: "blur"
-          },
-          signAccount: [
-            {
-              required: true,
-              message: this.$t("rules.require"),
-              trigger: "blur"
-            },
-            {
-              min: 4,
-              max: 10,
-              message: this.$t("rules.range4to10"),
-              trigger: "blur"
-            }
-          ],
-          signPassword: [
-            {
-              required: true,
-              message: this.$t("rules.require"),
-              trigger: "blur"
-            },
-            {
-              min: 6,
-              max: 20,
-              message: this.$t("rules.range6to20"),
-              trigger: "blur"
-            }
-          ]
-        },
-        authUser: null,
-        loading: false,
-        showDialog: false,
-        redirect: undefined,
-        otherQuery: {},
-        imageCode: "",
-        page: {
-          width: window.screen.width * 0.5,
-          height: window.screen.height * 0.5
-        }
-      };
-    },
-    created() {
-    },
-    mounted() {
-      db.clear();
-      this.getCodeImage();
-      this.$nextTick(
-        window.onload = function () { // 光标默认位置
-            var oInput = document.getElementById('qcodeUser');
-            oInput.focus();
-        }
-      )
-    },
-    destroyed() {
-      window.removeEventListener("message", this.resolveSocialLogin);
-    },
-    methods: {
-    	// Tabs切换-事件
-    	handleClick(tab, event) {
-        console.log(tab, event);
-      },
-    	
-      getCodeImage() {
-        loginApi
-          .getCaptcha(this.loginForm.key)
-          .then(response => {
-            const res = response.data;
-            if (res.byteLength <= 100) {
-              this.$message({
-                message: this.$t("tips.systemError"),
-                type: "error"
-              });
-            }
-            return (
-              "data:image/png;base64," +
-              btoa(
-                new Uint8Array(res).reduce(
-                  (data, byte) => data + String.fromCharCode(byte),
-                  ""
-                )
-              )
-            );
-          })
-          .then(res => {
-            this.imageCode = res;
-          })
-          .catch(e => {
-            if (e.toString().indexOf("429") !== -1) {
-              this.$message({
-                message: this.$t("tips.tooManyRequest"),
-                type: "error"
-              });
-            } else {
-              this.$message({
-                message: this.$t("tips.getCodeImageFailed"),
-                type: "error"
-              });
-            }
-          });
-      },
-      handleTabClick(tab) {
-        this.tabActiveName = tab.name;
-      },
-      resolveLogo(logo) {
-        return require(`@/assets/logo/${logo}`);
-      },
-      socialLogin(oauthType) {
-        const url = `${socialLoginUrl}/${oauthType}/login`;
-        window.open(
-          url,
-          "newWindow",
-          `resizable=yes, height=${this.page.height}, width=${this.page.width}, top=10%, left=10%, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no`
-        );
-        window.addEventListener("message", this.resolveSocialLogin, false);
-      },
-      resolveSocialLogin(e) {
-        const data = e.data;
-        const that = this;
-        if (data.message === "not_bind") {
-          that.login.type = "bind";
-          const authUser = data.data;
-          that.authUser = authUser;
-          that
-            .$confirm(
-              that.$t("common.current") +
-              authUser.source +
-              that.$t("common.socialAccount") +
-              authUser.nickname +
-              that.$t("common.socialTips"),
-              that.$t("common.tips"),
-              {
-                confirmButtonText: that.$t("common.signLogin"),
-                cancelButtonText: that.$t("common.bindLogin"),
-                type: "warning"
-              }
-            )
-            .then(() => {
-              that.tabActiveName = "signLogin";
-            })
-            .catch(() => {
-              that.tabActiveName = "bindLogin";
-            });
-        } else if (data.message === "social_login_success") {
-          that.saveLoginData(data.data);
-          that.getUserDetailInfo();
-          that.loginSuccessCallback(data.account);
-        } else {
-          // do nothing
-        }
-      },
-      bindLogin() {
-        let account_c = false;
-        let password_c = false;
-        this.$refs.loginForm.validateField("bindAccount", e => {
-          if (!e) {
-            account_c = true;
-          }
-        });
-        this.$refs.loginForm.validateField("bindPassword", e => {
-          if (!e) {
-            password_c = true;
-          }
-        });
-        if (account_c && password_c) {
-          this.loading = true;
-          const that = this;
-          const params = {
-            bindAccount: that.loginForm.bindAccount,
-            bindPassword: that.loginForm.bindPassword,
-            ...that.authUser
-          };
-          params.token = null;
-          that
-            .$post("auth/social/bind/login", params)
-            .then(r => {
-              const data = r.data.data;
-              this.saveLoginData(data);
-              this.getUserDetailInfo();
-              this.loginSuccessCallback(that.loginForm.bindAccount);
-            })
-            .catch(error => {
-              console.error(error);
-              that.loading = false;
-            });
-        }
-      },
-      signLogin() {
-        let account_c = false;
-        let password_c = false;
-        this.$refs.loginForm.validateField("signAccount", e => {
-          if (!e) {
-            account_c = true;
-          }
-        });
-        this.$refs.loginForm.validateField("signPassword", e => {
-          if (!e) {
-            password_c = true;
-          }
-        });
-        if (account_c && password_c) {
-          this.loading = true;
-          const that = this;
-          const params = {
-            bindAccount: that.loginForm.signAccount,
-            bindPassword: that.loginForm.signPassword,
-            ...that.authUser
-          };
-          params.token = null;
-          that
-            .$post("auth/social/sign/login", params)
-            .then(r => {
-              const data = r.data.data;
-              this.saveLoginData(data);
-              this.getUserDetailInfo();
-              this.loginSuccessCallback(that.loginForm.signAccount);
-            })
-            .catch(error => {
-              console.error(error);
-              that.loading = false;
-            });
-        }
-      },
-      handleLogin() {
-        this.loginForm.tenant = `${Base64.encode(this.loginForm.tenantView)}`;
-        this.$refs.loginForm.validate((valid) => {
-          if (valid) {
-            this.loginSubmit();
-          } else {
-            return false
-          }
-        })
-      },
-      loginSubmit() {
-        this.loading = true;
-        const that = this;
-        this.$store.commit("account/setTenant", this.loginForm.tenant);
-        loginApi.login(this.loginForm).then(response => {
-          const res = response.data;
-          if (res.isSuccess) {
-            that.saveLoginData(res.data['token'], res.data['refreshToken'], res.data['expiration']);
-            that.saveUserInfo(res.data);
-            that.getResource();
-          } else {
-            that.getCodeImage();
-          }
-        }).finally(() => that.loading = false);
-      },
-      saveLoginData(token, refreshToken, expiration) {
-        this.$store.commit("account/setToken", token);
-        this.$store.commit("account/setRefreshToken", refreshToken);
-        this.$store.commit("account/setExpireTime", expiration);
-      },
-      saveUserInfo(user) {
-        this.$store.commit("account/setUser", {
-          id: user.userId,
-          account: user.account,
-          name: user.name,
-          avatar: user.avatar,
-          workDescribe: user.workDescribe
-        });
-      },
-      getResource() {
-        oauthApi.getResource().then(response => {
-          const res = response.data;
-          if (res.isSuccess) {
-            const permissionsList = res.data;
-            this.$store.commit("account/setPermissions", permissionsList ? permissionsList : []);
-
-            this.loginSuccess();
-          } else {
-            this.getCodeImage();
-          }
-        });
-      },
-      loginSuccess() {
-        this.$message({
-          message: this.$t("tips.loginSuccess"),
-          type: "success"
-        });
-        this.$router.push("/");
-      },
-      loginSuccessCallback(user) {
-        console.log(user);
-      },
-
-      qcodelogin() {
-        this.loading = true;
-        const that = this;
-        this.loginForm.tenant = `${Base64.encode(this.loginForm.tenantView)}`;
-        this.$store.commit("account/setTenant", this.loginForm.tenant);
-        this.loginForm.grantType="password";
-        loginApi.qcodelogin(this.loginForm).then(response => {
-          const res = response.data;
-          if (res.isSuccess) {
-            that.saveLoginData(res.data['token'], res.data['refreshToken'], res.data['expiration']);
-            that.saveUserInfo(res.data);
-            that.getResource();
-          } else {
-            that.getCodeImage();
-          }
-        }).finally(() => that.loading = false);
-      },
-
-      showQcodeUser(){
-        console.log(this.loginForm.qcodeUser.substr(this.loginForm.qcodeUser.length-1,1));
-        if(this.loginForm.qcodeUser.substr(this.loginForm.qcodeUser.length-1,1) == "#"){
-            this.qcodelogin()
-        }
-      }
-    }
-  };
-</script>
-<style lang="scss">
-	.login-form {
-		.el-tabs__item {
-			font-size: 16px;
-			color: white;
-		}
-		.el-tabs__item.is-active {
-			color: #1890ff;
-		}
-		.el-tabs__active-bar {
-			background: none;
-		}
-	}
-</style>
-<style lang="scss" scoped>
-  $bg: #2d3a4b;
-  $dark_gray: #aaa;
-  $light_gray: #eee;
-
-  .login-container {
-  	/*background: url(../../assets/logo/loginBg.gif) 50% no-repeat;
-    background-size: cover;*/
-    /*background: url(../../assets/background.jpg) 50% no-repeat;*/
-   	/*background: url(../../assets/logo/logoBg1.jpg) 50% no-repeat;*/
-   	/*background: url(../../assets/logo/logoBg2.png) 50% no-repeat;
-    background-size: cover;*/
-   	background: #000000;
-
-    width: 100%;
-    height: 100vh;
-		.saomaDom {
-			text-align: center;
-			color: white;
-			cursor: pointer;
-		}
-    .login-info {
-    	display: flex;
-    	align-items: center;
-      position: absolute;
-      left: 10%;
-      top: 44%;
-      margin-top: -100px;
-      color: #fff;
-
-			img{
-				width: 300px;
-				margin-right: 40px;
-			}
-      .title {
-        font-size: 1.8rem;
-        font-weight: 600;
-      }
-			.title:first-child{
-				margin-bottom: 15px;
-			}
-      .sub-title {
-        font-size: 1.5rem;
-        margin: 0.3rem 0 0.7rem 1rem;
-      }
-
-      .desc {
-        font-size: 0.96rem;
-        line-height: 1.9rem;
-      }
-    }
-
-    .login-form {
-      position: absolute;
-      top: 45%;
-      left: 70%;
-      margin: -180px 0 0 -160px;
-      width: 320px;
-      height: 440px;
-      padding: 10px 36px 36px 36px;
-      background: #4F535B;
-      border-radius: 3px;
-			
-			.el-tabs__item {
-				font-size: 16px;
-			}
-      .code-input {
-        width: 50%;
-        display: inline-block;
-        vertical-align: middle;
-      }
-
-      .code-image {
-        display: inline-block;
-        vertical-align: top;
-        cursor: pointer;
-      }
-
-      .login-type {
-        text-align: right;
-        display: inline-block;
-        width: 100%;
-      }
-
-      .logo-wrapper {
-        display: inline-block;
-        margin: 10px 0;
-
-        img {
-          width: 1.9rem;
-          display: inline-block;
-          margin: 0.8rem 0.8rem -0.8rem 0.8rem;
-          cursor: pointer;
-
-          &.radius {
-            border-radius: 50%;
-          }
-        }
-      }
-    }
-
-    .login-footer {
-      position: fixed;
-      bottom: 1rem;
-      width: 100%;
-      text-align: center;
-      color: white;
-      font-size: 0.85rem;
-      line-height: 1rem;
-      height: 1rem;
-    }
-
-    .tips {
-      font-size: 14px;
-      color: #fff;
-      margin-bottom: 10px;
-
-      span {
-        &:first-of-type {
-          margin-right: 16px;
-        }
-      }
-    }
-
-    .title-container {
-      position: relative;
-
-      .title {
-        font-size: 20px;
-        color: #FFFFFF;
-        margin: 0 auto 40px auto;
-        text-align: center;
-        font-weight: bold;
-      }
-
-      .set-language {
-        color: #aaa;
-        position: absolute;
-        top: 3px;
-        font-size: 18px;
-        right: 0;
-        cursor: pointer;
-      }
-    }
-
-    .thirdparty-button {
-      position: absolute;
-      right: 0;
-      bottom: 6px;
-    }
-
-    @media only screen and (max-width: 470px) {
-      .thirdparty-button {
-        display: none;
-      }
-    }
-
-    @media screen and (max-width: 1100px) {
-      .login-info {
-        left: 8%;
-      }
-    }
-
-    @media screen and (max-width: 970px) {
-      .login-form {
-        left: 50%;
-      }
-      .login-info {
-        display: none;
-      }
-    }
-  }
-</style>
+<template>
+  <div class="login-container">
+    <div class="login-info">
+    	<img :src="require(`@/assets/logo/logo1.png`)"/>
+    	<div>
+	    	<div class="title">{{$t('login.shuoming.title')}}</div>
+	      <div class="title">{{$t('login.shuoming.tips')}}</div>
+      </div>
+    </div>
+    <el-form
+      :model="loginForm"
+      :rules="rules"
+      autocomplete="off"
+      class="login-form"
+      label-position="left"
+      ref="loginForm"
+    >
+	    <el-tabs v-model="activeName" @tab-click="handleClick">
+		    <el-tab-pane label="扫码登录" name="first">
+		    	<div class="saomaDom">
+		    		<img :src="require(`@/assets/logo/saoma.png`)"/>
+		    		<div>请扫码登录<el-input id="qcodeUser" name="qcodeUser" v-model="loginForm.qcodeUser" type="hidden" onfocus=""  @input="showQcodeUser()"/></div>
+		    	</div>
+		    </el-tab-pane>
+		    <el-tab-pane label="密码登录" name="second">
+		      <div class="title-container">
+		        <h3 class="title">{{$t('login.title')}}</h3>
+		        <lang-select class="set-language"/>
+		      </div>
+		      <span v-if="login.type === 'up'">
+		        <el-form-item prop="tenant" v-show="isMultiTenant">
+		          <el-input
+		            :placeholder="$t('login.tenant')"
+		            @keyup.enter.native="handleLogin"
+		            autocomplete="off"
+		            name="tenantView"
+		            prefix-icon="el-icon-user"
+		            ref="tenant"
+		            type="text"
+		            v-model="loginForm.tenantView"
+		          />
+		        </el-form-item>
+		        <el-form-item prop="account">
+		          <el-input
+		            :placeholder="$t('login.username')"
+		            @keyup.enter.native="handleLogin"
+		            autocomplete="off"
+		            name="account"
+		            prefix-icon="el-icon-user"
+		            ref="account"
+		            type="text"
+		            v-model="loginForm.account"
+		          />
+		        </el-form-item>
+		        <el-form-item prop="password">
+		          <el-input
+		            :placeholder="$t('login.password')"
+		            :show-password="true"
+		            @keyup.enter.native="handleLogin"
+		            autocomplete="off"
+		            name="password"
+		            prefix-icon="el-icon-key"
+		            ref="password"
+		            type="password"
+		            v-model="loginForm.password"
+		          />
+		        </el-form-item>
+		        <el-form-item class="code-input" prop="code" v-show="isCaptcha">
+		          <el-input
+		            :placeholder="$t('login.code')"
+		            @keyup.enter.native="handleLogin"
+		            autocomplete="off"
+		            name="code"
+		            prefix-icon="el-icon-lock"
+		            ref="code"
+		            style="width: 70%"
+		            type="text"
+		            v-model="loginForm.code"
+		          />
+		        </el-form-item>
+		        <img
+		          v-show="isCaptcha"
+		          :src="imageCode"
+		          @click="getCodeImage"
+		          alt="codeImage"
+		          class="code-image"
+		        />
+		        <el-button
+		          :loading="loading"
+		          @click.native.prevent="handleLogin"
+		          style="width:100%;margin-bottom:14px;"
+		          type="primary"
+		        >{{ $t("login.logIn") }}</el-button
+		        >
+		      </span>
+		      <span v-if="login.type === 'social'">
+		        {{ $t("login.chooseToSignIn") }}
+		        <div>
+		          <template v-for="(l, index) in logo">
+		            <div :key="index" class="logo-wrapper">
+		              <img
+		                :class="{ radius: l.radius }"
+		                :src="resolveLogo(l.img)"
+		                @click="socialLogin(l.name)"
+		                alt
+		              />
+		            </div>
+		          </template>
+		        </div>
+		      </span>
+		      <span style="margin-top: -1rem" v-if="login.type === 'bind'">
+		        <el-tabs @tab-click="handleTabClick" v-model="tabActiveName">
+		          <el-tab-pane :label="$t('common.bindLogin')" name="bindLogin">
+		            <el-form-item prop="bindAccount">
+		              <el-input
+		                :placeholder="$t('login.account')"
+		                autocomplete="off"
+		                name="bindAccount"
+		                prefix-icon="el-icon-user"
+		                ref="bindAccount"
+		                type="text"
+		                v-model="loginForm.bindAccount"
+		              />
+		            </el-form-item>
+		            <el-form-item prop="bindPassword">
+		              <el-input
+		                :placeholder="$t('login.password')"
+		                :show-password="true"
+		                autocomplete="off"
+		                name="bindPassword"
+		                prefix-icon="el-icon-key"
+		                ref="bindPassword"
+		                type="password"
+		                v-model="loginForm.bindPassword"
+		              />
+		            </el-form-item>
+		            <el-button
+		              :loading="loading"
+		              @click.native.prevent="bindLogin"
+		              style="width:100%;margin-bottom:14px;"
+		              type="primary"
+		            >{{ $t("common.bindLogin") }}</el-button
+		            >
+		          </el-tab-pane>
+		          <el-tab-pane :label="$t('common.signLogin')" name="signLogin">
+		            <el-form-item prop="signAccount">
+		              <el-input
+		                :placeholder="$t('login.account')"
+		                autocomplete="off"
+		                name="signAccount"
+		                prefix-icon="el-icon-user"
+		                ref="signAccount"
+		                type="text"
+		                v-model="loginForm.signAccount"
+		              />
+		            </el-form-item>
+		            <el-form-item prop="signPassword">
+		              <el-input
+		                :placeholder="$t('login.password')"
+		                :show-password="true"
+		                autocomplete="off"
+		                name="signPassword"
+		                prefix-icon="el-icon-key"
+		                ref="signPassword"
+		                type="password"
+		                v-model="loginForm.signPassword"
+		              />
+		            </el-form-item>
+		            <el-button
+		              :loading="loading"
+		              @click.native.prevent="signLogin"
+		              style="width:100%;margin-bottom:14px;"
+		              type="primary"
+		            >{{ $t("common.signLogin") }}</el-button
+		            >
+		          </el-tab-pane>
+		        </el-tabs>
+		      </span>
+		      <!--<el-dropdown class="login-type" placement="top-end">
+		        <span class="el-dropdown-link">
+		          <el-link type="primary">{{ $t("login.ortherLoginType") }}</el-link>
+		        </span>
+		        <el-dropdown-menu slot="dropdown">
+		          <el-dropdown-item
+		            :disabled="login.type === 'up'"
+		            @click.native="login.type = 'up'"
+		          >{{ $t("login.type.up") }}
+		          </el-dropdown-item
+		          >
+		          <el-dropdown-item
+		            :disabled="login.type === 'social'"
+		            @click.native="login.type = 'social'"
+		          >{{ $t("login.type.social") }}
+		          </el-dropdown-item
+		          >
+		        </el-dropdown-menu>
+		      </el-dropdown>-->
+		    </el-tab-pane>
+		  </el-tabs>
+    </el-form>
+    <span class="login-footer">
+      © 2019 - 2020
+      <span>{{$t('login.shuoming.tips')}}</span>
+    </span>
+  </div>
+</template>
+
+<script>
+  import LangSelect from "@/components/LangSelect";
+  import db from "@/utils/localstorage";
+  import {randomNum} from "@/utils";
+  import {socialLoginUrl} from "@/settings";
+  import loginApi from "@/api/Login.js";
+  import oauthApi from '@/api/Oauth'
+  import {Base64} from 'js-base64';
+
+  export default {
+    name: "Login",
+    components: {LangSelect},
+    data() {
+      return {
+      	activeName: 'first',
+        //是否启用多租户
+        isMultiTenant:
+          process.env.VUE_APP_IS_MULTI_TENANT === "true" ? true : false,
+        isCaptcha:
+          process.env.VUE_APP_IS_CAPTCHA === "true" ? true : false,
+        tabActiveName: "bindLogin",
+        login: {
+          type: "up"
+        },
+        logo: [
+          {img: "gitee.png", name: "gitee", radius: true},
+          {img: "github.png", name: "github", radius: true},
+          {img: "tencent_cloud.png", name: "tencent_cloud", radius: true},
+          {img: "qq.png", name: "qq", radius: false},
+          {img: "dingtalk.png", name: "dingtalk", radius: true},
+          {img: "microsoft.png", name: "microsoft", radius: false}
+        ],
+        loginForm: {
+          account: "zuihou",
+          password: "",   // zuihou
+          tenantView: "0000", //显示用的
+          tenant: "", //传递给后端的
+          key: randomNum(24, 16),
+          code: "",
+          grantType: process.env.VUE_APP_IS_CAPTCHA === "true" ? "captcha" : "password",
+          bindAccount: "",
+          bindPassword: "",
+          signAccount: "",
+          signPassword: "",
+          qcodeUser: ""
+        },
+        rules: {
+          account: {
+            required: true,
+            message: this.$t("rules.require"),
+            trigger: "blur"
+          },
+          tenantView: {
+            required: true,
+            message: this.$t("rules.require"),
+            trigger: "blur"
+          },
+          password: {
+            required: true,
+            message: this.$t("rules.require"),
+            trigger: "blur"
+          },
+          code: {
+            validator: (rule, value, callback) => {
+              if (this.isCaptcha && value === '') {
+                callback(this.$t("rules.require"))
+              } else {
+                callback()
+              }
+              callback()
+            }, trigger: 'blur'
+          },
+          bindAccount: {
+            required: true,
+            message: this.$t("rules.require"),
+            trigger: "blur"
+          },
+          bindPassword: {
+            required: true,
+            message: this.$t("rules.require"),
+            trigger: "blur"
+          },
+          signAccount: [
+            {
+              required: true,
+              message: this.$t("rules.require"),
+              trigger: "blur"
+            },
+            {
+              min: 4,
+              max: 10,
+              message: this.$t("rules.range4to10"),
+              trigger: "blur"
+            }
+          ],
+          signPassword: [
+            {
+              required: true,
+              message: this.$t("rules.require"),
+              trigger: "blur"
+            },
+            {
+              min: 6,
+              max: 20,
+              message: this.$t("rules.range6to20"),
+              trigger: "blur"
+            }
+          ]
+        },
+        authUser: null,
+        loading: false,
+        showDialog: false,
+        redirect: undefined,
+        otherQuery: {},
+        imageCode: "",
+        page: {
+          width: window.screen.width * 0.5,
+          height: window.screen.height * 0.5
+        }
+      };
+    },
+    created() {
+    },
+    mounted() {
+      db.clear();
+      this.getCodeImage();
+      this.$nextTick(
+        window.onload = function () { // 光标默认位置
+            var oInput = document.getElementById('qcodeUser');
+            oInput.focus();
+        }
+      )
+    },
+    destroyed() {
+      window.removeEventListener("message", this.resolveSocialLogin);
+    },
+    methods: {
+    	// Tabs切换-事件
+    	handleClick(tab, event) {
+        console.log(tab, event);
+      },
+
+      getCodeImage() {
+        loginApi
+          .getCaptcha(this.loginForm.key)
+          .then(response => {
+            const res = response.data;
+            if (res.byteLength <= 100) {
+              this.$message({
+                message: this.$t("tips.systemError"),
+                type: "error"
+              });
+            }
+            return (
+              "data:image/png;base64," +
+              btoa(
+                new Uint8Array(res).reduce(
+                  (data, byte) => data + String.fromCharCode(byte),
+                  ""
+                )
+              )
+            );
+          })
+          .then(res => {
+            this.imageCode = res;
+          })
+          .catch(e => {
+            if (e.toString().indexOf("429") !== -1) {
+              this.$message({
+                message: this.$t("tips.tooManyRequest"),
+                type: "error"
+              });
+            } else {
+              this.$message({
+                message: this.$t("tips.getCodeImageFailed"),
+                type: "error"
+              });
+            }
+          });
+      },
+      handleTabClick(tab) {
+        this.tabActiveName = tab.name;
+      },
+      resolveLogo(logo) {
+        return require(`@/assets/logo/${logo}`);
+      },
+      socialLogin(oauthType) {
+        const url = `${socialLoginUrl}/${oauthType}/login`;
+        window.open(
+          url,
+          "newWindow",
+          `resizable=yes, height=${this.page.height}, width=${this.page.width}, top=10%, left=10%, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no`
+        );
+        window.addEventListener("message", this.resolveSocialLogin, false);
+      },
+      resolveSocialLogin(e) {
+        const data = e.data;
+        const that = this;
+        if (data.message === "not_bind") {
+          that.login.type = "bind";
+          const authUser = data.data;
+          that.authUser = authUser;
+          that
+            .$confirm(
+              that.$t("common.current") +
+              authUser.source +
+              that.$t("common.socialAccount") +
+              authUser.nickname +
+              that.$t("common.socialTips"),
+              that.$t("common.tips"),
+              {
+                confirmButtonText: that.$t("common.signLogin"),
+                cancelButtonText: that.$t("common.bindLogin"),
+                type: "warning"
+              }
+            )
+            .then(() => {
+              that.tabActiveName = "signLogin";
+            })
+            .catch(() => {
+              that.tabActiveName = "bindLogin";
+            });
+        } else if (data.message === "social_login_success") {
+          that.saveLoginData(data.data);
+          that.getUserDetailInfo();
+          that.loginSuccessCallback(data.account);
+        } else {
+          // do nothing
+        }
+      },
+      bindLogin() {
+        let account_c = false;
+        let password_c = false;
+        this.$refs.loginForm.validateField("bindAccount", e => {
+          if (!e) {
+            account_c = true;
+          }
+        });
+        this.$refs.loginForm.validateField("bindPassword", e => {
+          if (!e) {
+            password_c = true;
+          }
+        });
+        if (account_c && password_c) {
+          this.loading = true;
+          const that = this;
+          const params = {
+            bindAccount: that.loginForm.bindAccount,
+            bindPassword: that.loginForm.bindPassword,
+            ...that.authUser
+          };
+          params.token = null;
+          that
+            .$post("auth/social/bind/login", params)
+            .then(r => {
+              const data = r.data.data;
+              this.saveLoginData(data);
+              this.getUserDetailInfo();
+              this.loginSuccessCallback(that.loginForm.bindAccount);
+            })
+            .catch(error => {
+              console.error(error);
+              that.loading = false;
+            });
+        }
+      },
+      signLogin() {
+        let account_c = false;
+        let password_c = false;
+        this.$refs.loginForm.validateField("signAccount", e => {
+          if (!e) {
+            account_c = true;
+          }
+        });
+        this.$refs.loginForm.validateField("signPassword", e => {
+          if (!e) {
+            password_c = true;
+          }
+        });
+        if (account_c && password_c) {
+          this.loading = true;
+          const that = this;
+          const params = {
+            bindAccount: that.loginForm.signAccount,
+            bindPassword: that.loginForm.signPassword,
+            ...that.authUser
+          };
+          params.token = null;
+          that
+            .$post("auth/social/sign/login", params)
+            .then(r => {
+              const data = r.data.data;
+              this.saveLoginData(data);
+              this.getUserDetailInfo();
+              this.loginSuccessCallback(that.loginForm.signAccount);
+            })
+            .catch(error => {
+              console.error(error);
+              that.loading = false;
+            });
+        }
+      },
+      handleLogin() {
+        this.loginForm.tenant = `${Base64.encode(this.loginForm.tenantView)}`;
+        this.$refs.loginForm.validate((valid) => {
+          if (valid) {
+            this.loginSubmit();
+          } else {
+            return false
+          }
+        })
+      },
+      loginSubmit() {
+        this.loading = true;
+        const that = this;
+        this.$store.commit("account/setTenant", this.loginForm.tenant);
+        loginApi.login(this.loginForm).then(response => {
+          const res = response.data;
+          if (res.isSuccess) {
+            that.saveLoginData(res.data['token'], res.data['refreshToken'], res.data['expiration']);
+            that.saveUserInfo(res.data);
+            that.getResource();
+          } else {
+            that.getCodeImage();
+          }
+        }).finally(() => that.loading = false);
+      },
+      saveLoginData(token, refreshToken, expiration) {
+        this.$store.commit("account/setToken", token);
+        this.$store.commit("account/setRefreshToken", refreshToken);
+        this.$store.commit("account/setExpireTime", expiration);
+      },
+      saveUserInfo(user) {
+        this.$store.commit("account/setUser", {
+          id: user.userId,
+          account: user.account,
+          name: user.name,
+          avatar: user.avatar,
+          workDescribe: user.workDescribe
+        });
+      },
+      getResource() {
+        oauthApi.getResource().then(response => {
+          const res = response.data;
+          if (res.isSuccess) {
+            const permissionsList = res.data;
+            this.$store.commit("account/setPermissions", permissionsList ? permissionsList : []);
+
+            this.loginSuccess();
+          } else {
+            this.getCodeImage();
+          }
+        });
+      },
+      loginSuccess() {
+        this.$message({
+          message: this.$t("tips.loginSuccess"),
+          type: "success"
+        });
+        this.$router.push("/");
+      },
+      loginSuccessCallback(user) {
+        console.log(user);
+      },
+
+      qcodelogin() {
+        this.loading = true;
+        const that = this;
+        this.loginForm.tenant = `${Base64.encode(this.loginForm.tenantView)}`;
+        this.$store.commit("account/setTenant", this.loginForm.tenant);
+        this.loginForm.grantType="password";
+        loginApi.qcodelogin(this.loginForm).then(response => {
+          const res = response.data;
+          if (res.isSuccess) {
+            that.saveLoginData(res.data['token'], res.data['refreshToken'], res.data['expiration']);
+            that.saveUserInfo(res.data);
+            that.getResource();
+          } else {
+            that.getCodeImage();
+          }
+        }).finally(() => that.loading = false);
+      },
+
+      showQcodeUser(){
+        console.log(this.loginForm.qcodeUser.substr(this.loginForm.qcodeUser.length-1,1));
+        if(this.loginForm.qcodeUser.substr(this.loginForm.qcodeUser.length-1,1) == "#"){
+            this.qcodelogin()
+        }
+      }
+    }
+  };
+</script>
+<style lang="scss">
+	.login-form {
+		.el-tabs__item {
+			font-size: 16px;
+			color: white;
+		}
+		.el-tabs__item.is-active {
+			color: #1890ff;
+		}
+		.el-tabs__active-bar {
+			background: none;
+		}
+	}
+</style>
+<style lang="scss" scoped>
+  $bg: #2d3a4b;
+  $dark_gray: #aaa;
+  $light_gray: #eee;
+
+  .login-container {
+  	/*background: url(../../assets/logo/loginBg.gif) 50% no-repeat;
+    background-size: cover;*/
+    /*background: url(../../assets/background.jpg) 50% no-repeat;*/
+   	/*background: url(../../assets/logo/logoBg1.jpg) 50% no-repeat;*/
+   	/*background: url(../../assets/logo/logoBg2.png) 50% no-repeat;
+    background-size: cover;*/
+   	background: #000000;
+
+    width: 100%;
+    height: 100vh;
+		.saomaDom {
+			text-align: center;
+			color: white;
+			cursor: pointer;
+		}
+    .login-info {
+    	display: flex;
+    	align-items: center;
+      position: absolute;
+      left: 10%;
+      top: 44%;
+      margin-top: -100px;
+      color: #fff;
+
+			img{
+				width: 300px;
+				margin-right: 40px;
+			}
+      .title {
+        font-size: 1.8rem;
+        font-weight: 600;
+      }
+			.title:first-child{
+				margin-bottom: 15px;
+			}
+      .sub-title {
+        font-size: 1.5rem;
+        margin: 0.3rem 0 0.7rem 1rem;
+      }
+
+      .desc {
+        font-size: 0.96rem;
+        line-height: 1.9rem;
+      }
+    }
+
+    .login-form {
+      position: absolute;
+      top: 45%;
+      left: 70%;
+      margin: -180px 0 0 -160px;
+      width: 320px;
+      height: 440px;
+      padding: 10px 36px 36px 36px;
+      background: #4F535B;
+      border-radius: 3px;
+
+			.el-tabs__item {
+				font-size: 16px;
+			}
+      .code-input {
+        width: 50%;
+        display: inline-block;
+        vertical-align: middle;
+      }
+
+      .code-image {
+        display: inline-block;
+        vertical-align: top;
+        cursor: pointer;
+      }
+
+      .login-type {
+        text-align: right;
+        display: inline-block;
+        width: 100%;
+      }
+
+      .logo-wrapper {
+        display: inline-block;
+        margin: 10px 0;
+
+        img {
+          width: 1.9rem;
+          display: inline-block;
+          margin: 0.8rem 0.8rem -0.8rem 0.8rem;
+          cursor: pointer;
+
+          &.radius {
+            border-radius: 50%;
+          }
+        }
+      }
+    }
+
+    .login-footer {
+      position: fixed;
+      bottom: 1rem;
+      width: 100%;
+      text-align: center;
+      color: white;
+      font-size: 0.85rem;
+      line-height: 1rem;
+      height: 1rem;
+    }
+
+    .tips {
+      font-size: 14px;
+      color: #fff;
+      margin-bottom: 10px;
+
+      span {
+        &:first-of-type {
+          margin-right: 16px;
+        }
+      }
+    }
+
+    .title-container {
+      position: relative;
+
+      .title {
+        font-size: 20px;
+        color: #FFFFFF;
+        margin: 0 auto 40px auto;
+        text-align: center;
+        font-weight: bold;
+      }
+
+      .set-language {
+        color: #aaa;
+        position: absolute;
+        top: 3px;
+        font-size: 18px;
+        right: 0;
+        cursor: pointer;
+      }
+    }
+
+    .thirdparty-button {
+      position: absolute;
+      right: 0;
+      bottom: 6px;
+    }
+
+    @media only screen and (max-width: 470px) {
+      .thirdparty-button {
+        display: none;
+      }
+    }
+
+    @media screen and (max-width: 1100px) {
+      .login-info {
+        left: 8%;
+      }
+    }
+
+    @media screen and (max-width: 970px) {
+      .login-form {
+        left: 50%;
+      }
+      .login-info {
+        display: none;
+      }
+    }
+  }
+</style>

+ 534 - 534
imcs-ui/src/views/zuihou/classScheduleMgr/shiftChangeMgr/Index.vue

@@ -1,534 +1,534 @@
-<template>
-  <div class="app-container">
-		<!-- 搜索模块 -->
-    <div class="filter-container">
-    	<span>
-    		<span>{{$t("calssSchedule.searchForm.applyName")}}:</span>
-    		<el-input v-model="queryParams.model.name" :placeholder='$t("common.pleaseEnter")' style="width: 150px;" size="medium"/>
-    	</span>
-    	<span style="margin-left: 15px;">
-    		<span>{{$t("calssSchedule.searchForm.applyTime")}}:</span>
-    		<el-date-picker
-		      v-model="queryParams.timeRange"
-		      type="daterange"
-		      :picker-options="pickerOptions"
-		      :range-separator='$t("common.separator")'
-		      :start-placeholder='$t("common.startTime")'
-		      :end-placeholder='$t("common.endTime")'
-		      format="yyyy-MM-dd"
-			    value-format="yyyy-MM-dd"
-		      align="right">
-		    </el-date-picker>
-    	</span>
-    	<span style="margin-left: 15px;">
-    		<span>{{$t("calssSchedule.searchForm.audioStatus")}}:</span>
-    		<el-select v-model="queryParams.model.status" :placeholder='$t("common.pleaseSelect")' size="medium" style="width: 150px;">
-        	<el-option
-			      v-for="item in audioStatus"
-			      :key="item.value"
-			      :label="item.label"
-			      :value="item.value">
-			    </el-option>
-      	</el-select>
-    	</span>
-      <span style="margin-left: 15px;">
-	      <el-button plain type="primary" icon="el-icon-search" size="medium" @click="search">
-	        {{ $t("table.search") }}
-	      </el-button>
-	      <el-button plain type="warning" icon="el-icon-refresh" size="medium" @click="reset">
-	        {{ $t("table.reset") }}
-	      </el-button>
-      </span>
-    </div>
-
-    <!-- 功能按钮 -->
-    <el-row class="filter-container">
-    	<el-col>
-    		<el-button v-has-permission="['shiftChange:add']" type="primary" icon="el-icon-plus" size="medium" @click="add">{{ $t("common.add") }}</el-button>
-	      <el-button v-has-permission="['shiftChange:update']" type="success" icon="el-icon-edit" size="medium" @click="editOne">
-	        {{ $t("common.edit") }}
-	      </el-button>
-	      <el-button v-has-permission="['shiftChange:delete']" type="danger" icon="el-icon-delete" size="medium" @click="batchDelete">
-	        {{ $t("table.delete") }}
-	      </el-button>
-        <el-button v-has-permission="['shiftChange:pushaudit']" type="primary" icon="el-icon-thumb" size="medium" @click="updateStatus('1')">{{$t("common.audio.addAudio")}}</el-button>
-        <el-button v-has-permission="['shiftChange:audit']" type="primary" icon="el-icon-suitcase" size="medium" @click="audioBtn()">{{$t("common.audio.audio")}}</el-button>
-    	</el-col>
-    </el-row>
-
-		<!-- 列表数据 -->
-    <el-table
-      :key="tableKey"
-      ref="table"
-      v-loading="loading"
-      :data="tableData.records"
-      border
-      fit
-      row-key="id"
-      style="width: 100%;"
-      @selection-change="onSelectChange"
-      @cell-click="cellClick"
-    >
-    	<el-table-column :label='$t("common.serialNo")' width="55px" align="center">
-	      <template slot-scope="scope">
-	        <div>
-	          {{scope.$index+(queryParams.current - 1) * queryParams.size + 1}}
-	        </div>
-	      </template>
-      </el-table-column>
-      <el-table-column align="center" type="selection" width="50" :reserve-selection="true" />
-      <el-table-column prop="applyDesc" :label='$t("calssSchedule.table.staffChange.auditUser")' :show-overflow-tooltip="true" width="180px"></el-table-column>
-      <el-table-column prop="applyTime" :label='$t("calssSchedule.table.staffChange.applyTime")' :show-overflow-tooltip="true" width="180px"></el-table-column>
-      <el-table-column prop="applyDictionary" :label='$t("calssSchedule.table.staffChange.model")' :show-overflow-tooltip="true" width="180px"></el-table-column>
-      <el-table-column prop="changeDesc" :label='$t("calssSchedule.table.staffChange.hours")' :show-overflow-tooltip="true" width="180px"></el-table-column>
-      <el-table-column prop="changeTime" :label='$t("calssSchedule.table.staffChange.changeTime")' :show-overflow-tooltip="true" width="180px"></el-table-column>
-      <el-table-column prop="changeDictionary" :label='$t("calssSchedule.table.staffChange.remark")' :show-overflow-tooltip="true" width="180px"></el-table-column>
-      <el-table-column prop="auditStatus" :label='$t("calssSchedule.table.staffChange.auditStatus")' align="center" width="90px">
-      	<template slot-scope="{ row }">
-          <el-tag :type="tags[row.auditStatus]">
-          	{{audioStatus[parseInt(row.auditStatus)+1].label}}
-          </el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column prop="createTime" :label='$t("calssSchedule.table.staffChange.createTime")' :show-overflow-tooltip="true" width="180px"></el-table-column>
-      <el-table-column prop="auditTime" :label='$t("calssSchedule.table.staffChange.statusTime")' width="180px"></el-table-column>
-      <el-table-column
-        :label="$t('table.operation')"
-        fixed="right"
-        align="center"
-        column-key="operation"
-        width="100px"
-      >
-        <template slot-scope="{ row }">
-        	<!--<el-tooltip class="item" content="查看详情" effect="dark" placement="top-start">
-	          <i
-	            class="el-icon-view table-operation"
-	            style="color: #87d068;"
-	            @click="view(row)"
-	          />
-          </el-tooltip>-->
-          <el-tooltip class="item" :content='$t("common.edit")' effect="dark" placement="top-start">
-	          <i
-	            class="el-icon-edit table-operation"
-	            style="color: #2db7f5;"
-	            @click="edit(row)"
-	          />
-          </el-tooltip>
-          <el-tooltip class="item" :content='$t("common.delete")' effect="dark" placement="top-start">
-	          <i
-	            class="el-icon-delete table-operation"
-	            style="color: #f50;"
-	            @click="singleDelete(row)"
-	          />
-          </el-tooltip>
-        </template>
-      </el-table-column>
-    </el-table>
-    <pagination
-      v-show="tableData.total > 0"
-      :limit.sync="queryParams.size"
-      :page.sync="queryParams.current"
-      :total="Number(tableData.total)"
-      @pagination="fetch"
-    />
-    <tenant-edit
-      ref="edit"
-      :dialog-visible="dialog.isVisible"
-      :title="dialog.title"
-      @close="editClose"
-      @success="editSuccess"
-    />
-    <tenant-view
-      ref="view"
-      :dialog-visible="tenantViewVisible"
-      @close="viewClose"
-    />
-    <el-dialog
-      v-el-drag-dialog
-      :close-on-click-modal="false"
-      :close-on-press-escape="true"
-      title="预览"
-      width="80%"
-      top="50px"
-      :visible.sync="preview.isVisible"
-    >
-      <el-scrollbar>
-        <div v-html="preview.context" />
-      </el-scrollbar>
-    </el-dialog>
-
-    <el-dialog
-      v-el-drag-dialog
-      :close-on-click-modal="false"
-      :close-on-press-escape="true"
-      :title='$t("common.audio.audio")'
-      width="400px"
-      top="150px"
-      :visible.sync="audioIsVisible"
-    >
-      <template>
-        <el-row>
-          <el-radio v-model="audioVal" label="2">{{$t("common.audio.audioOk")}}</el-radio>
-          <el-radio v-model="audioVal" label="3">{{$t("common.audio.aduioFail")}}</el-radio>
-        </el-row>
-        <el-row style="margin-top: 30px;text-align: center;">
-          <el-button plain type="primary" size="medium" @click="audioOk">
-            {{ $t("common.confirm") }}
-          </el-button>
-          <el-button plain type="danger" size="medium" @click="colseAudio">
-            {{ $t("common.cancel") }}
-          </el-button>
-        </el-row>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-	import Pagination from "@/components/Pagination"
-	import TenantEdit from "./components/Edit"
-	import TenantView from "./components/View"
-	// 【换班管理】-API
-	import shiftChangeMgrApi from "@/api/classScheduleMgr/shiftChangeMgr"
-	import elDragDialog from '@/directive/el-drag-dialog'
-	import {initDicts, initQueryParams } from '@/utils/commons'
-	export default {
-	  name: "ShiftChangeMgr",
-	  directives: { elDragDialog },
-	  components: { Pagination, TenantEdit, TenantView },
-	  props: {
-	  },
-	  data () {
-	    return {
-	    	tags: ['','warning','success','danger'],
-	    	audioStatus: [],
-        audioIsVisible: false,
-        audioVal: '2', //默认【审核通过】
-	      dialog: {
-	        isVisible: false,
-	        title: ""
-	      },
-	      preview: {
-	        isVisible: false,
-	        context: ''
-	      },
-	      tenantViewVisible: false,
-	      tableKey: 0,
-	      queryParams: initQueryParams({}),
-	      selection: [],
-	      loading: false,
-	      tableData: {
-	        total: 0
-	      },
-	      dicts: {
-          NATION: {}
-        },
-	      enums: {
-	        TenantTypeEnum: {},
-	        TenantStatusEnum: {}
-	      },
-	      pickerOptions: {
-          shortcuts: [{
-            text: '最近一周',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-              picker.$emit('pick', [start, end]);
-            }
-          }, {
-            text: '最近一个月',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
-              picker.$emit('pick', [start, end]);
-            }
-          }, {
-            text: '最近三个月',
-            onClick(picker) {
-              const end = new Date();
-              const start = new Date();
-              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
-              picker.$emit('pick', [start, end]);
-            }
-          }]
-        }
-	    }
-	  },
-	  // 实例已经在内存中创建好,此时data和methods已将ok,如果要操作data中的数据或是调用methods中的方法,最早只能在created中操作
-	  created() {
-	  	// 调用常量-审核状态
-	  	this.audioStatus = this.$constWKS.AUDIOLIST
-	  	// 加载【字典】
-	  	initDicts(['NATION'], this.dicts);
-	  	// 加载列表数据
-	  	this.fetch()
-		},
-	  computed: {
-	    currentUser () {
-	      return this.$store.state.account.user
-	    },
-	    nationList() {
-        return convertEnum(this.dicts.NATION)
-      }
-	  },
-	  mounted () {
-
-	  },
-	  methods: {
-	    viewClose () {
-	      this.tenantViewVisible = false
-	    },
-	    editClose () {
-	      this.dialog.isVisible = false
-	    },
-	    editSuccess () {
-	      this.search()
-	    },
-	    onSelectChange (selection) {
-	      this.selection = selection
-	    },
-	    search () {
-	      this.fetch({
-	        ...this.queryParams
-	      })
-	    },
-	    reset () {
-	      this.queryParams = initQueryParams({})
-	      this.$refs.table.clearSort()
-	      this.$refs.table.clearFilter()
-	      this.search()
-	    },
-	    add () {
-	      this.$refs.edit.type = "add"
-	      this.$refs.edit.setTenant(false, this.dicts)
-	      this.dialog.title = this.$t("common.add")
-	      this.dialog.isVisible = true
-	    },
-	    singleDelete (row) {
-	      this.$refs.table.clearSelection()
-	      this.$refs.table.toggleRowSelection(row, true)
-	      this.batchDelete()
-	    },
-	    batchDelete () {
-	      if (!this.selection.length) {
-	        this.$message({
-	          message: this.$t("tips.noDataSelected"),
-	          type: "warning"
-	        })
-	        return
-	      }
-
-	      const readonlyIndex = this.selection.findIndex(item => item.readonly)
-
-	      if (readonlyIndex > -1) {
-	        this.$message({
-	          message: this.$t("tips.systemData"),
-	          type: "warning"
-	        })
-	        return
-	      }
-
-	      this.$confirm(this.$t("calssSchedule.tips.shiftChangeTips"), this.$t("common.tips"), {
-	      	distinguishCancelAndClose: true,
-	        confirmButtonText: this.$t("common.confirm"),
-	        cancelButtonText: this.$t("common.cancel"),
-	        type: "warning"
-	      }).then(() => {
-	      	const ids = []
-		      let contain = false
-		      this.selection.forEach(item => {
-		        if (item.readonly) {
-		          contain = true
-		          return
-		        }
-		        ids.push(item.id)
-		      })
-		      if (contain) {
-		        this.$message({
-		          message: this.$t("tips.systemData"),
-		          type: "warning"
-		        })
-		      } else {
-		        this.delete(ids)
-		      }
-	      }).catch(() => {})
-	    },
-	    clearSelections () {
-	      this.$refs.table.clearSelection()
-	    },
-	    delete (ids) {
-	      shiftChangeMgrApi.delete({'ids': ids}).then(response => {
-	        const res = response.data
-	        if (res.isSuccess) {
-	          this.$message({
-	            message: this.$t("tips.deleteSuccess"),
-	            type: "success"
-	          })
-	          this.search()
-	          // 清理已经删除的数据
-	          this.$refs.table.clearSelection()
-	        }
-	      })
-	    },
-	    view (row) {
-	      this.$refs.view.setTenant(row)
-	      this.tenantViewVisible = true
-	    },
-	    // 【修改】表头上Btn-事件
-	    editOne() {
-	    	if (!this.selection.length) {
-	        this.$message({
-	          message: this.$t("tips.noDataSelected"),
-	          type: "warning"
-	        })
-	        return
-	      }
-	    	if (this.selection.length > 1) {
-	        this.$message({
-	          message: this.$t("tips.mustOne"),
-	          type: "warning"
-	        })
-	        return
-	      }
-	    	this.edit(this.selection[0]);
-	    },
-	    edit (row) {
-	      if (row.readonly) {
-	        this.$message({
-	          message: this.$t("tips.systemData"),
-	          type: "warning"
-	        })
-	        return
-	      }
-	      // 根据换班id查询用户之前的换班的          
-		  this.$refs.edit.type = "edit"
-	      this.$refs.edit.setTenant(row, this.dicts)		        
-	      this.dialog.title = this.$t("common.edit")
-	      this.dialog.isVisible = true
-	    },
-	    fetch (params = {}) {
-	      this.loading = true
-	      if (this.queryParams.timeRange) {
-	        this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
-	        this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
-	      }
-
-	      this.queryParams.current = params.current ? params.current : this.queryParams.current
-	      this.queryParams.size = params.size ? params.size : this.queryParams.size
-	      shiftChangeMgrApi.page(this.queryParams).then(response => {
-	        const res = response.data
-	        if (res.isSuccess) {
-	          this.tableData = res.data
-	        }
-	        // eslint-disable-next-line no-return-assign
-	      }).finally(() => this.loading = false)
-
-	    },
-	    cellClick (row, column) {
-	      if (column['columnKey'] === "operation") {
-	        return
-	      }
-	      let flag = false
-	      this.selection.forEach((item) => {
-	        if (item.id === row.id) {
-	          flag = true
-	          this.$refs.table.toggleRowSelection(row)
-	        }
-	      })
-
-	      if (!flag) {
-	        this.$refs.table.toggleRowSelection(row, true)
-	      }
-	    },
-      // 【提交审核】按钮-事件
-      updateStatus(status){
-          if (!this.selection.length) {
-              this.$message({
-                  message: this.$t("tips.noDataSelected"),
-                  type: "warning"
-              })
-              return
-          }
-          if (this.selection.length > 1) {
-              this.$message({
-                  message: this.$t("tips.mustOne"),
-                  type: "warning"
-              })
-              return
-          }
-          // 调用API
-          this.audio(status)
-      },
-      // 【取消】审核按钮-事件
-      colseAudio(){
-          this.audioIsVisible = false
-      },
-      // 【确定】审核按钮-事件
-      audioOk(){
-          // 调用审核
-          this.audio(false)
-      },
-      // 【审核产品】-按钮事件
-      audioBtn(){
-          if (!this.selection.length) {
-              this.$message({
-                  message: this.$t("tips.noDataSelected"),
-                  type: "warning"
-              })
-              return
-          }
-          if (this.selection.length > 1) {
-              this.$message({
-                  message: this.$t("tips.mustOne"),
-                  type: "warning"
-              })
-              return
-          }
-          this.audioIsVisible = true
-      },
-      // 【审核产品】-Table的Row操作事件
-      audioBtnRow(row) {
-          // 清除所有的选择数据
-          this.$refs.table.clearSelection()
-          // 设置当前行为选中的数据
-          this.$refs.table.toggleRowSelection(row, true)
-          // 弹出审核页面
-          this.audioIsVisible = true
-      },
-      // 【审核通过/审核不通过】接口-事件
-      audio(status){
-          if(!status){
-              status =  this.audioVal
-          }
-          // 赋值
-          this.selection[0].status = status
-          let msg = "提交审核成功!"
-          if(status == "2"){
-              msg = "审核通过!"
-          }
-          if(status == "3"){
-              msg = "审核不通过!"
-          }
-          shiftChangeMgrApi.updateStatus({ id: this.selection[0].id, auditStatus: status}).then(response => {
-              if (response.status == 200) {
-                  // 如果是审核,成功后,关闭弹出框
-                  if(status == '2' || status == '3'){
-                      this.audioIsVisible = false
-                      // 审核成功后,改成默认值
-                      this.audioVal = '2'
-                  }
-                  this.$message({
-                      message: msg,
-                      type: "success"
-                  })
-                  // 重新查询列表数据
-                  this.search()
-              }
-          })
-      }	 
-	  }
-	}
-</script>
-<style lang="scss" scoped></style>
+<template>
+  <div class="app-container">
+		<!-- 搜索模块 -->
+    <div class="filter-container">
+    	<span>
+    		<span>{{$t("calssSchedule.searchForm.applyName")}}:</span>
+    		<el-input v-model="queryParams.model.applyDesc" :placeholder='$t("common.pleaseEnter")' style="width: 150px;" size="medium"/>
+    	</span>
+    	<span style="margin-left: 15px;">
+    		<span>{{$t("calssSchedule.searchForm.applyTime")}}:</span>
+    		<el-date-picker
+		      v-model="queryParams.timeRange"
+		      type="daterange"
+		      :picker-options="pickerOptions"
+		      :range-separator='$t("common.separator")'
+		      :start-placeholder='$t("common.startTime")'
+		      :end-placeholder='$t("common.endTime")'
+		      format="yyyy-MM-dd"
+			    value-format="yyyy-MM-dd"
+		      align="right">
+		    </el-date-picker>
+    	</span>
+    	<span style="margin-left: 15px;">
+    		<span>{{$t("calssSchedule.searchForm.audioStatus")}}:</span>
+    		<el-select v-model="queryParams.model.auditStatus" :placeholder='$t("common.pleaseSelect")' size="medium" style="width: 150px;">
+        	<el-option
+			      v-for="item in audioStatus"
+			      :key="item.value"
+			      :label="item.label"
+			      :value="item.value">
+			    </el-option>
+      	</el-select>
+    	</span>
+      <span style="margin-left: 15px;">
+	      <el-button plain type="primary" icon="el-icon-search" size="medium" @click="search">
+	        {{ $t("table.search") }}
+	      </el-button>
+	      <el-button plain type="warning" icon="el-icon-refresh" size="medium" @click="reset">
+	        {{ $t("table.reset") }}
+	      </el-button>
+      </span>
+    </div>
+
+    <!-- 功能按钮 -->
+    <el-row class="filter-container">
+    	<el-col>
+    		<el-button v-has-permission="['shiftChange:add']" type="primary" icon="el-icon-plus" size="medium" @click="add">{{ $t("common.add") }}</el-button>
+	      <el-button v-has-permission="['shiftChange:update']" type="success" icon="el-icon-edit" size="medium" @click="editOne">
+	        {{ $t("common.edit") }}
+	      </el-button>
+	      <el-button v-has-permission="['shiftChange:delete']" type="danger" icon="el-icon-delete" size="medium" @click="batchDelete">
+	        {{ $t("table.delete") }}
+	      </el-button>
+        <el-button v-has-permission="['shiftChange:pushaudit']" type="primary" icon="el-icon-thumb" size="medium" @click="updateStatus('1')">{{$t("common.audio.addAudio")}}</el-button>
+        <el-button v-has-permission="['shiftChange:audit']" type="primary" icon="el-icon-suitcase" size="medium" @click="audioBtn()">{{$t("common.audio.audio")}}</el-button>
+    	</el-col>
+    </el-row>
+
+		<!-- 列表数据 -->
+    <el-table
+      :key="tableKey"
+      ref="table"
+      v-loading="loading"
+      :data="tableData.records"
+      border
+      fit
+      row-key="id"
+      style="width: 100%;"
+      @selection-change="onSelectChange"
+      @cell-click="cellClick"
+    >
+    	<el-table-column :label='$t("common.serialNo")' width="55px" align="center">
+	      <template slot-scope="scope">
+	        <div>
+	          {{scope.$index+(queryParams.current - 1) * queryParams.size + 1}}
+	        </div>
+	      </template>
+      </el-table-column>
+      <el-table-column align="center" type="selection" width="50" :reserve-selection="true" />
+      <el-table-column prop="applyDesc" :label='$t("calssSchedule.table.staffChange.auditUser")' :show-overflow-tooltip="true" width="180px"></el-table-column>
+      <el-table-column prop="applyTime" :label='$t("calssSchedule.table.staffChange.applyTime")' :show-overflow-tooltip="true" width="180px"></el-table-column>
+      <el-table-column prop="applyDictionary" :label='$t("calssSchedule.table.staffChange.model")' :show-overflow-tooltip="true" width="180px"></el-table-column>
+      <el-table-column prop="changeDesc" :label='$t("calssSchedule.table.staffChange.hours")' :show-overflow-tooltip="true" width="180px"></el-table-column>
+      <el-table-column prop="changeTime" :label='$t("calssSchedule.table.staffChange.changeTime")' :show-overflow-tooltip="true" width="180px"></el-table-column>
+      <el-table-column prop="changeDictionary" :label='$t("calssSchedule.table.staffChange.remark")' :show-overflow-tooltip="true" width="180px"></el-table-column>
+      <el-table-column prop="auditStatus" :label='$t("calssSchedule.table.staffChange.auditStatus")' align="center" width="90px">
+      	<template slot-scope="{ row }">
+          <el-tag :type="tags[row.auditStatus]">
+          	{{audioStatus[parseInt(row.auditStatus)+1].label}}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="createTime" :label='$t("calssSchedule.table.staffChange.createTime")' :show-overflow-tooltip="true" width="180px"></el-table-column>
+      <el-table-column prop="auditTime" :label='$t("calssSchedule.table.staffChange.statusTime")' width="180px"></el-table-column>
+      <el-table-column
+        :label="$t('table.operation')"
+        fixed="right"
+        align="center"
+        column-key="operation"
+        width="100px"
+      >
+        <template slot-scope="{ row }">
+        	<!--<el-tooltip class="item" content="查看详情" effect="dark" placement="top-start">
+	          <i
+	            class="el-icon-view table-operation"
+	            style="color: #87d068;"
+	            @click="view(row)"
+	          />
+          </el-tooltip>-->
+          <el-tooltip class="item" :content='$t("common.edit")' effect="dark" placement="top-start">
+	          <i
+	            class="el-icon-edit table-operation"
+	            style="color: #2db7f5;"
+	            @click="edit(row)"
+	          />
+          </el-tooltip>
+          <el-tooltip class="item" :content='$t("common.delete")' effect="dark" placement="top-start">
+	          <i
+	            class="el-icon-delete table-operation"
+	            style="color: #f50;"
+	            @click="singleDelete(row)"
+	          />
+          </el-tooltip>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      v-show="tableData.total > 0"
+      :limit.sync="queryParams.size"
+      :page.sync="queryParams.current"
+      :total="Number(tableData.total)"
+      @pagination="fetch"
+    />
+    <tenant-edit
+      ref="edit"
+      :dialog-visible="dialog.isVisible"
+      :title="dialog.title"
+      @close="editClose"
+      @success="editSuccess"
+    />
+    <tenant-view
+      ref="view"
+      :dialog-visible="tenantViewVisible"
+      @close="viewClose"
+    />
+    <el-dialog
+      v-el-drag-dialog
+      :close-on-click-modal="false"
+      :close-on-press-escape="true"
+      title="预览"
+      width="80%"
+      top="50px"
+      :visible.sync="preview.isVisible"
+    >
+      <el-scrollbar>
+        <div v-html="preview.context" />
+      </el-scrollbar>
+    </el-dialog>
+
+    <el-dialog
+      v-el-drag-dialog
+      :close-on-click-modal="false"
+      :close-on-press-escape="true"
+      :title='$t("common.audio.audio")'
+      width="400px"
+      top="150px"
+      :visible.sync="audioIsVisible"
+    >
+      <template>
+        <el-row>
+          <el-radio v-model="audioVal" label="2">{{$t("common.audio.audioOk")}}</el-radio>
+          <el-radio v-model="audioVal" label="3">{{$t("common.audio.aduioFail")}}</el-radio>
+        </el-row>
+        <el-row style="margin-top: 30px;text-align: center;">
+          <el-button plain type="primary" size="medium" @click="audioOk">
+            {{ $t("common.confirm") }}
+          </el-button>
+          <el-button plain type="danger" size="medium" @click="colseAudio">
+            {{ $t("common.cancel") }}
+          </el-button>
+        </el-row>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+	import Pagination from "@/components/Pagination"
+	import TenantEdit from "./components/Edit"
+	import TenantView from "./components/View"
+	// 【换班管理】-API
+	import shiftChangeMgrApi from "@/api/classScheduleMgr/shiftChangeMgr"
+	import elDragDialog from '@/directive/el-drag-dialog'
+	import {initDicts, initQueryParams } from '@/utils/commons'
+	export default {
+	  name: "ShiftChangeMgr",
+	  directives: { elDragDialog },
+	  components: { Pagination, TenantEdit, TenantView },
+	  props: {
+	  },
+	  data () {
+	    return {
+	    	tags: ['','warning','success','danger'],
+	    	audioStatus: [],
+        audioIsVisible: false,
+        audioVal: '2', //默认【审核通过】
+	      dialog: {
+	        isVisible: false,
+	        title: ""
+	      },
+	      preview: {
+	        isVisible: false,
+	        context: ''
+	      },
+	      tenantViewVisible: false,
+	      tableKey: 0,
+	      queryParams: initQueryParams({}),
+	      selection: [],
+	      loading: false,
+	      tableData: {
+	        total: 0
+	      },
+	      dicts: {
+          NATION: {}
+        },
+	      enums: {
+	        TenantTypeEnum: {},
+	        TenantStatusEnum: {}
+	      },
+	      pickerOptions: {
+          shortcuts: [{
+            text: '最近一周',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '最近一个月',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '最近三个月',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+              picker.$emit('pick', [start, end]);
+            }
+          }]
+        }
+	    }
+	  },
+	  // 实例已经在内存中创建好,此时data和methods已将ok,如果要操作data中的数据或是调用methods中的方法,最早只能在created中操作
+	  created() {
+	  	// 调用常量-审核状态
+	  	this.audioStatus = this.$constWKS.AUDIOLIST
+	  	// 加载【字典】
+	  	initDicts(['NATION'], this.dicts);
+	  	// 加载列表数据
+	  	this.fetch()
+		},
+	  computed: {
+	    currentUser () {
+	      return this.$store.state.account.user
+	    },
+	    nationList() {
+        return convertEnum(this.dicts.NATION)
+      }
+	  },
+	  mounted () {
+
+	  },
+	  methods: {
+	    viewClose () {
+	      this.tenantViewVisible = false
+	    },
+	    editClose () {
+	      this.dialog.isVisible = false
+	    },
+	    editSuccess () {
+	      this.search()
+	    },
+	    onSelectChange (selection) {
+	      this.selection = selection
+	    },
+	    search () {
+	      this.fetch({
+	        ...this.queryParams
+	      })
+	    },
+	    reset () {
+	      this.queryParams = initQueryParams({})
+	      this.$refs.table.clearSort()
+	      this.$refs.table.clearFilter()
+	      this.search()
+	    },
+	    add () {
+	      this.$refs.edit.type = "add"
+	      this.$refs.edit.setTenant(false, this.dicts)
+	      this.dialog.title = this.$t("common.add")
+	      this.dialog.isVisible = true
+	    },
+	    singleDelete (row) {
+	      this.$refs.table.clearSelection()
+	      this.$refs.table.toggleRowSelection(row, true)
+	      this.batchDelete()
+	    },
+	    batchDelete () {
+	      if (!this.selection.length) {
+	        this.$message({
+	          message: this.$t("tips.noDataSelected"),
+	          type: "warning"
+	        })
+	        return
+	      }
+
+	      const readonlyIndex = this.selection.findIndex(item => item.readonly)
+
+	      if (readonlyIndex > -1) {
+	        this.$message({
+	          message: this.$t("tips.systemData"),
+	          type: "warning"
+	        })
+	        return
+	      }
+
+	      this.$confirm(this.$t("calssSchedule.tips.shiftChangeTips"), this.$t("common.tips"), {
+	      	distinguishCancelAndClose: true,
+	        confirmButtonText: this.$t("common.confirm"),
+	        cancelButtonText: this.$t("common.cancel"),
+	        type: "warning"
+	      }).then(() => {
+	      	const ids = []
+		      let contain = false
+		      this.selection.forEach(item => {
+		        if (item.readonly) {
+		          contain = true
+		          return
+		        }
+		        ids.push(item.id)
+		      })
+		      if (contain) {
+		        this.$message({
+		          message: this.$t("tips.systemData"),
+		          type: "warning"
+		        })
+		      } else {
+		        this.delete(ids)
+		      }
+	      }).catch(() => {})
+	    },
+	    clearSelections () {
+	      this.$refs.table.clearSelection()
+	    },
+	    delete (ids) {
+	      shiftChangeMgrApi.delete({'ids': ids}).then(response => {
+	        const res = response.data
+	        if (res.isSuccess) {
+	          this.$message({
+	            message: this.$t("tips.deleteSuccess"),
+	            type: "success"
+	          })
+	          this.search()
+	          // 清理已经删除的数据
+	          this.$refs.table.clearSelection()
+	        }
+	      })
+	    },
+	    view (row) {
+	      this.$refs.view.setTenant(row)
+	      this.tenantViewVisible = true
+	    },
+	    // 【修改】表头上Btn-事件
+	    editOne() {
+	    	if (!this.selection.length) {
+	        this.$message({
+	          message: this.$t("tips.noDataSelected"),
+	          type: "warning"
+	        })
+	        return
+	      }
+	    	if (this.selection.length > 1) {
+	        this.$message({
+	          message: this.$t("tips.mustOne"),
+	          type: "warning"
+	        })
+	        return
+	      }
+	    	this.edit(this.selection[0]);
+	    },
+	    edit (row) {
+	      if (row.readonly) {
+	        this.$message({
+	          message: this.$t("tips.systemData"),
+	          type: "warning"
+	        })
+	        return
+	      }
+	      // 根据换班id查询用户之前的换班的
+		  this.$refs.edit.type = "edit"
+	      this.$refs.edit.setTenant(row, this.dicts)
+	      this.dialog.title = this.$t("common.edit")
+	      this.dialog.isVisible = true
+	    },
+	    fetch (params = {}) {
+	      this.loading = true
+	      if (this.queryParams.timeRange) {
+	        this.queryParams.map.createTime_st = this.queryParams.timeRange[0]
+	        this.queryParams.map.createTime_ed = this.queryParams.timeRange[1]
+	      }
+
+	      this.queryParams.current = params.current ? params.current : this.queryParams.current
+	      this.queryParams.size = params.size ? params.size : this.queryParams.size
+	      shiftChangeMgrApi.page(this.queryParams).then(response => {
+	        const res = response.data
+	        if (res.isSuccess) {
+	          this.tableData = res.data
+	        }
+	        // eslint-disable-next-line no-return-assign
+	      }).finally(() => this.loading = false)
+
+	    },
+	    cellClick (row, column) {
+	      if (column['columnKey'] === "operation") {
+	        return
+	      }
+	      let flag = false
+	      this.selection.forEach((item) => {
+	        if (item.id === row.id) {
+	          flag = true
+	          this.$refs.table.toggleRowSelection(row)
+	        }
+	      })
+
+	      if (!flag) {
+	        this.$refs.table.toggleRowSelection(row, true)
+	      }
+	    },
+      // 【提交审核】按钮-事件
+      updateStatus(status){
+          if (!this.selection.length) {
+              this.$message({
+                  message: this.$t("tips.noDataSelected"),
+                  type: "warning"
+              })
+              return
+          }
+          if (this.selection.length > 1) {
+              this.$message({
+                  message: this.$t("tips.mustOne"),
+                  type: "warning"
+              })
+              return
+          }
+          // 调用API
+          this.audio(status)
+      },
+      // 【取消】审核按钮-事件
+      colseAudio(){
+          this.audioIsVisible = false
+      },
+      // 【确定】审核按钮-事件
+      audioOk(){
+          // 调用审核
+          this.audio(false)
+      },
+      // 【审核产品】-按钮事件
+      audioBtn(){
+          if (!this.selection.length) {
+              this.$message({
+                  message: this.$t("tips.noDataSelected"),
+                  type: "warning"
+              })
+              return
+          }
+          if (this.selection.length > 1) {
+              this.$message({
+                  message: this.$t("tips.mustOne"),
+                  type: "warning"
+              })
+              return
+          }
+          this.audioIsVisible = true
+      },
+      // 【审核产品】-Table的Row操作事件
+      audioBtnRow(row) {
+          // 清除所有的选择数据
+          this.$refs.table.clearSelection()
+          // 设置当前行为选中的数据
+          this.$refs.table.toggleRowSelection(row, true)
+          // 弹出审核页面
+          this.audioIsVisible = true
+      },
+      // 【审核通过/审核不通过】接口-事件
+      audio(status){
+          if(!status){
+              status =  this.audioVal
+          }
+          // 赋值
+          this.selection[0].status = status
+          let msg = "提交审核成功!"
+          if(status == "2"){
+              msg = "审核通过!"
+          }
+          if(status == "3"){
+              msg = "审核不通过!"
+          }
+          shiftChangeMgrApi.updateStatus({ id: this.selection[0].id, auditStatus: status}).then(response => {
+              if (response.status == 200) {
+                  // 如果是审核,成功后,关闭弹出框
+                  if(status == '2' || status == '3'){
+                      this.audioIsVisible = false
+                      // 审核成功后,改成默认值
+                      this.audioVal = '2'
+                  }
+                  this.$message({
+                      message: msg,
+                      type: "success"
+                  })
+                  // 重新查询列表数据
+                  this.search()
+              }
+          })
+      }
+	  }
+	}
+</script>
+<style lang="scss" scoped></style>

+ 2 - 1
imcs-ui/src/views/zuihou/repairManger/repair/Index.vue

@@ -431,6 +431,7 @@
         this.queryParams = initQueryParams({})
         this.$refs.table.clearSort()
         this.$refs.table.clearFilter()
+        this.productionLineId = this.productionLines[0].id;
         this.search()
       },
       add() {
@@ -558,7 +559,7 @@
       // 产线查找
       queryProductionLines(){
           this.productionLines = []
-          productionLineMgrApi.getList({}).then(response => {
+          productionLineMgrApi.allSelect({}).then(response => {
               const res = response.data
               if (res.isSuccess) {
                   this.productionLines = res.data

+ 42 - 14
imcs-ui/src/views/zuihou/resourceProductMgr/areaMgr/components/Edit.vue

@@ -35,6 +35,9 @@
           <i class="el-icon-plus" />
         </imgUpload>
       </el-form-item>
+      <el-form-item :label='$t("resource.table.area.remark")+":"' prop="remark">
+      	<el-input v-model="tenant.remark" type="textarea" :rows="3" style="width: 100%;"/>
+      </el-form-item>
       <!--<el-form-item :label='$t("resource.table.area.layoutMap")+":"' prop="layoutMap">          
           <fileUpload :acceptSize="5*1024*1024" :auto-upload="false" :limit="1" :fileOtherData="fileData" @fileLengthVaild="fileLengthVaild" @setId="setIdAndSubmit" ref="fileRef">              
               <el-button size="small" slot="trigger" type="primary" >选取文件</el-button>              
@@ -44,8 +47,17 @@
 	          		<el-image :src="tenant.imgUrl" fit="cover" />
 	        </div> 
       </el-form-item>-->
-      <el-form-item :label='$t("resource.table.area.remark")+":"' prop="remark">
-      	<el-input v-model="tenant.remark" type="textarea" :rows="3" style="width: 100%;"/>
+      <el-form-item :label='$t("resource.table.area.orgId")+":"' prop="orgId">
+      		<treeselect
+          :clear-value-text="$t('common.clear')"
+          :load-options="loadListOptions"
+          :multiple="false"
+          :options="orgList"
+          :searchable="true"
+          placeholder=" "
+          style="width:100%"
+          v-model="tenant.orgId"
+        />
       </el-form-item>
     </el-form>
     <div slot="footer" class="dialog-footer">
@@ -61,11 +73,14 @@ import areaMgrApi from "@/api/resourceProductMgr/areaMgr";
 import imgUpload from "@/components/zuihou/imgUpload";
 import fileUpload from "@/components/zuihou/fileUpload"
 import elDragDialog from '@/directive/el-drag-dialog'
+import Treeselect from "@riophae/vue-treeselect"
+import orgApi from "@/api/Org.js";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 
 export default {
   name: 'TenantEdit',
   directives: {elDragDialog, fileUpload},
-  components: { fileUpload, imgUpload },
+  components: { fileUpload, imgUpload, Treeselect },
   props: {
     dialogVisible: {
       type: Boolean,
@@ -89,6 +104,7 @@ export default {
       fileData: {},
       formData: {},
       imgFileList: [],  // 图片集合
+      orgList: [],
       imgFileData: {
         bizId: "",
         bizType: "AREA_LINE"
@@ -140,6 +156,7 @@ export default {
         this.width = this.initWidth()
       })()
     } 
+    this.initOrg();
   },
   methods: {
     initTenant () {
@@ -148,6 +165,7 @@ export default {
         name: '',
         layoutMap: '',
         status: '1',
+        orgId: '',
         remark:'',
       }
     },
@@ -161,6 +179,9 @@ export default {
         return '800px'
       }
     },
+    loadListOptions({ callback }) {
+      callback();
+    },
     // 附件长度校验
     fileLengthVaild (data) {
       const vm = this;
@@ -170,7 +191,7 @@ export default {
     	if(val){        
     		this.tenant = { ...val }   
     		// 附件显示
-    		this.imgFileList = [{url: val.imgUrl}];
+    		this.imgFileList = [{url: val.imgUrl}];        
     	}
       // 字典表
       this.dicts = dicts     
@@ -182,6 +203,20 @@ export default {
       this.fileData.bizType = "TRAY"
       this.fileData.isSingle = true
     },
+    initOrg() {
+        orgApi
+          .allTree({status: true})
+          .then(response => {
+            const res = response.data;
+            this.orgList = res.data;
+          })
+          .catch(() => {
+            this.$message({
+              message: this.$t("tips.getDataFail"),
+              type: "error"
+            });
+          });
+      },
     close () {
       this.$emit('close')
     },
@@ -235,23 +270,16 @@ export default {
     
     editSubmit () {      
       this.disabled = true
-      this.loading = true
-      //let id =  this.tenant.layoutMap!=null? this.tenant.layoutMap: ""
-      // this.$refs.fileRef.submitFile(id, this.tenant.id, 'TRAY')
-      // console.log("22222222222222");
+      this.loading = true      
       if(this.type == 'add') {
       	 this.save(this.tenant);
       } else {
       	this.update(this.tenant);
       }
     },
-    submitForm () {
-    	// console.log("00000000000000000000000");
+    submitForm () {    
       this.$refs.form.validate((valid) => {
-        if (valid) {          
-        	// console.log("11111111111111111");
-          // this.formData = this.tenant 
-          // localStorage.setItem("formData", JSON.stringify(this.formData));         
+        if (valid) {
           this.confirmDisabled = true
           this.editSubmit()
           // 后续提交处理