前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用APICloud AVM多端框架开发消防检查助手App项目实践分享

使用APICloud AVM多端框架开发消防检查助手App项目实践分享

原创
作者头像
特特法爷
发布2022-06-14 14:04:41
4440
发布2022-06-14 14:04:41
举报
文章被收录于专栏:APICloudAPICloud

一、功能介绍

把消防检查过程中,需要手写填报的文档,在App端以表单填写进行实现。同时可以添加手写签名,关联照片,而且App端表单填报很多项目进行下拉选择,极大的提高了工作效率;表单填报完成之后可通过系统后台生成word模板文件,App端下载到手机,通过手机连接打印机,可把纸质文件进行打印。

App开发采用APICloud AVM框架,后台采用PHP。

功能要点:

1、场所登记,分为九小场所和合用场所登记

2、监督检查记录

3、责令整改通知书

4、基本情况拍照,检查过程记录拍照

5、后台针对上述数据进行多维度分析,导出Excel表格,Word模板文件

二、思维导图

三、用到的模块

四、项目目录

五、开发介绍

1、首页导航

系统首页使用tabLayout,可以将相关参数配置在JSON文件中,再在config.xml中将content的值设置成该JSON文件的路径。如果底部导航没有特殊需求这里强烈建议大家使用tabLayout为APP进行布局,官方已经将各类手机屏幕及不同的分辨率进行了适配,免去了很多关于适配方面的问题。

代码语言:javascript
复制
{
  "name": "root",
  "textOffset": 6,
  "color": "#999999",
  "selectedColor": "#004494",
  "scrollEnabled": false,
  "hideNavigationBar": false,
  "bgColor": "#fff",
  "navigationBar": {
      "background": "./images/navbk.png",
      "shadow": "rgba(0,0,0,0)",
      "color": "#fff",
      "fontSize": 18,
      "hideBackButton": true
  },
  "tabBar": {
    "background": "#fff",
    "shadow": "#eee",
    "color": "#5E5E5E",
    "selectedColor": "#004494",
    "textOffset": 3,
    "fontSize": 11,
    "scrollEnabled": true,
    "index": 0,
	"preload": 1,
    "frames": [
      {
        "title": "首页",
        "name": "home",
        "url": "./pages/index/home"
      },
      {
        "title": "历史记录",
        "name": "course",
        "url": "./pages/history/records"
      },
      {
        "title": "我的",
        "name": "user",
        "url": "./pages/user/wode"
      }
    ],
    "list": [
      {
        "text": "首页",
        "iconPath": "./images/home.png",
        "selectedIconPath": "./images/home-o.png"
      },
      {
        "text": "历史记录",
        "iconPath": "./images/his.png",
        "selectedIconPath": "./images/his-o.png"
      },
      {
        "text": "我的",
        "iconPath": "./images/my.png",
        "selectedIconPath": "./images/my-o.png"
      }
    ]
  }
}

由于导航使用的tablayout,所有App初始化需要执行的操作,只需要在第一个加载的页面执行即可全局响应。可通过 tabBar中的"index"字段来确定第一个需要加载的页面,通过"preload"来确定需要预加载几个页面。

2、动态权限

动态全选的获取在第一个初始化的页面执行即可。本项目中需要用到存储、相机、相册3个权限。用到的是官方的API方法hasPermission

代码语言:javascript
复制
                //提示获取存储权限
				var limits=[];
				var resultList = api.hasPermission({
					list: ['storage','camera','photos']
				});
				if (resultList[0].granted) {
					// 已授权,可以继续下一步操作
				} else {
					 limits.push(resultList[0].name);
				}
				if (resultList[1].granted) {
					// 已授权,可以继续下一步操作
				} else {
					 limits.push(resultList[1].name);
				}
				if (resultList[2].granted) {
					// 已授权,可以继续下一步操作
				} else {
					 limits.push(resultList[2].name);
				}
				if(limits.length>0){
					api.requestPermission({
                        list: limits,
                    }, function(res) {
						// console.log(JSON.stringify(res));
                    });
				}

manifest.xml文件,关于targetSdkVersion的值的大小,这里可以根据下文图片中的说明,结合自己的项目需要上架的平台自行设置。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <application name="targetSdkVersion" value="28"/>
</manifest>

3、消息事件

本项目中通过发送事件sendEvent和监听事件addEventListener,消息事件要学会合理的运用来提升APP中各个页面之间交互的体验。下面就实现在表单提交成功之后刷新列表页,登陆成功之后跳转页面时重新加载用户信息具体的操作说明以一下。

表单数据提交成功之后,在回调里发送事件"addbase",然后关闭页面,跳转至列表页,在列表页的apiready中监听“addbase”事件,在监听成功回调中执行刷新列表的操作。

代码语言:javascript
复制
onsubmit(e){
                let result = e.detail.value;
 
                this.data.dwmc = result.dwmc?result.dwmc:this.data.dwmc;
                this.data.dwdz = result.dwdz?result.dwdz:this.data.dwdz;
                //省略其他字段
                let params = {
						data:{
							values:{
								secret: Config.secret,
                                userid: api.getPrefs({sync: true,key: 'userid'}),
                                partid: api.getPrefs({sync: true,key: 'partid'}),
                                id:this.data.id,
								dwmc:this.data.dwmc,
                                dwdz:this.data.dwdz,
                                //省略
							}
						}
					}
					api.showProgress();
					Model.addbase(params, (res,err) => {
						// console.log(JSON.stringify(res));
						// console.log(JSON.stringify(err));
						if (res && res.flag == 'Success') {
							api.toast({
								msg:'登记成功'
							});	
                            api.sendEvent({
                                name: 'addbase',
                            });
                            api.closeWin();						
						} else {
							api.toast({
								msg:res.msg
							})
						}
						api.hideProgress();
					});
            },

代码语言:javascript
复制
            apiready(){
				this.data.tab=api.pageParam.tab;
				this.data.tabtitle=api.pageParam.tabtitle;
				this.data.refresherTriggered = true;
				this.loadData(false);
				api.addEventListener({
					name: 'setuserinfo'
				}, (ret, err) => {
					this.loadData(false);
				});
				//监听增加修改基本信息
				api.addEventListener({
					name: 'addbase'
				}, (ret, err) => {
					this.loadData(false);
				});
				api.addEventListener({
					name: 'delbase'
				}, (ret, err) => {
					this.loadData(false);
				});
			},

4、接口调用

将接口调用和接口配置分别封装了2个JS插件,model.js和config.js。这样来统一管理,避免了在每个页面进行接口调用的时候都重复写一遍代码,有效的简化了每个功能页面的代码量,只需要在回调里专注写自己的业务逻辑即可。

代码语言:javascript
复制
import $util from "../../utils/util.js"
import {Model} from "../../utils/model.js"
import {Config} from "../../utils/config.js"

config.js

