Commit 123e5ac13ef36e2f1c0ec1274e6018eba2cfdd34

Authored by zhangz
1 parent 220d4368

手机端新增人脸登陆;

src/mobile/login/LoginMobile.js
@@ -13,7 +13,8 @@ import * as commonServices from '../../services/services'; @@ -13,7 +13,8 @@ import * as commonServices from '../../services/services';
13 import * as commonFunc from '../../components/Common/commonFunc'; 13 import * as commonFunc from '../../components/Common/commonFunc';
14 import AppUtil from '../../utils/AppUtil'; 14 import AppUtil from '../../utils/AppUtil';
15 import * as commonUtils from '../../utils/utils'; 15 import * as commonUtils from '../../utils/utils';
16 - 16 +// import VConsole from 'vconsole';
  17 +// let vConsole;
17 18
18 // eslint-disable-next-line prefer-destructuring 19 // eslint-disable-next-line prefer-destructuring
19 const alert = Modal.alert; 20 const alert = Modal.alert;
@@ -124,8 +125,13 @@ class LoginMobile extends React.Component { @@ -124,8 +125,13 @@ class LoginMobile extends React.Component {
124 ); 125 );
125 } 126 }
126 } 127 }
  128 + // vConsole = new VConsole();
127 } 129 }
128 130
  131 + // componentWillUnmount() {
  132 + // vConsole.destroy();
  133 + // }
  134 +
