交接文档


参考内容

建安通

1. 开发前准备

  1. 使用 码云 git 托管代码
  2. 使用 SourceTree 客户端进行管理 git 的操作
  3. 参考 React Native 在Windows下搭建Android开发环境 教程
  4. 下载 建安通代码,解压
  5. 进入 jat 代码所在的目录,使用 npm install 安装 package.json 里面的依赖项,即加载node_modules 里面的文件

2. 目录文件功能

page_1.png
  • android文件夹里面包含了开发过程中的配置信息,和生成的APK。大部分内容是自动构建的
  • app文件夹属于主要的代码目录,包含页面和逻辑
  • 模块加载文件夹是npm加载的各个所需要的模块
  • index.android.js 安卓注册app页面

page_2.png
  • components 包含自定义的小模块,一般不需要更改
  • containers
    • Account 个人信息模块
    • Dash 消息模块
    • Work 主要功能模块
    • Login 登录页面
    • Main 登录后的主页面
    • Tutorial 起始页,介绍页面
  • images 图片文件夹
  • services 消息推送服务代码
  • utils 网络请求,输入判断,缓存数据代码
  • index.js 进入app代码的第一个页面,包含导航信息

3. 部分代码解释

  • app>containers>Login.js

加载所需要的模块


'use strict'; //严格模式

import React, { Component } from 'react'; //输入React模块

import {
  StyleSheet,
  ScrollView,
  Platform,
  View,
  Image,
  TouchableOpacity,
  Text,
} from 'react-native'; //引用react-native组件

import JPushModule from 'jpush-react-native';//引用极光推送组件

import {
 Color,   //颜色
 FontSize,   //字体
 Input,   //输入框
 Button,   //按钮
 Dialog,   //对话框
 Loading,   //加载组件
 Toast,   //悬浮自动消失提示框
} from '../components';  //引用自定义的小模块

import {
 request,  //数据请求
 Store,   //缓存数据
} from '../utils';

import Main from './Main'; //引用主页面
import Signin from './Account/Signin'; //引用注册页面

输出一个Login类


export default class Login extends Component {
state = {
    fetching: false,
    valid: false,
}
username = null
password = null

onValid = () => {
    this.setState({
      valid: this.username && this.password,
    });
}

signIn = () => {
    this.props.navigator.push({
     title: '注册',
     component: Signin,
 });
}

onLogin = async() => {
 this.setState({ fetching: true });
 const token = await request.login(this.username, this.password);
 if (!token) {
     this.setState({ fetching: false });
     return Toast.show('用户名或密码错误',Toast.LONG);
 }

 const user = await request.get('Sys/User/GetUserDetail', {
    UserCode: this.username
 })
 this.setState({ fetching: false });
 if (!user) return Toast.show('获取用户信息失败');
 Store.set('user', user);
 global.user = user;
 global.org = {};

 this.props.navigator.resetTo({
  title: '工作',
  component: Main,
 });

 if (Platform.OS == 'android') JPushModule.resumePush();

 request.get('Sys/User/GetUserOrgBasic', {
   UserCode: this.username
 }).then(data => {
  if (!data || !data.OrgBasic) return;
  global.org = data.OrgBasic;
  Store.set('org', data.OrgBasic);
  if (typeof(data.OrgBasic.OrgCode) == 'string') JPushModule.setTags([data.OrgBasic.OrgCode], () => {}, () => {});
  else JPushModule.setTags(data.OrgBasic.OrgCode, () => {}, () => {});
 });
}
render() {
 const { fetching, valid } = this.state;
 return (
  <View style={{flex: 1}} >
    <ScrollView style={styles.container} keyboardShouldPersistTaps={true}>
      <View style={styles.header}>
        <Image
          style={styles.image}
          source={require('../images/icon.png')} />
      </View>
      <Input
        ref='username'
        label='用户名'
        onChange={e => {this.username = e.nativeEvent.text; this.onValid();}}
        onSubmitEditing={e=>this.refs.password.focus()}
        keyboardType='default'
        returnKeyType='next'
        placeholder='请输入用户名'
      />
      <Input
        ref='password'
        label='密码'
        onChange={e => {this.password = e.nativeEvent.text; this.onValid();}}
        onSubmitEditing={this.onLogin}
        secureTextEntry={true} 
        keyboardType='default'
        returnKeyType='go'
        placeholder='请输入密码'
      />
      <Button style={styles.button} disabled={!valid} onPress={this.onLogin}>登录</Button>
      <TouchableOpacity activeOpacity={0.8}
        style={styles.signIn} onPress={this.signIn} >
        <Text style={styles.signText} > 去注册 > </Text>
      </TouchableOpacity>   
    </ScrollView>
    <Loading visible={fetching} />
  </View>
 );
}

使用Flexbox布局


const styles = StyleSheet.create({
  container: {
    backgroundColor: '#fff',
    padding: 15,
    paddingTop: 0,
    flex: 1,
  },
  header: {
    paddingVertical: 40,
    alignItems: 'center',
  },
  image: {
    width: 128,
    height: 128,
  },
  button: {
    marginVertical: 30,
  },
  signIn:{
    justifyContent: 'center',
    alignItems: 'center',
  },
 signText:{
   fontSize: FontSize.middle,
   color: Color.darkGray,
 }
});
  • app>utils>request.js

使用fetch方法get/post数据


function login(usercode, password) {
return fetch(ROOT_URL + 'login/doAction', {
method: 'POST',
headers: {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
},
body: JSON.stringify({
  usercode,
  password,
  app: true
})
}).then(res => res.json()).then(data => {
if (data && data.status && data.status === 'success') {
  token = data.token;
  return Store.set('token', token).then(() => {
    return token;
  });
}
return null;
}).catch(console.log.bind(console))
}

4. 打包签名APP

Android 打包生成 release APK 的方法

http://reactnative.cn/docs/0.41/signed-apk-android.html

5. 开发调试APP

page_3.png
  1. 连接手机,打开USB调试
  2. 使用 cmd 打个测试包并安装APP,此过程会安装依赖项,第一次需要耐心等待,并解决报错的各种问题 ,运行react-native run-android
  3. 开启APP的悬浮窗功能
  4. 运行npm run adb-fix, 反转控制手机
  5. 运行npm start, 打开package
  6. 使用摇一摇或者菜单键功能进行控制,Debug JS Remotely 与 Disable Live Reload 分别进行远程调试和实时更新

6. 业务逻辑功能