代码语言:javascript
复制
class Config{
    constructor(){}
}
 
Config.restUrl = 'http://xiaofang.*******.cn/api.php/Home/Index';
Config.secret = '99d0fd93-***************************';
 
Config.addbase ='/addbase';//登记基本信息表
Config.querylist ='/querylist';//查询登记单位列表
Config.querybasebyid ='/querybasebyid';//查询登记单位基本信息详情
Config.querybaseinfobyid ='/querybaseinfobyid';//查询登记单位基本信息详情
Config.exportbase ='/exportbase';//下载登记单位基本信息
Config.deletebasebyid ='/deletebasebyid';//删除登记单位基本信息
Config.login ='/login';//登陆
Config.getpart ='/getpart';//获取单位列表
Config.register ='/register';//用户注册
/**省略**/
Config.checkUserStatus ='/checkUserStatus';//获取用户状态
 
export {Config}; 

model.js

代码语言:javascript
复制
import {Config} from './config.js';
 
class Model {
  constructor() {}
}
 
/*登记基本信息表 */
Model.addbase = function (param, callback){
  param.url = Config.addbase;
  param.method = 'post';
  this.request(param, callback);
}
 
/*查询登记单位列表 */
Model.querylist = function (param, callback){
  param.url = Config.querylist;
  param.method = 'post';
  this.request(param, callback);
}
 
/*查询登记单位基本信息详情 */
Model.querybasebyid = function (param, callback){
  param.url = Config.querybasebyid;
  param.method = 'post';
  this.request(param, callback);
}
 
/*查询登记单位基本信息详情 */
Model.querybaseinfobyid = function (param, callback){
  param.url = Config.querybaseinfobyid;
  param.method = 'post';
  this.request(param, callback);
}
 
/*下载登记单位基本信息 */
Model.exportbase = function (param, callback){
  param.url = Config.exportbase;
  param.method = 'post';
  this.request(param, callback);
}
 
/*删除登记单位基本信息 */
Model.deletebasebyid = function (param, callback){
  param.url = Config.deletebasebyid;
  param.method = 'post';
  this.request(param, callback);
}
 
/*登陆模块 */
Model.login = function (param, callback){
  param.url = Config.login;
  param.method = 'post';
  this.request(param, callback);
}
 
/**省略**/
 
/*获取用户状态 */
Model.checkUserStatus = function (param, callback){
  param.url = Config.checkUserStatus;
  param.method = 'post';
  this.request(param, callback);
}
 
Model.request = function(p, callback) {
  var param = p;
  if (!param.headers) {
      param.headers = {};
  }
  
  if (param.data && param.data.body) {
      param.headers['Content-Type'] = 'application/json; charset=utf-8';
  }
  if (param.url) {
      param.url = Config.restUrl + param.url;
  }
 
  api.ajax(param, function(ret, err) {
      callback && callback(ret, err);
  });
}
 
export {Model};

5、数据列表及分页查询

数据列表的展示,采用scroll-view标签,通过onrefresherrefresh,onrefresherrefresh出发的事件中进行数据列表的刷新,和分页查询。refresher-triggered这个属性来设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发。如果想默认下拉刷新一下可以在apiready中将之设置为true,以此来代替执行数据刷新操作。

如果列表中的每一项的元素较少,而且没有样式的特殊要求,也可以使用list-view来实现。

下面是以单位列表的完整页面代码。其他页面的列表基本功能都是一致的,只是在每一项的样式及参数个数存在差异。

代码语言:javascript
复制
<template name='unitlist'>
    <view class="page">
		<scroll-view class="main" scroll-y enable-back-to-top refresher-enabled refresher-triggered={refresherTriggered} onrefresherrefresh={this.onrefresherrefresh} onscrolltolower={this.onscrolltolower}>
			<view class="search-box">
				<input class="serach-input"  placeholder="请输入单位名称检索" confirm-type="search" onconfirm="onconfirm" oninput={this.getKey}/>
				<text class="search-btn" onclick="onconfirm">搜索</text>
			</view>
			<view class="item-box">
				<view class="item" data-id={item.id} onclick={this.openTable} v-for="(item, index) in list">
					<text class="item-content">{{item.name}}</text>
					<view class="item-sub">
						<view class="item-sub-box">
							<image class="item-sub-ico" src="../../images/DW.png" mode="aspectFit"></image>
							<text class="item-info">{{item.address}}</text>
						</view>
						<view class="item-sub-box">
							<image class="item-sub-ico" src="../../images/CT.png" mode="aspectFit"></image>
							<text class="item-info">{{item.type}}</text>
						</view>
					</view>
				</view>
			</view>
			<view class="footer">
				<text class="loadDesc">{loadStateDesc}</text>
			</view>
		</scroll-view>
    </view>
</template>
<script>
	import {Model} from '../../utils/model.js'
	import {Config} from "../../utils/config.js"
	import $util from "../../utils/util.js"
	export default {
		name: 'unitlist',
		data() {
			return{
				list:[],
				skip: 0,
				loading: false,
				refresherTriggered: false,
				haveMoreData: true,
				tab:'',
				tabtitle:'',
				key:''
			}
		},
		computed: {
			loadStateDesc(){
				if (this.data.loading || this.data.haveMoreData) {
					return '加载中...';
				} else if (this.list.length > 0) {
					return '没有更多啦';
				} else {
					return '暂时没有内容';
				}
			}
		},
		methods: {
			apiready(){
				this.data.tab=api.pageParam.tab;
				this.data.tabtitle=api.pageParam.tabtitle;
				this.data.refresherTriggered = true;
				this.loadData(false);
				api.addEventListener({
					name: 'setuserinfo'
				}, (ret, err) => {
					this.loadData(false);
				});
				//监听增加修改基本信息
				api.addEventListener({
					name: 'addbase'
				}, (ret, err) => {
					this.loadData(false);
				});
				api.addEventListener({
					name: 'delbase'
				}, (ret, err) => {
					this.loadData(false);
				});
			},
			loadData(loadMore) {
				this.data.loading = true;
				var that = this;
				var limit = 20;
				var skip = loadMore?that.data.skip+1:0;
				let params = {
					data:{
						values:{
							secret: Config.secret,
							userid: api.getPrefs({sync: true,key: 'userid'}),
							roleid: api.getPrefs({sync: true,key: 'roleid'}),
							partid: api.getPrefs({sync: true,key: 'partid'}),
							skip: skip,
							limit: limit,
							key:this.data.key
						}
					}
				}
				api.showProgress();
				Model.querylist(params, (res,err) => {
					// console.log(JSON.stringify(res));
					// console.log(JSON.stringify(err));
					if (res && res.flag == 'Success') {
						let lists = res.data;
						that.data.haveMoreData = lists.length == limit;
						if (loadMore) {
							that.data.list = that.data.list.concat(lists);
						} else {
							that.data.list = lists;
						}
						that.data.skip = skip;
					} else {
						that.data.haveMoreData = false;
					}
					that.data.loading = false;
					that.data.refresherTriggered = false;
					api.hideProgress();
				});
			},
			//打开填写表格
			openTable(e) {
				var id = e.currentTarget.dataset.id;
				$util.openWin({
					name: this.data.tab,
					url: '../index/'+this.data.tab+'.stml',
					title: this.data.tabtitle,
					pageParam:{
						id:id
					}
				});
			},
			/*下拉刷新页面*/
			onrefresherrefresh(){
				this.data.refresherTriggered = true;
				this.loadData(false);
			},
			onscrolltolower() {
				if (this.data.haveMoreData) {
					this.loadData(true);
				}
			},
			getKey(e){
				this.data.key = e.detail.value;
			},
			onconfirm(){
				this.loadData(false);
			}
		}
	}