129 onChange = (name, newValue) => { 135 onChange = (name, newValue) => {
130 if (name === 'username') { 136 if (name === 'username') {
131 this.setState({ username: newValue }); 137 this.setState({ username: newValue });
@@ -138,7 +144,82 @@ class LoginMobile extends React.Component { @@ -138,7 +144,82 @@ class LoginMobile extends React.Component {
138 loginCompany: value, 144 loginCompany: value,
139 }); 145 });
140 } 146 }
141 - handleLogin = async () => { 147 +
  148 + takeTenPhotos = () => {
  149 + if (!window.plus) {
  150 + return Promise.reject(new Error('请在 HBuilder 打包的 App 中运行'));
  151 + }
  152 +
  153 + return new Promise((resolve, reject) => {
  154 + // 调用系统相机拍照(尽量指定前置)
  155 + plus.camera.getCamera(1).captureImage(
  156 + (imagePath) => {
  157 + // 直接用 FileReader 读取逻辑路径(如 _doc/...),无需 resolve
  158 + const reader = new plus.io.FileReader();
  159 + reader.onload = (e) => {
  160 + const img = new Image();
  161 + img.onload = () => {
  162 + const canvas = document.createElement('canvas');
  163 + canvas.width = 268;
  164 + canvas.height = 214;
  165 + const ctx = canvas.getContext('2d');
  166 + ctx.drawImage(img, 0, 0, 268, 214);
  167 + // 转为 JPEG,质量 0.85,去掉前缀
  168 + const base64 = canvas.toDataURL('image/jpeg', 0.85).split(',')[1];
  169 + resolve(base64);
  170 + };
  171 + img.onerror = () => reject(new Error('图片解析失败'));
  172 +
  173 + img.src = e.target.result; // Data URL 安全加载
  174 + };
  175 + reader.onerror = (e) => reject(new Error('读取照片失败: ' + e.target.error.message));
  176 +
  177 + plus.io.resolveLocalFileSystemURL(imagePath, (entry) => {
  178 + entry.file((file) => {
  179 + reader.readAsDataURL(file.fullPath); // 关键:直接读逻辑路径
  180 +
  181 + })
  182 + });
  183 + },
  184 + (error) => {
  185 + reject(new Error('拍照失败: ' + error.message));
  186 + },
  187 + {
  188 + filename: `_doc/camera/face_${Date.now()}.jpg`,
  189 + format: 'jpg'
  190 + }
  191 + );
  192 + });
  193 + };
  194 +
  195 + handleFaceLogin = () => {
  196 + this.takeTenPhotos()
  197 + .then(base64List => {
  198 + // 这里可以上传到你的 face/detectFaces 接口
  199 + const url = `${commonConfig.face_host}/face/faceSearch`;
  200 + commonServices.postValueService(null, [{
  201 + image: base64List,
  202 + image_type: "BASE64",
  203 + face_field: "age",
  204 + option: "COMMON"
  205 + }], url).then(({ data: dataReturn }) => {
  206 + // console.log('=====dataReturn', dataReturn);
  207 + if (dataReturn.code === 1) {
  208 + const value = {};
  209 + value.sEmployeeNo = dataReturn.dataset.rows[0].sEmployeeNo;
  210 + value.sParentId = dataReturn.dataset.rows[0].sBrandsId;
  211 + value.sId = dataReturn.dataset.rows[0].sSubsidiaryId;
  212 + this.handleLogin(value);
  213 + } else {
  214 + Toast.fail(dataReturn.msg);
  215 + }
  216 + })
  217 + })
  218 + .catch(err => {
  219 + console.error('拍摄过程出错:', err);
  220 + });
  221 + }
  222 + handleLogin = async (valueBase) => {
142 const { dispatch, app } = this.props; 223 const { dispatch, app } = this.props;
143 const { loginCompany, companys } = this.state; 224 const { loginCompany, companys } = this.state;
144 let sParentId = ''; 225 let sParentId = '';
@@ -150,12 +231,16 @@ class LoginMobile extends React.Component { @@ -150,12 +231,16 @@ class LoginMobile extends React.Component {
150 return; 231 return;
151 } 232 }
152 this.props.form.validateFields(async () => { 233 this.props.form.validateFields(async () => {
153 - const value = {};  
154 - value.username = this.state.username;  
155 - value.password = this.state.userpwd;  
156 - value.sParentId = this.state.sParentId;  
157 - // value.company = this.state.loginCompany;  
158 - value.sId = this.state.sId; 234 + let value = {};
  235 + if (valueBase) {
  236 + value = valueBase;
  237 + } else {
  238 + value.username = this.state.username;
  239 + value.password = this.state.userpwd;
  240 + value.sParentId = this.state.sParentId;
  241 + // value.company = this.state.loginCompany;
  242 + value.sId = this.state.sId;
  243 + }
159 const url = `${commonConfig.server_host}userlogin/${sParentId}/${loginCompany}?sLoginType=phoneLogin`; 244 const url = `${commonConfig.server_host}userlogin/${sParentId}/${loginCompany}?sLoginType=phoneLogin`;
160 const dataReturn = (await commonServices.postValueService(null, value, url)).data; 245 const dataReturn = (await commonServices.postValueService(null, value, url)).data;
161 if (dataReturn.code === 1) { 246 if (dataReturn.code === 1) {
@@ -200,6 +285,7 @@ class LoginMobile extends React.Component { @@ -200,6 +285,7 @@ class LoginMobile extends React.Component {
200 let sLanguage = commonUtils.isNotEmptyArr(companys) ? companys[0].sLanguage : 'sChinese'; 285 let sLanguage = commonUtils.isNotEmptyArr(companys) ? companys[0].sLanguage : 'sChinese';
201 const settingTitle = sLanguage === 'sEnglish' ? 'server settings' :'服务器设置'; 286 const settingTitle = sLanguage === 'sEnglish' ? 'server settings' :'服务器设置';
202 const loginTitle = sLanguage === 'sEnglish' ? 'Login' :'登录'; 287 const loginTitle = sLanguage === 'sEnglish' ? 'Login' :'登录';
  288 + const loginFaceTitle = sLanguage === 'sEnglish' ? 'Face Login' :'人脸登录';
203 const pleaseInputUser = sLanguage === 'sEnglish' ? 'please Input User' :'请输入用户'; 289 const pleaseInputUser = sLanguage === 'sEnglish' ? 'please Input User' :'请输入用户';
204 const pleaseInputPassword = sLanguage === 'sEnglish' ? 'please Input Password' :'请输入密码'; 290 const pleaseInputPassword = sLanguage === 'sEnglish' ? 'please Input Password' :'请输入密码';
205 291
@@ -263,6 +349,9 @@ class LoginMobile extends React.Component { @@ -263,6 +349,9 @@ class LoginMobile extends React.Component {
263 <Button type="primary" onClick={this.handleLogin.bind(this)} style={{ backgroundColor: "#5e81e5" }}> 349 <Button type="primary" onClick={this.handleLogin.bind(this)} style={{ backgroundColor: "#5e81e5" }}>
264 {loginTitle} 350 {loginTitle}
265 </Button> 351 </Button>
  352 + <Button type="primary" onClick={this.handleFaceLogin.bind(this)} style={{ backgroundColor: "#5e81e5" }}>
  353 + {loginFaceTitle}
  354 + </Button>
266 </div> 355 </div>
267 {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} 356 {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
268 <a 357 <a
src/mobile/login/LoginMobile.less
@@ -59,6 +59,12 @@ @@ -59,6 +59,12 @@
59 } 59 }
60 .loginSubmit{ 60 .loginSubmit{
61 padding: 0px 5%; 61 padding: 0px 5%;
  62 + display: flex;
  63 + align-items: center;
  64 + justify-content: space-between;
  65 + a {
  66 + width: 48%;
  67 + }
62 } 68 }
63 69
64 .setting{ 70 .setting{