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

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

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

一、功能介绍

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

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

功能要点:

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

2、监督检查记录

3、责令整改通知书

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

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

二、思维导图


编辑切换为居中

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


三、用到的模块


编辑切换为居中

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


四、项目目录


编辑

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


五、开发介绍

1、首页导航

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


编辑切换为居中

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


{  "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


编辑切换为居中

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


               //提示获取存储权限                 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的值的大小,这里可以根据下文图片中的说明,结合自己的项目需要上架的平台自行设置。


编辑

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



编辑切换为居中

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



编辑切换为居中

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


<?xml version="1.0" encoding="UTF-8"?><manifest>     <application name="targetSdkVersion" value="28"/></manifest>

3、消息事件

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

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

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();                     });             },             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。这样来统一管理,避免了在每个页面进行接口调用的时候都重复写一遍代码,有效的简化了每个功能页面的代码量,只需要在回调里专注写自己的业务逻辑即可。

import $util from "../../utils/util.js"import {Model} from "../../utils/model.js"import {Config} from "../../utils/config.js"

config.js

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

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来实现。

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

<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中执行。

           //监听返回  双击退出程序                 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中进行执行。

           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;每个控件的具体使用方法,在官方文档中否有详细的介绍。下面就具体的代码示例进行展示。


编辑切换为居中

添加图片注释,不超过 140 字(可选)


页面代码

<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> 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]             }         },

表单提交

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();                     });             },

数据回显

//查询已添加的数据             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接口,可选择拍照照片的质量,可配置使用摄像头方向,同时可配置照片不用存储到相册中,禁用显示相册按钮,保证用户只能现场拍照,可以满足项目需求。


编辑切换为居中

添加图片注释,不超过 140 字(可选)


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


编辑切换为居中

添加图片注释,不超过 140 字(可选)


           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中进行接收。

<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>         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

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中进行配置。


编辑切换为居中

添加图片注释,不超过 140 字(可选)


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

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)=>{                                              })                 }             });     },

单独页面中的配置

           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 效果的签名功能。

编辑切换为居中

添加图片注释,不超过 140 字(可选)


<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中先获取到应用中的缓存,然后点击清除缓存按钮即可清除。

<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>           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打开文档。


编辑切换为居中

添加图片注释,不超过 140 字(可选)


                  //监听右上角按钮点击事件                     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存储用户登录信息,退出登录清空数据。

//登陆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清除本地存储的数据。

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                         });                     }                 });             }

后台接口

导出word用到了PhpWord,通过composer进行安装,然后再需要调用的地方直接调用,具体使用方法请参代码中示例;其中导出word模板文件有涉及到图片的导出。