</script>
<style>
    .main {
        height: 100%;
		background-color: #eaf0fa;
    }
	.item-box{
		background-color: #fff;
		margin: 5px;
	}
	.item{
		border-bottom: 1px solid #efefef;
		margin: 0 10px;
		justify-content:flex-start;
		flex-direction:column;
	}
	.item-content{
		font-size: 17PX;
		margin-top: 10px;
	}
	.item-info{
		font-size: 13PX;
		color: #666;
		margin: 10px 0;
	}
	.item-sub{
		justify-content:space-between;
		flex-direction:row;
	}
	.footer {
        height: 44px;
        justify-content: center;
        align-items: center;
    }
    .loadDesc {
        width: 200px;
        text-align: center;
    }
	.item-sub-ico{
		width: 15px;
		margin: 10px 0;
	}
	.item-sub-box{
		flex-flow: row nowrap;
	}
	.search-box{
		flex-flow: row nowrap;
		align-items: center;
		background-color: #2c6ddc;
		border-radius: 5px;
		margin: 5px;
	}
	.serach-input{
		padding: 5px;
		width: 80%;
		height: 50px;
		border-top-left-radius: 5px;
		border-bottom-left-radius: 5px;
	}
	.search-btn{
		width: 20%;
		text-align: center;
		color: #ffffff;
	}
</style>

6、双击退出程序

在首页页面和登陆页面中,添加双击退出程序功能,避免出现单击退出键出现不必要的页面跳转失误。此监听事件要在apiready中执行。

代码语言:javascript
复制
            //监听返回  双击退出程序
				api.setPrefs({
					key: 'time_last',
					value: '0'
				});
				api.addEventListener({
					name : 'keyback'
					}, function(ret, err) {
					var time_last = api.getPrefs({sync: true,key: 'time_last'});
					var time_now = Date.parse(new Date());
					if (time_now - time_last > 2000) {
						api.setPrefs({key:'time_last',value:time_now});
						api.toast({
							msg : '再按一次退出APP',
							duration : 2000,
							location : 'bottom'
						});
					} else {
						api.closeWidget({
							silent : true
						});
					}
				});

7、账号有效性确认

由于后台针对用户账号,启用了停用功能,后台一旦设置账号停用,App中也应响应的将用户进行退出系统操作。此操作在首页的apiready中进行执行。

代码语言:javascript
复制
			isLogin(){
				if(!api.getPrefs({sync: true,key:'userid'})){
					$util.openWin({
						name: 'login',
						url: '../user/login.stml',
						title: '',
						hideNavigationBar:true
					});
				}
				else{
					let params = {
					data:{
						values:{
							secret: Config.secret,
							userid: api.getPrefs({sync: true,key:'userid'})
						}
					}
				}
				api.showProgress();
				Model.checkUserStatus(params, (res,err) => {
					// console.log(JSON.stringify(res));
					// console.log(JSON.stringify(err));
					if (res && res.flag == 'Success') {
						if(ret.data=='02'){
							//清楚缓存用户数据
							api.removePrefs({
									key: 'name'
							});
							api.removePrefs({
									key: 'userid'
							});
							api.removePrefs({
									key: 'partname'
							});
							api.removePrefs({
									key: 'partid'
							});
							api.removePrefs({
									key: 'role'
							});
							api.removePrefs({
									key: 'rolename'
							});
							api.removePrefs({
									key: 'username'
							});
							//用户已停用 退出系统
							$util.openWin({
								name: 'login',
								url: '../user/login.stml',
								title: '',
								hideNavigationBar:true
							});
						}
					} else {
						//清除用户信息
						api.removePrefs({
								key: 'name'
						});
						api.removePrefs({
								key: 'userid'
						});
						api.removePrefs({
								key: 'partname'
						});
						api.removePrefs({
								key: 'partid'
						});
						api.removePrefs({
								key: 'role'
						});
						api.removePrefs({
								key: 'rolename'
						});
						api.removePrefs({
								key: 'username'
						});
						//用户异常 退出重新登陆
						$util.openWin({
							name: 'login',
							url: '../user/login.stml',
							title: '',
							hideNavigationBar:true
						});
					}			
					api.hideProgress();
				});
				}
			}

8、表单提交、回显

表单使用的事AVM官方的 from组件,通过onsubmit进行表单数据的提交。其中主要用到了input、textarea、radio、checkbox;每个控件的具体使用方法,在官方文档中否有详细的介绍。下面就具体的代码示例进行展示。

页面代码

