野外泛在线考核系统(十三)

三、电脑端+平板

接着(十二)这段时间主要是解决两个问题:
1.平板端图片上传至电脑服务端的问题,同时将图片名称,地址,关联ID等写入数据库
2.平板端设计登录验证环节,通过登录确定使用者身份,而后从服务端下载考核任务,进行评分,评分完毕再次将评分成绩,拍摄的照片等上传服务器

(一)平板端上传图片至电脑服务端

  1. 平板端主要参考了新闻发布的例子:
  2. 上传文件用到了FileUtil.ets这个文件
    在这里插入图片描述
    主要包含fileSelect()和fileUpload()两个函数
/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import fs from '@ohos.file.fs';
import request from '@ohos.request';
import picker from '@ohos.file.picker';
import {CommonConstants as Const, ContentType, RequestMethod, UploadingState } from '../constants/CommonConstants';
import ResponseResult from '../bean/ResponseResult';
import Logger from './Logger';
import { showToast } from './ToastUtil';

/**
 * PhotoViewPicker
 * 在原来基础上改进,可以一次选择多个图片
 * @returns uri The uri for the selected file.
 */
export async function fileSelect(): Promise<string[]> {
  let photoSelectOptions = new picker.PhotoSelectOptions();
  photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
  photoSelectOptions.maxSelectNumber = 2;    //一次选择图片的上限
  let photoPicker = new picker.PhotoViewPicker();
  try {
    let photoSelectResult = await photoPicker.select(photoSelectOptions);
    if (photoSelectResult && photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) {
      let imgUri = photoSelectResult.photoUris;
      if (imgUri[0].indexOf('media/image') < 0) { //为什么是这个路径我没有搞懂,可能选择结果都是存在平板的这个目录中
        showToast($r('app.string.prompt_select_img'));
        return [''];
      }
      return imgUri;
    } else {
      return [''];
    }
  } catch (err) {
    Logger.error('SelectedImage failed', JSON.stringify(err));
    return [''];
  }
}

/**
 * Upload file.
 *
 * @param context Indicates the application BaseContext.
 * @param fileUri The local storage path of the file.
 * @returns the promise returned by the function.
 */
export function fileUpload(context: Context, fileUri: string[],content_id:string): Promise<ResponseResult> {
  // Obtaining the Application File Path.
  let imgName:string[]=[];  //数组申明必须初始化,不然引用会报错
  let dstPath:string[]=[];
  let fileUpload:Array<request.File>=[];
  let cacheDir = context.cacheDir;
  let index:number = 0;
  for (let fileU of fileUri) {
    imgName[index] = fileU.split('/').pop() + '.jpg';
    dstPath[index] = cacheDir + '/' + imgName[index];
    fileUpload[index] = {
      filename: imgName[index],
      name: 'contentImages',
      uri: 'internal://cache/' + imgName[index],
      type: 'jpg'
    }
    index += 1;
  }
  let url: string = Const.SERVER + Const.UPLOAD_FILE;
  let uploadRequestOptions: request.UploadConfig = {
    url: url,
    header: {
      'Content-Type': ContentType.FORM
    },
    method: RequestMethod.POST,
    files: fileUpload,
    data: [{ name: "content", value: content_id }]
  };

  let serverData = new ResponseResult();
  return new Promise((resolve: Function, reject: Function) => {
    try {
      // Copy the URI to the cacheDir directory and upload the file.
      // 将URI复制到cacheDir目录并上传文件
      let i:number = 0;
      for(let fileU of fileUri){
        let srcFile = fs.openSync(fileU);
        let dstFile = fs.openSync(dstPath[i], fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
        fs.copyFileSync(srcFile.fd, dstFile.fd);
        fs.closeSync(srcFile);
        fs.closeSync(dstFile);
        Logger.info('check-data1-i :',i.toString());
        i +=1;
      }

      // Upload the file.
      request.uploadFile(context, uploadRequestOptions).then((data: request.UploadTask) => {
        data.on(UploadingState.COMPLETE, (result: Array<request.TaskState>) => {
          Logger.info('uploadFile success', JSON.stringify(result));
          if (result && result.length >= 1) {
            serverData.code = Const.SERVER_CODE_SUCCESS;
            serverData.msg = result[0].message;
            serverData.data = Const.IMAGE_PREFIX + result[0].path;
            resolve(serverData);
          }
        });
        data.on(UploadingState.FAIL, (result: Array<request.TaskState>) => {
          Logger.info('uploadFile failed', JSON.stringify(result));
          if (result && result.length >= 1) {
            serverData.msg = $r('app.string.upload_error_message');
            reject(serverData);
          }
        })
      }).catch((err: Error) => {
        Logger.error('uploadFile failed', JSON.stringify(err));
        reject(serverData);
      });
    } catch (err) {
      Logger.error('uploadFile failed', JSON.stringify(err));
      reject(serverData);
    }
  })
}
  1. 新闻发布的例子中是将图片和提交的信息分开提交的,图片使用request.uploadFile(context, uploadRequestOptions)方法,其他信息则是使用httpRequest(url, http.RequestMethod.POST, newsData)方法,其实在uploadFile中在上传图片的时候也可以额外传递数据,方法就是将数据通过request.UploadConfig中的data来传递,可以参考@ohos.request (上传下载)的示例,我这里通过data传递了一个名为content,值为content_id的量,注意,content_id必须为string类型的。因为 ‘Content-Type’: ContentType.FORM, method: RequestMethod.POST,Django服务端获取数据可通过request.POST.get(‘content’)得到content_id的值。
 let uploadRequestOptions: request.UploadConfig = {
    url: url,
    header: {
      'Content-Type': ContentType.FORM
    },
    method: RequestMethod.POST,
    files: fileUpload,
    data: [{ name: "content", value: content_id }]
  };
 export const enum RequestMethod {
  POST = 'POST',
  GET = 'GET'
}

export const enum ContentType {
  JSON = 'application/json',
  FORM = 'multipart/form-data'
}
  1. 特别注意的是,如果平板端提交数据时,‘Content-Type’: ContentType.JSON,method:RequestMethod.POST,那么Django服务端只能通过json.loads(request.body.decode('utf-8))的方式获取数据,即两边都采用json格式发送接收数据。

(二)平板端登录验证

  1. 为了达到登录验证效果,需要在平板创建一个数据表用来保存账户信息,于是参照之前野外泛在线考核系统(十)的方法创建TeacherTable表,结果死活写不进数据,也没有报错。
  2. 经过一天的排查,终于找到问题:就是SQL语句有错。下面两段唯一的差别就在registerDate前面的那个“,”一个是中文的,一个时英文的,结果执行是中文的也不报错,奔溃!但是后面就是插入不进数据,应该是表没有创建成功。

'teacherName TEXT,teacherAccount TEXT,teacherPassword TEXT,registerDate TEXT)',
'teacherName TEXT,teacherAccount TEXT,teacherPassword TEXT,registerDate TEXT)',
  1. 为了避免踩坑,可以将SQL语句提交给百度的文心一言检查下。切记切记!!
    在这里插入图片描述
  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值