ProcessIndex.ets 60 KB

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