代码语言:javascript
复制
<template name='addbase'>
    <scroll-view class="page" scroll-y>
		<form onsubmit={this.onsubmit}>
			<view class="item">
                <text>单位名称:</text>
                <input name="dwmc" value={this.data.dwmc} placeholder="请输入单位名称"/>
            </view>
			<view class="item">
                <text>单位地址:</text>
                <input name="dwdz"  value={this.data.dwdz} placeholder="请输入单位详细地址"/>
            </view>
            <checkbox-group class="item" name="dwlb">
				<text>单位类别:</text>
				<view class="item-checkbox">
					<label v-for="item in dwlbarr">
						<checkbox value={item} v-bind:checked="this.data.seldwlb.indexOf(item)!=-1?true:false"/>
						<text>{item}</text>
					</label>
				</view>
                <input name="dwlb_qt" value={this.data.dwlb_qt} placeholder="请输入单位类别"/>
            </checkbox-group>
            <checkbox-group class="item" name="dwxz">
				<text>单位性质:</text>
				<view class="item-checkbox">
					<label v-for="item in dwxzarr">
						<checkbox value={item} v-bind:checked="this.data.seldwxz.indexOf(item)!=-1?true:false"/>
						<text>{item}</text>
					</label>
				</view>
            </checkbox-group>
            <view class="item">
                <text>职工总数:</text>
                <input name="zgzs" value={this.data.zgzs} keyboard-type="number" placeholder="请输入单位职工总数"/>
            </view>
            <view class="item">
                <text>消防安全责任人:</text>
                <input name="xfaqzrr_xm" value={this.data.xfaqzrr_xm} placeholder="请输入负责人姓名"/>
                <input name="xfaqzrr_zw" value={this.data.xfaqzrr_zw} placeholder="请输入负责人职务"/>
                <input name="xfaqzrr_dh" value={this.data.xfaqzrr_dh} keyboard-type="number" placeholder="请输入负责人电话"/>
            </view>
            <view class="item">
                <text>消防安全管理人:</text>
                <input name="xfaqglr_xm" value={this.data.xfaqglr_xm} placeholder="请输入管理人姓名"/>
                <input name="xfaqglr_zw" value={this.data.xfaqglr_zw} placeholder="请输入管理人职务"/>
                <input name="xfaqglr_dh" value={this.data.xfaqglr_dh} keyboard-type="number" placeholder="请输入管理人电话"/>
            </view>
            <view class="item">
                <text>专兼职防火干部:</text>
                <input name="zjzfhgb_xm" value={this.data.zjzfhgb_xm} placeholder="请输入专兼职防火干部姓名"/>
                <input name="zjzfhgb_zw" value={this.data.zjzfhgb_zw} placeholder="请输入专兼职防火干部职务"/>
                <input name="zjzfhgb_dh" value={this.data.zjzfhgb_dh} keyboard-type="number" placeholder="请输入专兼职防火干部电话"/>
            </view>
            <view class="item">
                <label class="label-box">
                    <text class="label-title">建筑层数(层)</text>
                    <input class="label-input" name="jzcs" value={this.data.jzcs} keyboard-type="number" placeholder="请输入建筑层数(层)"/>
                </label>
                <label class="label-box">
                    <text class="label-title">所在层数(层)</text>
                    <input class="label-input" name="szcs" value={this.data.szcs} keyboard-type="number" placeholder="请输入所在层数(层)"/>
                </label>
                <label class="label-box">
                    <text class="label-title">建筑高度(m)</text>
                    <input class="label-input" name="jzgd" value={this.data.jzgd} keyboard-type="number" placeholder="请输入建筑高度(m)"/>
                </label>
                <label class="label-box">
                    <text class="label-title">总建筑面积(㎡)</text>
                    <input class="label-input" name="zjzmj" value={this.data.zjzmj} keyboard-type="decimal" placeholder="请输入总建筑面积(㎡)"/>
                </label>
                <label class="label-box">
                    <text class="label-title">每层建筑面积(㎡)</text>
                    <input class="label-input" name="mcjzmj" value={this.data.mcjzmj} keyboard-type="decimal" placeholder="请输入每层建筑面积(㎡)"/>
                </label>
                <label class="label-box">
                    <text class="label-title">营业面积(㎡)</text>
                    <input class="label-input" name="yymj" value={this.data.yymj} keyboard-type="decimal" placeholder="请输入营业面积(㎡)"/>
                </label>
                <label class="label-box">
                    <text class="label-title">检查时间</text>
                    <input class="label-input" name="jcsj" value={this.data.jcsj} keyboard-type="number" placeholder="请输入检查时间"/>
                </label>
                <label class="label-box">
                    <text class="label-title">投入使用时间</text>
                    <input class="label-input" name="trsysj" value={this.data.trsysj} keyboard-type="number" placeholder="请输入投入使用时间"/>
                </label>
                <label class="label-box">
                    <text class="label-title">开业时间</text>
                    <input class="label-input" name="kysj" value={this.data.kysj} keyboard-type="number" placeholder="请输入开业时间"/>
                </label>
                <label class="label-box">
                    <text class="label-title">租赁房屋户主姓名</text>
                    <input class="label-input" name="zlfwhzxm" value={this.data.zlfwhzxm} placeholder="请输入租赁房屋户主姓名"/>
                </label>
            </view>
            <view class="item">
                <text>生产经营状况:</text>
                <input name="scjyzk" value={this.data.scjyzk} placeholder="请输入单位生产经营状况"/>
            </view>
            <view class="item">
                <text>隶属社区:</text>
                <input name="lssq" value={this.data.lssq} placeholder="请输入单位隶属社区"/>
            </view>
            <radio-group class="item" name="ssyjfl">
                <text>三色预警分类:</text>
                <view class="item-checkbox">
                    <label v-for="item in ssyjflarr">
                        <radio value={item} v-bind:checked="this.data.ssyjfl==item?true:false"/>
                        <text>{item}</text>
                    </label>
                </view>
            </radio-group> 
            <view class="item">
                <text>消防设置种类及数量:</text>
                <textarea name="xfsszljsl" value={this.data.xfsszljsl} placeholder="请输入消防设置种类及数量"/>
            </view>
            <view class="item">
                <text>检查登记情况:</text>
                <textarea name="jcqkdj_1" value={this.data.jcqkdj_1} placeholder="请输入检查登记情况"/>
                <textarea name="jcqkdj_2" value={this.data.jcqkdj_2} placeholder="请输入检查登记情况"/>
                <textarea name="jcqkdj_3" value={this.data.jcqkdj_3} placeholder="请输入检查登记情况"/>
                <textarea name="jcqkdj_4" value={this.data.jcqkdj_4} placeholder="请输入检查登记情况"/>
            </view>
            <view class="item">
                <text>填表说明:</text>                
            </view>
            <button class="btn-submit" type="submit">提交</button>
        </form>
        <button v-show="isdelete" class="btn-delete" type="button" @click="delbase">删除</button>
    </scroll-view>
</template>

代码语言:javascript
复制
data() {
			return{
                dwmc:'',
                dwdz:'',
                dwlb:'',
                dwxz:'',
                zgzs:0,
                xfaqzrr_xm:'',
                xfaqzrr_zw:'',
                xfaqzrr_dh:'',
                xfaqglr_xm:'',
                xfaqglr_zw:'',
                xfaqglr_dh:'',
                zjzfhgb_xm:'',
                zjzfhgb_zw:'',
                zjzfhgb_dh:'',
                jzcs:null,
                jzgd:null,
                zjzmj:null,
                mcjzmj:null,
                szcs:null,
                yymj:null,
                jcsj:'',
                trsysj:'',
                kysj:'',
                zlfwhzxm:'',
                scjyzk:'',
                lssq:'',
                ssyjfl:'',
                xfsszljsl:'',
                jcqkdj_1:'',
                jcqkdj_2:'',
                jcqkdj_3:'',
                jcqkdj_4:'',
                dwlb_qt:'',
                id:0,
                ssyjflarr:['红','黄','绿'],
                dwlbarr:['购物场所','餐饮场所','住宿场所','公共娱乐场所','休闲健身场所','医疗场所','教学场所','生产加工企业','易燃易爆危险品销售、储存场所','其他'],
                dwxzarr:['国有','集体','股份合作公司','股份有限公司','港澳台投资','中外合资','个体私营','其他'],
                seldwlb:[],
                seldwxz:[],
                isdelete:false,
                dateList: [$formatDate.lastYear30(),[1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]],
                jcsjSelectorValue:[0,0,0],
                trsysjSelectorValue:[0,0,0],
                kysjSelectorValue:[0,0,0]
			}
		},

