ProcessIndex.ets 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537
  1. import { TimeAndTitle } from '../common/component/TimeAndTitle';
  2. import router from '@ohos.router';
  3. import WorkOrderInfo from '../viewmodel/WorkOrderInfo';
  4. import CommonConstants from '../common/constants/CommonConstants';
  5. import ProcessRequest from '../common/util/request/ProcessRequest';
  6. import RequestParamModel from '../viewmodel/RequestParamModel';
  7. import OperationInfo from '../viewmodel/process/OperationInfo';
  8. import { SelectWorkOrderDialog } from '../view/SelectWorkOrderDialog';
  9. import { SwitchProductDialog, taskSeqItem } from '../view/SwitchProductDialog';
  10. import TaskSeqVO from '../viewmodel/process/TaskSeqInfo';
  11. import promptAction from '@ohos.promptAction';
  12. import { LoginInfoDialog } from '../view/LoginInfoDialog';
  13. import { SwitchDeptDialog, SwitchProductLineDialog, SwitchStationDialog } from '../view/SwitchStationDialog';
  14. import { SwitchUserDialog } from '../view/SwitchUserDialog';
  15. import OperationComponent from '../viewmodel/process/OperationComponent';
  16. import ProcessInfo from '../viewmodel/process/ProcessInfo';
  17. import { MaterialCollectView } from '../view/process/MaterialCollectView';
  18. import { WorkOrderPage } from '../viewmodel/WorkOrderPage';
  19. import { UserInfo } from '../viewmodel/UserInfo';
  20. import { CompleteReceiveDialog } from '../view/CompleteReceiveDialog';
  21. import { WorkInstructionsDialog } from '../view/WorkInstructionsDialog';
  22. import connection from '@ohos.net.connection';
  23. import { ReportWorkNumDialog } from '../view/ReportWorkNumDialog';
  24. import { ReportPieceworkDialog } from '../view/ReportPieceworkDialog';
  25. import { ReportTimeBasedDialog } from '../view/ReportTimeBasedDialog';
  26. import { JoinPersonNameDialog } from '../view/JoinPersonNameDialog';
  27. import ReportInfo from '../viewmodel/process/ReporterInfo';
  28. import { BindTaskSeq } from '../viewmodel/process/BindTaskSeq';
  29. import { MqttClientOptions, MqttConnectOptions } from '@ohos/mqtt';
  30. import MqttManager from '../common/util/mqtt';
  31. import { ReportDefectNumDialog } from '../view/ReportDefectNumDialog';
  32. import { SelfInspectView } from '../view/process/SelfInspectView';
  33. import { MultiMediaCollect } from '../view/process/MultiMediaCollect';
  34. import { BarcodeAssociationDialog } from '../view/BarcodeAssociationDialog';
  35. import WorkOrderSeq from '../viewmodel/WorkOrderSeq';
  36. import { USBDeviceManager } from '../common/util/UsbDevice';
  37. import { InAndOutBoundDialog } from '../view/InAndOutBoundDialog';
  38. import { LittleMaterialRequestDialog } from '../view/LittleMaterialRequestDialog';
  39. import { PictureDrawingDialog } from '../view/PictureDrawingDialog';
  40. import { AuxiliaryOperationView } from '../view/AuxiliaryOperationView';
  41. import { BusinessError } from '@ohos.base';
  42. import window from '@ohos.window';
  43. import { DeviceInspectionDialog } from '../view/DeviceInspectionDialog';
  44. import preferencesUtil from '../common/util/PerferencesUtil';
  45. import TimeUtil from '../common/util/TimeUtil';
  46. import ProcessDeviceDailyCheck from '../viewmodel/process/ProcessDeviceDailyCheck';
  47. import { DeviceCheckView } from '../view/process/DeviceCheckView';
  48. import { ReportWorkHourRateDialog } from '../view/ReportWorkHourRateDialog';
  49. import { ConfirmDialog } from '../view/ConfirmDialog';
  50. import VehicleInfo from '../viewmodel/VehicleInfo';
  51. // 声明接受参数的类型
  52. interface Params {
  53. // 辅助操作标志
  54. auxiliaryOperationFlag?: boolean,
  55. }
  56. @Entry
  57. @Component
  58. struct ProcessIndex {
  59. // 工单列表
  60. @State workOrders: WorkOrderInfo[] = []
  61. // 选中工单
  62. @State selectWorkOder: WorkOrderInfo = {}
  63. // 工位通知数量
  64. @State noticeNum: number = 100
  65. // 扫描或手动输入的流水/序列/铭牌号
  66. @State scanCode: string = ''
  67. // 当前流转卡号
  68. @State seqNo: string = ''
  69. //是否打开底部抽屉
  70. @State isAuxiliaryViewOpen: boolean = false
  71. // 选中工序id
  72. @State selectOperationId: string = ''
  73. // 绩效模式(0:计时 1:计件)
  74. @State operationPerformance: string = ''
  75. // 选中工序名称
  76. selectOperationName: string = ''
  77. //选择的按钮索引(默认加载全部)
  78. @State selectedButtonIndex: number = 0
  79. // 流转卡号信息集合
  80. @State taskSeqArray: TaskSeqVO[] = []
  81. // 工序组件(工步)
  82. @State opComponents: OperationComponent[] = []
  83. // 选中的工序组件类型
  84. @State selectComponentType: string = ''
  85. // 工序组件状态数组(0:未完成)
  86. @State componentStates: number[] = []
  87. // 工序组件对应的图标
  88. componentResMap: Map<string, Resource> = new Map([
  89. ['1', $r('app.media.process_component_material_collect')],
  90. ['2', $r('app.media.process_component_record_item')],
  91. ['3', $r('app.media.process_component_multi_media_collect')],
  92. ['4', $r('app.media.process_component_esop')],
  93. ['5', $r('app.media.process_component_self_inspect')],
  94. ['6', $r('app.media.process_component_device_record')],
  95. ['7', $r('app.media.process_component_fastening')],
  96. ['9', $r('app.media.process_component_label_bind')],
  97. ['10', $r('app.media.process_component_form')],
  98. ['11', $r('app.media.process_component_auto_test')],
  99. ['12', $r('app.media.process_component_device_record')],
  100. ])
  101. // 扫码开工后的生产过程信息
  102. @State process: ProcessInfo = {}
  103. // 扫码开工状态(0:未开工 1:已开工)
  104. @State @Watch('queryByScanState') scanState: number = 0
  105. // 工单下流转卡号列表
  106. @State seqList: WorkOrderSeq[] = []
  107. // 设备每日点检
  108. @State deviceChecks: ProcessDeviceDailyCheck[] = []
  109. // 报工人信息
  110. @State reporterList: ReportInfo[] = []
  111. @State currentReporterIndex:number =0
  112. @State currentReportNumIndex:number =0
  113. @State currentDefectIndex:number =0
  114. // mqtt是否连接
  115. @State isConnected: boolean = false
  116. // 当前订单扫码流水号数量
  117. @State scanSeqNos: number = 0
  118. //工序载具列表
  119. @State processVehicleList: VehicleInfo[] = []
  120. //所有流水号
  121. allTaskSeq: TaskSeqVO[] = []
  122. private scrollerList: Scroller = new Scroller()
  123. @Provide('currentDept') currentDept:string = ''
  124. @Provide('currentProductLine') currentProductLine:string = ''
  125. @Provide('currentStation') currentStation:string = ''
  126. @Provide('stationIp') stationIp:string = ''
  127. @Provide('currentPLCode') currentPLCode:string = ''
  128. @Provide('currentOrgId') currentOrgId:number = 0
  129. @Provide('currentStationId') @Watch('refreshWorkOrder') currentStationId: string = ''
  130. @Provide('currentUserName') currentUserName: string =''
  131. @Provide('currentUserId') currentUserId: number = 0
  132. // 报工人、报工流水号和不良流水号
  133. @Provide('bindTaskSeq') bindTaskSeq: BindTaskSeq[] = []
  134. startWorkTime: string = ''
  135. // 工位发生改变则可能需要重新选择工单
  136. async refreshWorkOrder() {
  137. if (!this.selectWorkOder || !this.selectWorkOder.workOrderCode) {
  138. return
  139. }
  140. console.log('hhtest', '执行刷新------' +this.currentStationId)
  141. let queryRes = await ProcessRequest.post('/api/v1/plan/workOrder/taskPage2', {
  142. stationId: this.currentStationId,
  143. queryComplete: 0,
  144. pageNo: 1,
  145. pageSize: 99999,
  146. } as RequestParamModel) as WorkOrderPage;
  147. this.workOrders = queryRes?.records??[]
  148. if (this.workOrders) {
  149. let clearFlag: boolean = true
  150. for (const element of this.workOrders) {
  151. console.log('hhtest', '工单编码-----------------' + element.workOrderCode)
  152. if (element.workOrderCode! === this.selectWorkOder.workOrderCode) {
  153. clearFlag = false
  154. break
  155. }
  156. }
  157. if (clearFlag) {
  158. this.selectWorkOder = {}
  159. this.clearSelectData()
  160. this.selectOrderController.open()
  161. console.log('hhtest', '选择工单被清空-----------------')
  162. }
  163. } else {
  164. this.selectWorkOder = {}
  165. this.clearSelectData()
  166. this.selectOrderController.open()
  167. console.log('hhtest', '选择工单被清空-----------------')
  168. }
  169. }
  170. async queryByScanState() {
  171. if (this.scanState === 1) {
  172. await this.scanCodeToStartWork()
  173. } else {
  174. await this.getComponentsForNotStartWork()
  175. }
  176. }
  177. // 扫码开工
  178. async scanCodeToStartWork() {
  179. this.process = await ProcessRequest.post('/api/v1/process/info/scan', {
  180. operationId: this.selectOperationId,
  181. qrCode: this.scanCode,
  182. workOrderCode: this.selectWorkOder.workOrderCode!,
  183. stationId: this.currentStationId
  184. } as RequestParamModel)
  185. if (!this.seqNo) {
  186. this.seqNo = this.scanCode
  187. }
  188. this.opComponents = []
  189. if (this.process && this.process.id) {
  190. this.opComponents = await ProcessRequest.get(`/api/v1/process/opCompent/get/${this.selectOperationId!}/${this.process?.id!}`)
  191. if (this.opComponents) {
  192. for (const element of this.opComponents) {
  193. if (CommonConstants.OPERATION_COMPONENT_TYPE.has(element.compentType!)) {
  194. element.compentType = CommonConstants.OPERATION_COMPONENT_TYPE.get(element.compentType!)
  195. }
  196. }
  197. }
  198. // 过滤掉点检工步
  199. this.opComponents = this.opComponents.filter(item => item.compentType !== '5');
  200. this.opComponents.unshift({
  201. compentName:'自检',
  202. compentType: '5',
  203. deleted:0,
  204. operationId: this.selectOperationId,
  205. processRouteId: this.process?.id,
  206. remark:'',
  207. sortNum:0
  208. })
  209. }
  210. // 保存此流转卡号到数据库中
  211. let seqNos: string[] = []
  212. seqNos = await preferencesUtil.get(CommonConstants.PREFERENCE_INSTANCE_NAME, this.selectWorkOder.workOrderCode!, seqNos)
  213. if (seqNos.includes(this.seqNo)) {
  214. return
  215. }
  216. seqNos.push(this.seqNo)
  217. preferencesUtil.put(CommonConstants.PREFERENCE_INSTANCE_NAME, this.selectWorkOder.workOrderCode!, seqNos)
  218. this.scanSeqNos = seqNos.length
  219. if (!this.startWorkTime) {
  220. this.startWorkTime = TimeUtil.getCurrentTime()
  221. }
  222. }
  223. // 未开工查询工序组件(工步)
  224. async getComponentsForNotStartWork() {
  225. this.opComponents = await ProcessRequest.get('/api/v1/op/compent/get/' + this.selectOperationId)
  226. if (this.opComponents) {
  227. for (const element of this.opComponents) {
  228. if (CommonConstants.OPERATION_COMPONENT_TYPE.has(element.compentType!)) {
  229. element.compentType = CommonConstants.OPERATION_COMPONENT_TYPE.get(element.compentType!)
  230. }
  231. }
  232. }
  233. // 过滤掉点检工步
  234. this.opComponents = this.opComponents.filter(item => item.compentType !== '5');
  235. this.opComponents.unshift({
  236. compentName: '自检',
  237. compentType: '5',
  238. deleted: 0,
  239. operationId: this.selectOperationId,
  240. processRouteId: '0',
  241. remark: '',
  242. sortNum: 0
  243. })
  244. }
  245. // 刷新当前工单已扫码流水号数量
  246. async refreshScanSeqNos() {
  247. let seqNoList: string[] = []
  248. seqNoList = await preferencesUtil.get(CommonConstants.PREFERENCE_INSTANCE_NAME, this.selectWorkOder.workOrderCode!, seqNoList)
  249. this.scanSeqNos = seqNoList.length
  250. }
  251. // 清除选中的相关数据(工单不做处理)
  252. clearSelectData() {
  253. this.selectOperationId = ''
  254. this.seqNo = ''
  255. this.scanCode = ''
  256. this.seqList = []
  257. this.scanState = 0
  258. this.process = {}
  259. this.opComponents = []
  260. this.taskSeqArray = []
  261. // this.handleAllClick()
  262. }
  263. handleAllClick():void {
  264. this.onQueryTask([])
  265. }
  266. handleReportedClick():void{
  267. this.onQueryTask([2])
  268. }
  269. handleUnreportedClick():void{
  270. this.onQueryTask([-1,0,1])
  271. }
  272. onQueryTask = async (currentStateList: Array<number>)=>{
  273. if (!this.selectWorkOder.workOrderCode || !this.currentStationId || !this.selectOperationId) {
  274. return
  275. }
  276. this.taskSeqArray = await ProcessRequest.post('/api/v1/plan/task/list', {
  277. stationId: this.currentStationId,
  278. workOrderCode: this.selectWorkOder.workOrderCode!,
  279. operationId: this.selectOperationId,
  280. stateList: currentStateList
  281. } as RequestParamModel) as TaskSeqVO[];
  282. if (currentStateList.length <= 0) {
  283. this.allTaskSeq = this.taskSeqArray
  284. }
  285. }
  286. //加载工序所有载具
  287. loadProcessVehicle = async () => {
  288. let res = await ProcessRequest.post('/api/v1/process/vehicleOperation/list', {
  289. workOrderCode:this.selectWorkOder.workOrderCode!,
  290. operationId: this.selectOperationId
  291. } as RequestParamModel) as OperationInfo;
  292. this.processVehicleList = res.processVehicleList ?? []
  293. };
  294. connectMQTT = async ()=> {
  295. const clientOptions: MqttClientOptions = {
  296. url: 'mqtt://192.168.1.3:1883', // 替换实际IP
  297. clientId: `process_client_${Date.now()}`,
  298. persistenceType: 1, // 使用英文逗号 // 建议开启自动重连
  299. };
  300. // MQTT连接配置
  301. const connectOptions: MqttConnectOptions = {
  302. cleanSession: true,
  303. connectTimeout: 30,
  304. keepAliveInterval: 60,
  305. userName: 'optional_username',
  306. password: 'optional_password'
  307. };
  308. try {
  309. MqttManager.init(clientOptions);
  310. this.isConnected = await MqttManager.connect(connectOptions);
  311. if (this.isConnected ) {
  312. console.info('hhtest', 'MQTT connected successfully');
  313. await MqttManager.subscribe(CommonConstants.mqttSubscribeTopic1);
  314. await MqttManager.subscribe(CommonConstants.mqttSubscribeTopic3);
  315. if (CommonConstants.mqttSubscribeTopic1 != CommonConstants.mqttSubscribeTopic2) {
  316. await MqttManager.subscribe(CommonConstants.mqttSubscribeTopic2);
  317. }
  318. } else {
  319. console.error('hhtest', 'MQTT connection failed');
  320. }
  321. } catch (err) {
  322. console.error('hhtest', `MQTT error: ${JSON.stringify(err)}`);
  323. }
  324. }
  325. connectUsbDevice=async()=>{
  326. return await USBDeviceManager.getInstance();
  327. }
  328. onPageShow() {
  329. const params = router.getParams() as Params; // 获取传递过来的参数对象
  330. if (params && params.auxiliaryOperationFlag) {
  331. this.isAuxiliaryViewOpen = true
  332. }
  333. }
  334. async aboutToAppear() {
  335. // 获取工位ip
  336. this.stationIp = CommonConstants.STATION_DEFAULT_IP
  337. try {
  338. const netHandle = connection.getDefaultNetSync();
  339. if (netHandle) {
  340. let connectionProperties = await connection.getConnectionProperties(netHandle)
  341. if (connectionProperties && connectionProperties.linkAddresses) {
  342. connectionProperties.linkAddresses.forEach((address: connection.LinkAddress, index: number) => {
  343. this.stationIp = address.address.address
  344. if (address.address.address.startsWith(CommonConstants.ipPrefix)) {
  345. // todo 部署时放开注释
  346. // CommonConstants.mqttSubscribeTopic1 = 'station' + address.address.address.replace(CommonConstants.ipPrefix, '') + '/data/devices'
  347. // CommonConstants.mqttSubscribePublish = 'station' + address.address.address.replace(CommonConstants.ipPrefix, '') + '/cmd/devices'
  348. }
  349. })
  350. }
  351. }
  352. } catch (err) {
  353. console.log('hhtest', err);
  354. }
  355. // 创建mqtt连接和usb设备连接
  356. this.connectMQTT()
  357. this.connectUsbDevice()
  358. // 判断是否选中工单,未选择则选则工单
  359. if (!this.selectWorkOder || !this.selectWorkOder.workOrderCode) {
  360. this.selectOrderController.open()
  361. } else {
  362. this.refreshScanSeqNos()
  363. }
  364. //判断今日是否进行设备点检,否则先进行点检
  365. this.deviceChecks = await ProcessRequest.post('/api/v1/process/deviceDailyCheck/list', {
  366. stationIp: this.stationIp,
  367. createDate: TimeUtil.getCurrentDate()
  368. } as RequestParamModel)
  369. if (!this.deviceChecks || this.deviceChecks.length <= 0) {
  370. this.deviceInspectionController.open()
  371. }
  372. // todo 删除
  373. let token:string = await ProcessRequest.post('api/auth/aioLogin', {
  374. password: '123456',
  375. userName: 'admin',
  376. } as RequestParamModel) ;
  377. if (token && token.length > 0) {
  378. CommonConstants.AUTH_TOKEN = token
  379. this.currentUserName = 'admin'
  380. }
  381. this.currentProductLine = '配件产线01'
  382. this.currentPLCode = 'PL000018'
  383. this.currentStationId = '66'
  384. this.currentStation = '装配工位'
  385. let res:UserInfo = await ProcessRequest.get('/api/auth') ;
  386. this.currentUserId = res.id! as number
  387. // ---------------删除以上内容------------------
  388. }
  389. build() {
  390. Stack() {
  391. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
  392. //时间和导航标
  393. Row() {
  394. TimeAndTitle()
  395. }.width('100%')
  396. .height('3.4%')
  397. .alignItems(VerticalAlign.Bottom)
  398. .justifyContent(FlexAlign.End)
  399. Row() {
  400. Image($r('app.media.general_return'))
  401. .height($r('app.float.virtualSize_56'))
  402. .width($r('app.float.virtualSize_56'))
  403. .fillColor($r('app.color.FFFFFF'))
  404. Text('生产执行')
  405. .fontColor($r('app.color.FFFFFF'))
  406. .fontSize($r('app.float.fontSize_30'))
  407. .fontWeight(FontWeight.Medium)
  408. }
  409. .height('4%')
  410. .width('94.8%')
  411. .justifyContent(FlexAlign.Start)
  412. .onClick(() => {
  413. // router.back()
  414. window.getLastWindow(getContext()).then((data) => {
  415. //获取窗口对象
  416. let windowClass = data;
  417. windowClass.minimize((err: BusinessError) => {
  418. const errCode: number = err.code;
  419. if (errCode) {
  420. console.error('Failed to minimize the window. Cause: ' + JSON.stringify(err));
  421. return;
  422. }
  423. console.info('Succeeded in minimizing the window.');
  424. });
  425. console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data));
  426. });
  427. return true;
  428. })
  429. Row().height('2.8%')
  430. // 主要操作栏
  431. Row() {
  432. // 左侧选择工单、工位、人员;工序查看
  433. Column() {
  434. if (this.selectWorkOder && this.selectWorkOder.workOrderCode) {
  435. Column() {
  436. Text(this.selectWorkOder.materialName!)
  437. .fontWeight(FontWeight.Medium)
  438. .fontColor($r('app.color.FFFFFF'))
  439. .fontSize($r('app.float.fontSize_24'))
  440. .width('88.9%')
  441. Text(this.selectWorkOder.materialCode!)
  442. .fontWeight(FontWeight.Lighter)
  443. .fontColor($r('app.color.FFFFFF'))
  444. .fontSize($r('app.float.fontSize_12'))
  445. .width('88.9%')
  446. Row() {
  447. Text('工单:')
  448. .fontWeight(FontWeight.Lighter)
  449. .fontColor($r('app.color.FFFFFF'))
  450. .fontSize($r('app.float.fontSize_12'))
  451. Text(this.selectWorkOder.workOrderCode!)
  452. .fontWeight(FontWeight.Bold)
  453. .fontColor($r('app.color.FFFFFF'))
  454. .fontSize($r('app.float.fontSize_16'))
  455. }
  456. .width('88.9%')
  457. }
  458. .width('100%')
  459. .height('12.4%')
  460. .justifyContent(FlexAlign.Center)
  461. .backgroundColor($r('app.color.20FFFFFF'))
  462. .borderRadius($r('app.float.fontSize_16'))
  463. .onClick(() => {
  464. this.selectOrderController.open()
  465. })
  466. } else {
  467. Button('请选择工单', { type: ButtonType.Normal })
  468. .width('100%')
  469. .height('12.4%')
  470. .fontWeight(FontWeight.Medium)
  471. .fontColor($r('app.color.FFFFFF'))
  472. .fontSize($r('app.float.fontSize_24'))
  473. .backgroundColor($r('app.color.20FFFFFF'))
  474. .borderRadius($r('app.float.fontSize_16'))
  475. .onClick(() => {
  476. this.selectOrderController.open()
  477. })
  478. }
  479. // 登录信息(工位、人员信息)
  480. Row() {
  481. Row().width('5.6%')
  482. Column() {
  483. Text(this.currentStation)
  484. .fontSize($r('app.float.fontSize_16'))
  485. .fontWeight(FontWeight.Regular)
  486. .fontColor($r('app.color.FFFFFF'))
  487. Text(this.currentUserName)
  488. .fontSize($r('app.float.fontSize_12'))
  489. .fontWeight(FontWeight.Lighter)
  490. .fontColor($r('app.color.FFFFFF'))
  491. }
  492. .width('48.8%')
  493. .height('100%')
  494. .justifyContent(FlexAlign.Center)
  495. .alignItems(HorizontalAlign.Start)
  496. Row() {
  497. Text(this.noticeNum > 99 ? '99+' : this.noticeNum.toString())
  498. .fontSize($r('app.float.fontSize_16'))
  499. .fontWeight(FontWeight.Bold)
  500. .fontColor($r('app.color.FFFFFF'))
  501. .textAlign(TextAlign.Center)
  502. .height('42.3%')
  503. .width('42%')
  504. .backgroundColor($r('app.color.20FFFFFF'))
  505. .borderRadius($r('app.float.fontSize_16'))
  506. }
  507. .width('40%')
  508. .height('100%')
  509. .justifyContent(FlexAlign.End)
  510. Row().width('5.6%')
  511. }
  512. .width('100%')
  513. .height('8.1%')
  514. .backgroundColor($r('app.color.20FFFFFF'))
  515. .borderRadius($r('app.float.fontSize_16'))
  516. .onClick(() => {
  517. this.loginInfoController.open()
  518. })
  519. // 工序
  520. Column({ space: 4 }) {
  521. Row() {
  522. Text('工序')
  523. .fontWeight(FontWeight.Medium)
  524. .fontColor($r('app.color.FFFFFF'))
  525. .fontSize($r('app.float.fontSize_24'))
  526. }
  527. .width('83.4%')
  528. .height('8.4%')
  529. .alignItems(VerticalAlign.Bottom)
  530. List() {
  531. ForEach(this.selectWorkOder.ops!, (item: OperationInfo, index: number) => {
  532. ListItem() {
  533. Column() {
  534. Row() {
  535. Row() {
  536. Text((index + 1).toString())
  537. .fontSize($r('app.float.fontSize_16'))
  538. .fontColor(this.selectOperationId === item.operationId ? $r('app.color.90000000') : $r('app.color.FFFFFF'))
  539. .fontWeight(FontWeight.Bold)
  540. }
  541. .width('14.6%')
  542. .height('80%')
  543. .justifyContent(FlexAlign.Center)
  544. Row() {
  545. Text(item.operationName)
  546. .fontSize($r('app.float.fontSize_16'))
  547. .fontColor(this.selectOperationId === item.operationId ? $r('app.color.90000000') : $r('app.color.FFFFFF'))
  548. .fontWeight(FontWeight.Regular)
  549. .padding({ left: 5 })
  550. }
  551. .width('70.8%')
  552. .height('100%')
  553. .alignItems(VerticalAlign.Center)
  554. .justifyContent(FlexAlign.Start)
  555. Row() {
  556. Image(this.selectOperationId === item.operationId ? $r('app.media.process_current_operation') : (item.isEnd! ? $r('app.media.process_complete') : ''))
  557. .width($r('app.float.virtualSize_24'))
  558. .height($r('app.float.virtualSize_24'))
  559. .fillColor(this.selectOperationId === item.operationId ? $r('app.color.90000000') : $r('app.color.FFFFFF'))
  560. .opacity(this.selectOperationId != item.operationId && !item.isEnd ? 0 : 1)
  561. }
  562. .width('14.6%')
  563. .height('100%')
  564. .justifyContent(FlexAlign.Center)
  565. }
  566. .width('100%')
  567. .height('70%')
  568. .borderRadius($r('app.float.virtualSize_40'))
  569. .backgroundImage(this.selectOperationId === item.operationId ? $r('app.media.process_select_operation') : $r('app.media.process_no_select_operation'))
  570. .backgroundImageSize(ImageSize.Cover)
  571. .onClick(() => {
  572. if (!this.selectWorkOder.workOrderCode || !this.currentUserName || !this.currentStationId) {
  573. return
  574. }
  575. this.selectOperationId = item.operationId!
  576. this.selectOperationName = item.operationName!
  577. this.operationPerformance = item.performance!
  578. if (!item.exists) {
  579. promptAction.showToast({
  580. message: `${item.operationName}需要在${item.stationName}工位上生产`,
  581. duration: 1500,
  582. })
  583. if (this.scanCode) {
  584. // 未开工查询工序组件
  585. this.getComponentsForNotStartWork()
  586. }
  587. } else if (this.scanState === 0 && this.seqNo) {
  588. // 未开工查询工序组件
  589. this.getComponentsForNotStartWork()
  590. } else if (this.scanState === 1) {
  591. this.scanCodeToStartWork()
  592. }
  593. if (!this.seqNo || this.seqNo.length <= 0) {
  594. this.handleAllClick()
  595. }
  596. })
  597. if (index < (this.selectWorkOder?.ops && this.selectWorkOder?.ops?.length ? this.selectWorkOder?.ops!.length : 0) - 1) {
  598. Row() {
  599. Divider()
  600. .vertical(true)
  601. .color($r('app.color.60FFFFFF'))
  602. .padding({ right: '15%' })
  603. }
  604. .justifyContent(FlexAlign.Center)
  605. .width('20%')
  606. .layoutWeight(1)
  607. }
  608. }
  609. .width('100%')
  610. .height('10.6%')
  611. .alignItems(HorizontalAlign.Start)
  612. }
  613. })
  614. }
  615. .width('83.4%')
  616. .height('88.6%')
  617. .alignListItem(ListItemAlign.Center)
  618. }
  619. .width('100%')
  620. .height('77.2%')
  621. .backgroundColor($r('app.color.20FFFFFF'))
  622. .borderRadius($r('app.float.fontSize_16'))
  623. .opacity(!this.selectWorkOder.workOrderCode || !this.currentUserName || !this.currentStationId ? 0.3 : 1)
  624. }
  625. .height('100%')
  626. .width('19.8%')
  627. .justifyContent(FlexAlign.SpaceBetween)
  628. // 右侧生产操作栏
  629. if (this.opComponents.length <= 0) {
  630. // 没有工序组件则展示扫码页面
  631. Column() {
  632. Row() {
  633. Text('录入流水号')
  634. .fontSize($r('app.float.fontSize_30'))
  635. .fontWeight(FontWeight.Medium)
  636. .fontColor($r('app.color.FFFFFF'))
  637. }
  638. .height('10%')
  639. .width('97.2%')
  640. .justifyContent(FlexAlign.Start)
  641. Row() {
  642. Column({ space: 8 }) {
  643. Row() {
  644. this.buildButton(0, '全部', () => this.handleAllClick())
  645. this.buildButton(1, '已报工', () => this.handleReportedClick())
  646. this.buildButton(2, '未报工', () => this.handleUnreportedClick())
  647. }
  648. .width('72%')
  649. .height('5.3%')
  650. .justifyContent(FlexAlign.Start)
  651. List({ space: 4, scroller: this.scrollerList }) {
  652. ForEach(this.taskSeqArray, (item: TaskSeqVO) => {
  653. ListItem() {
  654. taskSeqItem({
  655. item: item,
  656. scanSeqValue: this.scanCode,
  657. selectedButtonIndex: this.selectedButtonIndex
  658. })
  659. }
  660. })
  661. }
  662. .width('72%')
  663. .height('94.7%')
  664. }
  665. .width('52.9%')
  666. .height('100%')
  667. .alignItems(HorizontalAlign.End)
  668. .padding({ right: '2.6%' })
  669. Divider()
  670. .vertical(true)
  671. .color($r('app.color.15FFFFFF'))
  672. .height('100%')
  673. Column({ space: 5 }) {
  674. Row().height('37%')
  675. Row() {
  676. Text('扫描流水/序列/铭牌号')
  677. .fontSize($r('app.float.fontSize_16'))
  678. .fontWeight(FontWeight.Regular)
  679. .fontColor($r('app.color.FFFFFF'))
  680. }
  681. .width('62%')
  682. Row() {
  683. Row().width('3.4%')
  684. // 左侧二维码图标
  685. Image($r('app.media.material_qr_code'))// 请替换为您的二维码图片资源
  686. .width($r('app.float.virtualSize_24'))
  687. .height($r('app.float.virtualSize_24'))
  688. .fillColor($r('app.color.FFFFFF'))
  689. // 扫码输入框
  690. TextInput({ placeholder: '请扫描物料编码', text: this.scanCode })
  691. .type(InputType.Normal)
  692. .placeholderFont({ size: $r('app.float.fontSize_16') })
  693. .placeholderColor($r('app.color.30FFFFFF'))
  694. .fontSize($r('app.float.fontSize_16'))
  695. .fontColor($r('app.color.FFFFFF'))
  696. .enableKeyboardOnFocus(false)
  697. .onChange((value: string) => {
  698. if (!this.selectWorkOder.workOrderCode || !this.currentUserName || !this.currentStationId) {
  699. return
  700. }
  701. this.scanCode = value
  702. })
  703. .onSubmit(async () => {
  704. if (!this.selectWorkOder.workOrderCode || !this.currentUserName || !this.currentStationId || !this.scanCode) {
  705. return
  706. }
  707. // 流转卡号是否有效
  708. let seqNoFlag = false
  709. for (const element of this.allTaskSeq) {
  710. if (element.seqNo === this.scanCode) {
  711. seqNoFlag = true
  712. break;
  713. }
  714. }
  715. if (!seqNoFlag) {
  716. let queryRes = await ProcessRequest.post('/api/v1/plan/workOrder/taskPage2', {
  717. stationId: this.currentStationId,
  718. seqNo: this.scanCode,
  719. queryComplete: 0,
  720. } as RequestParamModel) as WorkOrderPage;
  721. this.workOrders = queryRes?.records ?? []
  722. if (this.workOrders && this.workOrders.length > 0) {
  723. this.switchWorkOrderController.open()
  724. } else {
  725. promptAction.showToast({
  726. message: `${this.scanCode}不是有效的流水号`,
  727. duration: 1500,
  728. bottom: 100
  729. })
  730. this.scanCode = ''
  731. return
  732. }
  733. return
  734. }
  735. // 查询工序组件
  736. this.getComponentsForNotStartWork()
  737. this.seqNo = this.scanCode
  738. // 保存此流转卡号到数据库中
  739. let seqNos: string[] = []
  740. seqNos = await preferencesUtil.get(CommonConstants.PREFERENCE_INSTANCE_NAME, this.selectWorkOder.workOrderCode, seqNos)
  741. if (seqNos.includes(this.seqNo)) {
  742. return
  743. }
  744. seqNos.push(this.seqNo)
  745. preferencesUtil.put(CommonConstants.PREFERENCE_INSTANCE_NAME, this.selectWorkOder.workOrderCode, seqNos)
  746. this.scanSeqNos = seqNos.length
  747. })
  748. }
  749. .width('65%')
  750. .height('6.5%')
  751. .borderRadius($r('app.float.virtualSize_16'))
  752. .backgroundColor($r('app.color.000000'))
  753. .justifyContent(FlexAlign.Start)
  754. }
  755. .width('52.9%')
  756. .height('100%')
  757. }
  758. .width('100%')
  759. .height('87.7%')
  760. .justifyContent(FlexAlign.Center)
  761. }
  762. .width('79.1%')
  763. .height('100%')
  764. .justifyContent(FlexAlign.Center)
  765. .backgroundColor($r('app.color.20FFFFFF'))
  766. .borderRadius($r('app.float.fontSize_16'))
  767. .opacity(!this.selectWorkOder.workOrderCode || !this.currentUserName || !this.currentStationId ? 0.3 : 1)
  768. } else {
  769. Column() {
  770. List({ space: 4 }) {
  771. ForEach(this.opComponents, (item: OperationComponent, index: number) => {
  772. ListItem() {
  773. Column() {
  774. Stack() {
  775. Image(this.selectComponentType === item.compentType! ? $r('app.media.process_component_state_select') : (this.componentStates.length >= (index + 1) && this.componentStates[index] === 1 ? $r('app.media.process_component_state_finish') : $r('app.media.process_component_state_no_select')))
  776. .height(this.selectComponentType === item.compentType! ? '100%' : '90%')
  777. .width('100%')
  778. .objectFit(ImageFit.Fill)
  779. .borderRadius($r('app.float.fontSize_16'))
  780. Column({ space: 2 }) {
  781. Image(this.componentResMap.get(item.compentType!))
  782. .height($r('app.float.virtualSize_24'))
  783. .width($r('app.float.virtualSize_24'))
  784. .fillColor(this.selectComponentType === item.compentType! ? $r('app.color.99000000') : (this.componentStates.length >= (index + 1) && this.componentStates[index] === 1 ? $r('app.color.30D158') : $r('app.color.FFFFFF')))
  785. Text(item.compentName!)
  786. .fontSize($r('app.float.fontSize_16'))
  787. .fontWeight(FontWeight.Regular)
  788. .fontColor(this.selectComponentType === item.compentType! ? $r('app.color.99000000') : (this.componentStates.length >= (index + 1) && this.componentStates[index] === 1 ? $r('app.color.30D158') : $r('app.color.FFFFFF')))
  789. }
  790. .width('100%')
  791. .height('90%')
  792. .justifyContent(FlexAlign.Center)
  793. }
  794. .width('100%')
  795. .height('100%')
  796. .alignContent(Alignment.Top)
  797. .onClick(() => {
  798. this.selectComponentType = item.compentType!
  799. })
  800. }
  801. .height('100%')
  802. .width('12.5%')
  803. }
  804. })
  805. }
  806. .listDirection(Axis.Horizontal)
  807. .height('9.3%')
  808. .width('79.1%')
  809. // 不同工序组件(工步)展示不同页面
  810. Column() {
  811. if (this.selectComponentType === '1') {
  812. MaterialCollectView({
  813. scanState: this.scanState,
  814. seqNo: this.seqNo,
  815. selectWorkOder: this.selectWorkOder,
  816. selectOperationId: this.selectOperationId,
  817. process: this.process,
  818. })
  819. } else if (this.selectComponentType === '3' && this.scanState === 1) {
  820. MultiMediaCollect({
  821. seqNo: this.seqNo,
  822. selectOperationId: this.selectOperationId,
  823. process: this.process,
  824. })
  825. } else if (this.selectComponentType === '5') {
  826. SelfInspectView({
  827. scanState: this.scanState,
  828. seqNo: this.seqNo,
  829. selectOperationId: this.selectOperationId,
  830. process: this.process,
  831. })
  832. } else if (this.selectComponentType === '6') {
  833. DeviceCheckView({
  834. deviceChecks: this.deviceChecks,
  835. scanState: this.scanState,
  836. seqNo: this.seqNo,
  837. selectOperationId: this.selectOperationId,
  838. process: this.process,
  839. })
  840. }
  841. }
  842. .width('79.1%')
  843. .height('90.7%')
  844. .backgroundColor($r('app.color.20FFFFFF'))
  845. .borderRadius($r('app.float.fontSize_16'))
  846. }
  847. }
  848. }
  849. .height('80%')
  850. .width('94.8%')
  851. .justifyContent(FlexAlign.SpaceBetween)
  852. // 底部按钮和抽屉
  853. Stack() {
  854. Column() {
  855. Blank()
  856. Stack() {
  857. Image($r('app.media.process_drawer_thumbnail'))
  858. .width('100%')
  859. .height('100%')
  860. Image($r('app.media.process_drawer_switch'))
  861. .width($r('app.float.virtualSize_48'))
  862. .height($r('app.float.virtualSize_48'))
  863. .fillColor($r('app.color.60FFFFFF'))
  864. }
  865. .width('100%')
  866. .height('47%')
  867. }
  868. .width('100%')
  869. .height('100%')
  870. Row() {
  871. Row({ space: 4 }) {
  872. Image($r('app.media.process_work_instruction'))
  873. .width($r('app.float.virtualSize_24'))
  874. .height($r('app.float.virtualSize_24'))
  875. .fillColor($r('app.color.0A84FF'))
  876. Text('作业指导')
  877. .fontColor($r('app.color.0A84FF'))
  878. .fontSize($r('app.float.fontSize_24'))
  879. .fontWeight(FontWeight.Medium)
  880. }
  881. .width('10%')
  882. .height('58.3%')
  883. .justifyContent(FlexAlign.Center)
  884. .backgroundColor($r('app.color.20FFFFFF'))
  885. .borderRadius($r('app.float.fontSize_16'))
  886. .onClick(() => {
  887. if (!this.selectWorkOder.workOrderCode) {
  888. return
  889. }
  890. this.workInstructionsController.open()
  891. })
  892. Row().width('1.5%')
  893. Row() {
  894. Stack() {
  895. Row() {
  896. Circle()
  897. .width($r('app.float.virtualSize_12'))
  898. .height($r('app.float.virtualSize_12'))
  899. .fill($r('app.color.FF453A'))
  900. .opacity(this.processVehicleList.length > 0 ? 1 : 0)
  901. }
  902. .width('11.5%')
  903. .height('39%')
  904. .justifyContent(FlexAlign.Start)
  905. .alignItems(VerticalAlign.Bottom)
  906. Row({ space: 4 }) {
  907. Image($r('app.media.process_complete_reception'))
  908. .width($r('app.float.virtualSize_24'))
  909. .height($r('app.float.virtualSize_24'))
  910. .fillColor($r('app.color.0A84FF'))
  911. Text('齐套接收')
  912. .fontColor($r('app.color.0A84FF'))
  913. .fontSize($r('app.float.fontSize_24'))
  914. .fontWeight(FontWeight.Medium)
  915. }
  916. .width('100%')
  917. .height('100%')
  918. .justifyContent(FlexAlign.Center)
  919. .backgroundColor($r('app.color.20FFFFFF'))
  920. .borderRadius($r('app.float.fontSize_16'))
  921. }
  922. .width('100%')
  923. .height('100%')
  924. .alignContent(Alignment.TopEnd)
  925. }
  926. .width('10%')
  927. .height('58.3%')
  928. .onClick(async () => {
  929. if (!this.selectWorkOder.workOrderCode || !this.selectOperationId) {
  930. return
  931. }
  932. this.loadProcessVehicle()
  933. if (this.processVehicleList.length > 0) {
  934. this.completeReceiveController.open()
  935. return
  936. }
  937. // 没有齐套物料,则发送叫料消息
  938. let result: string = await ProcessRequest.post('/api/v1/process/vehicleOperation/materialOut', {
  939. workOrderCode: this.selectWorkOder.workOrderCode!,
  940. operationId: this.selectOperationId,
  941. stationId: this.currentStationId
  942. } as RequestParamModel)
  943. promptAction.showToast({
  944. message: result,
  945. duration: 1500,
  946. })
  947. })
  948. Blank()
  949. .onClick(() => {
  950. this.isAuxiliaryViewOpen = true
  951. })
  952. Column({ space: 2 }) {
  953. Row() {
  954. Text(this.scanSeqNos + '/')
  955. .fontColor($r('app.color.FFFFFF'))
  956. .fontSize($r('app.float.fontSize_16'))
  957. .fontWeight(FontWeight.Lighter)
  958. Text((this.selectWorkOder && this.selectWorkOder.workOrderCode) ? parseInt(this.selectWorkOder.planNum).toString() : '')
  959. .fontColor($r('app.color.60FFFFFF'))
  960. .fontSize($r('app.float.fontSize_16'))
  961. .fontWeight(FontWeight.Lighter)
  962. }
  963. .width('100%')
  964. .height('50%')
  965. .justifyContent(FlexAlign.End)
  966. .alignItems(VerticalAlign.Bottom)
  967. Row() {
  968. if (this.seqNo.length > 0) {
  969. Text('S/N ')
  970. .fontColor($r('app.color.FFFFFF'))
  971. .fontSize($r('app.float.fontSize_16'))
  972. .fontWeight(FontWeight.Lighter)
  973. Text(this.seqNo)
  974. .fontColor($r('app.color.FFFFFF'))
  975. .fontSize($r('app.float.fontSize_16'))
  976. .fontWeight(FontWeight.Bold)
  977. }
  978. }
  979. .width('100%')
  980. .height('50%')
  981. .justifyContent(FlexAlign.End)
  982. .alignItems(VerticalAlign.Top)
  983. }
  984. .width('10.8%')
  985. .height('100%')
  986. Row().width('1%')
  987. Row({ space: 4 }) {
  988. Image($r('app.media.process_switch'))
  989. .width($r('app.float.virtualSize_24'))
  990. .height($r('app.float.virtualSize_24'))
  991. .fillColor($r('app.color.0A84FF'))
  992. Text('切换产品')
  993. .fontColor($r('app.color.0A84FF'))
  994. .fontSize($r('app.float.fontSize_24'))
  995. .fontWeight(FontWeight.Medium)
  996. }
  997. .width('10%')
  998. .height('58.3%')
  999. .justifyContent(FlexAlign.Center)
  1000. .backgroundColor($r('app.color.20FFFFFF'))
  1001. .borderRadius($r('app.float.fontSize_16'))
  1002. .onClick(() => {
  1003. if (!this.selectWorkOder.workOrderCode || !this.currentUserName || !this.currentStationId || !this.selectOperationId) {
  1004. return
  1005. }
  1006. this.switchingProductDialogController.open()
  1007. })
  1008. Row().width('1.5%')
  1009. Row({ space: 4 }) {
  1010. Image(this.scanState === 1 ? $r('app.media.process_report') : $r('app.media.process_start_work'))
  1011. .width($r('app.float.virtualSize_24'))
  1012. .height($r('app.float.virtualSize_24'))
  1013. .fillColor($r('app.color.FFFFFF'))
  1014. Text(this.scanState === 1 ? '工序报工' : '工序开工')
  1015. .fontColor($r('app.color.FFFFFF'))
  1016. .fontSize($r('app.float.fontSize_24'))
  1017. .fontWeight(FontWeight.Medium)
  1018. }
  1019. .width('10%')
  1020. .height('58.3%')
  1021. .justifyContent(FlexAlign.Center)
  1022. .backgroundColor(this.scanState === 1 ? $r('app.color.30D158') : $r('app.color.0A84FF'))
  1023. .borderRadius($r('app.float.fontSize_16'))
  1024. .onClick(async () => {
  1025. if (!this.scanCode || this.scanCode.length <= 0) {
  1026. promptAction.showToast({
  1027. message: `请先扫描流水/序列/铭牌号`,
  1028. duration: 1500,
  1029. bottom: 100
  1030. })
  1031. return
  1032. }
  1033. if (!this.selectOperationId || this.selectOperationId.length <= 0) {
  1034. promptAction.showToast({
  1035. message: `请先选择工序`,
  1036. duration: 1500,
  1037. bottom: 100
  1038. })
  1039. return
  1040. }
  1041. if (this.scanState === 0) {
  1042. this.scanState = 1
  1043. this.loadProcessVehicle()
  1044. // this.scanCodeToStartWork()
  1045. } else if (this.scanState === 1) {
  1046. this.reportTimeBasedController.open()
  1047. }
  1048. })
  1049. }
  1050. .height('90.6%')
  1051. .width('100%')
  1052. .padding({ left: '2.6%', right: '2.6%' })
  1053. .opacity(!this.selectWorkOder.workOrderCode || !this.currentUserName || !this.currentStationId ? 0.3 : 1)
  1054. }
  1055. .width('100%')
  1056. .height('9.8%')
  1057. .alignContent(Alignment.Top)
  1058. }
  1059. .width('100%')
  1060. .height('100%')
  1061. .backgroundColor($r('app.color.000000'))
  1062. if (this.isAuxiliaryViewOpen) {
  1063. Column() {
  1064. AuxiliaryOperationView({
  1065. workOrderCode: this.selectWorkOder?.workOrderCode!,
  1066. seqList: this.seqList,
  1067. isAuxiliaryViewOpen:this.isAuxiliaryViewOpen,
  1068. process: this.process,
  1069. openLittleMaterialRequestDialog: ()=>{
  1070. this.littleMaterialRequestController.open()
  1071. },
  1072. openBarcodeAssociationDialog: ()=>{
  1073. this.barcodeAssociationController.open()
  1074. },
  1075. openInAndOutBoundDialog: ()=>{
  1076. this.inAndOutBoundController.open()
  1077. },
  1078. openPictureDrawingDialog: ()=>{
  1079. this.pictureDrawingController.open()
  1080. },
  1081. openDeviceInspectionDialog: ()=>{
  1082. this.deviceInspectionController.open()
  1083. },
  1084. })
  1085. .height('93.5%')
  1086. .width('100%')
  1087. }
  1088. .height('100%')
  1089. .width('100%')
  1090. .justifyContent(FlexAlign.End)
  1091. //向下滑动关闭抽屉
  1092. .gesture(
  1093. GestureGroup(
  1094. GestureMode.Sequence,
  1095. PanGesture({ direction: PanDirection.Down })
  1096. .onActionStart(() => {
  1097. this.isAuxiliaryViewOpen = false
  1098. })
  1099. )
  1100. )
  1101. .transition(
  1102. TransitionEffect.OPACITY
  1103. .combine(TransitionEffect.translate({ y: 1000 }))
  1104. .animation({
  1105. duration:1500,
  1106. curve: Curve.EaseOut
  1107. })
  1108. )
  1109. .opacity(this.isAuxiliaryViewOpen ? 1 : 0)
  1110. .translate({ y: this.isAuxiliaryViewOpen ? 0 : 1000 })
  1111. }
  1112. }
  1113. .height('100%')
  1114. .width('100%')
  1115. //向上滑动打开抽屉
  1116. .gesture(
  1117. GestureGroup(
  1118. GestureMode.Sequence,
  1119. PanGesture({ direction: PanDirection.Up })
  1120. .onActionStart(() => {
  1121. this.isAuxiliaryViewOpen = true
  1122. })
  1123. )
  1124. )
  1125. }
  1126. @Builder
  1127. buildButton(index: number, text: string, onClick: () => void) {
  1128. Row({space: 5}){
  1129. if(this.selectedButtonIndex === index) {
  1130. Image($r('app.media.process_radio_check'))
  1131. .width($r('app.float.virtualSize_24'))
  1132. .height($r('app.float.virtualSize_24'))
  1133. .fillColor($r('app.color.0A84FF'))
  1134. } else {
  1135. Image($r('app.media.process_radio_no_check'))
  1136. .width($r('app.float.virtualSize_24'))
  1137. .height($r('app.float.virtualSize_24'))
  1138. .fillColor($r('app.color.FFFFFF'))
  1139. }
  1140. Text(text)
  1141. .fontSize($r('app.float.fontSize_16'))
  1142. .fontColor($r('app.color.FFFFFF'))
  1143. }
  1144. .justifyContent(FlexAlign.Center)
  1145. .width('24.3%')
  1146. .height('100%')
  1147. .backgroundColor(this.selectedButtonIndex === index ? $r('app.color.200A84FF') : $r('app.color.20FFFFFF')) // 选中蓝/未选中灰
  1148. .borderRadius($r('app.float.virtualSize_16'))
  1149. .margin({ right:'3%'})
  1150. .onClick(() => {
  1151. this.selectedButtonIndex = index
  1152. onClick();
  1153. })
  1154. }
  1155. // 选择工单弹窗控制器
  1156. selectOrderController: CustomDialogController = new CustomDialogController({
  1157. builder: SelectWorkOrderDialog({
  1158. selectWorkOder: this.selectWorkOder,
  1159. onConfirm: ()=>{
  1160. this.clearSelectData()
  1161. }
  1162. }),
  1163. autoCancel: true, // 点击遮罩关闭
  1164. customStyle: true,
  1165. alignment:DialogAlignment.Center,
  1166. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1167. })
  1168. // 选择工位和用户弹窗控制器
  1169. loginInfoController: CustomDialogController = new CustomDialogController({
  1170. builder: LoginInfoDialog({
  1171. scanState: this.scanState,
  1172. opComponents: this.opComponents,
  1173. selectComponentType: this.selectComponentType,
  1174. searchDept:()=>{this.SwitchDeptController.open()},
  1175. searchStation:()=>{this.SwitchStationController.open()},
  1176. searchProductLine:()=>{this.SwitchProductLineController.open()},
  1177. }),
  1178. autoCancel: true, // 点击遮罩关闭
  1179. customStyle: true,
  1180. alignment:DialogAlignment.Center,
  1181. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1182. })
  1183. //切换部门弹窗控制器
  1184. SwitchDeptController: CustomDialogController = new CustomDialogController({
  1185. builder: SwitchDeptDialog({}),
  1186. autoCancel: true, // 点击遮罩关闭
  1187. customStyle: true,
  1188. alignment:DialogAlignment.Center,
  1189. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1190. })
  1191. // 工序报工-报工数量弹窗
  1192. ReportWorkNumController: CustomDialogController = new CustomDialogController({
  1193. builder: ReportWorkNumDialog({
  1194. userName: this.reporterList[this.currentReportNumIndex].userName,
  1195. currentOperationId: this.selectOperationId,
  1196. currentWorkOrderCode: this.selectWorkOder.workOrderCode!,
  1197. onConfirm:(num:number)=>{
  1198. const index = this.currentReportNumIndex;
  1199. if (this.reporterList[index]) {
  1200. this.reporterList[index].reportNum = String(num);
  1201. this.reporterList = [...this.reporterList];
  1202. }
  1203. }
  1204. }),
  1205. autoCancel: true,
  1206. customStyle: true,
  1207. alignment:DialogAlignment.Center,
  1208. maskColor: 'rgba(0,0,0,0.8)',
  1209. })
  1210. // 工序报工-不良品报工弹窗
  1211. defectNumReportController: CustomDialogController = new CustomDialogController({
  1212. builder: ReportDefectNumDialog({
  1213. userName: this.reporterList[this.currentDefectIndex].userName,
  1214. onConfirm:(num:number)=>{
  1215. const index = this.currentDefectIndex;
  1216. if (this.reporterList[index]) {
  1217. this.reporterList[index].defectNum = String(num);
  1218. this.reporterList = [...this.reporterList];
  1219. }
  1220. }
  1221. }),
  1222. autoCancel: true,
  1223. customStyle: true,
  1224. alignment:DialogAlignment.Center,
  1225. maskColor: 'rgba(0,0,0,0.8)',
  1226. })
  1227. // 工序报工-用户用时占比
  1228. reportWorkHourRateController: CustomDialogController = new CustomDialogController({
  1229. builder: ReportWorkHourRateDialog({
  1230. onConfirm:(rateNum: number)=>{
  1231. const index = this.currentDefectIndex;
  1232. if (this.reporterList[index]) {
  1233. this.reporterList[index].workingHoursRate = rateNum / 100;
  1234. this.reporterList = [...this.reporterList];
  1235. }
  1236. }
  1237. }),
  1238. autoCancel: true,
  1239. customStyle: true,
  1240. alignment: DialogAlignment.Center,
  1241. maskColor: 'rgba(0,0,0,0.8)',
  1242. })
  1243. // 工序报工-添加参与人员
  1244. JoinPersonNameController: CustomDialogController = new CustomDialogController({
  1245. builder: JoinPersonNameDialog({
  1246. reporterList:this.reporterList,
  1247. currentReporterIndex:this.currentReporterIndex,
  1248. }),
  1249. autoCancel: true,
  1250. customStyle: true,
  1251. alignment:DialogAlignment.Center,
  1252. maskColor: 'rgba(0,0,0,0.8)',
  1253. })
  1254. // 工序报工(计件)弹窗
  1255. reportPieceworkController: CustomDialogController = new CustomDialogController({
  1256. builder: ReportPieceworkDialog({
  1257. onSelectReporter:(index:number)=>{
  1258. this.currentReporterIndex = index;
  1259. this.JoinPersonNameController.open();
  1260. },
  1261. onSelectReportNum:(index:number)=>{
  1262. if (!this.reporterList[index]?.userName?.trim()) {
  1263. promptAction.showToast({
  1264. message: '请先添加用户',
  1265. duration: 2000
  1266. });
  1267. return;
  1268. }
  1269. this.currentReportNumIndex = index
  1270. this.ReportWorkNumController.open()
  1271. },
  1272. onSelectDefectNum:(index:number)=>{
  1273. if (!this.reporterList[index]?.userName?.trim()) {
  1274. promptAction.showToast({
  1275. message: '请先添加用户',
  1276. duration: 2000
  1277. });
  1278. return;
  1279. }
  1280. this.currentDefectIndex = index
  1281. this.defectNumReportController.open()
  1282. },
  1283. clearSelectData:()=>{
  1284. this.clearSelectData()
  1285. },
  1286. reporterList:this.reporterList,
  1287. selectWorkOder: this.selectWorkOder,
  1288. selectOperationName: this.selectOperationName,
  1289. selectOperationId: this.selectOperationId,
  1290. process: this.process,
  1291. operationPerformance: this.operationPerformance,
  1292. }),
  1293. autoCancel: true,
  1294. customStyle: true,
  1295. alignment:DialogAlignment.Center,
  1296. maskColor: 'rgba(0,0,0,0.8)',
  1297. })
  1298. // 工序报工(计时)弹窗
  1299. reportTimeBasedController: CustomDialogController = new CustomDialogController({
  1300. builder: ReportTimeBasedDialog({
  1301. onSelectReporter:(index: number)=>{
  1302. this.currentReporterIndex = index;
  1303. this.JoinPersonNameController.open();
  1304. },
  1305. onSelectReportNum:(index: number)=>{
  1306. if (!this.reporterList[index]?.userName?.trim()) {
  1307. promptAction.showToast({
  1308. message: '请先添加用户',
  1309. duration: 2000
  1310. });
  1311. return;
  1312. }
  1313. this.currentReportNumIndex = index
  1314. this.ReportWorkNumController.open()
  1315. },
  1316. onSelectDefectNum:(index: number)=>{
  1317. if (!this.reporterList[index]?.userName?.trim()) {
  1318. promptAction.showToast({
  1319. message: '请先添加用户',
  1320. duration: 2000
  1321. });
  1322. return;
  1323. }
  1324. this.currentDefectIndex = index
  1325. this.defectNumReportController.open()
  1326. },
  1327. onSelectWorkHourRate:(index: number)=>{
  1328. if (!this.reporterList[index]?.userName?.trim()) {
  1329. promptAction.showToast({
  1330. message: '请先添加用户',
  1331. duration: 2000
  1332. });
  1333. return;
  1334. }
  1335. this.currentDefectIndex = index
  1336. this.reportWorkHourRateController.open()
  1337. },
  1338. clearSelectData:()=>{
  1339. this.clearSelectData()
  1340. },
  1341. reporterList:this.reporterList,
  1342. selectWorkOder: this.selectWorkOder,
  1343. selectOperationName: this.selectOperationName,
  1344. selectOperationId: this.selectOperationId,
  1345. process: this.process,
  1346. }),
  1347. autoCancel: true,
  1348. customStyle: true,
  1349. alignment:DialogAlignment.Center,
  1350. maskColor: 'rgba(0,0,0,0.8)',
  1351. })
  1352. // 切换产线弹窗控制器
  1353. SwitchProductLineController: CustomDialogController = new CustomDialogController({
  1354. builder: SwitchProductLineDialog({}),
  1355. autoCancel: true, // 点击遮罩关闭
  1356. customStyle: true,
  1357. alignment:DialogAlignment.Center,
  1358. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1359. })
  1360. // 切换工位弹窗控制器
  1361. SwitchStationController: CustomDialogController = new CustomDialogController({
  1362. builder: SwitchStationDialog({}),
  1363. autoCancel: true, // 点击遮罩关闭
  1364. customStyle: true,
  1365. alignment:DialogAlignment.Center,
  1366. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1367. })
  1368. //切换用户弹窗控制器
  1369. switchingUserController: CustomDialogController = new CustomDialogController({
  1370. builder: SwitchUserDialog({}),
  1371. autoCancel: true, // 点击遮罩关闭
  1372. customStyle: true,
  1373. alignment:DialogAlignment.Center,
  1374. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1375. })
  1376. // 产品不属于当前工单时,切换工单确认弹窗控制器
  1377. switchWorkOrderController: CustomDialogController = new CustomDialogController({
  1378. builder: ConfirmDialog({
  1379. title: '切换工单确认',
  1380. message: '扫描的流水号不属于本工单,是否切换工单?',
  1381. onConfirm: ()=> {
  1382. this.selectWorkOder = this.workOrders[0]
  1383. this.selectOperationId = ''
  1384. this.seqNo = this.scanCode
  1385. this.seqList = []
  1386. this.scanState = 0
  1387. this.process = {}
  1388. this.opComponents = []
  1389. this.taskSeqArray = []
  1390. this.switchingProductDialogController.close()
  1391. },
  1392. }),
  1393. autoCancel: true,
  1394. alignment: DialogAlignment.Center,
  1395. // gridCount: 3,
  1396. customStyle: true,
  1397. })
  1398. // 切换产品弹窗控制器
  1399. switchingProductDialogController: CustomDialogController = new CustomDialogController({
  1400. builder: SwitchProductDialog({
  1401. scanState: this.scanState,
  1402. process: this.process,
  1403. scanSeqValue: this.scanCode,
  1404. selectWorkOder: this.selectWorkOder,
  1405. currentOperationId: this.selectOperationId,
  1406. opComponents: this.opComponents,
  1407. seqNo: this.seqNo,
  1408. scanSeqNos: this.scanSeqNos,
  1409. workOrders: this.workOrders,
  1410. switchWorkOrderConfirm: ()=>{
  1411. this.switchWorkOrderController.open()
  1412. },
  1413. }),
  1414. autoCancel: true, // 点击遮罩关闭
  1415. customStyle: true,
  1416. alignment:DialogAlignment.Center,
  1417. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1418. })
  1419. // 作业指导弹窗控制器
  1420. workInstructionsController: CustomDialogController = new CustomDialogController({
  1421. builder: WorkInstructionsDialog({
  1422. materialCode: this.selectWorkOder.materialCode!,
  1423. }),
  1424. autoCancel: true, // 点击遮罩关闭
  1425. customStyle: true,
  1426. alignment:DialogAlignment.Center,
  1427. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1428. })
  1429. // 齐套接收弹窗控制器
  1430. completeReceiveController: CustomDialogController = new CustomDialogController({
  1431. builder: CompleteReceiveDialog({
  1432. currentWorkOrderCode: this.selectWorkOder.workOrderCode!,
  1433. currentOperationId: this.selectOperationId,
  1434. processVehicleList: this.processVehicleList,
  1435. }),
  1436. autoCancel: true, // 点击遮罩关闭
  1437. customStyle: true,
  1438. alignment:DialogAlignment.Center,
  1439. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1440. })
  1441. // 零星叫料弹窗控制器
  1442. littleMaterialRequestController: CustomDialogController = new CustomDialogController({
  1443. builder: LittleMaterialRequestDialog({
  1444. process: this.process,
  1445. selectWorkOder: this.selectWorkOder,
  1446. }),
  1447. autoCancel: true, // 点击遮罩关闭
  1448. customStyle: true,
  1449. alignment:DialogAlignment.Center,
  1450. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1451. })
  1452. // 仓储操作弹窗控制器
  1453. inAndOutBoundController: CustomDialogController = new CustomDialogController({
  1454. builder: InAndOutBoundDialog({
  1455. }),
  1456. autoCancel: true, // 点击遮罩关闭
  1457. customStyle: true,
  1458. alignment:DialogAlignment.Center,
  1459. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1460. })
  1461. // 条码关联弹窗控制器
  1462. barcodeAssociationController: CustomDialogController = new CustomDialogController({
  1463. builder: BarcodeAssociationDialog({
  1464. workOrderCode: this.selectWorkOder?.workOrderCode!,
  1465. seqList: this.seqList
  1466. }),
  1467. autoCancel: true, // 点击遮罩关闭
  1468. customStyle: true,
  1469. alignment:DialogAlignment.Center,
  1470. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1471. })
  1472. // 图纸资料弹窗控制器
  1473. pictureDrawingController: CustomDialogController = new CustomDialogController({
  1474. builder: PictureDrawingDialog({
  1475. materialCode: this.selectWorkOder?.materialCode!
  1476. }),
  1477. autoCancel: true, // 点击遮罩关闭
  1478. customStyle: true,
  1479. alignment:DialogAlignment.Center,
  1480. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1481. })
  1482. // 设备点检弹窗
  1483. deviceInspectionController: CustomDialogController = new CustomDialogController({
  1484. builder: DeviceInspectionDialog({
  1485. deviceChecks: this.deviceChecks,
  1486. }),
  1487. autoCancel: true, // 点击遮罩关闭
  1488. customStyle: true,
  1489. alignment:DialogAlignment.Center,
  1490. maskColor: 'rgba(0,0,0,0.8)', // 黑色遮罩
  1491. })
  1492. }