<?php namespace Home\Controller; use Think\Controller; class IndexController extends Controller {     //用户登陆     public function login(){         checkscret('secret');//验证授权码         checkdataPost('user');//用户名         checkdataPost('psw');//密码           $user=$_POST['user'];         $psw=$_POST['psw'];           $map['username']=$user;         $map['password']=$psw;           $map['status']='01';//注册之后 需要审核一下           $releaseInfo=M()->table('user')->field('id,name,username,part,role,getrolename(role) rolename,getpartname(part) partname')->where($map)->find();                    if($releaseInfo){           returnApiSuccess('查询成功',$releaseInfo);         }         else{           returnApiError('查询失败!');           exit();         }       }     //用户注册     public function register(){         checkscret('secret');//验证授权码         checkdataPost('username');//用户名         checkdataPost('password');//密码           $username=$_POST['username'];         $name=$_POST['name'];         $password=$_POST['password'];         $part=$_POST['part'];           $data['username']=$username;         $data['name']=$name;         $data['password']=$password;         $data['part']=$part;         $data['role']=3;         $data['status']='02';//已注册未审核           $releaseInfo=M()->table('user')->data($data)->add();                    if($releaseInfo){           returnApiSuccess('注册成功',$releaseInfo);         }         else{           returnApiError('注册失败!');           exit();         }     }       //基本信息登记     public function addbase(){         checkscret('secret');//验证授权码         checkdataPost('userid');         checkdataPost('partid');             //对应字段         $dwmc=$_POST['dwmc'];         $dwdz=$_POST['dwdz'];         $dwlb=$_POST['dwlb'];         $dwxz=$_POST['dwxz'];         $zgzs=$_POST['zgzs'];         $xfaqzrr_xm=$_POST['xfaqzrr_xm'];         $xfaqzrr_zw=$_POST['xfaqzrr_zw'];         $xfaqzrr_dh=$_POST['xfaqzrr_dh'];         $xfaqglr_xm=$_POST['xfaqglr_xm'];         $xfaqglr_zw=$_POST['xfaqglr_zw'];         $xfaqglr_dh=$_POST['xfaqglr_dh'];         $zjzfhgb_xm=$_POST['zjzfhgb_xm'];         $zjzfhgb_zw=$_POST['zjzfhgb_zw'];         $zjzfhgb_dh=$_POST['zjzfhgb_dh'];         $jzcs=$_POST['jzcs'];         $jzgd=$_POST['jzgd'];         $zjzmj=$_POST['zjzmj'];         $mcjzmj=$_POST['mcjzmj'];         $szcs=$_POST['szcs'];         $yymj=$_POST['yymj'];         $jcsj=$_POST['jcsj'];         $trsysj=$_POST['trsysj'];         $kysj=$_POST['kysj'];         $zlfwhzxm=$_POST['zlfwhzxm'];         $scjyzk=$_POST['scjyzk'];         $lssq=$_POST['lssq'];         $ssyjfl=$_POST['ssyjfl'];         $xfsszljsl=$_POST['xfsszljsl'];         $jcqkdj_1=$_POST['jcqkdj_1'];         $jcqkdj_2=$_POST['jcqkdj_2'];         $jcqkdj_3=$_POST['jcqkdj_3'];         $jcqkdj_4=$_POST['jcqkdj_4'];         $dwlb_qt=$_POST['dwlb_qt'];           $userid=$_POST['userid'];         $partid=$_POST['partid'];           $id=$_POST['id'];             //数据         $data['dwmc']=$dwmc;         $data['dwdz']=$dwdz;         $data['dwlb']=$dwlb;         $data['dwxz']=$dwxz;         $data['zgzs']=$zgzs;         $data['xfaqzrr_xm']=$xfaqzrr_xm;         $data['xfaqzrr_zw']=$xfaqzrr_zw;         $data['xfaqzrr_dh']=$xfaqzrr_dh;         $data['xfaqglr_xm']=$xfaqglr_xm;         $data['xfaqglr_zw']=$xfaqglr_zw;         $data['xfaqglr_dh']=$xfaqglr_dh;         $data['zjzfhgb_xm']=$zjzfhgb_xm;         $data['zjzfhgb_zw']=$zjzfhgb_zw;         $data['zjzfhgb_dh']=$zjzfhgb_dh;         $data['jzcs']=$jzcs;         $data['jzgd']=$jzgd;         $data['zjzmj']=$zjzmj;         $data['mcjzmj']=$mcjzmj;         $data['szcs']=$szcs;         $data['yymj']=$yymj;         $data['jcsj']=$jcsj;         $data['trsysj']=$trsysj;         $data['kysj']=$kysj;         $data['zlfwhzxm']=$zlfwhzxm;         $data['scjyzk']=$scjyzk;         $data['lssq']=$lssq;         $data['ssyjfl']=$ssyjfl;         $data['xfsszljsl']=$xfsszljsl;         $data['jcqkdj_1']=$jcqkdj_1;         $data['jcqkdj_2']=$jcqkdj_2;         $data['jcqkdj_3']=$jcqkdj_3;         $data['jcqkdj_4']=$jcqkdj_4;         $data['dwlb_qt']=$dwlb_qt;           $data['userid']=$userid;         $data['partid']=$partid;         $data['create_time']=time();                  if($id){             $map['id']=$id;               //插入数据             $releaseInfo=M()->table('base')->where($map)->save($data);         }         else{               //插入数据             $releaseInfo=M()->table('base')->data($data)->add();         }            if($releaseInfo){           returnApiSuccess('登记成功',$releaseInfo);         }         else{           returnApiError( '登记失败,请稍后再试');           exit();         }     }       //删除登记信息     public function deletebasebyid(){         checkscret('secret');//验证授权码         checkdataPost('id');           $id=$_POST['id'];           $map['id']=$id;           $releaseInfo=M()->table('base')->where($map)->delete();                    if($releaseInfo){           returnApiSuccess('删除成功',$releaseInfo);         }         else{           returnApiError('删除失败!');           exit();         }     }       //查询登记单位列表     public function querylist(){         checkscret('secret');//验证授权码         checkdataPost('limit');//下一次加载多少条         checkdataPost('userid');           $limit=$_POST['limit'];         $skip=$_POST['skip'];         if(empty($skip)){           $skip=0;         }           $userid=$_POST['userid'];           $map['userid']=$userid;           $releaseInfo=M()->table('base')->field('id,dwmc as name,dwdz as address,dwlb as type')->where($map)->limit($skip*$limit,$limit)->order('create_time desc')->select();                    if($releaseInfo){           returnApiSuccess('查询成功',$releaseInfo);         }         else{           returnApiError('查询失败!');           exit();         }     }       //查询单位基本信息详情     public function querybasebyid(){         checkscret('secret');//验证授权码         checkdataPost('id');//ID           $id=$_POST['id'];           $map['id']=$id;           $releaseInfo=M()->table('base')->where($map)->find();                    if($releaseInfo){           returnApiSuccess('查询成功',$releaseInfo);         }         else{           returnApiError('查询失败!');           exit();         }     }       //查询基本信息     public function querybaseinfobyid(){         checkscret('secret');//验证授权码         checkdataPost('id');//ID           $id=$_POST['id'];           $map['id']=$id;           $releaseInfo=M()->table('base')->field('dwmc,dwdz,dwxz,jzgd,jzcs,yymj')->where($map)->find();                    if($releaseInfo){           returnApiSuccess('查询成功',$releaseInfo);         }         else{           returnApiError('查询失败!');           exit();         }     }       //导出基本信息表     public function exportbase(){         checkscret('secret');//验证授权码         checkdataPost('id');//ID           $id=$_POST['id'];           $map['id']=$id;           $data=M()->table('base')->where($map)->find();           if ($data) {             require_once "./vendor/autoload.php";             $tmp = new \PhpOffice\PhpWord\TemplateProcessor('./Public/template/temp_base.docx'); //打开模板             $tmp->setValue('dwmc', $data['dwmc']);             $tmp->setValue('dwdz', $data['dwdz']);             $tmp->setValue('dwlb', $data['dwlb']);             $tmp->setValue('dwxz', $data['dwxz']);             $tmp->setValue('zgzs', $data['zgzs']);               $tmp->setValue('xfaqzrr_xm', $data['xfaqzrr_xm']);             $tmp->setValue('xfaqzrr_zw', $data['xfaqzrr_zw']);             $tmp->setValue('xfaqzrr_dh', $data['xfaqzrr_dh']);               $tmp->setValue('xfaqglr_xm', $data['xfaqglr_xm']);             $tmp->setValue('xfaqglr_zw', $data['xfaqglr_zw']);             $tmp->setValue('xfaqglr_dh', $data['xfaqglr_dh']);               $tmp->setValue('zjzfhgb_xm', $data['zjzfhgb_xm']);             $tmp->setValue('zjzfhgb_zw', $data['zjzfhgb_zw']);             $tmp->setValue('zjzfhgb_dh', $data['zjzfhgb_dh']);               $tmp->setValue('jzcs', $data['jzcs']);             $tmp->setValue('jzgd', $data['jzgd']);             $tmp->setValue('zjzmj', $data['zjzmj']);             $tmp->setValue('mcjzmj', $data['mcjzmj']);             $tmp->setValue('kysj', $data['kysj']);             $tmp->setValue('szcs', $data['szcs']);             $tmp->setValue('yymj', $data['yymj']);             $tmp->setValue('jcsj', $data['jcsj']);             $tmp->setValue('trsysj', $data['trsysj']);             $tmp->setValue('zlfwhzxm', $data['zlfwhzxm']);             $tmp->setValue('scjyzk', $data['scjyzk']);             $tmp->setValue('lssq', $data['lssq']);             $tmp->setValue('ssyjfl', $data['ssyjfl']);             $tmp->setValue('xfsszljsl', $data['xfsszljsl']);             $tmp->setValue('jcqkdj_1', $data['jcqkdj_1']);             $tmp->setValue('jcqkdj_2', $data['jcqkdj_2']);             $tmp->setValue('jcqkdj_3', $data['jcqkdj_3']);             $tmp->setValue('jcqkdj_4', $data['jcqkdj_4']);               $tmp->setValue('dwlb_qt', $data['dwlb_qt']);                        $tmp->saveAs('./Uploads/九小场所基本情况管理登记表_'.$data['dwmc'].'.docx');             returnApiSuccess('导出成功','http://xiaofang.*********.cn/Uploads/九小场所基本情况管理登记表_'.$data['dwmc'].'.docx');         }         else{             returnApiError('导出失败,请稍后再试!');               exit();         }     }       //消防安全综合治理登记     public function addxfaqzljl(){         checkscret('secret');//验证授权码         checkdataPost('userid');         checkdataPost('partid');                  //对应字段         $dwmc=$_POST['dwmc'];         $jcsj=$_POST['jcsj'];         $bjccsmc=$_POST['bjccsmc'];         $bjccsdz=$_POST['bjccsdz'];         $jyz=$_POST['jyz'];         $jyzlxfs=$_POST['jyzlxfs'];         $jzlx=$_POST['jzlx'];         $sfdjjc=$_POST['sfdjjc'];         $sfkf=$_POST['sfkf'];         $djcs=$_POST['djcs'];         $jclb=$_POST['jclb'];         $ltjzcl=$_POST['ltjzcl'];         $sfzr=$_POST['sfzr'];         $jzrs=$_POST['jzrs'];         $jzcs=$_POST['jzcs'];         $zsqysfyaqck=$_POST['zsqysfyaqck'];         $zsqysfytswc=$_POST['zsqysfytswc'];         $zrxs=$_POST['zrxs'];         $hzzdbjxt=$_POST['hzzdbjxt'];         $zdpsmhxt=$_POST['zdpsmhxt'];         $snxfs=$_POST['snxfs'];         $mhq=$_POST['mhq'];         $mhqsl=$_POST['mhqsl'];         $xfssqtqk=$_POST['xfssqtqk'];         $dqxlqk=$_POST['dqxlqk'];         $ddzxcsyqk=$_POST['ddzxcsyqk'];         $sfsymhgwjrqnsbd=$_POST['sfsymhgwjrqnsbd'];         $sfcfyrybwxp=$_POST['sfcfyrybwxp'];         $yrybwxpcfsyqk=$_POST['yrybwxpcfsyqk'];         $sfdqkzxfpx=$_POST['sfdqkzxfpx'];         $ydsh=$_POST['ydsh'];         $yhjzgqk=$_POST['yhjzgqk'];           $userid=$_POST['userid'];         $partid=$_POST['partid'];           $id=$_POST['id'];         $baseid=$_POST['baseid'];             //数据         $data['dwmc']=$dwmc;         $data['jcsj']=$jcsj;         $data['bjccsmc']=$bjccsmc;         $data['bjccsdz']=$bjccsdz;         $data['jyz']=$jyz;         $data['jyzlxfs']=$jyzlxfs;         $data['jzlx']=$jzlx;         $data['sfdjjc']=$sfdjjc;         $data['sfkf']=$sfkf;         $data['djcs']=$djcs;         $data['jclb']=$jclb;         $data['ltjzcl']=$ltjzcl;         $data['sfzr']=$sfzr;         $data['jzrs']=$jzrs;         $data['jzcs']=$jzcs;         $data['zsqysfyaqck']=$zsqysfyaqck;         $data['zsqysfytswc']=$zsqysfytswc;         $data['zrxs']=$zrxs;         $data['hzzdbjxt']=$hzzdbjxt;         $data['zdpsmhxt']=$zdpsmhxt;         $data['snxfs']=$snxfs;         $data['mhq']=$mhq;         $data['mhqsl']=$mhqsl;         $data['xfssqtqk']=$xfssqtqk;         $data['dqxlqk']=$dqxlqk;         $data['ddzxcsyqk']=$ddzxcsyqk;         $data['sfsymhgwjrqnsbd']=$sfsymhgwjrqnsbd;         $data['sfcfyrybwxp']=$sfcfyrybwxp;         $data['yrybwxpcfsyqk']=$yrybwxpcfsyqk;         $data['sfdqkzxfpx']=$sfdqkzxfpx;         $data['ydsh']=$ydsh;         $data['yhjzgqk']=$yhjzgqk;           $data['baseid']=$baseid;           $data['userid']=$userid;         $data['partid']=$partid;         $data['create_time']=time();           //保存文件         $upload = new \Think\Upload(); // 实例化上传类         $upload->rootPath = './Uploads/'; // 设置附件上传根目录         $upload->saveName = array('uniqid', mt_rand(1,999999).'_'.md5(uniqid())); // 自定义图片重命名         $upload->exts = array('jpg', 'jpeg' ,'png'); // 设置附件上传类型 只允许照片         // 上传文件         $uploadinfo = $upload->upload();           if($uploadinfo){             if($uploadinfo['file1']['savepath'] && $uploadinfo['file1']['savename']){                 $data['signature_check']="/Uploads/".$uploadinfo['file1']['savepath'].$uploadinfo['file1']['savename'];             }             if($uploadinfo['file2']['savepath'] && $uploadinfo['file2']['savename']){                 $data['signature_bcheck']="/Uploads/".$uploadinfo['file2']['savepath'].$uploadinfo['file2']['savename'];             }         }                  if($id){             $map['id']=$id;               //插入数据             $releaseInfo=M()->table('zhzljl')->where($map)->save($data);         }         else{               //插入数据             $releaseInfo=M()->table('zhzljl')->data($data)->add();         }            if($releaseInfo){           returnApiSuccess('登记成功',$releaseInfo);         }         else{           returnApiError( '登记失败,请稍后再试');           exit();         }     }       //查询综合检查记录     public function queryxfaqzljlyid(){         checkscret('secret');//验证授权码         checkdataPost('baseid');           $baseid=$_POST['baseid'];           $map['baseid']=$baseid;           $releaseInfo=M()->table('zhzljl')->where($map)->find();           if($releaseInfo){           returnApiSuccess('查询成功',$releaseInfo);         }         else{           returnApiError( '查询失败,请稍后再试');           exit();         }     }       //导出     public function exportxfaqzljl(){         checkscret('secret');//验证授权码         checkdataPost('id');//ID           $id=$_POST['id'];           $map['id']=$id;           $data=M()->table('xf_zhzljl')->where($map)->find();           if ($data) {             require_once "./vendor/autoload.php";             $tmp = new \PhpOffice\PhpWord\TemplateProcessor('./Public/template/temp_zljl.docx'); //打开模板             $tmp->setValue('dwmc', $data['dwmc']);             $tmp->setValue('jcsj', $data['jcsj']);             $tmp->setValue('bjccsmc', $data['bjccsmc']);             $tmp->setValue('bjccsdz', $data['bjccsdz']);             $tmp->setValue('jyz', $data['jyz']);             $tmp->setValue('jyzlxfs', $data['jyzlxfs']);             $tmp->setValue('jzlx', $data['jzlx']);             $tmp->setValue('sfdjjc', $data['sfdjjc']);             $tmp->setValue('djcs', $data['djcs']);             $tmp->setValue('sfkf', $data['sfkf']);             $tmp->setValue('jclb', $data['jclb']);             $tmp->setValue('ltjzcl', $data['ltjzcl']);             $tmp->setValue('sfzr', $data['sfzr']);             $tmp->setValue('jzrs', $data['jzrs']);             $tmp->setValue('jzcs', $data['jzcs']);             $tmp->setValue('zsqysfyaqck', $data['zsqysfyaqck']);             $tmp->setValue('zsqysfytswc', $data['zsqysfytswc']);             $tmp->setValue('zrxs', $data['zrxs']);               $tmp->setValue('hzzdbjxt', $data['hzzdbjxt']);             $tmp->setValue('zdpsmhxt', $data['zdpsmhxt']);             $tmp->setValue('snxfs', $data['snxfs']);             $tmp->setValue('mhq', $data['mhq']);             $tmp->setValue('mhqsl', $data['mhqsl']);             $tmp->setValue('xfssqtqk', $data['xfssqtqk']);               $tmp->setValue('dqxlqk', $data['dqxlqk']);             $tmp->setValue('ddzxcsyqk ', $data['ddzxcsyqk']);             $tmp->setValue('sfsymhgwjrqnsbd', $data['sfsymhgwjrqnsbd']);             $tmp->setValue('sfcfyrybwp', $data['sfcfyrybwxp']);             $tmp->setValue('yrybwxpcfsyqk', $data['yrybwxpcfsyqk']);             $tmp->setValue('sfdqkzxfpx', $data['sfdqkzxfpx']);             $tmp->setValue('ydsh', $data['ydsh']);             $tmp->setValue('yhjzgqk', $data['yhjzgqk']);               $tmp->setImageValue('signature_check', ['path' => '.'.$data['signature_check'], 'width' => 120, 'height' => 20]);             $tmp->setImageValue('signature_bcheck', ['path' => '.'.$data['signature_bcheck'], 'width' => 120, 'height' => 20]);               $tmp->saveAs('./Uploads/合用场所消防安全综合治理记录表_'.$data['bjccsmc'].'.docx');             returnApiSuccess('导出成功','http://xiaofang.********.cn/Uploads/合用场所消防安全综合治理记录表_'.$data['bjccsmc'].'.docx');                 }         else{             returnApiError('导出失败,请稍后再试!');               exit();         }     }       //添加基本信息照片     public function addbasepicbyid(){         checkscret('secret');//验证授权码         checkdataPost('baseid');         checkdataPost('type');           $baseid=$_POST['baseid'];         $type=$_POST['type'];           $map['baseid']=$baseid;           $data['baseid']=$baseid;           //保存文件         $upload = new \Think\Upload(); // 实例化上传类         $upload->rootPath = './Uploads/'; // 设置附件上传根目录         $upload->saveName = array('uniqid', mt_rand(1,999999).'_'.md5(uniqid())); // 自定义图片重命名         $upload->exts = array('jpg', 'jpeg' ,'png'); // 设置附件上传类型 只允许照片         // 上传文件         $uploadinfo = $upload->upload();           if($uploadinfo){             if($type=='01'){                 $data['mt']="/Uploads/".$uploadinfo['file']['savepath'].$uploadinfo['file']['savename'];             }             else if($type=='02'){                 $data['yyzz']="/Uploads/".$uploadinfo['file']['savepath'].$uploadinfo['file']['savename'];             }             else if($type=='03'){                 $data['dlqk']="/Uploads/".$uploadinfo['file']['savepath'].$uploadinfo['file']['savename'];             }             else if($type=='04'){                 $data['sfz']="/Uploads/".$uploadinfo['file']['savepath'].$uploadinfo['file']['savename'];             }         }         $data['create_time']=time();           if($this->checkbasepic($baseid)){             $releaseInfo=M()->table('basepic')->where($map)->save($data);         }         else{              $releaseInfo=M()->table('basepic')->data($data)->add();         }                    if($releaseInfo){           returnApiSuccess('添加成功',"http://xiaofang.******.cn/Uploads/".$uploadinfo['file']['savepath'].$uploadinfo['file']['savename']);         }         else{           returnApiError('添加失败!');           exit();         }     }       function checkbasepic($baseid){         $map['baseid']=$baseid;           $ret=M()->table('basepic')->where($map)->find();           if($ret){             return true;         }         else{             return false;         }     } }


目录
相关文章
|
3天前
|
供应链 搜索推荐 API
1688APP原数据API接口的开发、应用与收益(一篇文章全明白)
1688作为全球知名的B2B电商平台,通过开放的原数据API接口,为开发者提供了丰富的数据资源,涵盖商品信息、交易数据、店铺信息、物流信息和用户信息等。本文将深入探讨1688 APP原数据API接口的开发、应用及其带来的商业收益,包括提升流量、优化库存管理、增强用户体验等方面。
25 6
|
4天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
23 3
|
10天前
|
移动开发 小程序 PHP
校园圈子论坛系统采取的PHP语音和uni账号开发的小程序APP公众号H5是否只需要4800元?是的,就是只需要4800元
关于校园圈子论坛系统采用PHP语言和uni-app开发的小程序、APP、公众号和H5是否仅需4800元这个问题,实际上很难给出一个确定的答案。这个价格可能受到多种因素的影响
40 8
|
6天前
|
人工智能 小程序 数据处理
uni-app开发AI康复锻炼小程序,帮助肢体受伤患者康复!
近期,多家康复机构咨询AI运动识别插件是否适用于肢力运动受限患者的康复锻炼。本文介绍该插件在康复锻炼中的应用场景,包括康复运动指导、运动记录、恢复程度记录及过程监测。插件集成了人体检测、姿态识别等功能,支持微信小程序平台,使用便捷,安全可靠,帮助康复治疗更加高效精准。
|
2月前
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
682 7
|
2月前
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
742 1
|
27天前
|
人工智能 小程序 搜索推荐
uni app下开发AI运动小程序解决方案
本文介绍了在小程序中实现AI运动识别的解决方案。该方案依托于UNI平台,通过高效便捷的插件形式,实现包括相机抽帧控制、人体识别、姿态识别等在内的多项功能,无需依赖后台服务器,大幅提高识别效率和用户体验。方案内置多种运动模式,支持自定义扩展,适用于AI健身、云上赛事、AI体测等多场景,适合新开发和存量改造项目。
|
1月前
|
设计模式 Swift iOS开发
探索iOS开发:从基础到高级,打造你的第一款App
【10月更文挑战第40天】在这个数字时代,掌握移动应用开发已成为许多技术爱好者的梦想。本文将带你走进iOS开发的世界,从最基础的概念出发,逐步深入到高级功能实现,最终指导你完成自己的第一款App。无论你是编程新手还是有志于扩展技能的开发者,这篇文章都将为你提供一条清晰的学习路径。让我们一起开始这段旅程吧!
|
1月前
|
小程序 数据挖掘 UED
开发1个上门家政小程序APP系统,都有哪些功能?
在快节奏的现代生活中,家政服务已成为许多家庭的必需品。针对传统家政服务存在的问题,如服务质量不稳定、价格不透明等,我们历时两年开发了一套全新的上门家政系统。该系统通过完善信用体系、提供奖励机制、优化复购体验、多渠道推广和多样化盈利模式,解决了私单、复购、推广和盈利四大痛点,全面提升了服务质量和用户体验,旨在成为家政行业的领导者。
|
2月前
|
JavaScript 前端开发 小程序
uniapp一个人开发APP关键步骤和考虑因素
uniapp一个人开发APP关键步骤和考虑因素
142 1
uniapp一个人开发APP关键步骤和考虑因素

热门文章

最新文章

下一篇
DataWorks