表单提交

代码语言:javascript
复制
onsubmit(e){
                let result = e.detail.value;
                this.data.dwmc = result.dwmc?result.dwmc:this.data.dwmc;
                this.data.dwdz = result.dwdz?result.dwdz:this.data.dwdz;
                this.data.dwlb = result.dwlb?result.dwlb.join(','):this.data.dwlb;
                this.data.dwlb_qt = result.dwlb_qt?result.dwlb_qt:this.data.dwlb_qt;
                this.data.dwxz = result.dwxz?result.dwxz.join(','):this.data.dwxz;
                this.data.zgzs = result.zgzs?result.zgzs:this.data.zgzs;
                this.data.xfaqzrr_xm = result.xfaqzrr_xm?result.xfaqzrr_xm:this.data.xfaqzrr_xm;
                this.data.xfaqzrr_zw = result.xfaqzrr_zw?result.xfaqzrr_zw:this.data.xfaqzrr_zw;
                this.data.xfaqzrr_dh = result.xfaqzrr_dh?result.xfaqzrr_dh:this.data.xfaqzrr_dh;
                this.data.xfaqglr_xm = result.xfaqglr_xm?result.xfaqglr_xm:this.data.xfaqglr_xm;
                this.data.xfaqglr_zw = result.xfaqglr_zw?result.xfaqglr_zw:this.data.xfaqglr_zw;
                this.data.xfaqglr_dh = result.xfaqglr_dh?result.xfaqglr_dh:this.data.xfaqglr_dh;
                this.data.zjzfhgb_xm = result.zjzfhgb_xm?result.zjzfhgb_xm:this.data.zjzfhgb_xm;
                this.data.zjzfhgb_zw = result.zjzfhgb_zw?result.zjzfhgb_zw:this.data.zjzfhgb_zw;
                this.data.zjzfhgb_dh = result.zjzfhgb_dh?result.zjzfhgb_dh:this.data.zjzfhgb_dh;
                this.data.jzcs = result.jzcs?result.jzcs:this.data.jzcs;
                this.data.jzgd = result.jzgd?result.jzgd:this.data.jzgd;
                this.data.zjzmj = result.zjzmj?result.zjzmj:this.data.zjzmj;
                this.data.mcjzmj = result.mcjzmj?result.mcjzmj:this.data.mcjzmj;
                this.data.szcs = result.szcs?result.szcs:this.data.szcs;
                this.data.yymj = result.yymj?result.yymj:this.data.yymj;
                this.data.jcsj = result.jcsj?result.jcsj:this.data.jcsj;
                this.data.trsysj = result.trsysj?result.trsysj:this.data.trsysj;
                this.data.kysj = result.kysj?result.kysj:this.data.kysj;
                this.data.zlfwhzxm = result.zlfwhzxm?result.zlfwhzxm:this.data.zlfwhzxm;
                this.data.scjyzk = result.scjyzk?result.scjyzk:this.data.scjyzk;
                this.data.lssq = result.lssq?result.lssq:this.data.lssq;
                this.data.ssyjfl = result.ssyjfl?result.ssyjfl:this.data.ssyjfl;
                this.data.xfsszljsl = result.xfsszljsl?result.xfsszljsl:this.data.xfsszljsl;
                this.data.jcqkdj_1 = result.jcqkdj_1?result.jcqkdj_1:this.data.jcqkdj_1;
                this.data.jcqkdj_2 = result.jcqkdj_1?result.jcqkdj_2:this.data.jcqkdj_2;
                this.data.jcqkdj_3 = result.jcqkdj_1?result.jcqkdj_3:this.data.jcqkdj_3;
                this.data.jcqkdj_4 = result.jcqkdj_1?result.jcqkdj_4:this.data.jcqkdj_4;
 
                if(this.data.dwmc==''){
                    api.toast({
                        msg:'单位名称不能为空!'
                    });
                    return false;
                }
                if(this.data.dwdz==''){
                    api.toast({
                        msg:'单位地址不能为空!'
                    });
                    return false;
                }
                if(this.data.dwlb==''){
                    api.toast({
                        msg:'单位类别不能为空!'
                    });
                    return false;
                }
                if(this.data.dwxz==''){
                    api.toast({
                        msg:'单位性质不能为空!'
                    });
                    return false;
                }
                let params = {
						data:{
							values:{
								secret: Config.secret,
                                userid: api.getPrefs({sync: true,key: 'userid'}),
                                id:this.data.id,
								dwmc:this.data.dwmc,
                                dwdz:this.data.dwdz,
                                dwlb:this.data.dwlb,
                                dwxz:this.data.dwxz,
                                zgzs:this.data.zgzs,
                                xfaqzrr_xm:this.data.xfaqzrr_xm,
                                xfaqzrr_zw:this.data.xfaqzrr_zw,
                                xfaqzrr_dh:this.data.xfaqzrr_dh,
                                xfaqglr_xm:this.data.xfaqglr_xm,
                                xfaqglr_zw:this.data.xfaqglr_zw,
                                xfaqglr_dh:this.data.xfaqglr_dh,
                                zjzfhgb_xm:this.data.zjzfhgb_xm,
                                zjzfhgb_zw:this.data.zjzfhgb_zw,
                                zjzfhgb_dh:this.data.zjzfhgb_dh,
                                jzcs:this.data.jzcs,
                                jzgd:this.data.jzgd,
                                zjzmj:this.data.zjzmj,
                                mcjzmj:this.data.mcjzmj,
                                szcs:this.data.szcs,
                                yymj:this.data.yymj,
                                jcsj:this.data.jcsj,
                                trsysj:this.data.trsysj,
                                kysj:this.data.kysj,
                                zlfwhzxm:this.data.zlfwhzxm,
                                scjyzk:this.data.scjyzk,
                                lssq:this.data.lssq,
                                ssyjfl:this.data.ssyjfl,
                                xfsszljsl:this.data.xfsszljsl,
                                jcqkdj_1:this.data.jcqkdj_1,
                                jcqkdj_2:this.data.jcqkdj_2,
                                jcqkdj_3:this.data.jcqkdj_3,
                                jcqkdj_4:this.data.jcqkdj_4,
                                dwlb_qt:this.data.dwlb_qt
							}
						}
					}
					api.showProgress();
					Model.addbase(params, (res,err) => {
						// console.log(JSON.stringify(res));
						// console.log(JSON.stringify(err));
						if (res && res.flag == 'Success') {
							api.toast({
								msg:'登记成功'
							});	
                            api.sendEvent({
                                name: 'addbase',
                            });
                            api.closeWin();						
						} else {
							api.toast({
								msg:res.msg
							})
						}
						api.hideProgress();
					});
            },