  1. Account 个人账户
  • index.js 帐号首页
  • About.js 关于页面,包括三个功能
    • Feedback.js (应用反馈) 反馈APP使用情况
    • Tutorial.js(欢迎页面) 功能简介
    • Linking.openURL('http://www.jat360.com'); 跳转平台网址
  • Company.js 企业信息页面
  • Profile.js 个人信息页面,
    • Edit.js 修改个人信息,
    • Password.js 修改密码
    • 退出登录时,需要清除APP缓存
  • Setting.js 设置APP功能页面
    • Store.multiRemove清除缓存
    • Switch选择开关,进行控制权限
  • Signin.js 注册页面
  1. Work 业务工作
  • index.js 工作首页
  • Attendance 考勤页面
    • Create.js (创建考勤)
      • DeviceInfo 设备信息模块
      • react-native-baidu-map 百度地图定位模块
      • ImageSelect 拍照模块
    • Detail.js(考勤详情)
  • SafetyCheck 项目级安全检查
    • Create.js (创建安全检查)
      • Detail.js (检查详情)
      • Finish.js (提交检查)
      • List.js (隐患详情)
      • Plan.js (选择计划)
      • Project.js (选择项目)
      • SubType.js (隐患小类)
      • Type.js (隐患大类)
    • CheckDetail.js (安全检查详情)
      • 通过权限判断,处理业务流程,包括 提交 - 确认 - 通知
    • List.js (安全检查列表)
    • Notify.js (通知单编制)
    • Person.js (选择责任人)
    • Unit.js (选择单位)
  • CorpSafetyCheck 公司级安全检查(差异对比)
    • 创建时需要选择项目
    • 创建时检查类型不同
    • 提交数据时的字段部分不一样
  • DangerNotice 隐患整改
    • Detail.js (检查详情)
      • 通过判断status来确认显示的内容
    • index.js (整改首页)
      • ScrollableTabView选择业务进程
    • List.js (隐患列表)
    • NoticeDetail.js (确认下发页面)
    • Person.js (选择负责人)
    • ReCheck.js (复查页面)
    • ReCheckConfirm.js (复查确认页面)
    • ReCheckDetail.js (复查详情页面)
    • Rectify.js (确认整改页面)
    • Unit.js (选择单位)
  • Plan 检查计划
    • CheckRecord.js (安全检查记录)
    • CheckRecordDetail.js (安全检查记录详情)
    • Create.js (编制检查记录)
    • CreateDanger.js (确认提交记录)
    • index.js (计划首页)
    • NoticeRecord.js (整改通知及复查记录)
    • NoticeRecordDetail.js (整改通知及复查记录详情)
    • Score.js (安全检查分项菜单)
    • SubScore.js (次级检查项)
    • SubScoreList.js (检查内容列表)
    • Summary.js (安全检查评分统计)
    • SummaryDetail.js (安全检查评分统计详情)
  • Project 项目管理
    • Create.js (公司级用户可创建项目)
      • DatePicker 日期选择组件
      • onShowAreaPicker 选择地区方法
    • CreatePrjUser.js (添加项目用户)
    • Detail.js (项目详情)
    • index.js (项目列表首页)
    • Map.js (项目地址)
    • Roles.js (选择角色)
    • Subject.js (选择单位页面并提交新增项目)
    • Unit.js (选择具体的单位)
  • SafetyAssistant 安全助手
    • Book (法律规定)
      • index.js(主级目录)
      • Caregory.js(次级目录)
      • Detail.js (具体内容)
    • Danger (隐患描述库)
      • Detail.js(隐患详情)
      • List.js(具体内容)
      • SubType.js(次级目录)
      • Type.js(主级条目)
  1. Dash 消息推送
  • index.js 消息首页
  • Favorite.js 收藏页面
  • Log.js 日志页面
  • Message.js 消息页面
  • Stat.js 统计页面
  • Notice 公告页面
    • Create.js (创建公告)
    • Detail.js(公告详情)
    • index.js(公告首页)
    • Role.js(选择用户类型)

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 142,668评论 18 611
  • 尼玛 写的时候我最想表达的就是这两个字,第一,我不是一个多事的人,也懒得去管闲事,因为我很忙,忙到没时间去管理自己...
    澧沅芷阅读 46评论 0 2
  • 涂抹着温柔月色的远方里, 晕开了世间深处浓浓的思念, 星星点点散落在暗夜的凡人心尖, 漾醒安静的梦田, 辗转再难将...
    小小七阅读 58评论 3 7
  • 我突然想到这个题目是因为刚刚和一个朋友在微信上聊到我问他,两款蜜蜡毛衣链那一款更好看。他的原话和我说第一款颜...
    日语培训老师Vivid阅读 137评论 0 0