Commit 793b01fafe8c8d3a834c09f016400eadf85a9b76

Authored by chenxt
1 parent b5b0ca8a

下拉选择框增加筛选功能

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 &#39;../../utils/utils&#39;; /* 通用方法 */ @@ -9,7 +9,7 @@ import * as commonUtils from &#39;../../utils/utils&#39;; /* 通用方法 */
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) =&gt; { @@ -18,7 +18,13 @@ export default (ChildComponent) =&gt; {
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) =&gt; { @@ -389,10 +395,423 @@ export default (ChildComponent) =&gt; {
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) =&gt; { @@ -612,20 +1031,37 @@ export default (ChildComponent) =&gt; {
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
@@ -23,3 +23,6 @@ @@ -23,3 +23,6 @@
23 justify-content: space-between; 23 justify-content: space-between;
24 margin: 0.2rem; 24 margin: 0.2rem;
25 } 25 }
  26 +.searchPickerList :global .am-list-line {
  27 + justify-content: space-between;
  28 +}
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}`);