数据回显

代码语言:javascript
复制
//查询已添加的数据
            loadData(){
                let params = {
                    data:{
                        values:{
                            secret: Config.secret,
                            id:this.data.id
                        }
                    }
                }
                api.showProgress();
                Model.querybasebyid(params, (res,err) => {
                    // console.log(JSON.stringify(res));
                    // console.log(JSON.stringify(err));
                    if (res && res.flag == 'Success') {
                        //填充数据	
                        let result=res.data;
                        
                        this.data.dwmc = result.dwmc?result.dwmc:this.data.dwmc;
                        this.data.dwdz = result.dwdz?result.dwdz:this.data.dwdz;
                        this.data.seldwlb = result.dwlb?result.dwlb.split(','):this.data.dwlb;
                        this.data.dwlb_qt = result.dwlb_qt?result.dwlb_qt:this.data.dwlb_qt;
                        this.data.seldwxz = result.dwxz?result.dwxz.split(','):this.data.dwxz;
                        this.data.zgzs = result.zgzs?result.zgzs:this.data.zgzs;
                        this.data.xfaqzrr_xm = result.xfaqzrr_xm?result.xfaqzrr_xm:this.data.xfaqzrr_xm;
                        this.data.xfaqzrr_zw = result.xfaqzrr_zw?result.xfaqzrr_zw:this.data.xfaqzrr_zw;
                        this.data.xfaqzrr_dh = result.xfaqzrr_dh?result.xfaqzrr_dh:this.data.xfaqzrr_dh;
                        this.data.xfaqglr_xm = result.xfaqglr_xm?result.xfaqglr_xm:this.data.xfaqglr_xm;
                        this.data.xfaqglr_zw = result.xfaqglr_zw?result.xfaqglr_zw:this.data.xfaqglr_zw;
                        this.data.xfaqglr_dh = result.xfaqglr_dh?result.xfaqglr_dh:this.data.xfaqglr_dh;
                        this.data.zjzfhgb_xm = result.zjzfhgb_xm?result.zjzfhgb_xm:this.data.zjzfhgb_xm;
                        this.data.zjzfhgb_zw = result.zjzfhgb_zw?result.zjzfhgb_zw:this.data.zjzfhgb_zw;
                        this.data.zjzfhgb_dh = result.zjzfhgb_dh?result.zjzfhgb_dh:this.data.zjzfhgb_dh;
                        this.data.jzcs = result.jzcs?result.jzcs:this.data.jzcs;
                        this.data.jzgd = result.jzgd?result.jzgd:this.data.jzgd;
                        this.data.zjzmj = result.zjzmj?result.zjzmj:this.data.zjzmj;
                        this.data.mcjzmj = result.mcjzmj?result.mcjzmj:this.data.mcjzmj;
                        this.data.szcs = result.szcs?result.szcs:this.data.szcs;
                        this.data.yymj = result.yymj?result.yymj:this.data.yymj;
                        this.data.jcsj = result.jcsj?result.jcsj:this.data.jcsj;
                        this.data.trsysj = result.trsysj?result.trsysj:this.data.trsysj;
                        this.data.kysj = result.kysj?result.kysj:this.data.kysj;
                        this.data.zlfwhzxm = result.zlfwhzxm?result.zlfwhzxm:this.data.zlfwhzxm;
                        this.data.scjyzk = result.scjyzk?result.scjyzk:this.data.scjyzk;
                        this.data.lssq = result.lssq?result.lssq:this.data.lssq;
                        this.data.ssyjfl = result.ssyjfl?result.ssyjfl:this.data.ssyjfl;
                        this.data.xfsszljsl = result.xfsszljsl?result.xfsszljsl:this.data.xfsszljsl;
                        this.data.jcqkdj_1 = result.jcqkdj_1?result.jcqkdj_1:this.data.jcqkdj_1;
                        this.data.jcqkdj_2 = result.jcqkdj_1?result.jcqkdj_2:this.data.jcqkdj_2;
                        this.data.jcqkdj_3 = result.jcqkdj_1?result.jcqkdj_3:this.data.jcqkdj_3;
                        this.data.jcqkdj_4 = result.jcqkdj_1?result.jcqkdj_4:this.data.jcqkdj_4;
                        
                    } else {
                        api.toast({
                            msg:res.msg
                        })
                    }
                    api.hideProgress();
                });
            },

9、拍照及上传照片,图片预览

拍照使用的是FNPhotograph模块,自带UI的open接口,可选择拍照照片的质量,可配置使用摄像头方向,同时可配置照片不用存储到相册中,禁用显示相册按钮,保证用户只能现场拍照,可以满足项目需求。

项目中很多页面涉及到图片预览的功能,分为单图预览和多图预览。图片预览采用的是photoBrowser 模块。photoBrowser 是一个图片浏览器,支持单张、多张图片查看的功能,可放大缩小图片,支持本地和网络图片资源。若是网络图片资源则会被缓存到本地,缓存到本地上的资源可以通过 clearCache 接口手动清除。同时本模块支持横竖屏显示,在本app支持横竖屏的情况下,本模块底层会自动监听当前设备的位置状态,自动适配横竖屏以展示图片。使用此模块开发者看实现炫酷的图片浏览器。

代码语言:javascript
复制
			getPicture(e){
				this.data.type = e.currentTarget.dataset.type;
				api.actionSheet({
					title: '请选择',
					cancelTitle: '取消',
					buttons: ['选择图片','图片预览']
				}, (ret, err)=> {
					// console.log(JSON.stringify(ret));
					// console.log(JSON.stringify(err));
					// var index = ret.buttonIndex;
					if(ret.buttonIndex==1){
						var FNPhotograph = api.require('FNPhotograph');
						FNPhotograph.open({
							album: true ,
							quality: 'medium'
						}, (ret)=>{
							// console.log(JSON.stringify(ret));
							if(ret.eventType=='takePhoto'){
								FNPhotograph.close();
								//上传图片
								let params = {
									data:{
										values:{
											secret: Config.secret,
											baseid:this.data.baseid,
											type:this.data.type
										},
										files:{
											'file':ret.imagePath,
										}
									}
								}
								api.showProgress();
								Model.addbasepicbyid(params, (res,err) => {
									// console.log(JSON.stringify(res));
									// console.log(JSON.stringify(err));
									if (res && res.flag == 'Success') {    
										if(this.data.type=='01'){
											this.data.src1=res.data;
										}
										else if(this.data.type=='02'){
											this.data.src2=res.data;
										}
										else if(this.data.type=='03'){
											this.data.src3=res.data;
										}
										else if(this.data.type=='04'){
											this.data.src4=res.data;
										}
									} else {
										api.toast({
											msg:res.msg
										})
									}
									api.hideProgress();
								});							
							}
						});
					}
					else if(ret.buttonIndex==2){
						//图片预览
						let src='';
						if(this.data.type=='01'){
							src=this.data.src1;
						}
						else if(this.data.type=='02'){
							src=this.data.src2;
						}
						else if(this.data.type=='03'){
							src=this.data.src3;
						}
						else if(this.data.type=='04'){
							src=this.data.src4;
						}
						var photoBrowser = api.require('photoBrowser');
						photoBrowser.open({
							images: [
								src
							],
							placeholderImg: 'widget://res/img/apicloud.png',
							bgColor: '#000'
						}, (ret, err) => {
							if (ret) {
								if(ret.eventType=='click'){
									photoBrowser.close();
								}
							} else {
								api.toast({
									msg:'图片预览失败'
								})
							}
						});
					}
				});				
			}

