Commit 793b01fafe8c8d3a834c09f016400eadf85a9b76
1 parent
b5b0ca8a
下拉选择框增加筛选功能
Showing
6 changed files
with
602 additions
and
40 deletions
src/mobile/common/CommobileComponent.js
| 1 | /* eslint-disable */ | 1 | /* eslint-disable */ |
| 2 | import { List, InputItem, Picker, TextareaItem, DatePicker, Checkbox, Toast } from 'antd-mobile-v2'; | 2 | import { List, InputItem, Picker, TextareaItem, DatePicker, Checkbox, Toast } from 'antd-mobile-v2'; |
| 3 | +import SearchablePicker from '@/mobile/components/searchPicker' | ||
| 3 | import moment from 'moment'; | 4 | import moment from 'moment'; |
| 4 | import React, { Component } from 'react'; | 5 | import React, { Component } from 'react'; |
| 5 | import { debounce } from 'lodash'; | 6 | import { debounce } from 'lodash'; |
| @@ -30,7 +31,8 @@ export default class CommonComponent extends Component { | @@ -30,7 +31,8 @@ export default class CommonComponent extends Component { | ||
| 30 | dropDownData: [], | 31 | dropDownData: [], |
| 31 | // eslint-disable-next-line react/no-unused-state | 32 | // eslint-disable-next-line react/no-unused-state |
| 32 | bReGetDropDown: false, | 33 | bReGetDropDown: false, |
| 33 | - bOpenKeyboard : props.bOpenKeyboard, | 34 | + bOpenKeyboard: props.bOpenKeyboard, |
| 35 | + pickerVisble: false | ||
| 34 | 36 | ||
| 35 | }; | 37 | }; |
| 36 | this.firstDataIndex = props.showConfig.sName.substring(0, 1); /* 控件首字母(数据格式:字符串) */ | 38 | this.firstDataIndex = props.showConfig.sName.substring(0, 1); /* 控件首字母(数据格式:字符串) */ |
| @@ -119,7 +121,7 @@ export default class CommonComponent extends Component { | @@ -119,7 +121,7 @@ export default class CommonComponent extends Component { | ||
| 119 | dataValue, enabled, dropDownData, sFieldName, bNotEmpty, masterData, | 121 | dataValue, enabled, dropDownData, sFieldName, bNotEmpty, masterData, |
| 120 | } = this.state; | 122 | } = this.state; |
| 121 | // console.log('bOpenKeyboard:', nextProps.bOpenKeyboard); | 123 | // console.log('bOpenKeyboard:', nextProps.bOpenKeyboard); |
| 122 | - if(nextProps.bOpenKeyboard !==undefined) { | 124 | + if (nextProps.bOpenKeyboard !== undefined) { |
| 123 | return true; | 125 | return true; |
| 124 | } | 126 | } |
| 125 | return nextProps.showConfig !== undefined && (dataValue !== nextState.dataValue || enabled !== nextState.enabled || | 127 | return nextProps.showConfig !== undefined && (dataValue !== nextState.dataValue || enabled !== nextState.enabled || |
| @@ -253,6 +255,7 @@ export default class CommonComponent extends Component { | @@ -253,6 +255,7 @@ export default class CommonComponent extends Component { | ||
| 253 | 255 | ||
| 254 | /** 处理下拉选择事件 */ | 256 | /** 处理下拉选择事件 */ |
| 255 | handleSelectOptionEvent = (newValue) => { | 257 | handleSelectOptionEvent = (newValue) => { |
| 258 | + console.log("🚀 ~ CommonComponent ~ newValue:", newValue) | ||
| 256 | /* 下拉新增单独处理 */ | 259 | /* 下拉新增单独处理 */ |
| 257 | let value = newValue; | 260 | let value = newValue; |
| 258 | this.isDropdownFilter = true; | 261 | this.isDropdownFilter = true; |
| @@ -277,11 +280,11 @@ export default class CommonComponent extends Component { | @@ -277,11 +280,11 @@ export default class CommonComponent extends Component { | ||
| 277 | const returnValue = {}; | 280 | const returnValue = {}; |
| 278 | /* 回带值赋值(sName:value) */ | 281 | /* 回带值赋值(sName:value) */ |
| 279 | returnValue[this.props.showConfig.sName] = | 282 | returnValue[this.props.showConfig.sName] = |
| 280 | - // eslint-disable-next-line radix | ||
| 281 | - this.firstDataIndex === 'i' ? commonUtils.isEmpty(value) ? undefined : parseInt(value) : | ||
| 282 | - this.firstDataIndex === 'd' ? commonUtils.isEmpty(value) ? '' : this.floatNumberCheck(value) : | ||
| 283 | - this.firstDataIndex === 't' ? commonUtils.isEmpty(value) ? null : value : | ||
| 284 | - this.firstDataIndex === 'b' ? value.target.checked : value === null ? undefined : value; | 283 | + // eslint-disable-next-line radix |
| 284 | + this.firstDataIndex === 'i' ? commonUtils.isEmpty(value) ? undefined : parseInt(value) : | ||
| 285 | + this.firstDataIndex === 'd' ? commonUtils.isEmpty(value) ? '' : this.floatNumberCheck(value) : | ||
| 286 | + this.firstDataIndex === 't' ? commonUtils.isEmpty(value) ? null : value : | ||
| 287 | + this.firstDataIndex === 'b' ? value.target.checked : value === null ? undefined : value; | ||
| 285 | const { sAssignField } = this.props.showConfig; | 288 | const { sAssignField } = this.props.showConfig; |
| 286 | const [changeData] = this.state.dropDownData.filter(item => (!commonUtils.isEmpty(item.sSlaveId) ? item.sSlaveId : item.sId) === value.toString()); | 289 | const [changeData] = this.state.dropDownData.filter(item => (!commonUtils.isEmpty(item.sSlaveId) ? item.sSlaveId : item.sId) === value.toString()); |
| 287 | if (!commonUtils.isEmpty(sAssignField)) { | 290 | if (!commonUtils.isEmpty(sAssignField)) { |
| @@ -310,13 +313,13 @@ export default class CommonComponent extends Component { | @@ -310,13 +313,13 @@ export default class CommonComponent extends Component { | ||
| 310 | }; | 313 | }; |
| 311 | 314 | ||
| 312 | handleFocus = () => { | 315 | handleFocus = () => { |
| 313 | - if(this.props.onFocus) { | 316 | + if (this.props.onFocus) { |
| 314 | this.props.onFocus(this.props.showConfig); | 317 | this.props.onFocus(this.props.showConfig); |
| 315 | } | 318 | } |
| 316 | } | 319 | } |
| 317 | 320 | ||
| 318 | handleBlur = () => { | 321 | handleBlur = () => { |
| 319 | - if(this.props.onBlur) { | 322 | + if (this.props.onBlur) { |
| 320 | this.props.onBlur(this.props.showConfig); | 323 | this.props.onBlur(this.props.showConfig); |
| 321 | } | 324 | } |
| 322 | } | 325 | } |
| @@ -367,8 +370,8 @@ export default class CommonComponent extends Component { | @@ -367,8 +370,8 @@ export default class CommonComponent extends Component { | ||
| 367 | }; | 370 | }; |
| 368 | 371 | ||
| 369 | cancelValue = () => { | 372 | cancelValue = () => { |
| 370 | - const bClear = this.props.showConfig.sName!=='sLocationId' && this.props.showConfig.sName!=='sLocationNo' && this.props.showConfig.sName!=='sLocationName'; | ||
| 371 | - if(bClear) { | 373 | + const bClear = this.props.showConfig.sName !== 'sLocationId' && this.props.showConfig.sName !== 'sLocationNo' && this.props.showConfig.sName !== 'sLocationName'; |
| 374 | + if (bClear) { | ||
| 372 | if (this.inputRef) this.inputRef.clearInput(); | 375 | if (this.inputRef) this.inputRef.clearInput(); |
| 373 | } | 376 | } |
| 374 | } | 377 | } |
| @@ -387,8 +390,8 @@ export default class CommonComponent extends Component { | @@ -387,8 +390,8 @@ export default class CommonComponent extends Component { | ||
| 387 | render() { | 390 | render() { |
| 388 | const { sDateFormat: sDateFormatOld, sFieldValidation, bNotEmpty, bOpenKeyboard } = this.props.showConfig; | 391 | const { sDateFormat: sDateFormatOld, sFieldValidation, bNotEmpty, bOpenKeyboard } = this.props.showConfig; |
| 389 | let newValue = this.props.dataValue; | 392 | let newValue = this.props.dataValue; |
| 390 | - if(commonUtils.isNotEmptyObject(sFieldValidation)) { | ||
| 391 | - const [length1, length2] = commonUtils.isNotEmptyObject(sFieldValidation) ? sFieldValidation.split(',') :[]; | 393 | + if (commonUtils.isNotEmptyObject(sFieldValidation)) { |
| 394 | + const [length1, length2] = commonUtils.isNotEmptyObject(sFieldValidation) ? sFieldValidation.split(',') : []; | ||
| 392 | if (length2 !== undefined) { | 395 | if (length2 !== undefined) { |
| 393 | newValue = commonUtils.convertFixNum(this.props.dataValue, Number(length2)); | 396 | newValue = commonUtils.convertFixNum(this.props.dataValue, Number(length2)); |
| 394 | } | 397 | } |
| @@ -396,7 +399,7 @@ export default class CommonComponent extends Component { | @@ -396,7 +399,7 @@ export default class CommonComponent extends Component { | ||
| 396 | let sTitle = this.props.showConfig.showName; | 399 | let sTitle = this.props.showConfig.showName; |
| 397 | if (bNotEmpty) { /* 必填加星号 */ | 400 | if (bNotEmpty) { /* 必填加星号 */ |
| 398 | sTitle = <div className='th-div' ><span className={styles.requireStyle}>*</span> {this.props.showConfig.showName}</div>; | 401 | sTitle = <div className='th-div' ><span className={styles.requireStyle}>*</span> {this.props.showConfig.showName}</div>; |
| 399 | - }else { | 402 | + } else { |
| 400 | sTitle = <div className='th-div' > {this.props.showConfig.showName}</div>; | 403 | sTitle = <div className='th-div' > {this.props.showConfig.showName}</div>; |
| 401 | } | 404 | } |
| 402 | const outFormItemProps = { | 405 | const outFormItemProps = { |
| @@ -418,20 +421,32 @@ export default class CommonComponent extends Component { | @@ -418,20 +421,32 @@ export default class CommonComponent extends Component { | ||
| 418 | outFormItemProps.onVisibleChange = (visible) => { | 421 | outFormItemProps.onVisibleChange = (visible) => { |
| 419 | if (!visible) return; | 422 | if (!visible) return; |
| 420 | Toast.loading('加载中 ....', 0); | 423 | Toast.loading('加载中 ....', 0); |
| 421 | - this.getDropDownData(this.props, false).finally( () => { | 424 | + this.getDropDownData(this.props, false).finally(() => { |
| 422 | Toast.hide(); | 425 | Toast.hide(); |
| 423 | }); | 426 | }); |
| 424 | } | 427 | } |
| 428 | + // input = ( | ||
| 429 | + // <Picker data={this.getSelectOption()} cols={1} {...outFormItemProps} className="forss"> | ||
| 430 | + // <List.Item arrow="horizontal"> | ||
| 431 | + // {this.props.iconSettingShow ? | ||
| 432 | + // // eslint-disable-next-line jsx-a11y/alt-text | ||
| 433 | + // <img src={iconSetting} style={{ verticalAlign: 'sub', marginRight: '15px' }} alt="" /> : ''} | ||
| 434 | + // {sTitle} | ||
| 435 | + // </List.Item> | ||
| 436 | + // </Picker> | ||
| 437 | + // ); | ||
| 438 | + | ||
| 425 | input = ( | 439 | input = ( |
| 426 | - <Picker data={this.getSelectOption()} cols={1} {...outFormItemProps} className="forss"> | ||
| 427 | - <List.Item arrow="horizontal"> | ||
| 428 | - {this.props.iconSettingShow ? | ||
| 429 | - // eslint-disable-next-line jsx-a11y/alt-text | ||
| 430 | - <img src={iconSetting} style={{ verticalAlign: 'sub', marginRight: '15px' }} alt="" /> : ''} | ||
| 431 | - {sTitle} | ||
| 432 | - </List.Item> | ||
| 433 | - </Picker> | ||
| 434 | - ); | 440 | + <SearchablePicker |
| 441 | + data={this.getSelectOption()} | ||
| 442 | + cols={1} | ||
| 443 | + sTitle={sTitle} | ||
| 444 | + {...outFormItemProps} | ||
| 445 | + className="forss" | ||
| 446 | + iconSettingShow={this.props.iconSettingShow} | ||
| 447 | + /> | ||
| 448 | + | ||
| 449 | + ) | ||
| 435 | } else if (this.firstDataIndex === 's') { | 450 | } else if (this.firstDataIndex === 's') { |
| 436 | if (this.props.textArea) { /* 大文本输入框 */ | 451 | if (this.props.textArea) { /* 大文本输入框 */ |
| 437 | input = (<TextareaItem title={this.props.showConfig.showName} {...outFormItemProps} autoHeight />); | 452 | input = (<TextareaItem title={this.props.showConfig.showName} {...outFormItemProps} autoHeight />); |
| @@ -439,7 +454,7 @@ export default class CommonComponent extends Component { | @@ -439,7 +454,7 @@ export default class CommonComponent extends Component { | ||
| 439 | const pdaPro = { | 454 | const pdaPro = { |
| 440 | disabled: !this.state.enabled, | 455 | disabled: !this.state.enabled, |
| 441 | placeholder: this.props.showConfig.placeholder || '请输入或扫码', | 456 | placeholder: this.props.showConfig.placeholder || '请输入或扫码', |
| 442 | - onFocus:this.handleFocus, | 457 | + onFocus: this.handleFocus, |
| 443 | virtualkeyboardpolicy: 'manual', | 458 | virtualkeyboardpolicy: 'manual', |
| 444 | inputmode: 'none', | 459 | inputmode: 'none', |
| 445 | }; | 460 | }; |
src/mobile/common/CommobileListEvent.js
| @@ -9,7 +9,7 @@ import * as commonUtils from '../../utils/utils'; /* 通用方法 */ | @@ -9,7 +9,7 @@ import * as commonUtils from '../../utils/utils'; /* 通用方法 */ | ||
| 9 | import commonConfig from '../../utils/config'; | 9 | import commonConfig from '../../utils/config'; |
| 10 | import * as commonFunc from '../../components/Common/commonFunc'; | 10 | import * as commonFunc from '../../components/Common/commonFunc'; |
| 11 | import * as commonServices from '../../services/services'; | 11 | import * as commonServices from '../../services/services'; |
| 12 | - | 12 | +import instructSet from "@/components/Common/CommonInstructSet"; |
| 13 | const alert = Modal.alert; | 13 | const alert = Modal.alert; |
| 14 | 14 | ||
| 15 | export default (ChildComponent) => { | 15 | export default (ChildComponent) => { |
| @@ -18,7 +18,13 @@ export default (ChildComponent) => { | @@ -18,7 +18,13 @@ export default (ChildComponent) => { | ||
| 18 | super(props); | 18 | super(props); |
| 19 | this.state = { | 19 | this.state = { |
| 20 | textAreaContent: '', | 20 | textAreaContent: '', |
| 21 | + cameraVisible: false, | ||
| 22 | + videoStream: null, | ||
| 23 | + cameraError: null, | ||
| 24 | + autoCaptureTimer: null, | ||
| 25 | + faceRecognizing: false, | ||
| 21 | }; | 26 | }; |
| 27 | + this.videoRef = React.createRef(); | ||
| 22 | } | 28 | } |
| 23 | 29 | ||
| 24 | async componentWillReceiveProps(nextProps) { | 30 | async componentWillReceiveProps(nextProps) { |
| @@ -389,10 +395,423 @@ export default (ChildComponent) => { | @@ -389,10 +395,423 @@ export default (ChildComponent) => { | ||
| 389 | this.handleBatchCancelExamine(); | 395 | this.handleBatchCancelExamine(); |
| 390 | } else if (name === 'BtnAdd') { | 396 | } else if (name === 'BtnAdd') { |
| 391 | this.handleAdd(); | 397 | this.handleAdd(); |
| 398 | + } else if (name.includes('BtnScanFace')) { | ||
| 399 | + console.log("🚀 ~ name:", name) | ||
| 400 | + this.startCamera() | ||
| 401 | + } | ||
| 402 | + }; | ||
| 403 | + // 调用扫脸 | ||
| 404 | + startCamera = () => { | ||
| 405 | + navigator.mediaDevices.getUserMedia({ | ||
| 406 | + video: { | ||
| 407 | + facingMode: 'user', | ||
| 408 | + width: { ideal: 640 }, | ||
| 409 | + height: { ideal: 480 }, | ||
| 410 | + }, | ||
| 411 | + }) | ||
| 412 | + .then(stream => { | ||
| 413 | + this.setState({ | ||
| 414 | + cameraVisible: true, | ||
| 415 | + videoStream: stream, | ||
| 416 | + cameraError: null, | ||
| 417 | + autoCaptureTimer: setTimeout(() => { | ||
| 418 | + this.capturePhoto(); | ||
| 419 | + }, 2000), | ||
| 420 | + }, () => { | ||
| 421 | + if (this.videoRef.current) { | ||
| 422 | + this.videoRef.current.srcObject = stream; | ||
| 423 | + this.videoRef.current.play(); | ||
| 424 | + } | ||
| 425 | + }); | ||
| 426 | + }) | ||
| 427 | + .catch(error => { | ||
| 428 | + console.error('无法访问摄像头:', error); | ||
| 429 | + this.setState({ | ||
| 430 | + cameraError: '无法访问摄像头,请检查权限设置', | ||
| 431 | + cameraVisible: false, | ||
| 432 | + }); | ||
| 433 | + Toast.fail('无法访问摄像头,请检查权限'); | ||
| 434 | + }); | ||
| 435 | + }; | ||
| 436 | + capturePhoto = () => { | ||
| 437 | + if (!this.videoRef.current || !this.state.cameraVisible) return; | ||
| 438 | + | ||
| 439 | + const video = this.videoRef.current; | ||
| 440 | + const canvas = document.createElement('canvas'); | ||
| 441 | + canvas.width = video.videoWidth; | ||
| 442 | + canvas.height = video.videoHeight; | ||
| 443 | + const ctx = canvas.getContext('2d'); | ||
| 444 | + ctx.drawImage(video, 0, 0, canvas.width, canvas.height); | ||
| 445 | + | ||
| 446 | + const base64 = canvas.toDataURL('image/jpeg', 0.85).split(',')[1]; | ||
| 447 | + // 不再立即 closeCamera(),而是进入识别状态 | ||
| 448 | + this.setState({ faceRecognizing: true }); | ||
| 449 | + this.processFaceRecognition(base64); | ||
| 450 | + }; | ||
| 451 | + processFaceRecognition = (base64) => { | ||
| 452 | + const url = `${commonConfig.face_host}/face/faceSearch`; | ||
| 453 | + commonServices.postValueService(null, [{ | ||
| 454 | + image: base64, | ||
| 455 | + image_type: "BASE64", | ||
| 456 | + face_field: "age", | ||
| 457 | + option: "COMMON" | ||
| 458 | + }], url) | ||
| 459 | + .then(({ data: dataReturn }) => { | ||
| 460 | + console.log("🚀 ~ dataReturn:", dataReturn) | ||
| 461 | + if (dataReturn?.code === 1 && dataReturn.dataset.rows.length > 0) { | ||
| 462 | + const value = { | ||
| 463 | + sEmployeeNo: dataReturn.dataset.rows[0].sEmployeeNo, | ||
| 464 | + sParentId: dataReturn.dataset.rows[0].sBrandsId, | ||
| 465 | + sId: dataReturn.dataset.rows[0].sSubsidiaryId | ||
| 466 | + }; | ||
| 467 | + this.handleLogin(value, dataReturn.dataset.rows[0]); | ||
| 468 | + } | ||
| 469 | + }) | ||
| 470 | + .finally(() => { | ||
| 471 | + this.closeCamera(); | ||
| 472 | + this.setState({ | ||
| 473 | + cameraVisible: false, | ||
| 474 | + faceRecognizing: false | ||
| 475 | + }); | ||
| 476 | + }); | ||
| 477 | + }; | ||
| 478 | + closeCamera = () => { | ||
| 479 | + if (this.state.videoStream) { | ||
| 480 | + this.state.videoStream.getTracks().forEach(track => track.stop()); | ||
| 481 | + this.setState({ videoStream: null }); | ||
| 482 | + } | ||
| 483 | + if (this.videoRef.current) { | ||
| 484 | + this.videoRef.current.srcObject = null; | ||
| 485 | + } | ||
| 486 | + if (this.state.autoCaptureTimer) { | ||
| 487 | + clearTimeout(this.state.autoCaptureTimer); | ||
| 392 | } | 488 | } |
| 393 | }; | 489 | }; |
| 490 | + handleLogin = (result, dataReturn) => { | ||
| 491 | + const { faceData = [] } = result; | ||
| 492 | + const { slaveConfig, masterData } = this.props; | ||
| 493 | + const btnConfig = slaveConfig.gdsconfigformslave?.find(item => item.sControlName.toLowerCase().includes('btnscanface')); | ||
| 494 | + const { sButtonParam: sButtonParamStr } = btnConfig; | ||
| 495 | + const sButtonParam = commonUtils.convertStrToObj(sButtonParamStr); | ||
| 496 | + const { addData } = sButtonParam; | ||
| 497 | + console.log(this.props, btnConfig, '=====this.props'); | ||
| 498 | + this.handleProcedureCall( | ||
| 499 | + { | ||
| 500 | + btnConfig, | ||
| 501 | + faceData: result, | ||
| 502 | + ...dataReturn, | ||
| 503 | + onSuccess: (_, dataset) => { | ||
| 504 | + console.log("🚀 ~ dataset:", dataset) | ||
| 505 | + const { proData = [] } = dataset.rows[0].dataSet; | ||
| 506 | + const { [`${addData}Data`]: tableData = [], [`${addData}Config`]: config = {} } = this.props; | ||
| 507 | + const copyConfig = config?.gdsconfigformslave?.find(item => item.sControlName.toLowerCase().includes('btnscanface')) | ||
| 508 | + proData.forEach(item => { | ||
| 509 | + const data = commonFunc.getAssignFieldValue(copyConfig?.sAssignField, item) | ||
| 510 | + const index = tableData.findIndex(x => x.sEmployeeNo === item.sEmployeeNo) | ||
| 511 | + if (index !== -1) { | ||
| 512 | + Toast.fail('人员重复,请重新添加', 5); | ||
| 513 | + } else { | ||
| 514 | + tableData.push({ | ||
| 515 | + ...item, | ||
| 516 | + ...data, | ||
| 517 | + sId: commonUtils.createSid(), | ||
| 518 | + handleType: "add", | ||
| 519 | + sParentId: props.masterData.sId, | ||
| 520 | + slaveId: props?.slaveData ? props?.slaveData[0].sId : '' | ||
| 521 | + }) | ||
| 522 | + } | ||
| 523 | + | ||
| 524 | + }); | ||
| 525 | + console.log(tableData, 'tableData'); | ||
| 526 | + | ||
| 527 | + // props.onSaveState({ | ||
| 528 | + // [`${addData}Data`]: tableData, | ||
| 529 | + // mesRefresh: true | ||
| 530 | + // }); | ||
| 531 | + }, | ||
| 532 | + onConfirm: () => { }, | ||
| 533 | + onError: () => { } | ||
| 534 | + | ||
| 535 | + }) | ||
| 536 | + // instructSet({ | ||
| 537 | + // btnConfig, | ||
| 538 | + // faceData: result, | ||
| 539 | + // onSuccess: (_, dataset) => { | ||
| 540 | + // const { proData = [] } = dataset.rows[0].dataSet; | ||
| 541 | + // const { [`${addData}Data`]: tableData = [], [`${addData}Config`]: config = {} } = this.props; | ||
| 542 | + // const copyConfig = config?.gdsconfigformslave?.find(item => item.sControlName.toLowerCase().includes('btnscanface')) | ||
| 543 | + // proData.forEach(item => { | ||
| 544 | + // const data = commonFunc.getAssignFieldValue(copyConfig?.sAssignField, item) | ||
| 545 | + // const index = tableData.findIndex(x => x.sEmployeeNo === item.sEmployeeNo) | ||
| 546 | + // if (index !== -1) { | ||
| 547 | + // message.error('人员重复,请重新添加', 5) | ||
| 548 | + // } else { | ||
| 549 | + // tableData.push({ | ||
| 550 | + // ...item, | ||
| 551 | + // ...data, | ||
| 552 | + // sId: commonUtils.createSid(), | ||
| 553 | + // handleType: "add", | ||
| 554 | + // sParentId: props.masterData.sId, | ||
| 555 | + // slaveId: props?.slaveData ? props?.slaveData[0].sId : '' | ||
| 556 | + // }) | ||
| 557 | + // } | ||
| 558 | + | ||
| 559 | + // }); | ||
| 560 | + | ||
| 561 | + // // props.onSaveState({ | ||
| 562 | + // // [`${addData}Data`]: tableData, | ||
| 563 | + // // mesRefresh: true | ||
| 564 | + // // }); | ||
| 565 | + // }, | ||
| 566 | + // onConfirm: () => { }, | ||
| 567 | + // onError: () => { } | ||
| 568 | + // }); | ||
| 569 | + } | ||
| 570 | + handleProcedureCall = async (params, iFlag) => { | ||
| 571 | + const { | ||
| 572 | + btnConfig = {}, // 按钮配置 | ||
| 573 | + sValue = {}, // 额外参数 | ||
| 574 | + tableData: tableDataSelected, // 传过来的数据 | ||
| 575 | + faceData = {}, // 人脸数据 | ||
| 576 | + onSuccess, | ||
| 577 | + onConfirm, | ||
| 578 | + onError, | ||
| 579 | + nextProps, | ||
| 580 | + sUserId, | ||
| 581 | + sParentId, | ||
| 582 | + sEmployeeNo, | ||
| 583 | + | ||
| 584 | + } = params; | ||
| 585 | + | ||
| 586 | + const currentState = this.props || this.state; | ||
| 587 | + const { slaveSelectedRowKeys = [] } = this.props; | ||
| 588 | + | ||
| 589 | + // 加入mes通用参数 | ||
| 590 | + const { app } = this.props; | ||
| 591 | + const { tableNameCompareJson = {} } = currentState; | ||
| 592 | + const { | ||
| 593 | + sMachineNameSId: sMachineGuid, | ||
| 594 | + sTeamNameSId: sTeamGuid, | ||
| 595 | + sShift | ||
| 596 | + } = app; | ||
| 597 | + const commonData = { | ||
| 598 | + sMachineGuid, | ||
| 599 | + sTeamGuid, | ||
| 600 | + sShift | ||
| 601 | + }; | ||
| 602 | + | ||
| 603 | + const { sButtonParam } = btnConfig; | ||
| 604 | + console.log("🚀 ~ sButtonParam:", sButtonParam) | ||
| 605 | + const btn = commonUtils.convertStrToObj(sButtonParam, {}); | ||
| 606 | + if (commonUtils.isEmptyObject(btn)) { | ||
| 607 | + onSuccess && onSuccess(false); | ||
| 608 | + return; | ||
| 609 | + } | ||
| 610 | + const { sproName: sProName, inMap, sTableName, staticData = {} } = btn; | ||
| 611 | + console.log("🚀 ~ inMap:", inMap, sButtonParam) | ||
| 612 | + | ||
| 613 | + const inParams = []; | ||
| 614 | + const arr = {}; | ||
| 615 | + | ||
| 616 | + if (inMap) { | ||
| 617 | + const inlist = inMap.split(","); | ||
| 618 | + inlist.forEach(item => { | ||
| 619 | + const [ | ||
| 620 | + tableNameOld, | ||
| 621 | + sFieldName, | ||
| 622 | + sFieldNameNew = sFieldName | ||
| 623 | + ] = item.split("."); | ||
| 624 | + | ||
| 625 | + const tableName = tableNameCompareJson[tableNameOld] || tableNameOld; | ||
| 626 | + if (!tableName) return; | ||
| 627 | + if (!arr[tableName]) { | ||
| 628 | + arr[tableName] = []; | ||
| 629 | + } | ||
| 630 | + arr[tableName].push({ sFieldName, sFieldNameNew }); | ||
| 631 | + }); | ||
| 632 | + } | ||
| 394 | 633 | ||
| 395 | - /** 点击新增按钮 */ | 634 | + // 拼接params参数 |
| 635 | + Object.keys(arr).forEach(tableName => { | ||
| 636 | + const addState = { key: tableName }; | ||
| 637 | + if (tableName.includes("master")) { | ||
| 638 | + const { [`${tableName}Data`]: tableData = {} } = currentState; | ||
| 639 | + const allValue = []; | ||
| 640 | + const value = { ...commonData, ...staticData, ...faceData }; | ||
| 641 | + arr[tableName].forEach(({ sFieldName, sFieldNameNew }) => { | ||
| 642 | + value[`${sFieldNameNew}`] = tableData[`${sFieldName}`]; | ||
| 643 | + }); | ||
| 644 | + allValue.push(value); | ||
| 645 | + addState.value = allValue; | ||
| 646 | + inParams.push(addState); | ||
| 647 | + } else { | ||
| 648 | + let filterData = tableDataSelected; | ||
| 649 | + if (commonUtils.isEmptyArr(filterData)) { | ||
| 650 | + if ( | ||
| 651 | + [ | ||
| 652 | + "userinfo", | ||
| 653 | + "currentSelectedMachineTask", | ||
| 654 | + "currentStartWorkMachineTask", | ||
| 655 | + "currentWorkOrderInfo" | ||
| 656 | + ].includes(tableName) | ||
| 657 | + ) { | ||
| 658 | + // 如果是全局变量 | ||
| 659 | + const globalData = commonUtils.getAppData("globalData"); | ||
| 660 | + const tempProps = { | ||
| 661 | + userinfo: app.userinfo, | ||
| 662 | + currentSelectedMachineTask: globalData.currentSelectedMachineTask, | ||
| 663 | + currentStartWorkMachineTask: | ||
| 664 | + globalData.currentStartWorkMachineTask, | ||
| 665 | + currentWorkOrderInfo: globalData.currentWorkOrderInfo | ||
| 666 | + }; | ||
| 667 | + filterData = [tempProps[tableName]]; | ||
| 668 | + } else { | ||
| 669 | + // 如果不是全局变量 | ||
| 670 | + const { | ||
| 671 | + [`${tableName}Data`]: tableData = [], | ||
| 672 | + [`${tableName}SelectedRowKeys`]: selectedRowKeys = [] | ||
| 673 | + } = currentState; | ||
| 674 | + if (selectedRowKeys.length === 0 && nextProps) { | ||
| 675 | + filterData = tableData; | ||
| 676 | + } else { | ||
| 677 | + const iIndex = arr[tableName].findIndex( | ||
| 678 | + item => item.sFieldNameNew === "*" | ||
| 679 | + ); | ||
| 680 | + if (iIndex > -1) { | ||
| 681 | + filterData = tableData; | ||
| 682 | + } else { | ||
| 683 | + filterData = tableData.filter( | ||
| 684 | + item => | ||
| 685 | + true && | ||
| 686 | + (selectedRowKeys.includes(item.sId) || | ||
| 687 | + selectedRowKeys.includes(item.sSlaveId)) | ||
| 688 | + ); | ||
| 689 | + } | ||
| 690 | + } | ||
| 691 | + } | ||
| 692 | + if (sProName === "Sp_Mes_BindMaterials") { | ||
| 693 | + filterData = filterData.filter(item => item.sAdded == "1"); | ||
| 694 | + } | ||
| 695 | + } | ||
| 696 | + const addState = { key: tableName }; | ||
| 697 | + const allValue = []; | ||
| 698 | + filterData.forEach(currData => { | ||
| 699 | + let value = { ...commonData, ...staticData, ...faceData }; | ||
| 700 | + arr[tableName].forEach(({ sFieldName, sFieldNameNew }) => { | ||
| 701 | + if (sFieldNameNew === "*") { | ||
| 702 | + value = { ...value, ...currData }; | ||
| 703 | + delete value.sColumnConfig; | ||
| 704 | + } else { | ||
| 705 | + value[`${sFieldNameNew}`] = currData[`${sFieldName}`]; | ||
| 706 | + } | ||
| 707 | + }); | ||
| 708 | + allValue.push(value); | ||
| 709 | + }); | ||
| 710 | + addState.value = allValue; | ||
| 711 | + inParams.push(addState); | ||
| 712 | + } | ||
| 713 | + }); | ||
| 714 | + | ||
| 715 | + if ( | ||
| 716 | + commonUtils.isNotEmptyStr(sTableName) && | ||
| 717 | + commonUtils.isNotEmptyArr(inParams) | ||
| 718 | + ) { | ||
| 719 | + inParams.forEach(item => { | ||
| 720 | + if (commonUtils.isNotEmptyArr(item.value)) { | ||
| 721 | + item.value.forEach(item1 => { | ||
| 722 | + item1.sTableName = sTableName; | ||
| 723 | + }); | ||
| 724 | + } | ||
| 725 | + }); | ||
| 726 | + } | ||
| 727 | + | ||
| 728 | + const { token } = app; | ||
| 729 | + const { sModelsId } = this.props; | ||
| 730 | + | ||
| 731 | + const { sControlName: sBtnName } = btnConfig; | ||
| 732 | + | ||
| 733 | + if (iFlag !== undefined) { | ||
| 734 | + inParams[0]?.value?.forEach(item => { | ||
| 735 | + item.iFlag = iFlag; | ||
| 736 | + }); | ||
| 737 | + } | ||
| 738 | + | ||
| 739 | + const proInParam = JSON.stringify({ | ||
| 740 | + params: inParams.map(item => ({ | ||
| 741 | + ...item, | ||
| 742 | + sUserName: app.userinfo.sUserName, | ||
| 743 | + value: [{ | ||
| 744 | + sUserId, | ||
| 745 | + sParentId, | ||
| 746 | + sEmployeeNo, | ||
| 747 | + sId: slaveSelectedRowKeys[0], | ||
| 748 | + "sOperate": "start", | ||
| 749 | + ...commonData, | ||
| 750 | + | ||
| 751 | + }] | ||
| 752 | + })), | ||
| 753 | + changeValue: sValue, | ||
| 754 | + sButtonParam: btn | ||
| 755 | + }); | ||
| 756 | + const value = { sProName, sProInParam: proInParam, sBtnName }; | ||
| 757 | + if (iFlag !== undefined) { | ||
| 758 | + value.iFlag = iFlag; | ||
| 759 | + } | ||
| 760 | + | ||
| 761 | + console.log("=====存储过程参数", { | ||
| 762 | + params: inParams, | ||
| 763 | + changeValue: sValue, | ||
| 764 | + sButtonParam: btn | ||
| 765 | + }); | ||
| 766 | + console.log(value, 'value '); | ||
| 767 | + const url = `${commonConfig.server_host | ||
| 768 | + }procedureCall/doGenericProcedureCall?sModelsId=${sModelsId}`; | ||
| 769 | + const returnData = (await commonServices.postValueService( | ||
| 770 | + token, | ||
| 771 | + value, | ||
| 772 | + url | ||
| 773 | + )).data; | ||
| 774 | + const { code, msg, dataset } = returnData; | ||
| 775 | + if (code === 1) { | ||
| 776 | + Toast.info(msg); | ||
| 777 | + onSuccess && onSuccess(true, dataset); | ||
| 778 | + } else if (code === -7) { | ||
| 779 | + // Modal.confirm({ | ||
| 780 | + // title: FriendlyReminder, | ||
| 781 | + // content: <div>{this.handleGetMsg(msg)}</div>, | ||
| 782 | + // onOk() { | ||
| 783 | + // this.handleProcedureCall(params, 1); | ||
| 784 | + // }, | ||
| 785 | + // onCancel() { | ||
| 786 | + // onError && onError(); | ||
| 787 | + // } | ||
| 788 | + // }); | ||
| 789 | + } else if (code === -8) { | ||
| 790 | + // Modal.info({ | ||
| 791 | + // title: FriendlyReminder, | ||
| 792 | + // content: <div>{this.handleGetMsg(msg)}</div>, | ||
| 793 | + // onOk() { | ||
| 794 | + // onConfirm && onConfirm(); | ||
| 795 | + // }, | ||
| 796 | + // onCancel() { | ||
| 797 | + // onError && onError(); | ||
| 798 | + // } | ||
| 799 | + // }); | ||
| 800 | + } else { | ||
| 801 | + | ||
| 802 | + } | ||
| 803 | + }; | ||
| 804 | + handleGetMsg = str => { | ||
| 805 | + const msgArr = commonUtils.isNotEmptyObject(str) ? str.split("xpm") : ""; | ||
| 806 | + const divStr = []; | ||
| 807 | + if (commonUtils.isNotEmptyArr(msgArr)) { | ||
| 808 | + for (let i = 0; i < msgArr.length; i++) { | ||
| 809 | + divStr.push(<p>{msgArr[i]}</p>); | ||
| 810 | + } | ||
| 811 | + } | ||
| 812 | + return divStr; | ||
| 813 | + }; | ||
| 814 | + /** 点击新增按钮 */ | ||
| 396 | handleAdd = () => { | 815 | handleAdd = () => { |
| 397 | const { | 816 | const { |
| 398 | slaveConfig, dispatch, slaveFilterCondition, slavePagination, slaveOrderBy, formRoute, | 817 | slaveConfig, dispatch, slaveFilterCondition, slavePagination, slaveOrderBy, formRoute, |
| @@ -612,20 +1031,37 @@ export default (ChildComponent) => { | @@ -612,20 +1031,37 @@ export default (ChildComponent) => { | ||
| 612 | slaveSelectedRowKeys, | 1031 | slaveSelectedRowKeys, |
| 613 | }); | 1032 | }); |
| 614 | }; | 1033 | }; |
| 1034 | + | ||
| 615 | render() { | 1035 | render() { |
| 1036 | + const { loginCompany, companys, cameraVisible, cameraError } = this.state; | ||
| 616 | return ( | 1037 | return ( |
| 617 | - <ChildComponent | ||
| 618 | - {...this.props} | ||
| 619 | - {...this.state} | ||
| 620 | - onReturnForm={this.handleForm} | ||
| 621 | - onGetData={this.handleGetData} | ||
| 622 | - onCopyToClick={this.handleCopyToClick} | ||
| 623 | - onPrintView={this.handlePrintView} | ||
| 624 | - onCheckboxChange={this.handleCheckboxChange} | ||
| 625 | - onButtonClick={this.handleButtonClick} | ||
| 626 | - onDoubleClick={this.handleDoubleClick} | ||
| 627 | - onSelectAllClick={this.handleSelectAllClick} | ||
| 628 | - /> | 1038 | + <div> |
| 1039 | + {cameraVisible && ( | ||
| 1040 | + <div className='cameraOverlay' style={{ width: '100%', height: '100vh', position: 'fixed', top: 0, left: 0, zIndex: 1000, backgroundColor: '#000' }}> | ||
| 1041 | + <video | ||
| 1042 | + ref={this.videoRef} | ||
| 1043 | + autoPlay | ||
| 1044 | + playsInline | ||
| 1045 | + style={{ width: '100%', height: '100vh', objectFit: 'cover' }} | ||
| 1046 | + /> | ||
| 1047 | + {cameraError && ( | ||
| 1048 | + <div className={styles.cameraError}>{cameraError}</div> | ||
| 1049 | + )} | ||
| 1050 | + </div> | ||
| 1051 | + )} | ||
| 1052 | + <ChildComponent | ||
| 1053 | + {...this.props} | ||
| 1054 | + {...this.state} | ||
| 1055 | + onReturnForm={this.handleForm} | ||
| 1056 | + onGetData={this.handleGetData} | ||
| 1057 | + onCopyToClick={this.handleCopyToClick} | ||
| 1058 | + onPrintView={this.handlePrintView} | ||
| 1059 | + onCheckboxChange={this.handleCheckboxChange} | ||
| 1060 | + onButtonClick={this.handleButtonClick} | ||
| 1061 | + onDoubleClick={this.handleDoubleClick} | ||
| 1062 | + onSelectAllClick={this.handleSelectAllClick} | ||
| 1063 | + /> | ||
| 1064 | + </div> | ||
| 629 | ); | 1065 | ); |
| 630 | } | 1066 | } |
| 631 | }; | 1067 | }; |
src/mobile/components/searchPicker.jsx
0 → 100644
| 1 | +import { Popup, SearchBar, PickerView, Button } from 'antd-mobile'; | ||
| 2 | +import { List,} from 'antd-mobile-v2'; | ||
| 3 | +import { useState, useMemo } from 'react'; | ||
| 4 | +import styles from "./selectInput.less"; | ||
| 5 | +export default function SearchablePicker(props) { | ||
| 6 | + console.log("🚀 ~ SearchablePicker ~ props:", props) | ||
| 7 | + const { onConfirm, initialValue, data, sTitle, onChange, value:newValue } = props; | ||
| 8 | + | ||
| 9 | + const [searchValue, setSearchValue] = useState(''); | ||
| 10 | + const [visible, setVisible] = useState(false) | ||
| 11 | + | ||
| 12 | + // 安全初始化 values | ||
| 13 | + const initialVal = useMemo(() => { | ||
| 14 | + if (!initialValue || !Array.isArray(data)) return []; | ||
| 15 | + const exists = data.some(item => item?.value === initialValue); | ||
| 16 | + return exists ? [initialValue] : []; | ||
| 17 | + }, [initialValue, data]); | ||
| 18 | + | ||
| 19 | + const [values, setValues] = useState(initialVal); | ||
| 20 | + | ||
| 21 | + // 安全过滤选项 | ||
| 22 | + const filteredOptions = useMemo(() => { | ||
| 23 | + const options = Array.isArray(data) ? data : []; | ||
| 24 | + | ||
| 25 | + if (!searchValue.trim()) { | ||
| 26 | + return options; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + return options.filter(item => | ||
| 30 | + item && | ||
| 31 | + typeof item.label === 'string' && | ||
| 32 | + item.label.toLowerCase().includes(searchValue.toLowerCase()) | ||
| 33 | + ); | ||
| 34 | + }, [searchValue, data]); // ✅ 必须包含 data | ||
| 35 | + const label = filteredOptions?.find(x=>x.value === newValue[0])?.label || '' | ||
| 36 | + const handleConfirm = () => { | ||
| 37 | + onChange(values); | ||
| 38 | + setVisible(false); | ||
| 39 | + }; | ||
| 40 | + | ||
| 41 | + const handleCancel = () => { | ||
| 42 | + setVisible(false); | ||
| 43 | + }; | ||
| 44 | + | ||
| 45 | + const changeOption = (val) => { | ||
| 46 | + setValues(val); | ||
| 47 | + }; | ||
| 48 | + | ||
| 49 | + return ( | ||
| 50 | + <div> | ||
| 51 | + <List.Item arrow="horizontal" className={styles.searchPickerList} onClick={() => { | ||
| 52 | + setVisible(true) | ||
| 53 | + }} extra={label}> | ||
| 54 | + {props.iconSettingShow ? | ||
| 55 | + // eslint-disable-next-line jsx-a11y/alt-text | ||
| 56 | + <img src={iconSetting} style={{ verticalAlign: 'sub', marginRight: '15px' }} alt="" /> : ''} | ||
| 57 | + {sTitle} | ||
| 58 | + </List.Item> | ||
| 59 | + <Popup | ||
| 60 | + visible={visible} | ||
| 61 | + onMaskClick={handleCancel} | ||
| 62 | + onClose={handleCancel} | ||
| 63 | + bodyStyle={{ height: '50vh' }} | ||
| 64 | + > | ||
| 65 | + <div style={{ display: 'flex', justifyContent: 'space-between', padding: '0 1.5rem', marginTop: '1rem' }}> | ||
| 66 | + <Button onClick={handleCancel} color="primary" fill="none"> | ||
| 67 | + 取消 | ||
| 68 | + </Button> | ||
| 69 | + <Button onClick={handleConfirm} color="primary" fill="none"> | ||
| 70 | + 确认 | ||
| 71 | + </Button> | ||
| 72 | + </div> | ||
| 73 | + | ||
| 74 | + <div style={{ padding: '0 1.5rem', marginTop: '1rem' }}> | ||
| 75 | + <SearchBar | ||
| 76 | + placeholder="请输入内容" | ||
| 77 | + value={searchValue} | ||
| 78 | + onChange={setSearchValue} | ||
| 79 | + /> | ||
| 80 | + </div> | ||
| 81 | + | ||
| 82 | + <PickerView | ||
| 83 | + columns={[filteredOptions]} | ||
| 84 | + value={values} | ||
| 85 | + onChange={changeOption} | ||
| 86 | + style={{ '--height': '200px', '--item-height': '2.8rem' }} | ||
| 87 | + /> | ||
| 88 | + </Popup> | ||
| 89 | + </div> | ||
| 90 | + | ||
| 91 | + ); | ||
| 92 | +} | ||
| 0 | \ No newline at end of file | 93 | \ No newline at end of file |
src/mobile/components/selectInput.css
src/mobile/components/selectInput.less
| @@ -23,4 +23,13 @@ | @@ -23,4 +23,13 @@ | ||
| 23 | align-items: center; | 23 | align-items: center; |
| 24 | justify-content: space-between; | 24 | justify-content: space-between; |
| 25 | margin: 0.2rem; | 25 | margin: 0.2rem; |
| 26 | +} | ||
| 27 | +.searchPickerList{ | ||
| 28 | + :global .am-list-line{ | ||
| 29 | + justify-content: space-between; | ||
| 30 | + // .am-list-extra{ | ||
| 31 | + // text-align: right !important; | ||
| 32 | + // } | ||
| 33 | + } | ||
| 34 | + | ||
| 26 | } | 35 | } |
| 27 | \ No newline at end of file | 36 | \ No newline at end of file |
src/utils/utils.js
| @@ -29,7 +29,14 @@ export function getCursortPosition(obj) { | @@ -29,7 +29,14 @@ export function getCursortPosition(obj) { | ||
| 29 | } | 29 | } |
| 30 | return cursorIndex; | 30 | return cursorIndex; |
| 31 | } | 31 | } |
| 32 | - | 32 | +export function getAppData(name, key) { |
| 33 | + const appData = convertStrToObj(localStorage.getItem(`${config.prefix}${name}`)); | ||
| 34 | + if (key === undefined) { | ||
| 35 | + return appData; | ||
| 36 | + } else { | ||
| 37 | + return appData[key]; | ||
| 38 | + } | ||
| 39 | +} | ||
| 33 | /* 为输入框聚焦 */ | 40 | /* 为输入框聚焦 */ |
| 34 | export function focus(id, e, currentRef = document) { | 41 | export function focus(id, e, currentRef = document) { |
| 35 | const element = currentRef.querySelector(`#${id}`); | 42 | const element = currentRef.querySelector(`#${id}`); |