10、页面之间的跳转和参数传递

分装工具类until.js,在其中定义了openWin方法来实现页面之间的跳转。页面跳转时参数的传递通过pageParam添加参数进行传递,在跳转到的页面通过api.pageParam.xxx在paiready中进行接收

代码语言:javascript
复制
<view class="tab-item" data-url="addbase" data-title="九小场所登记" tapmode @click="openPage">
	<image class="tab-item-logo" src="../../images/JB.png" mode="scaleToFill"></image>
	<text class="tab-item-title"> 九小场所登记</text>
</view>

代码语言:javascript
复制
        methods: {
			apiready(){//like created
				this.data.id=api.pageParam.id;
			},
			openPage(e){
				let title = e.currentTarget.dataset.title;
				let url = e.currentTarget.dataset.url;
				$util.openWin({
					name: url,
					url: '../index/'+url+'.stml',
					title: title,
					pageParam:{
						id:this.data.id
					}
				});
			}
		}

util.js

代码语言:javascript
复制
const $util = {
    openWin(param){
        var param = {
            name: param.name,
            url: param.url,
            title: param.title||'',
            pageParam: param.pageParam||{},
            hideNavigationBar: param.hideNavigationBar || false,
            navigationBar:{
                background:'../../images/navbk.png',
                shadow: '#fff',
                color: '#fff'
            }
        };
        if (this.isApp()) {
            api.openTabLayout(param);
        } else {
            api.openWin(param);
        }
    },
    isApp(){
        if (api.platform && api.platform == 'app') {
            return true;
        }
        return false;
    },
    fitRichText(richtext, width){
        var str = `<img style="max-width:${width}px;"`;
        var result = richtext.replace(/\<img/gi, str);
        return result;
    }
}
export default $util;

11、导航栏自定义按钮点击事件

如果是首页加载的页面,可以在首页中通过索引index进行判断然后分别配置;如果在单独的页面中需要添加的话,可在页面的apiready中进行配置。

首页中的配置,在首页中配置的话需要注意点是,如果是页面直接的跳转的话配置多个页面时没有问题,但是如果按钮事件是执行某个页面具体的方法的时候,就会出现问题。这里建议如果按钮事件是执行某个页面具体的方法,不要在首页中配置,可在页面中通过其他方式进行实现。因为首页配置的内容会在全局使用,而且加载成功之后,通过tabbar切换页面的时候,是不会进行页面刷新操作的。

代码语言:javascript
复制
apiready() {
        //导航设置
			api.addEventListener({
				name:'tabitembtn'
			}, (ret) => {
				api.setTabBarAttr({
					index: ret.index
				});
				if(ret.index==0){
                    api.setTabLayoutAttr({
                        hideNavigationBar:true,
                        animated:false
                    });
				}
                else if(ret.index==2){
                    api.setNavBarAttr({
                        rightButtons: [{
                            iconPath:'widget://image/chart.png'
                        }]
                    });
                     api.setTabLayoutAttr({
                        hideNavigationBar:false,
                        animated:false
                    });
                    api.addEventListener({
                        name:'navitembtn'
                    }, (ret)=>{
                        if(ret.type=='right'){
                            $util.openWin({
                                name: 'chart',
                                url: 'widget://html/test.html',
                                title: '统计分析',
                                pageParam:{
                                    
                                }
                            })
                        }
                    })
                }
				else{
					 api.setTabLayoutAttr({
                        hideNavigationBar:false,
                        animated:false
                    });
                    api.setNavBarAttr({
                        rightButtons: [{
                        }]
                    });
                    api.addEventListener({
                        name:'navitembtn'
                    }, (ret)=>{
                        
                    })
				}
			});
    },

单独页面中的配置

代码语言:javascript
复制
            apiready(){			
				//添加右上角按钮
				api.setNavBarAttr({
					rightButtons: [{
						text: '添加'
					}]
				});
				//监听右上角按钮点击事件
				api.addEventListener({
					name: 'navitembtn'
				}, (ret, err)=> {
					if (ret.type == 'right') {
						$util.openWin({
							name: 'addjcpics',
							url: 'addjcpics.stml',
							title: '添加检查记录照片',
							pageParam:{
								baseid:this.data.baseid
							}
						});
					}
				});				
			},

12、手写签名

手写签名用到的是 drawingBoard模块,drawingBoard 模块是一个手写签名模块。开发者可自定义个固定宽高(w、h)的 “frame”,该 “frame” 即是可手写签名的背景透明的画板,可将此画板固定在指定的 frame 或 window 上,从而自定义出符合自己需求的各种 UI 效果的签名功能。

代码语言:javascript
复制
<template name='signature'>
    <view class="page">
		<view class="flowbottom">
			<button class="btn-clear" tapmode @click="clear">重写</button>
			<button class="btn" tapmode @click="submit" disabled={this.data.btn_disabled}>确定</button>
		</view>
    </view>
</template>
<script>
	export default {
		name: 'signature',
		data() {
			return{
				btn_disabled:false,
				type:''
			}
		},
		methods: {
			apiready(){
				this.data.type = api.pageParam.type;
				var drawingBoard = api.require('drawingBoard');
				drawingBoard.open({
					rect: {
						x: 10,
						y: 100,
						w: api.frameWidth-20,
						h: (api.frameWidth-20)/2
					},
					styles: {
						brush: {
							color: '#000000',
							width: 3
						},
						bgColor: '#f0f0f0'
					},
					fixedOn: api.frameName
				});
			},
			clear(){
				var drawingBoard = api.require('drawingBoard');
				drawingBoard.clear();
			},
			submit(){
				this.data.btn_disabled = true;
				var drawingBoard = api.require('drawingBoard');
				drawingBoard.save({
					savePath: 'fs://drawingBoard/'+Date.now()+'.png',
					copyToAlbum: false
				}, (ret)=> {
					// console.log(JSON.stringify(ret));
					if(ret.absolutePath=='undefined'){
						this.data.btn_disabled = false;
						api.toast({
							msg:'签名失败,请稍后再试'
						});
					}
					else{
						//
						api.sendEvent({
							name: 'singture_success',
							extra: {
								src: ret.absolutePath,
								type:this.data.type
							}
						});
						drawingBoard.close();
						api.closeWin();
					}
				});
			}
		}
	}
</script>
<style>
    .page {
        display: flex;
		flex-flow: row nowrap;
		height: 100%;
		width: 100%;
		background-color: #eaf0fa;
    }
	.flowbottom{
		width: 100%;
		align-self: flex-end;
		padding: 10px;
	}
	.btn {
		display: block;
		height: 50px;
		width: 100%;
		background:#1492ff;
		border-radius: 5px;
		color: #fff;
		font-size: 20px;
		font-weight: bolder;
		padding: 0;
		margin-top: 10px;
	}
	.btn-clear {
		display: block;
		height: 50px;
		width: 100%;
		background:#ff0000;
		border-radius: 5px;
		color: #fff;
		font-size: 20px;
		font-weight: bolder;
		padding: 0;
		margin-top: 10px;
	}
</style>

13、清除缓存

由于项目中有很多拍照,查看照片,在使用的过程中,就会产生很多的缓存,缓存多了会导致应用反应变慢。所以在应用中增加了清楚缓存的功能,用的是官方提供的api.clearCache。

在个人中心 apiready中先获取到应用中的缓存,然后点击清除缓存按钮即可清除。

代码语言:javascript
复制
<view class="item" onclick="clearCache">
	<image class="item-icon" src="../../images/w_02.png" mode="widthFix"></image>
	<text class="item-title">缓存</text>
	<text class="item-right-cache">{cache}M</text>
</view>

代码语言:javascript
复制
          apiready(){
				//获取APP缓存 异步返回结果:
				api.getCacheSize((ret) => {
					this.data.cache = parseInt(ret.size/1024/1024).toFixed(1);
				});		
			},
			clearCache(){
				api.clearCache(() => {
					api.toast({
						msg: '清除完成'
					});
				});
				this.data.cache=0;
			},

14、下载并打开word文件

点击下载word文件按钮,调用系统接口,接口会把文件的路径进行返回,在接口会调用先通过api.download将文件下载到本地,然后通过模块docInteraction调用第三方APP打开文档。

代码语言:javascript
复制
                   //监听右上角按钮点击事件
                    api.addEventListener({
                        name: 'navitembtn'
                    }, (ret, err) => {
                        if (ret.type == 'right') {
                             let params = {
                                data:{
                                    values:{
                                        secret: Config.secret,
                                        id:this.data.id
                                    }
                                }
					        }
                            api.showProgress();
                            Model.exportbase(params, (res,err) => {
                                if (res && res.flag == 'Success') {                                  
                                    //下载文件
                                    api.download({
                                        url: res.data,
                                        report: true,
                                        cache: false,
                                        allowResume: true
                                    }, (ret, err)=> {
                                        // console.log(JSON.stringify(ret));
                                        if (ret.state == 1) {                                      
                                            //下载成功 跳转WORD预览页面
                                            var docInteraction = 
                                            api.require('docInteraction');
                                            docInteraction.open({
                                                path: ret.savePath
                                            }, (ret, err) => {
                                            });
                                        } else {
                                            if(ret.percent>0){
                                                api.toast({
                                                    msg:'正在下载'+ret.percent+'%'
                                                })
                                            }
                                            else{
                                                api.toast({
                                                    msg:'下载失败,请稍后再试'
                                                })
                                            }
                                        }
                                    });                                   
                                } else {
                                    api.toast({
                                        msg:'下载失败,请稍后再试'
                                    })
                                }
                                api.hideProgress();
                            });
                        }                      
                    });

15、登录、退出

通过 api.setPrefs 存储用户登录信息,退出登录清空数据。

代码语言:javascript
复制
//登陆APP
			submit() {
				var that = this;
				var user = that.data.user;
				var psw = that.data.psw;
				if (!user) {
					this.showToast("姓名不能为空");
					return;
				}
				if (!psw) {
					this.showToast("密码不能为空");
					return;
				} 
 
				api.showProgress();
				const params = {
					data: {
						values:{
							secret: Config.secret,
							user:user,
							psw:psw
						}
					}
				};
				Model.login(params, (res,err) => {
					// console.log(JSON.stringify(res));
					// console.log(JSON.stringify(err));
					if (res && res.flag == "Success") {
						that.showToast("提交成功");
						api.setPrefs({key:'name',value:res.data.name});
						api.setPrefs({key:'userid',value:res.data.id});
						api.setPrefs({key:'roleid',value:res.data.role});
						api.setPrefs({key:'rolename',value:res.data.rolename});
						api.setPrefs({key:'partid',value:res.data.part});
						api.setPrefs({key:'partname',value:res.data.partname});
						api.setPrefs({key:'username',value:res.data.username});			
 
						api.toast({
							msg:'登陆成功,欢迎使用'
						})
 
						api.sendEvent({
							name: 'setuserinfo',
						});
						api.closeWin();
					} else {
						that.showToast('登陆失败,请稍后再试');
					}
					api.hideProgress();
				});
			},

api.setPrefs 设置偏好数据,数据会存储到本地文件系统。api.removePrefs清除本地存储的数据。

代码语言:javascript
复制
loginout(){
				api.confirm({
					title: '提示',
					msg: '确定要退出登录?',
					buttons: ['确定', '取消']
				}, (ret, err) => {
					var index = ret.buttonIndex;
					if(index == 1){
						//清除用户信息
						api.removePrefs({
								key: 'name'
						});
						api.removePrefs({
								key: 'userid'
						});
						api.removePrefs({
								key: 'partname'
						});
						api.removePrefs({
								key: 'partid'
						});
						api.removePrefs({
								key: 'role'
						});
						api.removePrefs({
								key: 'rolename'
						});
						api.removePrefs({
								key: 'username'
						});
 
						api.toast({
							msg:'请重新登陆APP'
						})
						$util.openWin({
							name: 'login',
							url: '../user/login.stml',
							title: '',
							hideNavigationBar:true
						});
					}
				});
			}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、思维导图
  • 三、用到的模块
  • 四、项目目录
  • 五、开发介绍
    • 1、首页导航
      • 2、动态权限
        • 3、消息事件
          • 4、接口调用
            • 5、数据列表及分页查询
              • 6、双击退出程序
                • 7、账号有效性确认
                  • 8、表单提交、回显
                    • 9、拍照及上传照片,图片预览
                      • 10、页面之间的跳转和参数传递
                        • 11、导航栏自定义按钮点击事件
                          • 12、手写签名
                            • 13、清除缓存
                              • 14、下载并打开word文件
                                • 15、登录、退出
                                相关产品与服务
                                云开发 CloudBase
                                云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档