dedsudiyu 1 年之前
当前提交
de3694c2bd
共有 100 个文件被更改,包括 12979 次插入0 次删除
  1. 5 0
      .gitignore
  2. 343 0
      App.vue
  3. 90 0
      api/basicsModules/index.js
  4. 5 0
      api/manage/index.js
  5. 21 0
      api/request/config.js
  6. 361 0
      api/request/request.js
  7. 21 0
      api/request/util.js
  8. 5 0
      api/student/index.js
  9. 537 0
      component/cropper.js
  10. 75 0
      component/cropper.vue
  11. 340 0
      component/homeConfigurationSlot.vue
  12. 199 0
      component/mineConfigurationSlot.vue
  13. 126 0
      component/navbar.vue
  14. 51 0
      component/permissionsSlot.vue
  15. 70 0
      component/system-info.js
  16. 149 0
      component/tabBar.vue
  17. 187 0
      component/topWarn.vue
  18. 19 0
      components/dengrq-datetime-picker/customPickerView/index.css
  19. 53 0
      components/dengrq-datetime-picker/customPickerView/index.js
  20. 11 0
      components/dengrq-datetime-picker/customPickerView/index.vue
  21. 57 0
      components/dengrq-datetime-picker/dateSelector/index.css
  22. 209 0
      components/dengrq-datetime-picker/dateSelector/index.js
  23. 41 0
      components/dengrq-datetime-picker/dateSelector/index.vue
  24. 15 0
      components/dengrq-datetime-picker/dateTimePicker/constant.js
  25. 93 0
      components/dengrq-datetime-picker/dateTimePicker/dateUtil.js
  26. 378 0
      components/dengrq-datetime-picker/dateTimePicker/index.js
  27. 9 0
      components/dengrq-datetime-picker/dateTimePicker/index.vue
  28. 二进制
      images/basicsModules/btn_sy_xz.png
  29. 二进制
      images/basicsModules/btn_sy_zc.png
  30. 二进制
      images/basicsModules/btn_wd_jfdh.png
  31. 二进制
      images/basicsModules/btn_wd_xz.png
  32. 二进制
      images/basicsModules/btn_wd_zc.png
  33. 二进制
      images/basicsModules/btn_xx_xz.png
  34. 二进制
      images/basicsModules/btn_xx_zc.png
  35. 二进制
      images/basicsModules/button_1.png
  36. 二进制
      images/basicsModules/button_2.png
  37. 二进制
      images/basicsModules/icon_04.png
  38. 二进制
      images/basicsModules/icon_12.png
  39. 二进制
      images/basicsModules/icon_13.png
  40. 二进制
      images/basicsModules/icon_14.png
  41. 二进制
      images/basicsModules/icon_15.png
  42. 二进制
      images/basicsModules/icon_dzt_pzjc.png
  43. 二进制
      images/basicsModules/icon_sy_aqjc.png
  44. 二进制
      images/basicsModules/icon_sy_aqxx.png
  45. 二进制
      images/basicsModules/icon_sy_fjgk.png
  46. 二进制
      images/basicsModules/icon_sy_hxp.png
  47. 二进制
      images/basicsModules/icon_sy_qpgl.png
  48. 二进制
      images/basicsModules/icon_sy_ssp.png
  49. 二进制
      images/basicsModules/icon_sy_tzsb.png
  50. 二进制
      images/basicsModules/icon_sy_wdsys.png
  51. 二进制
      images/basicsModules/icon_sy_zrsq.png
  52. 二进制
      images/basicsModules/icon_wdwg_gd.png
  53. 二进制
      images/basicsModules/img_bg_cjcx.png
  54. 二进制
      images/basicsModules/img_bg_jfmx.png
  55. 二进制
      images/basicsModules/img_bg_wgjl.png
  56. 二进制
      images/basicsModules/img_log_in_account.png
  57. 二进制
      images/basicsModules/img_log_in_password.png
  58. 二进制
      images/basicsModules/null-data-1.png
  59. 16 0
      main.js
  60. 76 0
      manifest.json
  61. 821 0
      package-lock.json
  62. 15 0
      package.json
  63. 73 0
      pages.json
  64. 58 0
      pages/home/home.vue
  65. 1018 0
      pages/home/manageWorkbench.vue
  66. 533 0
      pages/home/studentWorkbench.vue
  67. 445 0
      pages/home/supplierWorkbench.vue
  68. 249 0
      pages/information/information.vue
  69. 194 0
      pages/information/informationInfo.vue
  70. 309 0
      pages/information/notPassInfo.vue
  71. 355 0
      pages/login/login.vue
  72. 641 0
      pages/mine/mine.vue
  73. 36 0
      pages/saoCode/hazardousChemicalsDescription.vue
  74. 36 0
      pages/saoCode/safetyManagement.vue
  75. 62 0
      pages/saoCode/saoCode.vue
  76. 137 0
      pages/saoCode/scan.vue
  77. 26 0
      styles/animation.styl
  78. 73 0
      styles/button.styl
  79. 22 0
      styles/color.styl
  80. 68 0
      styles/flex.styl
  81. 3 0
      styles/font.styl
  82. 6 0
      styles/index.styl
  83. 91 0
      styles/layout.styl
  84. 19 0
      styles/variable.styl
  85. 256 0
      styles/w-e-text.styl
  86. 76 0
      uni.scss
  87. 196 0
      uni_modules/mmmm-image-tools/index.js
  88. 11 0
      uni_modules/mmmm-image-tools/package.json
  89. 52 0
      uni_modules/uni-data-picker/changelog.md
  90. 45 0
      uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
  91. 546 0
      uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
  92. 563 0
      uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
  93. 385 0
      uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
  94. 92 0
      uni_modules/uni-data-picker/package.json
  95. 22 0
      uni_modules/uni-data-picker/readme.md
  96. 16 0
      uni_modules/uni-icons/changelog.md
  97. 1115 0
      uni_modules/uni-icons/components/uni-icons/icons.js
  98. 89 0
      uni_modules/uni-icons/components/uni-icons/uni-icons.vue
  99. 663 0
      uni_modules/uni-icons/components/uni-icons/uniicons.css
  100. 0 0
      uni_modules/uni-icons/components/uni-icons/uniicons.ttf

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+/.idea
+/unpackage
+/.hbuilderx
+/.node_modules
+/node_modules

+ 343 - 0
App.vue

@@ -0,0 +1,343 @@
+<script>
+	import {systemInfo} from '@/component/system-info.js'
+    import $mqtt from '@/utils/mqtt.min.js';
+    import { config } from '@/api/request/config.js'
+	export default {
+		onLaunch: function() {
+			/* 获取设备信息 */
+			const SystemInfomations = systemInfo()
+			this.navHeight = SystemInfomations.navHeight + SystemInfomations.statusBarHeight //头部导航栏总高度
+			uni.setStorageSync('navHeight', this.navHeight)
+			//获取openid
+			uni.login({
+				success(loginRes) {
+					console.log('获取code成功');
+					uni.setStorageSync('code', loginRes.code);
+				}
+			})
+			//小程序热更新
+			if (wx.canIUse('getUpdateManager')) {
+			  const updateManager = wx.getUpdateManager()
+			  updateManager.onCheckForUpdate(function (res) {
+			   if (res.hasUpdate) {
+				updateManager.onUpdateReady(function () {
+				 wx.showModal({
+				  title: '更新提示',
+				  content: '新版本已经准备好,是否重启应用?',
+				  success: function (res) {
+				   if (res.confirm) {
+					updateManager.applyUpdate()
+				   }
+				  }
+				 })
+				})
+				updateManager.onUpdateFailed(function () {
+				 wx.showModal({
+				  title: '已经有新版本了哟~',
+				  content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~'
+				 })
+				})
+			   }
+			  })
+			 } else {
+			  wx.showModal({
+			   title: '提示',
+			   content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
+			  })
+			 }
+		},
+		onShow: function() {
+		},
+		onHide: function() {
+		},
+        data(){
+		    return{
+		        //MQTT数据
+                client:{},
+                //MQTT请求参数
+                mtopicBigview:"lab/bigview",
+                mtopicFunction:"lab/function/data",
+                mtopicHardware:"lab/hardware/data",
+				mtopicLine:"lab/riskPlan/trigger/notice",
+                //监听数据
+                watchObj:{},
+				//当前通道数组
+				mqttIdList:[],
+            }
+        },
+        globalData:{
+            mqttAlarmData:{},
+            mqttSensorData:{},
+            mqttDeviceData:{},
+			warnData:{},
+			lineData:{},
+			mqttfireData:{},//灭火传感器状态异常
+			mqttOnlineData:{},//设备是否在线
+			mqttPerformData:{},//是否正在执行灭火操作
+        },
+		created() {
+			
+			
+		},
+        methods: {
+			//删除报警监听
+			delWarnData(){
+				delete this.watchObj.warnData;
+			},
+		    //删除报警监听
+            deleteAlarmWatch(){
+                delete this.watchObj.mqttAlarmData;
+            },
+		    //删除传感器监听
+            deleteSensorWatch(){
+                delete this.watchObj.mqttSensorData;
+            },
+		    //删除设备监听
+            deleteDeviceWatch(){
+                delete this.watchObj.mqttDeviceData;
+            },
+		    //删除应急监听
+            deleteLineData(){
+                delete this.watchObj.lineData;
+            },
+			//删除一键灭火-传感器状态
+			deletefireData(){
+			    delete this.watchObj.mqttfireData;
+			},
+			//删除一键灭火-设备是否在线
+			deleteOnlineData(){
+			    delete this.watchObj.mqttOnlineData;
+			},
+			//删除一键灭火-是否正在执行灭火
+			deletePerformData(){
+			    delete this.watchObj.mqttPerformData;
+			},
+            //监听对应的mqtt数据
+            watch:function(method,istr){
+                this.watchObj = this.globalData;
+                Object.defineProperty(this.watchObj,istr,{
+                    configurable:true,
+                    enumerable:true,
+                    immediate: true,
+                    deep: true,
+                    set:function(value){
+                        this._consumerGoodsStatus=value
+                        method(value)
+                    },
+                    get:function(value){
+                        return this._consumerGoodsStatus
+                    }
+                })
+            },
+            // 子页面调用
+            appMqttOn(type,list){
+            	let self = this;
+            	if(this.mqttIdList){
+            		this.offMQTT();
+            	}
+            	uni.setStorageSync('mqttIdList',JSON.stringify(list));
+            	this.mqttIdList = list;
+            	setTimeout(function(){
+            		self.subscriptionMQTT();
+            	},100);
+            },
+			//MQTT订阅
+            subscriptionMQTT(){
+                let self = this;
+                const mqttOptions = {
+                    keepalive: 30,
+                    clean: true,//保留会话
+                    connectTimeout: 5000, // 超时时间
+                    reconnectPeriod:5000, // 重连间隔
+                    clientId: uni.getStorageSync('token')+'lab/function/data',
+                    username: uni.getStorageSync('mqttUser'),
+                    password: uni.getStorageSync('mqttPassword'),
+                }
+                const connectUrl = uni.getStorageSync('mqttUrl');
+                // this.client = $mqtt.connect('wxs://' + connectUrl, mqttOptions);
+                this.client = $mqtt.connect('wxs://' + connectUrl, mqttOptions);
+                this.client.on('connect', () => {
+                    // 这是为了给自己发条消息,其它无作用
+					for(let i=0;i<self.mqttIdList.length;i++){
+						if(self.mqttIdList[i].type == 'lab/function/data'){
+							//传感器
+							for(let o=0;o<self.mqttIdList[i].idList.length;o++){
+								self.client.subscribe(self.mqttIdList[i].type+self.mqttIdList[i].idList[o], (err) => {
+								    if (!err) {
+								        console.log("传感器信息订阅成功",self.mqttIdList[i].type+self.mqttIdList[i].idList[o])
+								    }
+								});
+							}
+						}else if(self.mqttIdList[i].type == 'lab/hardware/data'){
+							//传感器
+							for(let o=0;o<self.mqttIdList[i].idList.length;o++){
+								self.client.subscribe(self.mqttIdList[i].type+self.mqttIdList[i].idList[o], (err) => {
+								    if (!err) {
+								        console.log("硬件订阅成功",self.mqttIdList[i].type+self.mqttIdList[i].idList[o])
+								    }
+								});
+							}
+						}else if(self.mqttIdList[i].type == 'lab/bigview'){
+							self.client.subscribe(self.mqttIdList[i].type, (err) => {
+							    if (!err) {
+							        console.log("报警信息订阅成功",self.mqttIdList[i].type)
+							    }
+							});
+						}else if(self.mqttIdList[i].type == 'lab/riskPlan/trigger/notice'){
+							self.client.subscribe(self.mqttIdList[i].type, (err) => {
+							    if (!err) {
+							        console.log("应急疏散订阅成功",self.mqttIdList[i].type)
+							    }
+							});
+						}else if(self.mqttIdList[i].type == 'lab/fireDevice/Warn/'){
+							self.client.subscribe(self.mqttIdList[i].type+self.mqttIdList[i].fireCode, (err) => {
+							    if (!err) {
+							        console.log("火灾传感器状态-订阅成功",self.mqttIdList[i].type+self.mqttIdList[i].fireCode)
+							    }
+							});
+
+						}else if(self.mqttIdList[i].type == 'lab/fireDevice/isOnline/'){
+							self.client.subscribe(self.mqttIdList[i].type+self.mqttIdList[i].fireCode, (err) => {
+							    if (!err) {
+							        console.log("火灾设备是否在线-订阅成功",self.mqttIdList[i].type+self.mqttIdList[i].fireCode)
+							    }
+							});
+
+						}else if(self.mqttIdList[i].type == 'lab/fireDevice/executing/'){
+							self.client.subscribe(self.mqttIdList[i].type+self.mqttIdList[i].fireCode, (err) => {
+							    if (!err) {
+							        console.log("火灾是否正在执行灭火操作-订阅成功:",self.mqttIdList[i].type+self.mqttIdList[i].fireCode)
+							    }
+							});
+
+						}
+					}
+                });
+                // 自动重连
+                this.client.on('reconnect', (msg) => {
+                    console.log('自动重连-reconnect-1', msg)
+                });
+                // 错误
+                this.client.on('error', () => {
+                    console.log('错误-error-1')
+                });
+                // 断开
+                this.client.on('end', () => {
+                    console.log('断开-end-1')
+                });
+                // 掉线
+                this.client.on('offline', (msg) => {
+                    console.log('掉线-offline-1',msg)
+                });
+                // 收到消息
+                this.client.on('message', (topic, message) => {
+                    let data = JSON.parse(message)
+					 //console.log('消息message',data);
+					if(data){
+						if(topic == 'lab/riskPlan/trigger/notice'){
+							// console.log("应急",data);
+							this.globalData.lineData = data.data;
+						}else if(topic.search("lab/fireDevice/Warn/") != -1){
+							 console.log("一键灭火-传感器状态",data);
+							this.globalData.mqttfireData = data;
+						}else if(topic.search("lab/fireDevice/isOnline/") != -1){
+							 console.log("一键灭火-设备是否在线",data);
+							this.globalData.mqttOnlineData = data;
+						}else if(topic.search("lab/fireDevice/executing/") != -1){
+							 console.log("一键灭火-是否正在执行灭火",data);
+							this.globalData.mqttPerformData = data;
+						}else if(topic == 'lab/bigview'){
+							if(data.data == 'SUB_RISKPLAN_GROUP'){
+								this.globalData.mqttAlarmData = data.data;
+							}
+						}else {
+							if(data.data.subId){
+							    this.globalData.mqttSensorData = data.data;
+							}else{
+								this.globalData.mqttDeviceData = data.data;
+							}
+						}
+					}
+                })
+                // 全局监听是否有关闭mqtt的消息的事件
+                uni.$on('closeMqtt',() => {
+                    this.client.end(true); // 主动断开连接
+                })
+            },
+            //取消订阅关闭MQTT连接
+            offMQTT(){
+				let self = this;
+				if(self.mqttIdList[0]){
+					uni.removeStorageSync('mqttIdList')
+					for(let i=0;i<self.mqttIdList.length;i++){
+						if(self.mqttIdList[i].type == 'lab/function/data'){
+							//断开传感器
+							for(let o=0;o<self.mqttIdList[i].idList.length;o++){
+								self.client.unsubscribe(self.mqttIdList[i].type+self.mqttIdList[i].idList[o], error => {
+									if (error) {
+										console.log('Unsubscribe error mtopicBigview', error)
+									}
+								})
+							}
+						}else if(self.mqttIdList[i].type == 'lab/hardware/data'){
+							//断开硬件
+							for(let o=0;o<self.mqttIdList[i].idList.length;o++){
+								self.client.unsubscribe(self.mqttIdList[i].type+self.mqttIdList[i].idList[o], error => {
+									if (error) {
+										console.log('Unsubscribe error mtopicBigview', error)
+									}
+								})
+							}
+						}else if(self.mqttIdList[i].type == 'lab/bigview'){
+							//断开报警
+							self.client.unsubscribe(self.mqttIdList[i].type, error => {
+								if (error) {
+									console.log('Unsubscribe error mtopicBigview', error)
+								}
+							})
+						}else if(self.mqttIdList[i].type == 'lab/riskPlan/trigger/notice'){
+							//断开疏散
+							self.client.unsubscribe(self.mqttIdList[i].type, error => {
+								if (error) {
+									console.log('Unsubscribe error mtopicBigview', error)
+								}
+							})
+						}
+					}
+					this.client.end(true);
+					this.client = null;
+					this.mqttIdList = [];
+				}
+            },
+        }
+	}
+</script>
+
+<style lang="stylus">
+	page{
+		height:100%;
+		width:100%;
+		background:#f5f5f5;
+		font-family: PingFang SC;
+		font-weight: 400;
+		font-size:30rpx;
+		color:#333;
+	}
+	img{
+        margin:0;
+        padding:0;
+		display:block;
+	}
+	.name-box-p{
+		display block
+		overflow:hidden;
+		text-overflow:ellipsis;
+		white-space:nowrap;
+	}
+    view{
+        margin:0;
+        padding:0;
+    }
+    /*每个页面公共css */
+    @import './styles/index.styl'
+</style>

+ 90 - 0
api/basicsModules/index.js

@@ -0,0 +1,90 @@
+import { apiResquest } from '../request/request.js'
+import { apiResquestForm } from '../request/request.js'
+import { apiResquestJsonList } from '../request/request.js'
+import { apiResquestFormVideo } from '../request/request.js'
+import { apiResquestTimer } from '../request/request.js'
+
+
+//登录
+export const login = (data) => {
+	return apiResquest({
+		url: `/auth/login`,
+		method: 'POST',
+		data: { ...data }
+	})
+};
+
+//查询公共配置
+export const configInfo = (data) => {
+	return apiResquest({
+		url: `/auth/configInfo`,
+		method: 'GET',
+		data: data,
+	})
+};
+
+/*                分类获取公共配置
+* category        1.系统参数 2.公共配置
+* configType      1.基础配置 2.管控一体机 3.化学品终端 4.小程序配置 5.开发配置 6.首页配置
+*/
+export function getConfigByType(data) {
+	return apiResquest({
+		url: '/system/config/info/getConfigByType',
+		method: 'post',
+		data: {
+			...data
+		}
+	})
+}
+
+//查询人员身份标识
+export const getGentleIdentifier = (data) => {
+	return apiResquest({
+		url: `/security/checkSet/getGentle`,
+		method: 'GET',
+		data: data,
+	})
+};
+
+//查询小程序布局配置
+export const systemAppletLayoutSelect = (data) => {
+	return apiResquest({
+    url: '/system/applet/layout/select',
+		method: 'GET',
+		data: data,
+	})
+};
+//查询权限字段
+export const systemAppletRolePermission = (data) => {
+	return apiResquest({
+    url: '/system/applet/role/permission',
+		method: 'GET',
+		data: data,
+	})
+};
+
+
+
+
+
+/************************未调试************************/
+
+
+
+//获取离开检查配置
+export const outSubjectPhoto  = (id,data) => {
+    return apiResquestForm({
+        url: `/base/app/lab/api/outSubjectPhoto`,
+        method: 'GET',
+        data: data,
+    })
+};
+
+//分级管控未完成工作列表
+export const gradingControl  = (data) => {
+    return apiResquest({
+        url: `/base/app/lab/manage/havingList`,
+        method: 'POST',
+        data: {...data}
+    })
+};

+ 5 - 0
api/manage/index.js

@@ -0,0 +1,5 @@
+import { apiResquest } from '../request/request.js'
+import { apiResquestForm } from '../request/request.js'
+import { apiResquestJsonList } from '../request/request.js'
+import { apiResquestFormVideo } from '../request/request.js'
+import { apiResquestTimer } from '../request/request.js'

+ 21 - 0
api/request/config.js

@@ -0,0 +1,21 @@
+const config = {
+	base_url: 'http://192.168.1.9:8080',//柴
+	// base_url: 'http://192.168.1.7:8080',//刘波
+	// base_url: 'http://192.168.1.17:8080',//小飞
+	// base_url: 'http://192.168.1.20:8080',//志伟
+    // base_url: 'http://192.168.1.8:8080',//高升
+	// base_url: 'http://192.168.1.29:8080',//何成
+    // base_url: 'http://192.168.1.43:9800',//43服务器
+	// base_url: 'https://demo.zjznai.com/xzgd/',
+
+    //base_url: 'https://lab.zjznai.com/labNhSystem/',//43服务器高升测试
+	// base_url: 'https://lab.zjznai.com/labAppTest/',//43服务器线上
+    // base_url: 'https://lab.zjznai.com/appTest/',//88服务器线上
+    //base_url: 'https://lab.zjznai.com/labSystem/', //矿大地址
+	// base_url: 'https://lab.zjznai.com/jdlabSystem/', //交大地址
+   // base_url: 'https://lab.zjznai.com/jndxlabSystem/', //暨大地址
+   // base_url: 'https://lab.zjznai.com/api/', //暨大化材
+   //  base_url: 'https://lab.zjznai.com/kdwclabSystem/', //矿大文昌地址
+   //base_url: 'https://znyj.zjznai.suda.edu.cn/labSystem/', //苏大临时地址
+}
+export { config }

+ 361 - 0
api/request/request.js

@@ -0,0 +1,361 @@
+import { config } from './config.js'
+import { tansParams } from "./util.js";
+
+export const apiResquest = (prams) => {
+	return new Promise((resolve, reject) => {
+		let url = config.base_url + prams.url;
+		uni.showLoading({
+			title: '加载中',
+			mask: true
+		});
+        // get请求映射params参数
+        if (prams.method === 'GET' && prams.data) {
+            url = url + '?' + tansParams(prams.data);
+            url = url.slice(0, -1);
+            prams.data = {};
+        }
+
+		return uni.request({
+			url: url,
+			data: {
+				...prams.data
+			},
+			method: prams.method,
+			header: {
+			  	// 'content-type': 'application/x-www-form-urlencoded',
+			  	'content-type': 'application/json;charset=utf-8',
+				'Authorization':uni.getStorageSync('token')
+			},
+			success: (res) => {
+				// 成功
+				uni.hideLoading()
+				if(res.data.code == 200){
+					resolve(res);
+				}else if(res.data.code == 401){
+					uni.showToast({
+						mask:true,
+						icon:"none",
+						position:"center",
+						title: "登录超时,请重新登录~",
+						duration: 2000
+					});
+                    uni.removeStorageSync('token');
+                    uni.removeStorageSync('userId');
+                    uni.removeStorageSync('userType');
+					setTimeout(function(){
+						uni.redirectTo({
+							url: '/pages/login',
+						});
+					},2000);
+				}else{
+					uni.showToast({
+						mask:true,
+						icon:"none",
+						position:"center",
+						title: res.data.msg,
+						duration: 2000
+					});
+					resolve(res);
+				}
+			},
+			fail: (err) => {
+				// 失败
+				uni.hideLoading()
+				uni.showToast({
+					mask:true,
+					icon:"none",
+					position:"center",
+					title: '出错啦~请联系管理员!',
+					duration: 2000
+				});
+			},
+			complete: () => {
+				// 完成
+			}
+		});
+	})
+}
+export const apiResquestForm = (prams) => {
+    return new Promise((resolve, reject) => {
+        let url = config.base_url + prams.url;
+        uni.showLoading({
+            title: '加载中',
+            mask: true
+        });
+        // get请求映射params参数
+        if (prams.method === 'GET' && prams.data) {
+            url = url + '?' + tansParams(prams.data);
+            url = url.slice(0, -1);
+            prams.data = {};
+        }
+        return uni.request({
+            url: url,
+            data: {
+                ...prams.data
+            },
+            method: prams.method,
+            header: {
+                'content-type': 'application/x-www-form-urlencoded',
+                'Authorization':uni.getStorageSync('token')
+            },
+            success: (res) => {
+                // 成功
+                uni.hideLoading()
+                if(res.data.code == 200){
+                    resolve(res);
+                }else if(res.data.code == 401){
+                    uni.showToast({
+                        mask:true,
+                        icon:"none",
+                        position:"center",
+                        title: "登录超时,请重新登录~",
+                        duration: 2000
+                    });
+                    uni.removeStorageSync('token');
+                    uni.removeStorageSync('userId');
+                    uni.removeStorageSync('userType');
+                    setTimeout(function(){
+                        uni.redirectTo({
+                            url: '/pages/login',
+                        });
+                    },2000);
+                }else{
+                    uni.showToast({
+                        mask:true,
+                        icon:"none",
+                        position:"center",
+                        title: res.data.msg,
+                        duration: 2000
+                    });
+                    resolve(res);
+                }
+            },
+            fail: (err) => {
+                // 失败
+                uni.hideLoading()
+                uni.showToast({
+                    mask:true,
+                    icon:"none",
+                    position:"center",
+                    title: '出错啦~请联系管理员!',
+                    duration: 2000
+                });
+            },
+            complete: () => {
+                // 完成
+            }
+        });
+    })
+}
+export const apiResquestJsonList = (prams) => {
+    return new Promise((resolve, reject) => {
+        let url = config.base_url + prams.url;
+        uni.showLoading({
+            title: '加载中',
+            mask: true
+        });
+        // get请求映射params参数
+        if (prams.method === 'GET' && prams.data) {
+            url = url + '?' + tansParams(prams.data);
+            url = url.slice(0, -1);
+            prams.data = {};
+        }
+        return uni.request({
+            url: url,
+            data: prams.data,
+            method: prams.method,
+            header: {
+                'content-type': 'application/json',
+                'Authorization':uni.getStorageSync('token')
+            },
+            success: (res) => {
+                // 成功
+                uni.hideLoading()
+                if(res.data.code == 200){
+                    resolve(res);
+                }else if(res.data.code == 401){
+                    uni.showToast({
+                        mask:true,
+                        icon:"none",
+                        position:"center",
+                        title: "登录超时,请重新登录~",
+                        duration: 2000
+                    });
+                    uni.removeStorageSync('token');
+                    uni.removeStorageSync('userId');
+                    uni.removeStorageSync('userType');
+                    setTimeout(function(){
+                        uni.redirectTo({
+                            url: '/pages/login',
+                        });
+                    },2000);
+                }else{
+                    uni.showToast({
+                        mask:true,
+                        icon:"none",
+                        position:"center",
+                        title: res.data.msg,
+                        duration: 2000
+                    });
+                    resolve(res);
+                }
+            },
+            fail: (err) => {
+                // 失败
+                uni.hideLoading()
+                uni.showToast({
+                    mask:true,
+                    icon:"none",
+                    position:"center",
+                    title: '出错啦~请联系管理员!',
+                    duration: 2000
+                });
+            },
+            complete: () => {
+                // 完成
+            }
+        });
+    })
+}
+export const apiResquestFormVideo = (prams) => {
+    return new Promise((resolve, reject) => {
+        let url = uni.getStorageSync('cameraExtranetAgent') + prams.url;
+        uni.showLoading({
+            title: '加载中',
+            mask: true
+        });
+        // get请求映射params参数
+        if (prams.method === 'GET' && prams.data) {
+            url = url + '?' + tansParams(prams.data);
+            url = url.slice(0, -1);
+            prams.data = {};
+        }
+        return uni.request({
+            url: url,
+            data: {
+                ...prams.data
+            },
+            method: prams.method,
+            header: {
+                'content-type': 'application/x-www-form-urlencoded',
+                'Authorization':uni.getStorageSync('token')
+            },
+            success: (res) => {
+                // 成功
+                uni.hideLoading()
+                if(res.data.code == 200){
+                    resolve(res);
+                }else if(res.data.code == 401){
+                    uni.showToast({
+                        mask:true,
+                        icon:"none",
+                        position:"center",
+                        title: "登录超时,请重新登录~",
+                        duration: 2000
+                    });
+                    uni.removeStorageSync('token');
+                    uni.removeStorageSync('userId');
+                    uni.removeStorageSync('userType');
+                    setTimeout(function(){
+                        uni.redirectTo({
+                            url: '/pages/login',
+                        });
+                    },2000);
+                }else{
+                    uni.showToast({
+                        mask:true,
+                        icon:"none",
+                        position:"center",
+                        title: res.data.msg,
+                        duration: 2000
+                    });
+                    resolve(res);
+                }
+            },
+            fail: (err) => {
+                // 失败
+                uni.hideLoading()
+                uni.showToast({
+                    mask:true,
+                    icon:"none",
+                    position:"center",
+                    title: '出错啦~请联系管理员!',
+                    duration: 2000
+                });
+            },
+            complete: () => {
+                // 完成
+            }
+        });
+    })
+}
+export const apiResquestTimer = (prams) => {
+	return new Promise((resolve, reject) => {
+		let url = config.base_url + prams.url;
+        // get请求映射params参数
+        if (prams.method === 'GET' && prams.data) {
+            url = url + '?' + tansParams(prams.data);
+            url = url.slice(0, -1);
+            prams.data = {};
+        }
+
+		return uni.request({
+			url: url,
+			data: {
+				...prams.data
+			},
+			method: prams.method,
+			header: {
+			  	// 'content-type': 'application/x-www-form-urlencoded',
+			  	'content-type': 'application/json;charset=utf-8',
+				'Authorization':uni.getStorageSync('token')
+			},
+			success: (res) => {
+				// 成功
+				uni.hideLoading()
+				if(res.data.code == 200){
+					resolve(res);
+				}else if(res.data.code == 401){
+					uni.showToast({
+						mask:true,
+						icon:"none",
+						position:"center",
+						title: "登录超时,请重新登录~",
+						duration: 2000
+					});
+                    uni.removeStorageSync('token');
+                    uni.removeStorageSync('userId');
+                    uni.removeStorageSync('userType');
+					setTimeout(function(){
+						uni.redirectTo({
+							url: '/pages/login',
+						});
+					},2000);
+				}else{
+					uni.showToast({
+						mask:true,
+						icon:"none",
+						position:"center",
+						title: res.data.msg,
+						duration: 2000
+					});
+					resolve(res);
+				}
+			},
+			fail: (err) => {
+				// 失败
+				uni.hideLoading()
+				uni.showToast({
+					mask:true,
+					icon:"none",
+					position:"center",
+					title: '出错啦~请联系管理员!',
+					duration: 2000
+				});
+			},
+			complete: () => {
+				// 完成
+			}
+		});
+	})
+}

+ 21 - 0
api/request/util.js

@@ -0,0 +1,21 @@
+export function tansParams(params) {
+    let result = ''
+    for (const propName of Object.keys(params)) {
+        const value = params[propName];
+        var part = encodeURIComponent(propName) + "=";
+        if (value !== null && typeof (value) !== "undefined") {
+            if (typeof value === 'object') {
+                for (const key of Object.keys(value)) {
+                    if (value[key] !== null && typeof (value[key]) !== 'undefined') {
+                        let params = propName + '[' + key + ']';
+                        var subPart = encodeURIComponent(params) + "=";
+                        result += subPart + encodeURIComponent(value[key]) + "&";
+                    }
+                }
+            } else {
+                result += part + encodeURIComponent(value) + "&";
+            }
+        }
+    }
+    return result
+}

+ 5 - 0
api/student/index.js

@@ -0,0 +1,5 @@
+import { apiResquest } from '../request/request.js'
+import { apiResquestForm } from '../request/request.js'
+import { apiResquestJsonList } from '../request/request.js'
+import { apiResquestFormVideo } from '../request/request.js'
+import { apiResquestTimer } from '../request/request.js'

+ 537 - 0
component/cropper.js

@@ -0,0 +1,537 @@
+const ABS = Math.abs
+const calcLen = (v) => { // distance between two coordinate
+  return Math.sqrt(v.x * v.x + v.y * v.y)
+}
+const calcAngle = (a, b) => { // angle of the two vectors
+  var l = calcLen(a) * calcLen(b); var cosValue; var angle
+  if (l) {
+    cosValue = (a.x * b.x + a.y * b.y) / l
+    angle = Math.acos(Math.min(cosValue, 1))
+    angle = a.x * b.y - b.x * a.y > 0 ? -angle : angle
+    return angle * 180 / Math.PI
+  }
+  return 0
+}
+const generateCanvasId = () => { // generate a random string
+  const seeds = 'abcdefghijklmnopqrstuvwxyz'
+  const arr = seeds.split('').concat(seeds.toUpperCase().split('')).concat('0123456789'.split(''))
+  let m = arr.length; let i
+  while (m) {
+    i = Math.floor(Math.random() * m--)
+    const temp = arr[m]
+    arr[m] = arr[i]
+    arr[i] = temp
+  }
+  return arr.slice(0, 16).join('')
+}
+
+export default {
+  props: {
+    width: { // width of the container
+      type: [String, Number],
+      default: '100%'
+    },
+    height: { // height of the container
+      type: [String, Number],
+      default: '100%'
+    },
+    cutWidth: { // cutter width
+      type: [String, Number],
+      default: '50%'
+    },
+    cutHeight: { // cutter height
+      type: [String, Number],
+      default: 0
+    },
+    minWidth: { // minWidth of the cutter
+      type: Number,
+      default: 50
+    },
+    minHeight: { // minHeight of the cutter
+      type: Number,
+      default: 50
+    },
+    center: { // autoCenter
+      type: Boolean,
+      default: true
+    },
+    src: String,
+    disableScale: Boolean, // disable to zoom
+    disableRotate: Boolean,
+    disableTranslate: Boolean,
+    disableCtrl: Boolean, // disable to resize the cutter
+    boundDetect: Boolean, // open boundary detection
+    freeBoundDetect: Boolean, // open boundary detection while doing rotation
+    keepRatio: Boolean, // keep the ratio of the cutter
+    disablePreview: Boolean, // disable preview after cutting
+    showCtrlBorder: Boolean, // show cutter border
+    resetCut: Boolean, // reset cut while img change
+    fit: {
+      type: Boolean,
+      default: true
+    },
+    imageCenter: Boolean, // auto center/middle for image
+    maxZoom: { // maximum scaling factor
+      type: Number,
+      default: 10 // can not be Infinity in baidu-MiniProgram
+    },
+    minZoom: { // minimum scaling factor
+      type: Number,
+      default: 1
+    },
+    angle: { // initial angle of rotation
+      type: Number,
+      default: 0
+    },
+    zoom: { // initial scaling factor
+      type: Number,
+      default: 1
+    },
+    offset: { // initial offset relative to the cutter left border
+      type: Array,
+      default() {
+        return [0, 0]
+      }
+    },
+    background: {
+      type: String,
+      default: '#000'
+    },
+    canvasBackground: { // background for the exported image
+      type: String,
+      default: '#fff'
+    },
+    canvasZoom: {  // export multiples of the cutter size
+      type: Number,
+      default: 1
+    },
+    fileType: {
+      type: String,
+      default: 'png',
+      validator(t) {
+        return ['png', 'jpg'].includes(t)
+      }
+    },
+    quality: {
+      type: Number,
+      default: 1
+    },
+    maskType: { // type for mask
+      type: String,
+      default: "shadow"
+    },
+    circleView: Boolean // circle clip view
+  },
+  data() {
+    return {
+      transform: {
+        angle: 0,
+        translate: {
+          x: 0,
+          y: 0
+        },
+        zoom: 1
+      },
+      corner: {
+        left: 50,
+        right: 50,
+        bottom: 50,
+        top: 50
+      },
+      image: {
+        originWidth: 0,
+        originHeight: 0,
+        width: 0,
+        height: 0
+      },
+      ctrlWidth: 0,
+      ctrlHeight: 0,
+      view: false,
+      canvasId: ''
+    }
+  },
+  computed: {
+    transformMeta: function() {
+      const transform = this.transform
+      return `translate3d(${transform.translate.x}px, ${transform.translate.y}px, 0) rotate(${transform.angle}deg) scale(${transform.zoom})`
+    },
+    ctrlStyle: function() {
+      const corner = this.corner
+      let cssStr = `left: ${corner.left}px;top: ${corner.top}px;right: ${corner.right}px;bottom: ${corner.bottom }px;`
+      if(this.maskType !== 'outline') {
+        cssStr += `box-shadow: 0 0 0 50000rpx rgba(0,0,0, ${this.view ? 0.8 : 0.4})`
+      } else {
+        cssStr += `outline: rgba(0,0,0, ${this.view ? 0.8 : 0.4}) solid 5000px`
+      }
+      return cssStr
+    }
+  },
+  watch: {
+    src: function() {
+      if(this.resetCut) this.resetCutReact()
+      this.initImage()
+    }
+  },
+  created() {
+    this.canvasId = generateCanvasId()
+    uni.getSystemInfo().then(result => {
+      result = result[1] || {windowWidth: 375, windowHeight: 736}
+      this.ratio = result.windowWidth / 750
+      this.windowHeight = result.windowHeight
+      this.init()
+      this.initCanvas()
+    })
+  },
+  methods: {
+    toPx(str) {
+      if (str.indexOf('%') !== -1) {
+        return Math.floor(Number(str.replace('%', '')) / 100 * this.containerWidth)
+      }
+      if (str.indexOf('rpx') !== -1) {
+        return Math.floor(Number(str.replace('rpx', '')) * this.ratio)
+      }
+      return Math.floor(Number(str.replace('px', '')))
+    },
+    initCanvas() {
+			// #ifdef MP-ALIPAY
+			const context = uni.createSelectorQuery()
+			// #endif
+			// #ifndef MP-ALIPAY
+			const context = uni.createSelectorQuery().in(this)
+			// #endif
+
+      // get contianer size
+      context.select('.nice-cropper').boundingClientRect()
+      context.exec(res => {
+        this.containerWidth = res[0].width
+        this.containerHeight = res[0].height
+        this.initCut()
+      })
+    },
+    resetCutReact() {// init size and position of the cutter
+      this.ctrlWidth = Math.min(this.toPx(this.cutWidth), this.containerWidth)
+      if (this.cutHeight) {
+        this.ctrlHeight = Math.min(this.toPx(this.cutHeight), this.containerHeight)
+      } else { // 默认为正方形
+        this.ctrlHeight = Math.min(this.ctrlWidth, this.containerHeight)
+      }
+      const cornerStartX = this.center ? Math.floor((this.containerWidth - this.ctrlWidth) / 2) : 0
+      const cornerStartY = this.center ? Math.floor((this.containerHeight - this.ctrlHeight) / 2) : 0
+      this.cutRatio = this.ctrlHeight / this.ctrlWidth
+      this.corner = {
+        left: cornerStartX,
+        right: this.containerWidth - this.ctrlWidth - cornerStartX,
+        top: cornerStartY,
+        bottom: this.containerHeight - this.ctrlHeight - cornerStartY
+      }
+    },
+    initCut() {
+      this.resetCutReact()
+      this.initImage()
+    },
+    async initImage() {
+
+      if (!this.src) return
+
+      const [err, res] = await uni.getImageInfo({
+        src: this.src
+      })
+
+      if(err) {
+        this.$emit("error", err)
+      } else {
+        this.$emit('load', res)
+      }
+      // init image size
+      this.image.originWidth = err ? this.ctrlWidth : res.width
+      this.image.originHeight = err ? this.ctrlHeight : res.height
+      this.image.width = this.fit ? this.ctrlWidth : this.image.originWidth
+      this.image.height = err ? this.ctrlHeight : res.height / res.width * this.image.width
+      this.img = res.path
+
+      const offset = [0, 0]
+      if(this.imageCenter) {
+        offset[0] = (this.ctrlWidth - this.image.width) / 2
+        offset[1] = (this.ctrlHeight - this.image.height) / 2
+      }
+      offset[0] += this.offset[0] || 0
+      offset[1] += this.offset[1] || 0
+
+      this.setTranslate(offset)
+      this.setZoom(this.zoom)
+      this.transform.angle = this.freeBoundDetect || !this.disableRotate ? this.angle : 0
+
+      this.setBoundary() // boundary detect
+      this.preview() // preview
+      this.draw()
+    },
+    init() {
+      this.pretouch = {}
+      this.handles = {}
+      this.preVector = {
+        x: 0,
+        y: 0
+      }
+      this.distance = 30
+      this.touch = {}
+      this.movetouch = {}
+      this.cutMode = false
+      this.params = {
+        zoom: 1,
+        deltaX: 0,
+        deltaY: 0,
+        diffX: 0,
+        diffY: 0,
+        angle: 0
+      }
+    },
+    start(e) {
+      if(!this.src) e.preventDefault()
+      const point = e.touches ? e.touches[0] : e
+      const touch = this.touch
+      const now = Date.now()
+      touch.startX = point.pageX
+      touch.startY = point.pageY
+      touch.startTime = now
+      this.doubleTap = false
+      this.view = false
+      clearTimeout(this.previewTimer)
+      if (e.touches.length > 1) {
+        var point2 = e.touches[1]
+        this.preVector = {
+          x: point2.pageX - this.touch.startX,
+          y: point2.pageY - this.touch.startY
+        }
+        this.startDistance = calcLen(this.preVector)
+      } else {
+        let pretouch = this.pretouch
+        this.doubleTap = this.pretouch.time && now - this.pretouch.time < 300 && ABS(touch.startX - pretouch.startX) < 30 && ABS(touch.startY - pretouch.startY) < 30 && ABS(touch.startTime - pretouch.time) < 300
+        pretouch = { // reserve the last touch
+          startX: this.touch.startX,
+          startY: this.touch.startY,
+          time: this.touch.startTime
+        }
+      }
+    },
+    move(e) {
+      if(!this.src) return
+      const point = e.touches ? e.touches[0] : e
+      if (e.touches.length > 1) { // multi touch
+        const point2 = e.touches[1]
+        const v = {
+          x: point2.pageX - point.pageX,
+          y: point2.pageY - point.pageY
+        }
+
+        if (this.preVector.x !== null) {
+          if (this.startDistance) { // zoom
+            const len = calcLen(v)
+            this.params.zoom = calcLen(v) / this.startDistance
+            this.startDistance = len
+            this.cutMode && !this.disableCtrl ? this.setCut() : !this.disableScale && this.pinch()
+          }
+          // rotate
+          this.params.angle = calcAngle(v, this.preVector)
+          this.cutMode && !this.disableCtrl ? this.setCut() : !this.disableRotate && this.rotate()
+        }
+        this.preVector.x = v.x
+        this.preVector.y = v.y
+      } else { // translate
+        const diffX = point.pageX - this.touch.startX
+        const diffY = point.pageY - this.touch.startY
+        this.params.diffY = diffY
+        this.params.diffX = diffX
+        if (this.movetouch.x) {
+          this.params.deltaX = point.pageX - this.movetouch.x
+          this.params.deltaY = point.pageY - this.movetouch.y
+        } else {
+          this.params.deltaX = this.params.deltaY = 0
+        }
+        if (ABS(diffX) > 30 || ABS(diffY) > 30) {
+          this.doubleTap = false
+        }
+        this.cutMode && !this.disableCtrl ? this.setCut() : !this.disableTranslate && this.translate()
+        this.movetouch.x = point.pageX
+        this.movetouch.y = point.pageY
+      }
+      !this.cutMode && this.setBoundary()
+      if (e.touches.length > 1) {
+        e.preventDefault()
+      }
+    },
+    end() {
+      this.doubleTap && this.$emit('doubleTap')
+      this.cutMode && this.setBoundary()
+      this.init()
+      !this.disablePreview && this.preview()
+      this.draw()
+    },
+    translate() {
+      const transform = this.transform.translate
+      const meta = this.params
+      transform.x += meta.deltaX
+      transform.y += meta.deltaY
+    },
+    pinch() {
+      this.transform.zoom *= this.params.zoom
+    },
+    rotate() {
+      this.transform.angle += this.params.angle
+    },
+    setZoom(scale) {
+      scale = Math.min(Math.max(Number(scale) || 1, this.minZoom), this.maxZoom)
+      this.transform.zoom = scale
+    },
+    setTranslate(offset) {
+      if(Array.isArray(offset)) {
+        const x = Number(offset[0])
+        const y = Number(offset[1])
+        this.transform.translate.x = isNaN(x) ? this.transform.translate.x : this.corner.left + x
+        this.transform.translate.y = isNaN(y) ? this.transform.translate.y : this.corner.top + y
+      }
+    },
+    setRotate(angle) {
+      this.transform.angle = Number(angle) || 0
+    },
+    setTransform(x, y, angle, scale) {
+      this.setTranslate([x, y])
+      this.setZoom(scale)
+      this.setRotate(angle)
+    },
+    setCutMode(type) {
+      if(!this.src) return
+      this.cutMode = true
+      this.cutDirection = type
+    },
+    setCut() {
+      const corner = this.corner
+      const meta = this.params
+      this.setMeta(this.cutDirection, meta) // correct cutter position
+      if (this.keepRatio) {
+        if (this.cutDirection === 'lt' || this.cutDirection === 'rb') {
+          meta.deltaY = meta.deltaX * this.cutRatio
+        } else {
+          meta.deltaX = meta.deltaY / this.cutRatio
+        }
+      }
+      switch (this.cutDirection) {
+        case 'lt':
+          corner.top += meta.deltaY
+          corner.left += meta.deltaX
+          break
+        case 'rt':
+          corner.top += meta.deltaY
+          corner.right -= this.keepRatio ? -meta.deltaX : meta.deltaX
+          break
+        case 'rb':
+          corner.right -= meta.deltaX
+          corner.bottom -= meta.deltaY
+          break
+        case 'lb':
+          corner.bottom -= meta.deltaY
+          corner.left += this.keepRatio ? -meta.deltaX : meta.deltaX
+          break
+      }
+      this.ctrlWidth = this.containerWidth - corner.left - corner.right
+      this.ctrlHeight = this.containerHeight - corner.top - corner.bottom
+    },
+    setMeta(direction, meta) {
+      const {ctrlWidth, ctrlHeight, minWidth, minHeight } = this
+      switch(direction) {
+        case 'lt':
+          if(meta.deltaX > 0 || meta.deltaY > 0) {
+            meta.deltaX = Math.min(meta.deltaX, ctrlWidth - minWidth)
+            meta.deltaY = Math.min(meta.deltaY, ctrlHeight - minHeight)
+          }
+          break
+        case 'rt':
+          if(meta.deltaX < 0 || meta.deltaY > 0) {
+            meta.deltaX = Math.max(meta.deltaX, minWidth - ctrlWidth)
+            meta.deltaY = Math.min(meta.deltaY, ctrlHeight - minHeight)
+          }
+          break
+        case 'rb':
+          if(meta.deltaX < 0 || meta.deltaY < 0) {
+            meta.deltaX = Math.max(meta.deltaX, minWidth - ctrlWidth)
+            meta.deltaY = Math.max(meta.deltaY, minHeight - ctrlHeight)
+          }
+          break
+        case 'lb':
+          if(meta.deltaX > 0 || meta.deltaY < 0) {
+            meta.deltaX = Math.min(meta.deltaX, ctrlWidth - minWidth)
+            meta.deltaY = Math.max(meta.deltaY, minHeight - ctrlHeight)
+          }
+          break
+      }
+
+    },
+    setBoundary() {
+      let zoom = this.transform.zoom
+      zoom = zoom < this.minZoom ? this.minZoom : (zoom > this.maxZoom ? this.maxZoom : zoom)
+      this.transform.zoom = zoom
+      if (!this.boundDetect || !this.disableRotate && !this.freeBoundDetect) return true
+      const translate = this.transform.translate
+      const corner = this.corner
+      const minX = corner.left - this.image.width + this.ctrlWidth - this.image.width * (zoom - 1) / 2
+      const maxX = corner.left + this.image.width * (zoom - 1) / 2
+      const minY = corner.top - this.image.height + this.ctrlHeight - this.image.height * (zoom - 1) / 2
+      const maxY = corner.top + this.image.height * (zoom - 1) / 2
+      translate.x = Math.floor(translate.x < minX ? minX : (translate.x > maxX ? maxX : translate.x))
+      translate.y = Math.floor(translate.y < minY ? minY : (translate.y > maxY ? maxY : translate.y))
+    },
+    preview() {
+      clearTimeout(this.previewTimer)
+      this.previewTimer = setTimeout(() => {
+        this.view = true
+      }, 500)
+    },
+    draw() {
+      // #ifdef MP-ALIPAY
+      const context = uni.createCanvasContext(this.canvasId)
+      // #endif
+      // #ifndef MP-ALIPAY
+      const context = uni.createCanvasContext(this.canvasId, this)
+      // #endif
+      const transform = this.transform
+      const corner = this.corner
+      const canvasZoom = this.canvasZoom
+      const img = this.image
+      context.save()
+      context.setFillStyle(this.canvasBackground)
+      this.$emit('beforeDraw', context, transform) // beforeDraw hook
+
+      const zoom = transform.zoom
+      context.fillRect(0, 0, this.ctrlWidth * canvasZoom, this.ctrlHeight * canvasZoom) // clear canvas
+      context.translate((transform.translate.x - corner.left + img.width / 2) *canvasZoom, (transform.translate.y - corner.top + img.height / 2) * canvasZoom) // translate the canvas's orgin to the image center
+      context.rotate(transform.angle * Math.PI / 180)
+      context.translate(-img.width * zoom * 0.5 * canvasZoom, -img.height * zoom * 0.5 * canvasZoom)
+      context.drawImage(this.img, 0, 0, img.width * zoom * canvasZoom, img.height * zoom * canvasZoom)
+      context.restore()
+      this.$emit('afterDraw', context, {
+        width: this.ctrlWidth * canvasZoom,
+        height: this.ctrlHeight * canvasZoom
+      }) // afterDraw hook
+      context.draw(false, () => {
+        uni.canvasToTempFilePath({
+          canvasId: this.canvasId,
+          quality: this.quality || 1,
+          fileType: this.fileType,
+          success: (res) => {
+            this.$emit('cropped', res.tempFilePath, {
+              originWidth: this.image.originWidth,
+              originHeight: this.image.originHeight,
+              width: this.ctrlWidth * canvasZoom,
+              height: this.ctrlHeight * canvasZoom,
+              scale: zoom,
+              translate: {
+                x: transform.translate.x,
+                y: transform.translate.y
+              },
+              rotate: transform.angle
+            }) // draw callback
+          }
+        }, this)
+      })
+    }
+  }
+}

+ 75 - 0
component/cropper.vue

@@ -0,0 +1,75 @@
+<template>
+  <view class="nice-cropper" :style="{height: height, width: width, background: background}" @touchstart="start" @touchmove.stop="move" @touchcancel="end" @touchend="end">
+    <img class="nice-cropper__image" :src="src" :style="{transform: transformMeta, width: image.width + 'px', height: image.height + 'px'}" />
+    <view class="nice-cropper__ctrls" :class="{'nice-cropper__ctrls--view' : view, 'nice-cropper__ctrls--border': showCtrlBorder, 'nice-cropper__ctrls--circle': view && circleView && maskType !== 'outline'}" :style="ctrlStyle">
+      <view class="nice-cropper__corner nice-cropper__corner--lt" @touchstart="setCutMode('lt')" />
+      <view class="nice-cropper__corner nice-cropper__corner--rt" @touchstart="setCutMode('rt')" />
+      <view class="nice-cropper__corner nice-cropper__corner--rb" @touchstart="setCutMode('rb')" />
+      <view class="nice-cropper__corner nice-cropper__corner--lb" @touchstart="setCutMode('lb')" />
+    </view>
+    <canvas v-if="canvasId" :id="canvasId" :canvas-id="canvasId" style="position: absolute;left:-500000px;top: -500000px" :style="{width: ctrlWidth * canvasZoom+'px', height: ctrlHeight * canvasZoom + 'px'}" />
+  </view>
+</template>
+<script src="./cropper.js"></script>
+<style>
+.nice-cropper {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  background: #000;
+  overflow: hidden;
+}
+.nice-cropper__image {
+  position: absolute;
+  left: 0;
+  top: 0;
+  transform-origin: 50% 50%;
+}
+.nice-cropper__corner {
+  width: 30rpx;
+  height: 30rpx;
+  position: absolute;
+}
+.nice-cropper__corner::after {
+  position: absolute;
+  left: -5px;
+  right: -5px;
+  bottom: -5px;
+  top: -5px;
+  content: '';
+}
+.nice-cropper__ctrls {
+  position: absolute;
+  box-shadow: inset 0 0 10rpx 0 rgba(0,0,0,.3);
+}
+.nice-cropper__ctrls--circle {
+  border-radius: 50%;
+}
+.nice-cropper__ctrls--border {
+  border: 2rpx solid #fff;
+}
+.nice-cropper__corner--lt {
+  left: 0;
+  top: 0;
+  border-top: 4rpx solid #FFF;
+  border-left: 4rpx solid #FFF;
+}
+.nice-cropper__corner--rt {
+  right: 0;
+  top: 0;
+  border-top: 4rpx solid #FFF;
+  border-right: 4rpx solid #FFF;
+}
+.nice-cropper__corner--rb {
+  right: 0;
+  bottom: 0;
+  border-right: 4rpx solid #FFF;
+  border-bottom: 4rpx solid #FFF;
+}
+.nice-cropper__corner--lb {
+  left: 0;
+  bottom: 0;
+  border-left: 4rpx solid #FFF;
+  border-bottom: 4rpx solid #FFF;
+}
+</style>

+ 340 - 0
component/homeConfigurationSlot.vue

@@ -0,0 +1,340 @@
+<!-- 
+ 首页按钮匹配组件
+	<homeConfigurationSlot v-if="homeConfigData[0]" :homeConfig="homeConfigData[0]"></homeConfigurationSlot>
+	<homeConfigurationSlot v-if="homeConfigData[1]" :homeConfig="homeConfigData[1]"></homeConfigurationSlot>
+	<homeConfigurationSlot v-if="homeConfigData[2]" :homeConfig="homeConfigData[2]"></homeConfigurationSlot>
+	<homeConfigurationSlot v-if="homeConfigData[3]" :homeConfig="homeConfigData[3]"></homeConfigurationSlot>
+	
+ 	import { homeConfigurationSlot } from '@/component/homeConfigurationSlot'
+	import { getHomeConfig } from '@/utils/homeConfig.js'
+
+	components: {
+		homeConfigurationSlot,
+	},
+	
+	homeConfigData: [],
+	
+	demo() {
+		let data = [
+			{
+				type: 'stripBox', //容器类型 minBox-小按钮 bigBox-大按钮 threeBox-三格按钮 stripBox-条形按钮
+				layout: [
+					{
+						limits: "system:post:list", //权限字段
+						route: "grading", //路由名称
+						name: "分级管控", //名称
+					}, 
+				],
+			},
+		];
+		this.$set(this,'homeConfigData',getHomeConfig(data));
+	},
+ -->
+<template>
+	<view class="homeConfigurationSlot">
+		<!-- 小型按钮模块 -->
+		<view class="min-icon-button-box" v-if="homeConfig.type == 'minBox'">
+			<permissionsSlot v-for="(item,index) in homeConfig.layout" :key="index" :hasPermi="item.limits">
+				<view class="min-button-box" @click="buttonClick(item)">
+					<img :src="item.img">
+					<view>{{item.name}}</view>
+				</view>
+			</permissionsSlot>
+		</view>
+		<!-- 大型按钮模块 -->
+		<view class="big-icon-button-box" v-if="homeConfig.type == 'bigBox'">
+			<permissionsSlot class="imgBox" v-for="(item,index) in homeConfig.layout" :key="index"
+				:hasPermi="item.limits">
+				<img :src="item.img" @click="buttonClick(item)">
+			</permissionsSlot>
+		</view>
+		<!-- 三格按钮 -->
+		<view class="three-big-icon-button-box" v-if="homeConfig.type == 'threeBox'">
+			<permissionsSlot class="imgBox" v-for="(item,index) in homeConfig.layout" :key="index"
+				:hasPermi="item.limits">
+				<img v-if="index<3" :src="item.img" @click="buttonClick(item)">
+			</permissionsSlot>
+		</view>
+		<!-- 条型按钮 -->
+		<view v-if="homeConfig.type == 'stripBox'">
+			<permissionsSlot v-for="(item,index) in homeConfig.layout" :key="index" :hasPermi="item.limits">
+				<view class="grading">
+					<img class="grading_l" :src="item.img" />
+					<view class="grading_c">{{item.name}}</view>
+					<view class="grading_r" v-if="item.route === 'grading'" @click="buttonClick(item)">
+						{{gradingCount>0?gradingCount+'项工作待完成':''}}
+						<img src="@/images/basicsModules/icon_wdwg_gd.png" />
+					</view>
+				</view>
+			</permissionsSlot>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		outSubjectPhoto,
+		gradingControl
+	} from '@/api/basicsModules/index.js'
+	export default {
+		name: "homeConfigurationSlot",
+		props: {
+			homeConfig: {},
+		},
+		data() {
+			return {
+				gradingCount: 0, //分级管控未完成总数
+			}
+		},
+		created() {
+
+		},
+		mounted() {
+			this.initializeData();
+		},
+		methods: {
+			//初始化
+			initializeData() {
+				let self = this;
+				for (let i = 0; i < self.homeConfig.layout.length; i++) {
+					//分级管控
+					if (self.homeConfig.layout[i].route === 'grading') {
+						self.getGrading();
+					}
+				}
+			},
+			//按钮点击事件
+			buttonClick(item) {
+				if (item.buttonType === 'page') {
+					uni.navigateTo({
+						url: item.routeUrl,
+					});
+				} else if (item.buttonType === 'button') {
+					if (item.route === 'photoInspection') {
+						this.outSubjectPhoto();
+					}
+				} else if (item.buttonType === 'none') {
+					uni.showToast({
+						title: '暂未开放',
+						icon: "none",
+						mask: true,
+						duration: 2000
+					});
+				}
+			},
+			//获取拍照检查配置
+			async outSubjectPhoto() {
+				const {
+					data
+				} = await outSubjectPhoto();
+				if (data.code == 200) {
+					if (data.data == null) {
+						//需要检查(重新填写)
+						let obj = {
+							sub: "实验室照片",
+							subUrl: "",
+							garbage: "垃圾桶清理后照片",
+							garbageUrl: "",
+							dangerous: "使用危险设备照片(选填)",
+							dangerousUrl: "",
+							sourceRisk: "危险源设备使用登记本照片(选填)",
+							sourceRiskUrl: "",
+						};
+						uni.navigateTo({
+							url: '/pages_student/workbench/photoInspection?newData=' + encodeURIComponent(JSON
+								.stringify(obj)),
+						});
+					} else if (data.data == false) {
+						//不需要检查
+						uni.showToast({
+							title: '暂无检查数据',
+							icon: "none",
+							mask: true,
+							duration: 2000
+						});
+					} else {
+						//需要检查(修改内容)
+						let obj = {
+							id: data.data.id,
+							sub: "实验室照片",
+							subUrl: data.data.subUrl,
+							garbage: "垃圾桶清理后照片",
+							garbageUrl: data.data.garbageUrl,
+							dangerous: "使用危险设备照片(选填)",
+							dangerousUrl: data.data.dangerousUrl,
+							sourceRisk: "危险源设备使用登记本照片(选填)",
+							sourceRiskUrl: data.data.sourceRiskUrl,
+						};
+						uni.navigateTo({
+							url: '/pages_student/workbench/photoInspection?newData=' + encodeURIComponent(JSON
+								.stringify(obj)),
+						});
+					}
+				}
+			},
+			//获取分级管控未完成总数
+			async getGrading() {
+				const {
+					data
+				} = await gradingControl({})
+				if (data.code == 200) {
+					this.$set(this, 'gradingCount', data.data.length);
+				}
+			},
+			//调用摄像头
+			saoCode() {
+				uni.scanCode({
+					onlyFromCamera: true,
+					success: function(res) {
+						uni.navigateTo({
+							url: '/pages_student/mine/codeSuccess?q=' + encodeURIComponent(JSON
+								.stringify(res.result))
+						});
+					}
+				});
+			},
+		},
+	}
+</script>
+
+<style lang="stylus" scoped>
+	.homeConfigurationSlot {
+		margin: 0;
+		padding: 0;
+
+		.min-icon-button-box {
+			display flex;
+			justify-content: flex-start;
+			flex-wrap: wrap;
+			width: 710rpx;
+			margin: 20rpx;
+			background: #ffffff;
+			border-radius: 20rpx;
+			padding-bottom: 20rpx;
+
+			.min-button-box {
+				width: 176rpx;
+
+				img {
+					height: 75rpx;
+					width: 75rpx;
+					margin: 30rpx auto 10rpx;
+				}
+
+				view {
+					text-align: center;
+					font-size: 24rpx;
+				}
+			}
+		}
+
+		.big-icon-button-box {
+			margin: 10rpx 0 0 20rpx;
+
+			.imgBox {
+				display: inline-block;
+				width: 350rpx;
+				height: 150rpx;
+				margin: 10rpx 10rpx 0 0;
+			}
+
+			img {
+				width: 350rpx;
+				height: 150rpx;
+			}
+		}
+
+		.three-big-icon-button-box {
+			width: 710rpx;
+			height: 354rpx;
+			margin: 20rpx 20rpx 0;
+			background: #ffffff;
+			border-radius: 20rpx;
+			position: relative;
+
+			.imgBox:nth-child(1) {
+				position: absolute;
+				left: 13rpx;
+				top: 20rpx;
+				width: 310rpx;
+				height: 150rpx;
+				margin-bottom: 14rpx;
+
+				img {
+					width: 310rpx;
+					height: 150rpx;
+				}
+			}
+
+			.imgBox:nth-child(2) {
+				position: absolute;
+				left: 13rpx;
+				top: 180rpx;
+				width: 310rpx;
+				height: 150rpx;
+
+				img {
+					width: 310rpx;
+					height: 150rpx;
+				}
+			}
+
+			.imgBox:nth-child(3) {
+				position: absolute;
+				right: 13rpx;
+				top: 20rpx;
+				width: 362rpx;
+				height: 310rpx;
+
+				// margin: 22rpx 13rpx 22rpx 0;
+				img {
+					width: 362rpx;
+					height: 310rpx;
+				}
+			}
+		}
+
+		.grading {
+			width: 712rpx;
+			height: 80rpx;
+			background: #FFFFFF;
+			border-radius: 20rpx;
+			margin: 20rpx 0 20rpx 20rpx;
+			display: flex;
+			justify-content: flex-start;
+			align-items: center;
+
+			.grading_l {
+				width: 34rpx;
+				height: 34rpx;
+				margin-left: 16rpx;
+			}
+
+			.grading_c {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				margin-left: 16rpx;
+			}
+
+			.grading_r {
+				width: 504rpx;
+				height: 80rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #EE3A3A;
+				display: flex;
+				justify-content: flex-end;
+				align-items: center;
+
+				>img {
+					width: 20rpx;
+					height: 20rpx;
+					margin-left: 20rpx;
+				}
+			}
+		}
+	}
+</style>

+ 199 - 0
component/mineConfigurationSlot.vue

@@ -0,0 +1,199 @@
+<!-- 
+ 个人中心按钮匹配组件
+	<mineConfigurationSlot :mineConfig="mineConfigData"></mineConfigurationSlot>
+	
+	import { mineConfigurationSlot } from '@/component/mineConfigurationSlot'
+	import { getMineConfig } from '@/utils/mineConfig'
+	
+	components: {
+		mineConfigurationSlot,
+	},
+	
+	mineConfigData: [],
+	
+	demo() {
+		let data = [
+			{
+				limits: "system:post:list", //权限字段
+				route: "alarm", //路由名称
+				name: "预警记录", //名称
+			}, 
+		];
+		this.$set(this,'mineConfigData',getMineConfig(data));
+	},
+ -->
+<template>
+	<view class="mineConfigurationSlot">
+		<view class="button-max-big-box">
+			<permissionsSlot class="button-for-box" v-for="(item,index) in mineConfig" :key="index" :hasPermi="item.limits">
+				<view class="button-max-box" @click="buttonClick(item)">
+					<img class="left-img" :src="item.img">
+					<view>{{item.name}}</view>
+					<view class="view-three-one" v-if="item.route === 'alarm' && securityAlertNum>0">{{securityAlertNum}}</view>
+					<view class="view-three-two" v-if="item.route === 'laboratory' && adminSubCount>0">{{adminSubCount}}</view>
+					<view class="view-three-two" v-if="item.route === 'record' && wranDoCount>0">{{wranDoCount}}</view>
+					<view class="view-three-type" v-if="item.route === 'faceImage'"
+					:class="!ifFaceFeature?'colorA':'marginType'">
+						{{!ifFaceFeature?'去认证':'已认证'}}
+					</view>
+					<view class="view-three-type" v-if="item.route === 'signature'" :class="!isUpload?'colorA':'marginType'">{{!isUpload?'未上传':'已上传'}}</view>
+					<view class="view-three-type" v-if="item.route === 'fingerprint'" :class="Quantity>0?'marginType':'colorA'">{{Quantity>0?'已配置'+Quantity+'个':''}}</view>
+					<img class="right-img" src="@/images/icon_04.png">
+				</view>
+			</permissionsSlot>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		fingerprintQueryList
+	} from '@/api/index.js'
+	export default {
+		name: "mineConfigurationSlot",
+		props: {
+			mineConfig: {},
+			// 人脸
+			ifFaceFeature: "",
+			//签名
+			isUpload:"",
+			Quantity:0,//指纹录取数量	
+			//用户签名
+			signatureUrl: "",
+			//预案执行记录
+			wranDoCount: 0,
+			//我的实验室
+			adminSubCount: 0,
+			//预警记录
+			securityAlertNum: 0,
+		},
+		data() {
+			return {
+			}
+		},
+		created() {
+
+		},
+		mounted() {
+			
+		},
+		methods: {
+			//按钮点击事件
+			buttonClick(item) {
+				if (item.buttonType === 'page') {
+					uni.navigateTo({
+						url: item.routeUrl,
+					});
+				} else if (item.buttonType === 'button') {
+					if (item.route === 'fingerprint') {
+						this.fingerprintClick();
+					}
+				} else if (item.buttonType === 'none') {
+					uni.showToast({
+						title: '暂未开放',
+						icon: "none",
+						mask: true,
+						duration: 2000
+					});
+				}
+			},
+			//电子签名
+			signatureButton() {
+				uni.navigateTo({
+					url: '/pages_manage/workbench/signature/signature?item=' + this.signatureUrl, //电子签名
+				});
+			},
+			//查询用户指纹录取数据
+			async fingerprintClick() {
+				let _this = this;
+				const {
+					data
+				} = await fingerprintQueryList(uni.getStorageSync('userId'));
+				if (data.code == 200) {
+					uni.navigateTo({
+						url: '/pages/fingerprint', //指纹信息
+					});
+				}
+			},
+		},
+	}
+</script>
+
+<style lang="stylus" scoped>
+	.mineConfigurationSlot {
+		margin: 0;
+		background: #fff;
+		padding: 0 20rpx;
+		margin-top: 30rpx;
+		.button-for-box:last-of-type{
+			.button-max-box{
+				border:none !important;
+			}
+		}
+		.button-max-box {
+			height: 100rpx;
+			display flex;
+			border-bottom: 1px solid #e0e0e0;
+			.left-img {
+				height: 30rpx;
+				width: 30rpx;
+				margin: 34rpx 44rpx 0 0;
+			}
+
+			view {
+				line-height: 100rpx;
+			}
+
+			view:nth-child(2) {
+				flex: 1;
+				color: #333333;
+				font-size: 30rpx;
+			}
+
+			.right-img {
+				height: 24rpx;
+				width: 12rpx;
+				margin: 39rpx 0 0 0;
+			}
+
+			.colorA {
+				color: #E45656 !important;
+			}
+
+			.marginType {
+				margin-right: 12rpx;
+			}
+
+			.view-three-one {
+				width: 30rpx;
+				height: 30rpx;
+				text-align center;
+				background #FF4552;
+				border-radius: 50%;
+				font-size: 20rpx;
+				line-height: 30rpx;
+				color: #fff;
+				margin: 36rpx 20rpx;
+			}
+
+			.view-three-two {
+				width: 30rpx;
+				height: 30rpx;
+				text-align center;
+				border-radius: 50%;
+				font-size: 20rpx;
+				line-height: 30rpx;
+				color: #999;
+				margin: 36rpx 20rpx;
+
+			}
+
+			.view-three-type {
+				width: 120rpx;
+				text-align center;
+				color: #CCCCCC;
+				font-size: 26rpx;
+			}
+		}
+	}
+</style>

+ 126 - 0
component/navbar.vue

@@ -0,0 +1,126 @@
+<template>
+	<view>
+		<view class="wx-head-mod" :style="{height:navHeight+'rpx'}">
+			<view class="wx-head-mod-nav" :style="{height:navigationBarHeight+'rpx',top:statusBarHeight+'rpx'}">
+				<view class="wx-head-mod-nav-content"
+					:style="{height:customHeight+'rpx',justifyContent:'left'}">
+					<!-- 文本区 -->
+					<view class="wx-head-mod-nav-content-mian"
+						:style="{lineHeight:customHeight + 'rpx'}">
+						{{title}}
+					</view>
+				</view>
+			</view>
+		</view>
+
+	
+	</view>
+</template>
+ 
+<script>
+	import {systemInfo} from '@/component/system-info.js'
+	export default {
+		name: "HeadView",
+		props: {
+			// 文本区内容
+			title:'',
+		},
+		data() {
+			return {
+				statusBarHeight: 0, //状态栏高度
+				navHeight: 0, //头部导航栏总体高度
+				navigationBarHeight:0, //导航栏高度
+				customHeight: 0, //胶囊高度
+				scaleFactor: 0, //比例系数
+				menubarLeft:0, //胶囊定位的左边left
+				windowWidth: 0
+			};
+		},
+		methods: {
+
+		},
+		created() {
+			/* 获取设备信息 */
+			const SystemInfomations = systemInfo()
+			/* 通用平台 */
+			this.statusBarHeight = SystemInfomations.statusBarHeight //状态栏高度
+			this.scaleFactor = SystemInfomations.scaleFactor //比例系数
+			this.windowWidth = SystemInfomations.windowWidth //当前设备的屏幕宽度
+			/* 微信小程序平台 */
+			// #ifdef MP-WEIXIN
+			this.navHeight = SystemInfomations.navHeight + SystemInfomations.statusBarHeight //头部导航栏总高度
+			this.navigationBarHeight = SystemInfomations.navHeight //头部导航栏高度
+			this.customHeight = SystemInfomations.menuButtonHeight //胶囊高度
+			this.menubarLeft = SystemInfomations.menuButtonLeft //胶囊左边界距离左上角的距离
+			// #endif
+		}
+	}
+</script>
+ 
+<style>
+
+	.wx-head-mod {
+		box-sizing: border-box;
+		width: 100%;
+		position: fixed;
+		top: 0;
+		left: 0;
+		background: #0183FA;
+		/* background: linear-gradient(-35deg, #613A19 0%, #6F4E2B 100%); */
+	}
+ 
+	.wx-head-mod-nav {
+		box-sizing: border-box;
+		width: 100%;
+		position: absolute;
+		left: 0;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+ 
+	}
+ 
+	.wx-head-mod-nav-content {
+		box-sizing: border-box;
+		width: 100%;
+		display: flex;
+		justify-content: left;
+		align-items: center;
+		position: relative;
+		padding-left: 30rpx;
+		box-sizing: border-box;
+		
+	}
+ 
+	/* 文本区 */
+	.wx-head-mod-nav-content-mian {
+		box-sizing: border-box;
+		height: 100%;
+		text-align: center;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		overflow: hidden;
+		color:#fff;
+		font-size:36rpx;
+	}
+ 
+	/* 返回按钮 */
+	.wx-head-mod-nav-content-back {
+		box-sizing: border-box;
+		width: 60rpx;
+		height: 100%;
+		/* background-color: aqua; */
+		position: absolute;
+		top: 0;
+		left: 32rpx;
+		display: flex;
+		align-items: center;
+		justify-content: left;
+	}
+ 
+	.wx-head-mod-nav-content-back-img {
+		box-sizing: border-box;
+	}
+ 
+	
+ </style>

+ 51 - 0
component/permissionsSlot.vue

@@ -0,0 +1,51 @@
+<template>
+	<view class="permissionsSlot" v-if='permissionType'>
+		<slot ></slot>
+	</view>
+</template>
+
+<script>
+export default {
+  name: "permissionsSlot",
+	props: {
+		hasPermi:'',
+	},
+  data() {
+    return {
+		permissionType:false,
+		objStore:uni.getStorageSync('permissions'),
+    }
+  },
+  created() {
+	console.log('12312321123132123123')
+  },
+  mounted(){
+	console.log('657575466446')
+	  this.permissionVerification();
+  },
+  methods:{
+	  permissionVerification(){
+		let self = this;
+		console.log('self.objStore',self.objStore)
+		console.log('self.hasPermi',self.hasPermi)
+		if(this.objStore[0] == "*:*:*"){
+			this.$set(self,'permissionType',true);
+			return
+		}
+		for(let i=0;i<self.objStore.length;i++){
+			if(self.objStore[i] === self.hasPermi){
+				this.$set(self,'permissionType',true);
+				return
+			}
+		}
+	  },
+  },
+}
+</script>
+
+<style lang="stylus" scoped>
+	.permissionsSlot{
+		margin:0;
+		padding:0;
+	}
+</style>

+ 70 - 0
component/system-info.js

@@ -0,0 +1,70 @@
+/**
+ * 此js文件管理关于当前设备的机型系统信息
+ */
+const systemInfo = function() {
+	/****************** 所有平台共有的系统信息 ********************/
+	// 设备系统信息
+	let systemInfomations = uni.getSystemInfoSync()
+	// 机型适配比例系数
+	let scaleFactor = 750 / systemInfomations.windowWidth
+	// 当前机型-屏幕高度
+	let windowHeight = systemInfomations.windowHeight * scaleFactor //rpx
+	// 当前机型-屏幕宽度
+	let windowWidth = systemInfomations.windowWidth * scaleFactor //rpx
+	// 状态栏高度
+	let statusBarHeight = (systemInfomations.statusBarHeight) * scaleFactor //rpx
+ 
+	// 导航栏高度  注意:此导航栏高度只针对微信小程序有效 其他平台如自定义导航栏请使用:状态栏高度+自定义文本高度
+	let navHeight = 0 //rpx
+	// console.log(windowHeight,'哈哈哈哈哈');
+	
+	/****************** 微信小程序头部胶囊信息 ********************/
+	// #ifdef MP-WEIXIN
+	const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
+	// 胶囊高度
+	let menuButtonHeight = menuButtonInfo.height * scaleFactor //rpx
+	// 胶囊宽度
+	let menuButtonWidth = menuButtonInfo.width * scaleFactor //rpx
+	// 胶囊上边界的坐标
+	let menuButtonTop = menuButtonInfo.top * scaleFactor //rpx
+	// 胶囊右边界的坐标
+	let menuButtonRight = menuButtonInfo.right * scaleFactor //rpx
+	// 胶囊下边界的坐标
+	let menuButtonBottom = menuButtonInfo.bottom * scaleFactor //rpx
+	// 胶囊左边界的坐标
+	let menuButtonLeft = menuButtonInfo.left * scaleFactor //rpx
+ 
+	// 微信小程序中导航栏高度 = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
+	navHeight = menuButtonHeight + (menuButtonTop - statusBarHeight) * 2
+	// #endif
+ 
+ 
+	// #ifdef MP-WEIXIN
+	return {
+		scaleFactor,
+		windowHeight,
+		windowWidth,
+		statusBarHeight,
+		menuButtonHeight,
+		menuButtonWidth,
+		menuButtonTop,
+		menuButtonRight,
+		menuButtonBottom,
+		menuButtonLeft,
+		navHeight
+	}
+	// #endif
+ 
+	// #ifndef MP-WEIXIN
+	return {
+		scaleFactor,
+		windowHeight,
+		windowWidth,
+		statusBarHeight
+	}
+	// #endif
+}
+ 
+export {
+	systemInfo
+}

+ 149 - 0
component/tabBar.vue

@@ -0,0 +1,149 @@
+<!-- 底部导航组件 -->
+<template>
+	<view class="tabBar" :style="{'padding-bottom': paddingBottomHeight + 'rpx'}">
+		<view class="tab-bar-box">
+			<view class="null-box"></view>
+			<view class="tba-bar-min-box" @click="tabBarGoPage(1)">
+				<img src="@/images/basicsModules/btn_sy_xz.png" v-if="currentRoute == 'pages/home'">
+				<img src="@/images/basicsModules/btn_sy_zc.png" v-else>
+				<view :class="currentRoute == 'pages/home'?'primary':''">首页</view>
+			</view>
+			<view class="null-box"></view>
+			<view class="tba-bar-min-box" @click="tabBarGoPage(2)">
+				<img src="@/images/basicsModules/btn_xx_xz.png" v-if="currentRoute == 'pages/information/information'">
+				<img src="@/images/basicsModules/btn_xx_zc.png" v-else>
+				<view class="tip" v-if="totalCount!=0">{{totalCount}}</view>
+				<view :class="currentRoute == 'pages/information/information'?'primary':''">消息</view>
+			</view>
+			<view class="null-box"></view>
+			<view class="tba-bar-min-box" @click="tabBarGoPage(3)">
+				<img src="@/images/basicsModules/btn_wd_xz.png" v-if="currentRoute == 'pages/mine'">
+				<img src="@/images/basicsModules/btn_wd_zc.png" v-else>
+				<view :class="currentRoute == 'pages/mine'?'primary':''">我的</view>
+			</view>
+			<view class="null-box"></view>
+		</view>
+	</view>
+</template>
+
+<script>
+ import { infoTotalCount } from '@/api/basicsModules/index.js'
+	export default {
+		data() {
+			return {
+				paddingBottomHeight: 0,  //苹果X以上手机底部适配高度
+				currentRoute:"",
+				userType:"",
+				totalCount:0,
+			}
+		},
+		created() {
+			let that = this;
+			uni.getSystemInfo({
+			    success: function (res) {
+			        let model = ['X', 'XR', 'XS', '11', '12', '13', '14', '15'];
+			        model.forEach(item => {
+			            //适配iphoneX以上的底部,给tabbar一定高度的padding-bottom
+			            if(res.model.indexOf(item) != -1 && res.model.indexOf('iPhone') != -1) {
+			                that.paddingBottomHeight = 40;
+			            }
+			        })
+			    }
+			});
+		},
+
+		onShow(){
+			// this.getTotalList();
+		},
+		mounted(){
+
+			// this.getTotalList();
+			this.totalCount=uni.getStorageSync('totalCount')
+            // 获取当前路由
+            let pages = getCurrentPages();
+            let page = pages[pages.length - 1];
+            this.currentRoute = page.route;
+            // 获取当前角色
+			this.userType = uni.getStorageSync('userType');
+		},
+		methods: {
+			//获取消息总数接口
+			async getTotalList(){
+				const {data} = await infoTotalCount();
+				if(data.code==200){
+					this.totalCount=data.data.totalCount
+				}
+
+			},
+            tabBarGoPage(type){
+                if(type === 1){
+                    if (this.currentRoute !== 'pages/home') {
+                        uni.redirectTo({
+                            url: '/pages/home',
+                        });
+                    }
+				}else if(type === 2){
+                    if (this.currentRoute !== 'pages/information/information') {
+                        uni.redirectTo({
+                            url: '/pages/information/information',
+                        });
+                    }
+                }else if(type === 3){
+                    if (this.currentRoute !== 'pages/mine') {
+                        uni.redirectTo({
+                            url: '/pages/mine',
+                        });
+                    }
+                }
+
+			},
+		}
+	}
+</script>
+
+<style lang="stylus" scoped>
+	.tabBar{
+		z-index:9999;
+		width:100%;
+		height:98rpx;
+		background:#ffffff;
+		position fixed
+		bottom:0;
+		left:0;
+		box-shadow: 0 -3rpx 13rpx 0 rgba(0, 0, 0, 0.1);
+		.tab-bar-box{
+			display flex;
+			.null-box{
+				flex:1;
+			}
+			.tba-bar-min-box{
+				width:64rpx;
+				position :relative;
+				img{
+					width:44rpx;
+					height:44rpx;
+					margin:14rpx auto 0;
+				}
+				view{
+					line-height:37rpx;
+					font-size:19rpx;
+					text-align center;
+					color:#666666;
+				}
+				.tip{
+					display inline-block;
+					background :#EF0909;
+					border-radius 50%;
+					position :absolute;
+					font-size 24rpx;
+					line-height 24rpx;
+					color #fff;
+					top :10rpx;
+					left :44rpx;
+					padding:6rpx 10rpx;
+					box-sizing border-box;
+				}
+			}
+		}
+	}
+</style>

+ 187 - 0
component/topWarn.vue

@@ -0,0 +1,187 @@
+<!-- 顶部警告 -->
+<template>
+	<view class="top-warn" v-if="pageType">
+		<view>{{text}}</view>
+		<view @click="buttonClick" v-if="whetherRoute">查看</view>
+	</view>
+</template>
+
+<script>
+    import { selectTriggerInfo,evacuate,closeRiskPlan } from '@/api/basicsModules/index.js'
+
+	export default {
+		data() {
+			return {
+				pageType:false,
+				text:"",
+				buildId:"",
+				floorId:"",
+				subId:"",
+				closePlan:false,//  true 火焰报警,false 没有火焰报警
+				whetherRoute:true,
+
+				subjectId:"",
+				buildingId:"",
+				subjectName:"",
+				groupId:"",
+			}
+		},
+		created() {
+
+		},
+		mounted(){
+			// this.getWarn();
+			// getApp().watch(this.lineDataFunction,'lineData');
+		},
+		methods: {
+			//应急变更
+			lineDataFunction(val){
+				this.getWarn();
+			},
+			buttonClick(){
+				let self = this;
+				let list = [];
+				if(self.closePlan){
+					list = ['查看', '结束预案'];
+				}else{
+					self.goPage();
+				}
+				uni.showActionSheet({
+					itemList: list,
+					success: function (res) {
+						if(res.tapIndex == 0){
+							self.goPage();
+						}else if(res.tapIndex == 1){
+							self.offEvacuationClick();
+						}
+					},
+					fail: function (res) {
+						console.log(res.errMsg);
+					}
+				});
+			},
+			//结束预案
+			offEvacuationClick(){
+				let self = this;
+				uni.showModal({
+					content: '确认结束预案?',
+					cancelColor:"#999",
+					confirmColor:"#0183FA",
+					success: function (res) {
+						if (res.confirm) {
+							self.closeRiskPlan();
+						} else if (res.cancel) {
+						}
+					}
+				});
+			},
+			async closeRiskPlan(){
+				const {data} = await closeRiskPlan({id:this.groupId});
+				if(data.code == 200){
+					uni.showToast({
+						title: '操作成功',
+						icon:"none",
+						mask:true,
+						duration: 2000
+					});
+					this.pageType = false;
+				}
+			},
+			//页面跳转
+			goPage(){
+				let obj = {
+				  buildId: this.buildId,
+				  floorId:this.floorId,
+				  subId:this.subId,
+				  groupId:this.groupId,
+				}
+				uni.navigateTo({
+					url:'/pages_manage/emergencyEvacuationBig?item='+encodeURIComponent(JSON.stringify(obj))
+				});
+			},
+			//获取报警信息
+			async getWarn(){
+				let self = this;
+				const {data} = await selectTriggerInfo();
+					if(data.data[0]){
+					  this.$set(this,'text',data.data.length>1?'有多个实验室发生预案':'有实验室发生预案');
+					  this.$set(this,'buildId',data.data[0].buildId);
+					  this.$set(this,'floorId',data.data[0].floorId);
+					  this.$set(this,'subId',data.data[0].subId);
+					  if(data.data[0].riskAttribute == 1){
+						this.$set(this,'closePlan',true);
+						this.$set(this,'groupId',data.data[0].groupId);
+					  }
+					  this.$set(this,'pageType',true);
+					 //  for(let i=0;i<data.data.length;i++){
+						// if(data.data[i].riskAttribute == '1'&&data.data[i].ifCheck != '1'){
+						// 	let obj = {
+						// 	  buildId: data.data[i].buildId,
+						// 	  floorId:data.data[i].floorId,
+						// 	  subId:data.data[i].subId,
+						// 	  riskPlanId:data.data[i].riskPlanId,
+						// 	}
+						// 	uni.navigateTo({
+						// 		url:'/pages/emergencyEvacuationBig?item='+encodeURIComponent(JSON.stringify(obj))
+						// 	});
+						// 	return
+						// }
+					 //  }
+					  //没有火焰预案并且没有查看过
+					  for(let i=0;i<data.data.length;i++){
+						if(data.data[i].riskAttribute != '1'&&data.data[i].ifCheck != '1'){
+							let obj = {
+							  buildId: data.data[i].buildId,
+							  floorId:data.data[i].floorId,
+							  subId:data.data[i].subId,
+							  groupId:data.data[i].groupId,
+							}
+							uni.navigateTo({
+								url:'/pages_manage/emergencyEvacuationBig?item='+encodeURIComponent(JSON.stringify(obj))
+							});
+							return
+						}
+					  }
+					}else{
+					  this.$set(this,'pageType',false);
+					}
+			},
+			timeFuncontion(){
+				let self = this;
+				var t1 = setInterval(refreshCount, 300);
+				function refreshCount() {
+					let txt = self.text
+					let start = txt.substring(0, 1);//取该字符串的第一个字符
+					let end = txt.substring(1);//取该字符串的从1之后的所有字符
+					let newText = end + start;//拼接新的字符串
+					self.$set(self,'text',newText)
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="stylus" scoped>
+	.top-warn{
+		height:80rpx;
+		line-height:80rpx;
+		background rgba(2550,0,0,0.2)
+		margin:20rpx 0;
+		display flex;
+		overflow hidden
+		view:nth-child(1){
+			padding-left:20rpx;
+			color:#FF0000;
+			flex:1;
+			view{
+				padding-left:20rpx;
+				white-space:nowrap;
+			}
+		}
+		view:nth-child(2){
+			width:140rpx;
+			color:#0183FA;
+			text-align center;
+		}
+	}
+</style>

+ 19 - 0
components/dengrq-datetime-picker/customPickerView/index.css

@@ -0,0 +1,19 @@
+.picker-view {
+  height: 356rpx;
+}
+
+.picker-view-column {
+  font-size: 14px;
+  line-height: 34px;
+  text-align: center;
+  color: #333;
+}
+
+/* 覆盖默认样式,样式可以按需自己改 */
+.uni-picker-view-indicator {
+  background-color: rgba(106, 123, 255, 0.1);
+}
+.uni-picker-view-indicator::before,
+.uni-picker-view-indicator::after {
+  content: none;
+}

+ 53 - 0
components/dengrq-datetime-picker/customPickerView/index.js

@@ -0,0 +1,53 @@
+export default {
+  data() {
+    return {};
+  },
+  props: {
+    // 所有列选项数据
+    columns: {
+      type: Array,
+      default: () => []
+    },
+    // 每一列默认选中值数组,不传默认选中第一项
+    selectVals: {
+      type: Array,
+      default: () => []
+    }
+  },
+  computed: {
+    // 每一列选中项的索引,当默认选中值变化的时候这个值也要变化
+    indexArr: {
+      // 多维数组,深度监听
+      cache: false,
+      get() {
+        if (this.selectVals.length > 0) {
+          return this.columns.map((col, cIdx) => {
+            return col.findIndex((i) => i == this.selectVals[cIdx]);
+          });
+        } else {
+          return [].fill(0, 0, this.columns.length);
+        }
+      }
+    }
+  },
+  methods: {
+    onChange(e) {
+      const { value } = e.detail;
+
+      let ret = this.columns.map((item, index) => {
+        let idx = value[index];
+        if (idx < 0) {
+          idx = 0;
+        }
+        if (idx > item.length - 1) {
+          idx = item.length - 1;
+        }
+        return item[idx];
+      });
+
+      this.$emit('onChange', {
+        value: ret
+      });
+    }
+  }
+};

+ 11 - 0
components/dengrq-datetime-picker/customPickerView/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <picker-view class="picker-view" :value="indexArr" @change="onChange">
+    <picker-view-column class="picker-view-column" v-for="(col, colIdx) in columns" :key="colIdx">
+      <view v-for="(item, idx) in col" :key="idx">{{ item }}</view>
+    </picker-view-column>
+  </picker-view>
+</template>
+
+<script src="./index.js"></script>
+
+<style lang="css" scoped src="./index.css"></style>

+ 57 - 0
components/dengrq-datetime-picker/dateSelector/index.css

@@ -0,0 +1,57 @@
+.date-selector {
+  width: 100%;
+  font-size: 12px;
+  color: #333;
+}
+
+.select-date-wrapper {
+  margin-bottom: 8px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.select-date {
+  padding: 10px;
+  flex: 1;
+  border-radius: 2px;
+  border: 1px solid rgba(6, 7, 46, 0.05);
+  font-size: 12px;
+}
+
+.select-date.active {
+  border-color: #6a7bff;
+}
+
+.select-date-placeholder {
+  color: rgba(6, 7, 46, 0.3);
+}
+
+.btn-group {
+  display: flex;
+  margin: 48rpx 0;
+  justify-content: space-between;
+}
+
+.btn-confirm {
+  width: 180px;
+  height: 40px;
+  line-height: 40px;
+  background: rgba(33, 58, 255, 0.85);
+  border-radius: 4px;
+  font-size: 14px;
+  color: #fff;
+  text-align: center;
+}
+
+.btn-cancel {
+  width: 144px;
+  height: 40px;
+  line-height: 38px;
+  text-align: center;
+  background: #fff;
+  border-radius: 4px;
+  border: 1px solid #979797;
+  font-size: 14px;
+  color: #06072e;
+}

+ 209 - 0
components/dengrq-datetime-picker/dateSelector/index.js

@@ -0,0 +1,209 @@
+import DateTimePicker from '../dateTimePicker/index.vue';
+import DateUtil from '../dateTimePicker/dateUtil';
+import { DATE_TYPES } from '../dateTimePicker/constant';
+
+export default {
+  components: {
+    DateTimePicker
+  },
+  data() {
+    return {
+      showStartDatePicker: false,
+      showEndDatePicker: false,
+      startDate: '',
+      endDate: '',
+      activeDate: 'startDate' // 正在处理哪一个日期值,startDate/endDate
+    };
+  },
+  props: {
+    // 日期筛选模式,1:年月日(默认),2:年月,3:年,4:年月日时分秒,5:时分秒,6:时分
+    mode: {
+      type: Number,
+      default: DATE_TYPES.YMD
+    },
+    // 默认开始日期
+    defaultStartDate: {
+      type: String,
+      default: ''
+    },
+    // 默认结束日期
+    defaultEndDate: {
+      type: String,
+      default: ''
+    },
+    // 可选的最小日期
+    minDate: {
+      type: String,
+      default: ''
+    },
+    // 可选的最大日期
+    maxDate: {
+      type: String,
+      default: ''
+    }
+  },
+  watch: {
+    mode() {
+      // 筛选模式更换时清空一下数据
+      this.resetData();
+    },
+    startDate() {
+      this.$emit('onChange', {
+        startDate: this.startDate,
+        endDate: this.endDate
+      });
+    },
+    endDate() {
+      this.$emit('onChange', {
+        startDate: this.startDate,
+        endDate: this.endDate
+      });
+    },
+    defaultStartDate: {
+      handler(defaultStartDate) {
+        if (!defaultStartDate) {
+          return;
+        }
+
+        if (this.mode == DATE_TYPES.HMS || this.mode == DATE_TYPES.HM) {
+          console.error('时分秒/时分模式不支持设置默认开始时间');
+          return;
+        }
+
+        if (DateUtil.isBefore(defaultStartDate, this.minDate)) {
+          console.warn(
+            `默认开始日期不可小于最小可选日期,已把默认开始日期设为最小可选日期。默认开始日期:${defaultStartDate},最小可选日期:${this.minDate}`
+          );
+          this.startDate = this.getModeFormatDateString(this.minDate);
+        } else {
+          this.startDate = this.getModeFormatDateString(defaultStartDate);
+        }
+      },
+      immediate: true
+    },
+    defaultEndDate: {
+      handler(defaultEndDate) {
+        if (!defaultEndDate) {
+          return;
+        }
+
+        if (this.mode == DATE_TYPES.HMS || this.mode == DATE_TYPES.HM) {
+          console.error('时分秒/时分模式不支持设置默认结束时间');
+          return;
+        }
+
+        if (DateUtil.isAfter(defaultEndDate, this.maxDate)) {
+          console.warn(
+            `默认结束日期不可大于最大可选日期,已把默认结束日期设为最大可选日期。默认结束日期:${defaultEndDate},最大可选日期:${this.maxDate}`
+          );
+          this.endDate = this.getModeFormatDateString(this.maxDate);
+        } else {
+          this.endDate = this.getModeFormatDateString(defaultEndDate);
+        }
+      },
+      immediate: true
+    },
+    minDate(val) {
+      if ((val && this.mode == DATE_TYPES.HMS) || this.mode == DATE_TYPES.HM) {
+        console.error('时分秒/时分模式不支持设置最小可选时间');
+        return;
+      }
+    },
+    maxDate(val) {
+      if ((val && this.mode == DATE_TYPES.HMS) || this.mode == DATE_TYPES.HM) {
+        console.error('时分秒/时分模式不支持设置最大可选时间');
+        return;
+      }
+    }
+  },
+  methods: {
+    onTapStartDate() {
+      this.showEndDatePicker = false;
+      if (!this.startDate) {
+        this.startDate = this.getModeFormatDateString(new Date());
+      }
+      this.activeDate = 'startDate';
+      this.showStartDatePicker = true;
+    },
+    onTapEndDate() {
+      this.showStartDatePicker = false;
+      if (!this.endDate) {
+        this.endDate = this.startDate;
+      }
+      this.activeDate = 'endDate';
+      this.showEndDatePicker = true;
+    },
+    onChangeStartDate(date) {
+      this.startDate = date;
+    },
+    onChangeEndDate(date) {
+      this.endDate = date;
+    },
+    validateInput() {
+      if (!this.startDate) {
+        uni.showToast({
+          title: '请选择开始时间',
+          icon: 'none'
+        });
+        return false;
+      } else if (!this.endDate) {
+        uni.showToast({
+          title: '请选择结束时间',
+          icon: 'none'
+        });
+        return false;
+      } else if (DateUtil.isAfter(this.startDate, this.endDate)) {
+        uni.showToast({
+          title: '结束时间不能小于开始时间',
+          icon: 'none'
+        });
+        return false;
+      }
+      return true;
+    },
+    onCancel() {
+      this.resetData();
+    },
+    onConfirm() {
+      if (this.validateInput()) {
+        this.$emit('onSubmit', {
+          startDate: this.startDate,
+          endDate: this.endDate
+        });
+        this.showStartDatePicker = false;
+        this.showEndDatePicker = false;
+      }
+    },
+    resetData() {
+      this.startDate = '';
+      this.endDate = '';
+      this.activeDate = 'startDate';
+      this.showStartDatePicker = false;
+      this.showEndDatePicker = false;
+    },
+    // 返回对应日期模式的时间字符串
+    getModeFormatDateString(date) {
+      let fmt = 'YYYY-MM-DD';
+      switch (this.mode) {
+        case DATE_TYPES.YM:
+          fmt = 'YYYY-MM';
+          break;
+        case DATE_TYPES.Y:
+          fmt = 'YYYY';
+          break;
+        case DATE_TYPES['YMD-HMS']:
+          fmt = 'YYYY-MM-DD HH:mm:ss';
+          break;
+        case DATE_TYPES.HMS:
+          fmt = 'HH:mm:ss';
+          break;
+        case DATE_TYPES.HM:
+          fmt = 'HH:mm';
+          break;
+        default:
+          break;
+      }
+      return DateUtil.formatDate(date, fmt);
+    }
+  }
+};

+ 41 - 0
components/dengrq-datetime-picker/dateSelector/index.vue

@@ -0,0 +1,41 @@
+<template>
+  <view class="date-selector">
+    <view class="select-date-wrapper">
+      <view class="select-date" :class="{ active: activeDate == 'startDate' }" @tap="onTapStartDate">
+        <view class="select-date-value" v-if="startDate">{{ startDate }}</view>
+        <view class="select-date-placeholder" v-else>请选择时间</view>
+      </view>
+      <view style="margin: 0 16px">至</view>
+      <view class="select-date" :class="{ active: activeDate == 'endDate' }" @tap="onTapEndDate">
+        <view class="select-date-value" v-if="endDate">{{ endDate }}</view>
+        <view class="select-date-placeholder" v-else>请选择时间</view>
+      </view>
+    </view>
+
+    <DateTimePicker
+      v-if="showStartDatePicker"
+      @onChange="onChangeStartDate"
+      :defaultDate="startDate"
+      :minDate="minDate || ''"
+      :maxDate="endDate || maxDate || ''"
+      :mode="mode"
+    />
+    <DateTimePicker
+      v-if="showEndDatePicker"
+      @onChange="onChangeEndDate"
+      :defaultDate="endDate"
+      :minDate="startDate || minDate || ''"
+      :maxDate="maxDate || ''"
+      :mode="mode"
+    />
+
+    <view class="btn-group" v-if="showStartDatePicker || showEndDatePicker">
+      <view class="btn-cancel" @tap="onCancel">取消</view>
+      <view class="btn-confirm" @tap="onConfirm">确定</view>
+    </view>
+  </view>
+</template>
+
+<script src="./index.js"></script>
+
+<style lang="css" scoped src="./index.css"></style>

+ 15 - 0
components/dengrq-datetime-picker/dateTimePicker/constant.js

@@ -0,0 +1,15 @@
+// 日期模式
+export const DATE_TYPES = {
+  // 年月日
+  YMD: 1,
+  // 年月
+  YM: 2,
+  // 年份
+  Y: 3,
+  // 年月日时分秒
+  'YMD-HMS': 4,
+  // 时分秒
+  HMS: 5,
+  // 时分
+  HM: 6
+};

+ 93 - 0
components/dengrq-datetime-picker/dateTimePicker/dateUtil.js

@@ -0,0 +1,93 @@
+/**
+ * 日期时间格式化
+ * @param {Date} date 要格式化的日期对象
+ * @param {String} fmt 格式化字符串,eg:YYYY-MM-DD HH:mm:ss
+ * @returns 格式化后的日期字符串
+ */
+function formatDate(date, fmt) {
+  if (typeof date == 'string') {
+    date = new Date(handleDateStr(date));
+  }
+
+  const o = {
+    'M+': date.getMonth() + 1, // 月份
+    'd+': date.getDate(), // 日
+    'D+': date.getDate(), // 日
+    'H+': date.getHours(), // 小时
+    'h+': date.getHours(), // 小时
+    'm+': date.getMinutes(), // 分
+    's+': date.getSeconds(), // 秒
+    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
+    S: date.getMilliseconds() // 毫秒
+  };
+
+  if (/([y|Y]+)/.test(fmt)) {
+    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').slice(4 - RegExp.$1.length));
+  }
+
+  for (const k in o) {
+    if (new RegExp('(' + k + ')').test(fmt)) {
+      fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).slice(('' + o[k]).length));
+    }
+  }
+
+  return fmt;
+}
+
+/**
+ * 处理时间字符串,兼容ios下new Date()返回NaN问题
+ * @param {*} dateStr 日期字符串
+ * @returns
+ */
+function handleDateStr(dateStr) {
+  return dateStr.replace(/\-/g, '/');
+}
+
+/**
+ * 判断日期1是否在日期2之前,即日期1小于日期2
+ * @param {Date} date1
+ * @param {Date} date2
+ * @returns
+ */
+function isBefore(date1, date2) {
+  if (typeof date1 == 'string') {
+    date1 = new Date(handleDateStr(date1));
+  }
+  if (typeof date2 == 'string') {
+    date2 = new Date(handleDateStr(date2));
+  }
+  return date1.getTime() < date2.getTime();
+}
+
+/**
+ * 判断日期1是否在日期2之后,即日期1大于日期2
+ * @param {Date} date1
+ * @param {Date} date2
+ * @returns
+ */
+function isAfter(date1, date2) {
+  if (typeof date1 == 'string') {
+    date1 = new Date(handleDateStr(date1));
+  }
+  if (typeof date2 == 'string') {
+    date2 = new Date(handleDateStr(date2));
+  }
+  return date1.getTime() > date2.getTime();
+}
+
+/**
+ * 检查传入的字符串是否能转换为有效的Date对象
+ * @param {String} date
+ * @returns {Boolean}
+ */
+function isValid(date) {
+  return new Date(date) !== 'Invalid Date' && !isNaN(new Date(date));
+}
+
+export default {
+  formatDate,
+  handleDateStr,
+  isBefore,
+  isAfter,
+  isValid
+};

+ 378 - 0
components/dengrq-datetime-picker/dateTimePicker/index.js

@@ -0,0 +1,378 @@
+import CustomPickerView from '../customPickerView/index.vue';
+import DateUtil from '../dateTimePicker/dateUtil';
+import { DATE_TYPES } from './constant';
+
+export default {
+  components: {
+    CustomPickerView
+  },
+  props: {
+    // 日期模式,1:年月日(默认),2:年月,3:年份,4:年月日时分秒,5:时分秒,6:时分
+    mode: {
+      type: Number,
+      default: DATE_TYPES.YMD
+    },
+    // 可选的最小日期,默认十年前
+    minDate: {
+      type: String,
+      default: ''
+    },
+    // 可选的最大日期,默认十年后
+    maxDate: {
+      type: String,
+      default: ''
+    },
+    // 默认选中日期(注意要跟日期模式对应)
+    defaultDate: {
+      type: String,
+      default: ''
+    }
+  },
+  data() {
+    return {
+      selectYear: new Date().getFullYear(),
+      selectMonth: new Date().getMonth() + 1, // 选中的月份,1~12
+      selectDay: new Date().getDate(),
+      selectHour: new Date().getHours(),
+      selectMinute: new Date().getMinutes(),
+      selectSecond: new Date().getSeconds()
+    };
+  },
+  watch: {
+    defaultDate: {
+      immediate: true,
+      handler(val) {
+        if (val) {
+          if (this.mode == DATE_TYPES.YM && val.replace(/\-/g, '/').split('/').length == 2) {
+            // 日期模式为年月时有可能传进来的defaultDate是2022-02这样的格式,在ios下new Date会报错,加上日期部分做兼容
+            val += '-01';
+          } else if (this.mode == DATE_TYPES.HMS || this.mode == DATE_TYPES.HM) {
+            // 只有时分秒或者只有时分是不能调用new Date生成Date对象的,先加上一个假设的年月日(就取当年一月一日)来兼容
+            const now = new Date();
+            val = `${now.getFullYear()}-01-01 ${val}`;
+          }
+
+          let date = new Date(DateUtil.handleDateStr(val));
+          this.selectYear = date.getFullYear();
+          this.selectMonth = date.getMonth() + 1;
+          this.selectDay = date.getDate();
+          this.selectHour = date.getHours();
+          this.selectMinute = date.getMinutes();
+          this.selectSecond = date.getSeconds();
+        }
+      }
+    }
+  },
+  computed: {
+    minDateObj() {
+      let minDate = this.minDate;
+      if (minDate) {
+        if (this.mode == DATE_TYPES.YM && minDate.replace(/\-/g, '/').split('/').length == 2) {
+          // 日期模式为年月时有可能传进来的minDate是2022-02这样的格式,在ios下new Date会报错,加上日期部分做兼容
+          minDate += '-01';
+        } else if (this.mode == DATE_TYPES.HMS || this.mode == DATE_TYPES.HM) {
+          // 只有时分秒或者只有时分是不能调用new Date生成Date对象的,先加上一个假设的年月日(就取当年一月一日)来兼容
+          const now = new Date();
+          minDate = `${now.getFullYear()}-01-01 ${minDate}`;
+        }
+        return new Date(DateUtil.handleDateStr(minDate));
+      } else {
+        // 没有传最小日期,默认十年前
+        let year = new Date().getFullYear() - 10;
+        minDate = new Date(year, 0, 1);
+        return minDate;
+      }
+    },
+    maxDateObj() {
+      let maxDate = this.maxDate;
+      if (maxDate) {
+        if (this.mode == DATE_TYPES.YM && maxDate.replace(/\-/g, '/').split('/').length == 2) {
+          // 日期模式为年月时有可能传进来的maxDate是2022-02这样的格式,在ios下new Date会报错,加上日期部分做兼容
+          maxDate += '-01';
+        } else if (this.mode == DATE_TYPES.HMS || this.mode == DATE_TYPES.HM) {
+          // 只有时分秒或者只有时分是不能调用new Date生成Date对象的,先加上一个假设的年月日(就取当年一月一日)来兼容
+          const now = new Date();
+          maxDate = `${now.getFullYear()}-01-01 ${maxDate}`;
+        }
+        return new Date(DateUtil.handleDateStr(maxDate));
+      } else {
+        // 没有传最大日期,默认十年后
+        let year = new Date().getFullYear() + 10;
+        maxDate = new Date(year, 11, 31);
+        return maxDate;
+      }
+    },
+    years() {
+      let years = [];
+      let minYear = this.minDateObj.getFullYear();
+      let maxYear = this.maxDateObj.getFullYear();
+      for (let i = minYear; i <= maxYear; i++) {
+        years.push(i);
+      }
+
+      return years;
+    },
+    months() {
+      let months = [];
+      let minMonth = 1;
+      let maxMonth = 12;
+
+      // 如果选中的年份刚好是最小可选日期的年份,那月份就要从最小日期的月份开始
+      if (this.selectYear == this.minDateObj.getFullYear()) {
+        minMonth = this.minDateObj.getMonth() + 1;
+      }
+      // 如果选中的年份刚好是最大可选日期的年份,那月份就要在最大日期的月份结束
+      if (this.selectYear == this.maxDateObj.getFullYear()) {
+        maxMonth = this.maxDateObj.getMonth() + 1;
+      }
+
+      for (let i = minMonth; i <= maxMonth; i++) {
+        months.push(i);
+      }
+
+      return months;
+    },
+    days() {
+      // 一年中12个月每个月的天数
+      let monthDaysConfig = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+      // 闰年2月有29天
+      if (this.selectMonth == 2 && this.selectYear % 4 == 0) {
+        monthDaysConfig[1] = 29;
+      }
+
+      let minDay = 1;
+      let maxDay = monthDaysConfig[this.selectMonth - 1];
+
+      if (this.selectYear == this.minDateObj.getFullYear() && this.selectMonth == this.minDateObj.getMonth() + 1) {
+        minDay = this.minDateObj.getDate();
+      }
+      if (this.selectYear == this.maxDateObj.getFullYear() && this.selectMonth == this.maxDateObj.getMonth() + 1) {
+        maxDay = this.maxDateObj.getDate();
+      }
+
+      let days = [];
+      for (let i = minDay; i <= maxDay; i++) {
+        days.push(i);
+      }
+
+      return days;
+    },
+    hours() {
+      let hours = [];
+      let minHour = 0;
+      let maxHour = 23;
+
+      if (
+        this.selectYear == this.minDateObj.getFullYear() &&
+        this.selectMonth == this.minDateObj.getMonth() + 1 &&
+        this.selectDay == this.minDateObj.getDate()
+      ) {
+        minHour = this.minDateObj.getHours();
+      }
+      if (
+        this.selectYear == this.maxDateObj.getFullYear() &&
+        this.selectMonth == this.maxDateObj.getMonth() + 1 &&
+        this.selectDay == this.maxDateObj.getDate()
+      ) {
+        maxHour = this.maxDateObj.getHours();
+      }
+
+      for (let i = minHour; i <= maxHour; i++) {
+        hours.push(i);
+      }
+
+      return hours;
+    },
+    minutes() {
+      let mins = [];
+      let minMin = 0;
+      let maxMin = 59;
+
+      if (
+        this.selectYear == this.minDateObj.getFullYear() &&
+        this.selectMonth == this.minDateObj.getMonth() + 1 &&
+        this.selectDay == this.minDateObj.getDate() &&
+        this.selectHour == this.minDateObj.getHours()
+      ) {
+        minMin = this.minDateObj.getMinutes();
+      }
+      if (
+        this.selectYear == this.maxDateObj.getFullYear() &&
+        this.selectMonth == this.maxDateObj.getMonth() + 1 &&
+        this.selectDay == this.maxDateObj.getDate() &&
+        this.selectHour == this.maxDateObj.getHours()
+      ) {
+        maxMin = this.maxDateObj.getMinutes();
+      }
+
+      for (let i = minMin; i <= maxMin; i++) {
+        mins.push(i);
+      }
+
+      return mins;
+    },
+    seconds() {
+      let seconds = [];
+      let minSecond = 0;
+      let maxSecond = 59;
+
+      if (
+        this.selectYear == this.minDateObj.getFullYear() &&
+        this.selectMonth == this.minDateObj.getMonth() + 1 &&
+        this.selectDay == this.minDateObj.getDate() &&
+        this.selectHour == this.minDateObj.getHours() &&
+        this.selectMinute == this.minDateObj.getMinutes()
+      ) {
+        minSecond = this.minDateObj.getSeconds();
+      }
+      if (
+        this.selectYear == this.maxDateObj.getFullYear() &&
+        this.selectMonth == this.maxDateObj.getMonth() + 1 &&
+        this.selectDay == this.maxDateObj.getDate() &&
+        this.selectHour == this.maxDateObj.getHours() &&
+        this.selectMinute == this.maxDateObj.getMinutes()
+      ) {
+        maxSecond = this.maxDateObj.getSeconds();
+      }
+
+      for (let i = minSecond; i <= maxSecond; i++) {
+        seconds.push(i);
+      }
+
+      return seconds;
+    },
+    // 传给pickerView组件的数组,根据mode来生成不同的数据
+    dateConfig() {
+      let years = this.years.map((y) => y + '年');
+      let months = this.months.map((m) => m + '月');
+      let days = this.days.map((d) => d + '日');
+      let hours = this.hours.map((h) => h + '时');
+      let minutes = this.minutes.map((m) => m + '分');
+      let seconds = this.seconds.map((s) => s + '秒');
+
+      let ret = [];
+      switch (this.mode) {
+        case DATE_TYPES.YM:
+          ret = [years, months];
+          break;
+        case DATE_TYPES.Y:
+          ret = [years];
+          break;
+        case DATE_TYPES['YMD-HMS']:
+          ret = [years, months, days, hours, minutes, seconds];
+          break;
+        case DATE_TYPES.HMS:
+          ret = [hours, minutes, seconds];
+          break;
+        case DATE_TYPES.HM:
+          ret = [hours, minutes];
+          break;
+        default:
+          ret = [years, months, days];
+          break;
+      }
+
+      return ret;
+    },
+    selectVals() {
+      let ret = [];
+      switch (this.mode) {
+        case DATE_TYPES.YM:
+          ret = [this.selectYear + '年', this.selectMonth + '月'];
+          break;
+        case DATE_TYPES.Y:
+          ret = [this.selectYear + '年'];
+          break;
+        case DATE_TYPES['YMD-HMS']:
+          ret = [
+            this.selectYear + '年',
+            this.selectMonth + '月',
+            this.selectDay + '日',
+            this.selectHour + '时',
+            this.selectMinute + '分',
+            this.selectSecond + '秒'
+          ];
+          break;
+        case DATE_TYPES.HMS:
+          ret = [this.selectHour + '时', this.selectMinute + '分', this.selectSecond + '秒'];
+          break;
+        case DATE_TYPES.HM:
+          ret = [this.selectHour + '时', this.selectMinute + '分'];
+          break;
+        default:
+          ret = [this.selectYear + '年', this.selectMonth + '月', this.selectDay + '日'];
+          break;
+      }
+      return ret;
+    }
+  },
+  methods: {
+    onChangePickerValue(e) {
+      const { value } = e;
+
+      if (this.mode == DATE_TYPES.YM && value[0] && value[1]) {
+        // 年月模式
+        this.selectYear = Number(value[0].replace('年', ''));
+        this.selectMonth = Number(value[1].replace('月', ''));
+      } else if (this.mode == DATE_TYPES.Y && value[0]) {
+        // 只有年份模式
+        this.selectYear = Number(value[0].replace('年', ''));
+      } else if (this.mode == DATE_TYPES['YMD-HMS'] && value[0] && value[1] && value[2] != '' && value[3] && value[4] && value[5]) {
+        // 年月日时分秒模式
+        this.selectYear = Number(value[0].replace('年', ''));
+        this.selectMonth = Number(value[1].replace('月', ''));
+        this.selectDay = Number(value[2].replace('日', ''));
+        this.selectHour = Number(value[3].replace('时', ''));
+        this.selectMinute = Number(value[4].replace('分', ''));
+        this.selectSecond = Number(value[5].replace('秒', ''));
+      } else if (this.mode == DATE_TYPES.HMS && value[0] && value[1] && value[2]) {
+        // 时分秒模式
+        this.selectHour = Number(value[0].replace('时', ''));
+        this.selectMinute = Number(value[1].replace('分', ''));
+        this.selectSecond = Number(value[2].replace('秒', ''));
+      } else if (this.mode == DATE_TYPES.HM && value[0] && value[1]) {
+        // 时分模式
+        this.selectHour = Number(value[0].replace('时', ''));
+        this.selectMinute = Number(value[1].replace('分', ''));
+      } else if (value[0] && value[1] && value[2]) {
+        // 默认,年月日模式
+        this.selectYear = Number(value[0].replace('年', ''));
+        this.selectMonth = Number(value[1].replace('月', ''));
+        this.selectDay = Number(value[2].replace('日', ''));
+      } else {
+        // 其他情况可能是pickerView返回的数据有问题,不处理
+        console.log('onChangePickerValue其他情况');
+        return;
+      }
+
+      let formatTmpl = 'YYYY-MM-DD';
+      switch (this.mode) {
+        case DATE_TYPES.YM:
+          formatTmpl = 'YYYY-MM';
+          break;
+        case DATE_TYPES.Y:
+          formatTmpl = 'YYYY';
+          break;
+        case DATE_TYPES['YMD-HMS']:
+          formatTmpl = 'YYYY-MM-DD HH:mm';
+          break;
+        case DATE_TYPES.HMS:
+          formatTmpl = 'HH:mm:ss';
+          break;
+        case DATE_TYPES.HM:
+          formatTmpl = 'HH:mm';
+          break;
+        default:
+          break;
+      }
+
+      this.$emit(
+        'onChange',
+        DateUtil.formatDate(
+          new Date(`${this.selectYear}/${this.selectMonth}/${this.selectDay} ${this.selectHour}:${this.selectMinute}:${this.selectSecond}`),
+          formatTmpl
+        )
+      );
+    }
+  }
+};

+ 9 - 0
components/dengrq-datetime-picker/dateTimePicker/index.vue

@@ -0,0 +1,9 @@
+<template>
+  <view class="datetime-picker">
+    <CustomPickerView :columns="dateConfig" :selectVals="selectVals" @onChange="onChangePickerValue" />
+  </view>
+</template>
+
+<script src="./index.js"></script>
+
+<style scoped lang="css"></style>

二进制
images/basicsModules/btn_sy_xz.png


二进制
images/basicsModules/btn_sy_zc.png


二进制
images/basicsModules/btn_wd_jfdh.png


二进制
images/basicsModules/btn_wd_xz.png


二进制
images/basicsModules/btn_wd_zc.png


二进制
images/basicsModules/btn_xx_xz.png


二进制
images/basicsModules/btn_xx_zc.png


二进制
images/basicsModules/button_1.png


二进制
images/basicsModules/button_2.png


二进制
images/basicsModules/icon_04.png


二进制
images/basicsModules/icon_12.png


二进制
images/basicsModules/icon_13.png


二进制
images/basicsModules/icon_14.png


二进制
images/basicsModules/icon_15.png


二进制
images/basicsModules/icon_dzt_pzjc.png


二进制
images/basicsModules/icon_sy_aqjc.png


二进制
images/basicsModules/icon_sy_aqxx.png


二进制
images/basicsModules/icon_sy_fjgk.png


二进制
images/basicsModules/icon_sy_hxp.png


二进制
images/basicsModules/icon_sy_qpgl.png


二进制
images/basicsModules/icon_sy_ssp.png


二进制
images/basicsModules/icon_sy_tzsb.png


二进制
images/basicsModules/icon_sy_wdsys.png


二进制
images/basicsModules/icon_sy_zrsq.png


二进制
images/basicsModules/icon_wdwg_gd.png


二进制
images/basicsModules/img_bg_cjcx.png


二进制
images/basicsModules/img_bg_jfmx.png


二进制
images/basicsModules/img_bg_wgjl.png


二进制
images/basicsModules/img_log_in_account.png


二进制
images/basicsModules/img_log_in_password.png


二进制
images/basicsModules/null-data-1.png


+ 16 - 0
main.js

@@ -0,0 +1,16 @@
+import Vue from 'vue'
+import App from './App'
+
+// 权限组件
+import { permissionsSlot } from '@/component/permissionsSlot'
+
+Vue.config.productionTip = false
+
+Vue.component('permissionsSlot', permissionsSlot)
+
+App.mpType = 'app'
+
+const app = new Vue({
+    ...App
+})
+app.$mount()

+ 76 - 0
manifest.json

@@ -0,0 +1,76 @@
+{
+    "name" : "实验室小程序",
+    "appid" : "__UNI__20A0072",
+    "description" : "",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "usingComponents" : true,
+        "nvueStyleCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {},
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            /* ios打包配置 */
+            "ios" : {},
+            /* SDK配置 */
+            "sdkConfigs" : {}
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "wx0cbc02ca7f6e7f25",
+        "setting" : {
+            "urlCheck" : false,
+            "minified" : true
+        },
+        "usingComponents" : true,
+        "permission" : {},
+        "optimization" : {
+            "subPackages" : true
+        }
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    }
+}

+ 821 - 0
package-lock.json

@@ -0,0 +1,821 @@
+{
+  "name": "基于DataPicker(uni-data-picker)的带有搜索功能的选择器",
+  "version": "0.1.3",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
+    },
+    "balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.nlark.com/balanced-match/download/balanced-match-1.0.2.tgz",
+      "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4="
+    },
+    "base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.nlark.com/base64-js/download/base64-js-1.5.1.tgz?cache=0&sync_timestamp=1624607950711&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbase64-js%2Fdownload%2Fbase64-js-1.5.1.tgz",
+      "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo="
+    },
+    "bl": {
+      "version": "4.1.0",
+      "resolved": "https://registry.nlark.com/bl/download/bl-4.1.0.tgz",
+      "integrity": "sha1-RRU1JkGCvsL7vIOmKrmM8R2fezo=",
+      "requires": {
+        "buffer": "^5.5.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.4.0"
+      }
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.nlark.com/brace-expansion/download/brace-expansion-1.1.11.tgz",
+      "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.nlark.com/buffer/download/buffer-5.7.1.tgz",
+      "integrity": "sha1-umLnwTEzBTWCGXFghRqPZI6Z7tA=",
+      "requires": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "buffer-from": {
+      "version": "1.1.2",
+      "resolved": "https://registry.nlark.com/buffer-from/download/buffer-from-1.1.2.tgz?cache=0&sync_timestamp=1627578361955&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbuffer-from%2Fdownload%2Fbuffer-from-1.1.2.tgz",
+      "integrity": "sha1-KxRqb9cugLT1XSVfNe1Zo6mkG9U="
+    },
+    "callback-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/callback-stream/-/callback-stream-1.1.0.tgz",
+      "integrity": "sha512-sAZ9kODla+mGACBZ1IpTCAisKoGnv6PykW7fPk1LrM+mMepE18Yz0515yoVcrZy7dQsTUp3uZLQ/9Sx1RnLoHw==",
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "> 1.0.0 < 3.0.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "2.3.7",
+          "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "commist": {
+      "version": "1.1.0",
+      "resolved": "https://registry.nlark.com/commist/download/commist-1.1.0.tgz",
+      "integrity": "sha1-F4EexpePbBXuTegMRcm+t3zuNdU=",
+      "requires": {
+        "leven": "^2.1.0",
+        "minimist": "^1.1.0"
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.nlark.com/concat-map/download/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmmirror.com/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "2.3.7",
+          "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "core-util-is": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+    },
+    "d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "requires": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
+    "debug": {
+      "version": "4.3.2",
+      "resolved": "https://registry.nlark.com/debug/download/debug-4.3.2.tgz?cache=0&sync_timestamp=1625374653719&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdebug%2Fdownload%2Fdebug-4.3.2.tgz",
+      "integrity": "sha1-8KScGKyHeeMdSgxgKd+3aHPHQos=",
+      "requires": {
+        "ms": "2.1.2"
+      }
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.nlark.com/end-of-stream/download/end-of-stream-1.4.4.tgz?cache=0&sync_timestamp=1624607958717&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fend-of-stream%2Fdownload%2Fend-of-stream-1.4.4.tgz",
+      "integrity": "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA=",
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "es5-ext": {
+      "version": "0.10.62",
+      "resolved": "https://registry.npmmirror.com/es5-ext/-/es5-ext-0.10.62.tgz",
+      "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+      "requires": {
+        "es6-iterator": "^2.0.3",
+        "es6-symbol": "^3.1.3",
+        "next-tick": "^1.1.0"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "es6-map": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmmirror.com/es6-map/-/es6-map-0.1.5.tgz",
+      "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==",
+      "requires": {
+        "d": "1",
+        "es5-ext": "~0.10.14",
+        "es6-iterator": "~2.0.1",
+        "es6-set": "~0.1.5",
+        "es6-symbol": "~3.1.1",
+        "event-emitter": "~0.3.5"
+      }
+    },
+    "es6-set": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmmirror.com/es6-set/-/es6-set-0.1.6.tgz",
+      "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==",
+      "requires": {
+        "d": "^1.0.1",
+        "es5-ext": "^0.10.62",
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "^3.1.3",
+        "event-emitter": "^0.3.5",
+        "type": "^2.7.2"
+      },
+      "dependencies": {
+        "type": {
+          "version": "2.7.2",
+          "resolved": "https://registry.npmmirror.com/type/-/type-2.7.2.tgz",
+          "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
+        }
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.3.tgz",
+      "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+      "requires": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmmirror.com/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+      "requires": {
+        "d": "1",
+        "es5-ext": "~0.10.14"
+      }
+    },
+    "ext": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmmirror.com/ext/-/ext-1.7.0.tgz",
+      "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+      "requires": {
+        "type": "^2.7.2"
+      },
+      "dependencies": {
+        "type": {
+          "version": "2.7.2",
+          "resolved": "https://registry.npmmirror.com/type/-/type-2.7.2.tgz",
+          "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.nlark.com/fs.realpath/download/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+    },
+    "glob": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmmirror.com/glob/download/glob-7.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fglob%2Fdownload%2Fglob-7.2.0.tgz",
+      "integrity": "sha1-0VU1r3cy4C6Uj0xBYovZECk/YCM=",
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-3.1.0.tgz",
+      "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
+      "requires": {
+        "is-glob": "^3.1.0",
+        "path-dirname": "^1.0.0"
+      }
+    },
+    "glob-stream": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/glob-stream/-/glob-stream-6.1.0.tgz",
+      "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==",
+      "requires": {
+        "extend": "^3.0.0",
+        "glob": "^7.1.1",
+        "glob-parent": "^3.1.0",
+        "is-negated-glob": "^1.0.0",
+        "ordered-read-streams": "^1.0.0",
+        "pumpify": "^1.3.5",
+        "readable-stream": "^2.1.5",
+        "remove-trailing-separator": "^1.0.1",
+        "to-absolute-glob": "^2.0.0",
+        "unique-stream": "^2.0.2"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "2.3.7",
+          "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "help-me": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/help-me/-/help-me-1.1.0.tgz",
+      "integrity": "sha512-P/IZ8yOMne3SCTHbVY429NZ67B/2bVQlcYGZh2iPPbdLrEQ/qY5aGChn0YTDmt7Sb4IKRI51fypItav+lNl76w==",
+      "requires": {
+        "callback-stream": "^1.0.2",
+        "glob-stream": "^6.1.0",
+        "through2": "^2.0.1",
+        "xtend": "^4.0.0"
+      }
+    },
+    "ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.nlark.com/ieee754/download/ieee754-1.2.1.tgz",
+      "integrity": "sha1-jrehCmP/8l0VpXsAFYbRd9Gw01I="
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.nlark.com/inflight/download/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.nlark.com/inherits/download/inherits-2.0.4.tgz",
+      "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w="
+    },
+    "is-absolute": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-absolute/-/is-absolute-1.0.0.tgz",
+      "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+      "requires": {
+        "is-relative": "^1.0.0",
+        "is-windows": "^1.0.1"
+      }
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
+    },
+    "is-glob": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-3.1.0.tgz",
+      "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
+      "requires": {
+        "is-extglob": "^2.1.0"
+      }
+    },
+    "is-negated-glob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+      "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug=="
+    },
+    "is-relative": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-relative/-/is-relative-1.0.0.tgz",
+      "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+      "requires": {
+        "is-unc-path": "^1.0.0"
+      }
+    },
+    "is-unc-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-unc-path/-/is-unc-path-1.0.0.tgz",
+      "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+      "requires": {
+        "unc-path-regex": "^0.1.2"
+      }
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+    },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
+    },
+    "leven": {
+      "version": "2.1.0",
+      "resolved": "https://registry.nlark.com/leven/download/leven-2.1.0.tgz",
+      "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA="
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.nlark.com/minimatch/download/minimatch-3.0.4.tgz?cache=0&sync_timestamp=1624607996146&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fminimatch%2Fdownload%2Fminimatch-3.0.4.tgz",
+      "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.nlark.com/minimist/download/minimist-1.2.5.tgz?cache=0&sync_timestamp=1624607886507&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz",
+      "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI="
+    },
+    "mqtt-packet": {
+      "version": "6.10.0",
+      "resolved": "https://registry.nlark.com/mqtt-packet/download/mqtt-packet-6.10.0.tgz",
+      "integrity": "sha1-yLUHgyxBUuPlEcDvoQSuSmTNQY8=",
+      "requires": {
+        "bl": "^4.0.2",
+        "debug": "^4.1.1",
+        "process-nextick-args": "^2.0.1"
+      }
+    },
+    "ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/ms/download/ms-2.1.2.tgz",
+      "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
+    },
+    "next-tick": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/next-tick/-/next-tick-1.1.0.tgz",
+      "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.nlark.com/once/download/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "ordered-read-streams": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+      "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==",
+      "requires": {
+        "readable-stream": "^2.0.1"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "2.3.7",
+          "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q=="
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.nlark.com/path-is-absolute/download/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+    },
+    "process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.nlark.com/process-nextick-args/download/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I="
+    },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.nlark.com/pump/download/pump-3.0.0.tgz?cache=0&sync_timestamp=1624607960506&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpump%2Fdownload%2Fpump-3.0.0.tgz",
+      "integrity": "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ=",
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "pumpify": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/pumpify/-/pumpify-1.5.1.tgz",
+      "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+      "requires": {
+        "duplexify": "^3.6.0",
+        "inherits": "^2.0.3",
+        "pump": "^2.0.0"
+      },
+      "dependencies": {
+        "duplexify": {
+          "version": "3.7.1",
+          "resolved": "https://registry.npmmirror.com/duplexify/-/duplexify-3.7.1.tgz",
+          "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+          "requires": {
+            "end-of-stream": "^1.0.0",
+            "inherits": "^2.0.1",
+            "readable-stream": "^2.0.0",
+            "stream-shift": "^1.0.0"
+          }
+        },
+        "pump": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmmirror.com/pump/-/pump-2.0.1.tgz",
+          "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.7",
+          "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "readable-stream": {
+      "version": "3.6.0",
+      "resolved": "https://registry.nlark.com/readable-stream/download/readable-stream-3.6.0.tgz",
+      "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=",
+      "requires": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      }
+    },
+    "reinterval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/reinterval/download/reinterval-1.1.0.tgz",
+      "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc="
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="
+    },
+    "safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.nlark.com/safe-buffer/download/safe-buffer-5.2.1.tgz",
+      "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY="
+    },
+    "split2": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmmirror.com/split2/download/split2-3.2.2.tgz",
+      "integrity": "sha1-vyzyo32DgxLCSciSBv16F90SNl8=",
+      "requires": {
+        "readable-stream": "^3.0.0"
+      }
+    },
+    "stream-shift": {
+      "version": "1.0.1",
+      "resolved": "https://registry.nlark.com/stream-shift/download/stream-shift-1.0.1.tgz",
+      "integrity": "sha1-1wiCgVWasneEJCebCHfaPDktWj0="
+    },
+    "string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.nlark.com/string_decoder/download/string_decoder-1.3.0.tgz",
+      "integrity": "sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4=",
+      "requires": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "requires": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "2.3.7",
+          "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "through2-filter": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/through2-filter/-/through2-filter-3.0.0.tgz",
+      "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
+      "requires": {
+        "through2": "~2.0.0",
+        "xtend": "~4.0.0"
+      }
+    },
+    "to-absolute-glob": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+      "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==",
+      "requires": {
+        "is-absolute": "^1.0.0",
+        "is-negated-glob": "^1.0.0"
+      }
+    },
+    "type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/type/-/type-1.2.0.tgz",
+      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.nlark.com/typedarray/download/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
+    },
+    "ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
+    },
+    "unc-path-regex": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+      "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="
+    },
+    "unique-stream": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/unique-stream/-/unique-stream-2.3.1.tgz",
+      "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
+      "requires": {
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "through2-filter": "^3.0.0"
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.nlark.com/util-deprecate/download/util-deprecate-1.0.2.tgz?cache=0&sync_timestamp=1624607944834&other_urls=https%3A%2F%2Fregistry.nlark.com%2Futil-deprecate%2Fdownload%2Futil-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+    },
+    "websocket-stream": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmmirror.com/websocket-stream/-/websocket-stream-5.5.2.tgz",
+      "integrity": "sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ==",
+      "requires": {
+        "duplexify": "^3.5.1",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.3",
+        "safe-buffer": "^5.1.2",
+        "ws": "^3.2.0",
+        "xtend": "^4.0.0"
+      },
+      "dependencies": {
+        "duplexify": {
+          "version": "3.7.1",
+          "resolved": "https://registry.npmmirror.com/duplexify/-/duplexify-3.7.1.tgz",
+          "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+          "requires": {
+            "end-of-stream": "^1.0.0",
+            "inherits": "^2.0.1",
+            "readable-stream": "^2.0.0",
+            "stream-shift": "^1.0.0"
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.7",
+          "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          },
+          "dependencies": {
+            "safe-buffer": {
+              "version": "5.1.2",
+              "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+              "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+            }
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          },
+          "dependencies": {
+            "safe-buffer": {
+              "version": "5.1.2",
+              "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+              "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+            }
+          }
+        },
+        "ws": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmmirror.com/ws/-/ws-3.3.3.tgz",
+          "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+          "requires": {
+            "async-limiter": "~1.0.0",
+            "safe-buffer": "~5.1.0",
+            "ultron": "~1.1.0"
+          },
+          "dependencies": {
+            "safe-buffer": {
+              "version": "5.1.2",
+              "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+              "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+            }
+          }
+        }
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.nlark.com/wrappy/download/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+    },
+    "xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.nlark.com/xtend/download/xtend-4.0.2.tgz",
+      "integrity": "sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q="
+    }
+  }
+}

+ 15 - 0
package.json

@@ -0,0 +1,15 @@
+{
+    "id": "song-data-picker",
+    "name": "基于DataPicker(uni-data-picker)的带有搜索功能的选择器",
+    "version": "0.1.3",
+    "description": "在uni官方的DataPicker(uni-data-picker)基础上添加搜索功能",
+    "keywords": [
+        "picker",
+        "级联",
+        "省市区",
+        "地址",
+        "搜索"
+    ],
+	"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
+    "dependencies": {}
+}

+ 73 - 0
pages.json

@@ -0,0 +1,73 @@
+{
+	"pages": [
+		{
+			"path": "pages/login/login",//登录
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationBarTextStyle": "white", //导航文字颜色
+				"navigationStyle":"custom"  //关闭原生导航
+			}
+		},
+		// ,
+		// {
+		// 	"path": "pages/mine/mine",//我的
+		// 	"style": {
+		// 		"navigationBarTitleText": "我的",
+		// 		"navigationBarTextStyle": "white", //导航文字颜色
+		// 		"navigationBarBackgroundColor": "#0183FA" //导航背景色
+		// 	}
+		// },
+		// {
+		// 	"path": "pages/information/information",//消息
+		// 	"style": {
+		// 		"navigationBarTitleText": "消息"
+		// 	}
+		// },
+		{
+			"path": "pages/home/home",//首页
+			"style": {
+				"navigationBarTitleText": "实验室安全智能监测与控制系统",
+				"navigationBarTextStyle": "white", //导航文字颜色
+				"navigationBarBackgroundColor": "#0183FA" ,//导航背景色
+				"navigationStyle": "custom"
+			}
+		}
+	],
+	"subPackages": [
+		{
+			/* 供应商端分包 */
+			"root": "pages_supplier",  //分包根路径
+			"name": "supplier", //分包名字可写可不写
+			"pages": [
+				
+			]
+		},
+		{
+			/* 学生端分包 */
+			"root": "pages_student",  //分包根路径
+			"name": "student", //分包名字可写可不写
+			"pages": [
+				
+			]
+		},
+		{/* 管理端分包 */
+			"root": "pages_manage",  //分包根路径
+			"name": "manage", //分包名字可写可不写
+			"pages": [
+				
+			]
+		},
+		{
+			/* 安全检查分包 */
+			"root": "pages_safetyExamine",  //分包根路径
+			"name": "safetyExamine", //分包名字可写可不写
+			"pages": [
+				
+			]
+		}
+	],
+	"globalStyle": {
+		"navigationBarTextStyle": "white", //导航文字颜色
+		"navigationBarBackgroundColor": "#0183FA" //导航背景色
+	}
+}

+ 58 - 0
pages/home/home.vue

@@ -0,0 +1,58 @@
+<template>
+  <view id="home">
+   <manage-home v-if="userType==1" ref="manage"></manage-home>
+<!--    <user-home v-if="userType==2"></user-home>
+    <supplier-home v-if="userType==3"></supplier-home> -->
+    <tab-bar v-if="userType!=3"></tab-bar>
+  </view>
+</template>
+<script>
+import { manageHome } from '@/pages/home/manageWorkbench'
+// import { userHome } from '@/pages/home/studentWorkbench.vue'
+// import { supplierHome } from '@/pages/home/supplierWorkbench.vue'
+import { tabBar } from '@/component/tabBar.vue'
+export default {
+  name: "home",
+  components: {
+    manageHome,
+    // userHome,
+    // supplierHome,
+    tabBar
+  },
+  data() {
+    return {
+      userType:0,
+    }
+  },
+  onLoad() {
+
+  },
+  onShow(){
+    if(uni.getStorageSync('token')&&uni.getStorageSync('userId')&&uni.getStorageSync('userType')){
+      this.userType = uni.getStorageSync('userType')
+    }else{
+      uni.removeStorageSync('token');
+      uni.removeStorageSync('userId');
+      uni.removeStorageSync('userType');
+      uni.redirectTo({
+        url: '/pages/login/login',
+      });
+    }
+  },
+  methods: {
+
+  },
+  onHide(){
+    this.userType = 0;
+  },
+  onUnload(){
+    this.userType = 0;
+  }
+}
+</script>
+
+<style lang="stylus" scoped>
+#home{
+  height:100%;
+}
+</style>

文件差异内容过多而无法显示
+ 1018 - 0
pages/home/manageWorkbench.vue


+ 533 - 0
pages/home/studentWorkbench.vue

@@ -0,0 +1,533 @@
+<!-- 学生端工作台 -->
+<template>
+  <view class="user-workbench" :style="{paddingTop:navHeight+'rpx'}">
+	<nav-bar :title="title"></nav-bar>  
+    <img class="top-big-img" :src="homepageBanner">
+    <view class="min-icon-button-box">
+      <view @click="goPage('casuallyPat')">
+        <img src="@/images/Version2.2/icon_sy_ssp.png">
+        <view>随手拍</view>
+      </view>
+      <view @click="saoCode">
+        <img src="@/images/Version2.2/btn_wd_jfdh.png">
+        <view>积分兑换</view>
+      </view>
+      <view @click="goPage('safeAccess')">
+        <img src="@/images/Version2.2/icon_sy_zrsq.png">
+        <view>准入申请</view>
+      </view>
+      <view @click="goPage('safetyInspect')">
+        <img src="@/images/Version2.2/icon_sy_aqjc.png">
+        <view>安全检查</view>
+      </view>
+      <view @click="goPage('photoInspection')">
+        <img src="@/images/icon_dzt_pzjc.png">
+        <view>离开检查</view>
+      </view>
+      <view @click="goPage('gas')">
+        <img src="@/images/Version3.0/icon_sy_qpgl.png">
+        <view>气瓶管理</view>
+      </view>
+      <view @click="goPage('none')">
+        <img src="@/images/Version3.0/icon_sy_hxp.png">
+        <view>化学品管理</view>
+      </view>
+      <view @click="goPage('none')">
+        <img src="@/images/Version3.0/icon_sy_tzsb.png">
+        <view>特种设备</view>
+      </view>
+    </view>
+    <!-- 分级管控 -->
+    <view class="grading">
+      <img class="grading_l" src="@/images/icon_sy_fjgk.png"/>
+      <view class="grading_c">分级管控</view>
+      <view class="grading_r" @click="goPage('grading')">{{gradingCount>0?gradingCount+'项工作待完成':''}}<img src="@/images/icon_wdwg_gd.png"/></view>
+    </view>
+    <view class="big-icon-button-box">
+      <view class="left-box">
+        <img class="left-top-img" @click="goNull" src="@/images/Version2.2/img_bg_cjcx.png">
+        <img class="left-bottom-img" @click="goPage('meViolation')" src="@/images/Version2.2/img_bg_wgjl.png">
+      </view>
+      <img class="right-img" @click="goNull" src="@/images/Version2.2/img_bg_jfmx.png">
+    </view>
+    <view class="bottom-max-box">
+      <view class="bottom-title">
+        <img src="@/images/Version2.2/icon_sy_wdzs.png">
+        <view>我的证书</view>
+      </view>
+      <view class="bottom-big-box">
+        <view class="bottom-for-box" v-for="(item,index) in dataList" :key="index">
+          <view class="bottom-top-box">{{item.certTitle}}</view>
+          <view class="bottom-bottom-box">
+            <view class="bottom-right-box">{{item.createTime}}获得</view>
+            <view class="bottom-right-box">到期时间:{{item.expirationTime}}</view>
+          </view>
+        </view>
+        <view class="null-view" v-if="!dataList[0]">暂无数据</view>
+      </view>
+    </view>
+    <tab-bar></tab-bar>
+  </view>
+</template>
+
+<script>
+import { myViolationCount,queryMyCert,outSubjectPhoto,gradingControl,getGentleIdentifier} from '@/api/basicsModules/index.js'
+import { tabBar } from '@/component/tabBar.vue'
+import { navBar } from '@/component/navbar.vue'
+export default {
+  components: {
+    tabBar,
+	navBar
+  },
+  data() {
+    return {
+		navHeight: uni.getStorageSync('navHeight'),
+	    title:'实验室安全智能监测与控制系统',		
+		hintType:false,
+		dataList:[],
+		violationData:{},
+		gradingCount:0,
+		homepageBanner:uni.getStorageSync('homepageBanner'),
+    }
+  },
+  created() {
+
+  },
+  mounted(){
+    this.myViolationCount();
+    this.getGrading();
+
+    this.queryMyCert();
+  },
+  methods: {
+    //获取分级管控未完成总数
+    async getGrading(){
+      let obj = {
+
+      }
+      const {data} = await gradingControl(obj)
+      if(data.code==200){
+        this.gradingCount=data.count;
+      }
+
+    },
+    //暂无提示
+    goNull(){
+      uni.showToast({
+        title: '暂未开放',
+        mask:true,
+        icon:"none",
+        duration: 2000
+      });
+    },
+
+    //调用摄像头
+    saoCode(){
+      uni.scanCode({
+        onlyFromCamera: true,
+        success: function (res) {
+          uni.navigateTo({
+            url: '/pages_student/mine/codeSuccess?q='+encodeURIComponent(JSON.stringify(res.result))
+          });
+        }
+      });
+    },
+    // 查询违规记录列表 (用户端)
+    async myViolationCount(){
+      let self = this;
+      let {data} = await myViolationCount()
+      if(data.code == 200){
+        this.violationData = data.data;
+      }
+    },
+    // 查询证书列表 (用户端)
+    async queryMyCert(){
+      let self = this;
+      let {data} = await queryMyCert({})
+      if(data.code == 200){
+        let list = [];
+        for(let i=0;i<data.rows.length;i++){
+          let timeOne = (new Date(data.rows[i].createTime)).getTime();
+          let timeTwo = (new Date(data.rows[i].expirationTime)).getTime();
+          data.rows[i].createTime = self.formatDate(timeOne);
+          data.rows[i].expirationTime = self.formatDate(timeTwo);
+        }
+        this.dataList = data.rows;
+      }
+    },
+    formatDate(date) {
+      let newDate = new Date(date);
+      let YY = newDate.getFullYear() + '-';
+      let MM = (newDate.getMonth() + 1 < 10 ? '0' + (newDate.getMonth() + 1) : newDate.getMonth() + 1) + '-';
+      let DD = (newDate.getDate() < 10 ? '0' + (newDate.getDate()) : newDate.getDate());
+      return YY + MM + DD;
+    },
+    //页面跳转
+    goPage(type){
+      if(type == 'meViolation'){//我的违规
+        uni.navigateTo({
+          url: '/pages_student/workbench/meViolation',
+        });
+      }else if(type == 'photoInspection'){//离开检查
+        this.outSubjectPhoto();
+      }else if(type == 'resultInquiry'){//成绩查询
+        uni.navigateTo({
+          url: '/pages_student/workbench/resultInquiry',
+        });
+      }else if(type == 'casuallyPat'){//随手拍
+        uni.navigateTo({
+          url: '/pages/casuallyPat',//随手拍
+        });
+      }else if(type == 'safeAccess'){//安全准入
+        uni.navigateTo({
+          url: '/pages_student/workbench/safeAccess/safeAccess',
+        });
+      }else if(type == 'examList'){//在线考试
+        uni.navigateTo({
+          url: '/pages_student/workbench/exam/examList',
+        });
+      }else if(type == 'grading'){
+        uni.navigateTo({
+          url: '/pages_student/gradingControl/gradingControl',//分级管控
+        });
+      }else if(type == 'safetyInspect'){//安全检查
+
+		this.getGentleIdentifier();
+        // uni.navigateTo({
+        //   url: '/pages_manage/workbench/problemRectification/rectifyList',//安全检查
+        // });
+		
+      }else if(type == 'gas'){//气瓶管理
+        uni.navigateTo({
+          url: '/pages_student/gasManage/gasManage',
+        });
+      }else if(type == 'none'){
+		  uni.showToast({
+		    title: '暂未开放',
+		    icon:"none",
+		    mask:true,
+		    duration: 2000
+		  });
+	  }
+    },
+    //获取拍照检查配置
+    async outSubjectPhoto(){
+      const {data} = await outSubjectPhoto();
+      if(data.code == 200){
+        if(data.data == null){
+          //需要检查(重新填写)
+          let obj = {
+            sub:"实验室照片",
+            subUrl:"",
+            garbage:"垃圾桶清理后照片",
+            garbageUrl:"",
+            dangerous:"使用危险设备照片(选填)",
+            dangerousUrl:"",
+            sourceRisk:"危险源设备使用登记本照片(选填)",
+            sourceRiskUrl:"",
+          };
+          uni.navigateTo({
+            url: '/pages_student/workbench/photoInspection?newData='+encodeURIComponent(JSON.stringify(obj)),
+          });
+        }else if(data.data == false){
+          //不需要检查
+          uni.showToast({
+            title: '暂无检查数据',
+            icon:"none",
+            mask:true,
+            duration: 2000
+          });
+        }else{
+          //需要检查(修改内容)
+          let obj = {
+            id:data.data.id,
+            sub:"实验室照片",
+            subUrl:data.data.subUrl,
+            garbage:"垃圾桶清理后照片",
+            garbageUrl:data.data.garbageUrl,
+            dangerous:"使用危险设备照片(选填)",
+            dangerousUrl:data.data.dangerousUrl,
+            sourceRisk:"危险源设备使用登记本照片(选填)",
+            sourceRiskUrl:data.data.sourceRiskUrl,
+          };
+          uni.navigateTo({
+            url: '/pages_student/workbench/photoInspection?newData='+encodeURIComponent(JSON.stringify(obj)),
+          });
+        }
+      }
+    },
+	//获取用户身份标识"adminGentle": false,   管理员身份 "rectifyGentle": false,   整改身份"applyGentle": false    检查者身份
+	async getGentleIdentifier(){
+		let self = this;
+		const {data} = await getGentleIdentifier();
+		if(data.code==200){
+			let pageType = null
+		  // 如果是管理员 检查者和整改者 
+		  if(data.data.adminGentle && (data.data.applyGentle || data.data.myApplyGentle) && data.data.rectifyGentle){
+			  pageType=1
+		  }else if(data.data.adminGentle && (data.data.applyGentle || data.data.myApplyGentle) && !data.data.rectifyGentle){
+			  pageType=1
+		  }else if(data.data.adminGentle && !data.data.applyGentle && data.data.rectifyGentle){
+			  pageType=1
+		  }else if(!data.data.adminGentle && (data.data.applyGentle || data.data.myApplyGentle) && data.data.rectifyGentle){
+			  pageType=2
+		  }else if(data.data.adminGentle && !data.data.applyGentle && !data.data.rectifyGentle){
+			  pageType=1
+		  }else if(!data.data.adminGentle && (data.data.applyGentle || data.data.myApplyGentle) && !data.data.rectifyGentle){
+			  pageType=2
+		  }else if(!data.data.adminGentle && !data.data.applyGentle && data.data.rectifyGentle){
+			  pageType=3
+		  }
+		  uni.setStorageSync('gentleIdentifier',pageType)
+		  uni.setStorageSync('gentleIdentifierData',data.data)
+		  if(pageType){
+			  uni.navigateTo({
+			    url: '/pages/safetyExamineWorkbench',
+			  });
+		  }else{
+			  uni.showToast({
+				title: '没有相关权限',
+				icon:"none",
+				mask:true,
+				duration: 2000
+			  });
+		  }
+		}
+	},
+  }
+}
+</script>
+
+<style lang="stylus" scoped>
+.user-workbench{
+  height:100%;
+  flex:1;
+  box-sizing: border-box;
+  .top-big-img{
+    height:342rpx;
+    width:750rpx;
+    background :#ffffff;
+  }
+  .min-icon-button-box{
+    display flex;
+    justify-content: flex-start;
+    flex-wrap: wrap;
+    width:710rpx;
+    margin:20rpx;
+    background :#ffffff;
+    border-radius:20rpx;
+    padding-bottom: 20rpx;
+    view{
+      width: 176rpx;
+      img{
+        height:75rpx;
+        width:75rpx;
+        margin:30rpx auto 10rpx;
+      }
+      view{
+        text-align center
+        font-size:24rpx;
+      }
+    }
+  }
+  /* 分级管控 */
+  .grading{
+    width :712rpx;
+    height :80rpx;
+    background: #FFFFFF;
+    border-radius: 20rpx;
+    margin-left:20rpx;
+    margin-bottom :20rpx;
+    display:flex;
+    justify-content :flex-start;
+    align-items :center;
+    .grading_l{
+      width :34rpx;
+      height :34rpx;
+      margin-left:16rpx;
+    }
+    .grading_c{
+      font-size: 28rpx;
+      font-family: PingFang SC;
+      font-weight: 500;
+      color: #333333;
+      margin-left:16rpx;
+    }
+    .grading_r{
+      width :504rpx;
+      height :80rpx;
+      font-size: 26rpx;
+      font-family: PingFang SC;
+      font-weight: 500;
+      color: #EE3A3A;
+      display :flex;
+      justify-content :flex-end;
+      align-items: center;
+      >img{
+        width: 20rpx;
+        height: 20rpx;
+        margin-left :20rpx;
+        margin-top :8rpx;
+      }
+    }
+  }
+
+  .big-icon-button-box{
+    width:710rpx;
+    height:354rpx;
+    margin:0 20rpx 20rpx;
+    background :#ffffff;
+    border-radius:20rpx;
+    display flex
+    .left-box{
+      width:310rpx;
+      height:310rpx;
+      margin:22rpx 10rpx 22rpx 15rpx;
+      .left-top-img{
+        width:310rpx;
+        height:150rpx;
+        margin-bottom:14rpx;
+      }
+      .left-bottom-img{
+        width:310rpx;
+        height:150rpx;
+      }
+    }
+    .right-img{
+      width:362rpx;
+      height:310rpx;
+      margin:22rpx 13rpx 22rpx 0;
+    }
+  }
+  .top-max-box{
+    height:119rpx;
+    background #fff
+    overflow hidden
+    .top-big-box{
+      height:60rpx;
+      width:649rpx;
+      background: #F5F5F5;
+      border-radius: 30px;
+      margin:30rpx auto;
+      padding:0 30rpx;
+    }
+    .top-big-one-type{
+      color:#F95F5F;
+      line-height:60rpx;
+      font-size: 26rpx;
+    }
+    .top-big-two-type{
+      line-height:60rpx;
+      font-size: 26rpx;
+      display flex
+      .left-view{
+        flex:1;
+        display flex
+        color:#333;
+        .left-min-view{
+          color:#e45656;
+        }
+      }
+      .left-button-view{
+        color:#0183fa;
+      }
+    }
+  }
+  .button-max-box{
+    /*height:446rpx;*/
+    background #fff
+    margin-bottom:20rpx;
+    .button-title{
+      line-height:100rpx;
+      border-bottom:1rpx solid #E0E0E0;
+      padding-left:20rpx;
+    }
+    .button-max-box{
+      /*height:345rpx;*/
+      .button-min-box{
+        width:250rpx;
+        height:172rpx;
+        display inline-block
+        img{
+          width:80rpx;
+          height:80rpx;
+          margin:34rpx auto 0;
+        }
+        view{
+          line-height:50rpx;
+          text-align center;
+          font-size:28rpx;
+          color: #333;
+        }
+      }
+    }
+  }
+  .bottom-max-box{
+    flex:1;
+    background #fff
+    margin:0 20rpx 100rpx;
+    border-radius:20rpx;
+    display flex
+    flex-direction column
+    overflow-y hidden
+    .bottom-title{
+      display flex
+      border-bottom:1rpx solid #E0E0E0;
+      img{
+        width:34rpx;
+        height:34rpx;
+        margin:35rpx 16rpx 0 10rpx;
+      }
+      view{
+        line-height:100rpx;
+      }
+    }
+    .bottom-big-box{
+      flex:1;
+      overflow-y scroll
+      .bottom-for-box:nth-child(1){
+        border:none;
+      }
+      .bottom-for-box{
+        height:154rpx;
+        margin:0 20rpx;
+        border-top:1rpx solid #E0E0E0;
+        overflow hidden
+        .bottom-top-box{
+          font-size:28rpx;
+          line-height:28rpx;
+          color:#333;
+          display:block;
+          overflow:hidden;
+          text-overflow:ellipsis;
+          white-space:nowrap;
+          margin:36rpx 0 30rpx;
+        }
+        .bottom-bottom-box{
+          display flex
+          view{
+            flex:1;
+            line-height:48rpx;
+            font-size: 28rpx;
+            color: #999999;
+            display:block;
+            overflow:hidden;
+            text-overflow:ellipsis;
+            white-space:nowrap;
+          }
+          view:nth-child(2){
+            text-align right
+          }
+
+        }
+      }
+      .null-view{
+        text-align center;
+        color:#999;
+        line-height:80rpx;
+        font-size:28rpx;
+      }
+    }
+  }
+}
+</style>

+ 445 - 0
pages/home/supplierWorkbench.vue

@@ -0,0 +1,445 @@
+<!-- 整改列表 -->
+<template>
+  <view class="supplier" style="display: flex;flex-direction: column;flex: 1;">
+    <view v-if="pageType==0">
+      <view class="supplier_h" @click="handleClick('mine')">
+        <img src="@/images/Version3.0/img_gysglpt_bg.png">
+        <img src="@/images/Version3.0/img_gysglpt_icom.png">
+        <img src="@/images/Version3.0/icon_gyspt_gd.png">
+        <view>{{form.companyName}}</view>
+      </view>
+      <view class="supplier_tab">
+        <view class="supplier_tab_li" @click="handleClick('people')">
+          <text>{{form.peopleSum}}</text>
+          <text>运输人员</text>
+        </view>
+        <view class="supplier_tab_line"></view>
+        <view class="supplier_tab_li" @click="handleClick('car')">
+          <text>{{form.carSum}}</text>
+          <text>运输车辆</text>
+        </view>
+        <view class="supplier_tab_line"></view>
+        <view class="supplier_tab_li" @click="handleClick('bottle')">
+          <text>{{form.bottleSum}}</text>
+          <text>气瓶管理</text>
+        </view>
+      </view>
+      <scroll-view scroll-y @scrolltolower="scrollGet" class="for-max-box">
+        <view class="for-big-box">
+          <view class="backlog" @click="handleClick('backlog')">
+            <img class="backlog_l" src="@/images/Version3.0/icon_glpt_dbqd.png">
+            <view class="backlog_c">待办清单</view>
+            <img class="backlog_r"  src="@/images/icon_wdwg_gd.png">
+          </view>
+          <view class="for-box" @click="goInfo(item)" v-for="(item,index) in dataList" :key="index">
+            <view class="for-title-box">
+              <view v-if="item.remark=='gq'"  class="viewColor1">供气</view>
+              <view v-if="item.remark=='hs'" class="viewColor3">回收</view>
+              <view v-if="item.remark=='wt'" class="viewColor2">问题</view>
+              <view v-if="item.remark=='hs' || item.remark=='wt'">{{item.airName}}-{{item.configName}}</view>
+              <view  v-if="item.remark=='gq'" ><text v-for="(item2,index2) in item.detailListVO" :key="index2" v-if="index2<2">{{item2.airName}}-{{item2.configName}}*{{item2.bottleNumber}}<text>{{index2<1?' ':'...'}}</text></text></view>
+            </view>
+            <view class="for-address-box">
+              <img src="@/images/Version2.2/icon_wtzg_xx.png">
+              <view >{{item.campus}}-{{item.building}}-{{item.room}}</view>
+            </view>
+            <view class="for-time-box">
+              <img src="@/images/Version2.2/icon_wtzg_sj.png">
+              <view>{{item.createTime}}</view>
+            </view>
+          </view>
+        </view>
+        <img class="null-img" v-if="!dataList[0]" src="@/images/null-data-1.png">
+      </scroll-view>
+      <img class="supernatant"  @click="handleClick('recycle')"  src="@/images/Version3.0/icon_glpt_gqhsjl.png">
+    </view>
+    <view class="empty" v-if="emptyList==4 && pageType==0">
+      <img class="for-back-img" src="@/images/Version3.0/img_ysrygl_zwsj.png">
+      <view>暂无数据</view>
+    </view>
+    <hasten-page v-if="pageType==1"></hasten-page>
+    <reject-page v-if="pageType==2" :infoData="infoData"></reject-page>
+    <forbidden-page v-if="pageType==3"></forbidden-page>
+  </view>
+
+</template>
+
+<script>
+import { config } from '@/api/request/config.js'
+import { supplierDetail,storageListTaskIndex} from '@/api/basicsModules/index.js'
+import { hastenPage } from '@/pages/supplier/mine/hasten.vue'
+import { rejectPage } from '@/pages/supplier/mine/reject.vue'
+import { forbiddenPage } from '@/pages/supplier/mine/forbidden.vue'
+export default {
+  name: "rectifyList",
+  components: {
+    hastenPage,//供应商正在审核
+    rejectPage,//供应商驳回
+    forbiddenPage,//供应商停用
+  },
+  data() {
+    return {
+      emptyList:0,
+      pageType:4,
+      dataList:[],
+      //列表请求参数
+      getData:{
+        pageNum:1,
+        pageSize:5,
+      },
+      form:{
+        companyName:'',//企业名称
+        peopleSum:'0',//人员数量总数
+        carSum:'0',//运输车辆总数
+        bottleSum:'0',//气瓶数量总数
+      },
+      infoData:'',//驳回原因
+      state:'',
+    }
+  },
+  onLoad() {
+
+  },
+  onShow() {
+
+    this.infoList=[];
+
+  },
+  mounted(){
+    this.getInfo();
+    this.getList();
+  },
+  methods: {
+    //滚动加载事件
+    scrollGet(){
+      if(this.getData.getType){
+        this.getData.page += 1;
+        this.getList();
+      }
+    },
+    goInfo(d){
+      if(d.remark=='gq'){
+        uni.navigateTo({
+          url:'/pages_supplier/backlogManage/backlogManageAirDetail?item='+encodeURIComponent(JSON.stringify(d))
+        });
+      }else if(d.remark=='hs'){
+        uni.navigateTo({
+          url:'/pages_supplier/backlogManage/backlogManageRecycleDetail?item='+encodeURIComponent(JSON.stringify(d))
+        });
+      }else if(d.remark=='wt'){
+        uni.navigateTo({
+          url:'/pages_supplier/backlogManage/backlogManageIssueDetail?item='+encodeURIComponent(JSON.stringify(d))
+        });
+      }
+
+    },
+    handleClick(doType) {
+      if(doType=='people'){
+        uni.navigateTo({
+          url:'/pages_supplier/transportPerson/transportPerson'
+        });
+      }else if(doType=='car'){
+        uni.navigateTo({
+          url:'/pages_supplier/transportCar/transportCar'
+        });
+      }else if(doType=='bottle'){
+        uni.navigateTo({
+          url:'/pages_supplier/gasManage/gasManage'
+        });
+      }else if(doType=='mine'){
+        uni.navigateTo({
+          url: '/pages_supplier/mine/mine?state='+this.state
+        });
+      }else if(doType=='backlog'){//待办清单
+        uni.navigateTo({
+          url:'/pages_supplier/backlogManage/backlogManage'
+        });
+      }else if(doType=='recycle'){//供气回收
+        uni.navigateTo({
+          url:'/pages_supplier/gasRecycle/gasRecycle'
+        });
+      }
+
+
+    },
+    //获取首页详情
+    async getInfo(){
+      let _this = this;
+      const {data} = await supplierDetail()
+      let res=data.data
+      if(data.code==200){
+        this.state=res.state;
+        if(res.state==0){//审核状态(0:未审核,1:审核通过,2:审核未通过)
+          this.pageType=1;
+        }else if(res.state==1){
+          this.pageType=0;
+        }else if(res.state==2){
+          this.pageType=2;
+          this.infoData=res.audit.auditContent//驳回原因
+        }
+        this.form.companyName=res.companyName
+        this.form.peopleSum=res.peopleSum
+        this.form.carSum=res.carSum
+        this.form.bottleSum=res.bottleSum
+
+      }else if(data.code==500){//资格状态status(0:启用,1:停用)
+        this.pageType=3;
+      }
+    },
+    //获取列表数据
+    async getList(){
+      let _this = this;
+      const {data} = await storageListTaskIndex(_this.getData);
+      if(data.code==200){
+        let res=data.rows;
+        _this.dataList=res;
+        if(_this.dataList.length<=0){
+          _this.emptyList=4
+        }
+      }
+    },
+  }
+}
+</script>
+
+<style lang="stylus" scoped>
+.empty{
+  text-align: center;
+  margin-top: 116rpx;
+  >img{
+    width: 336rpx;
+    height: 222rpx;
+    margin-left: 208rpx;
+  }
+  >view{
+    font-size: 30rpx;
+    font-family: PingFang SC;
+    font-weight: 500;
+    color: #E0E0E0;
+    line-height: 30rpx;
+    margin-top: 48rpx;
+  }
+}
+.supplier{
+  .supplier_h{
+    width: 750rpx;
+    height: 200rpx;
+    position: relative;
+    >img:nth-child(1){
+      width: 750rpx;
+      height: 200rpx;
+      position: absolute;
+      left: 0;
+      top: 0;
+    }
+    >img:nth-child(2){
+      width: 110rpx;
+      height: 110rpx;
+      position: absolute;
+      left: 18rpx;
+      top: 44rpx;
+    }
+    >img:nth-child(3){
+      width: 12rpx;
+      height: 24rpx;
+      position: absolute;
+      left: 716rpx;
+      top: 92rpx;
+    }
+    >view{
+      width: 550rpx;
+      font-size: 30rpx;
+      font-family: PingFang SC;
+      font-weight: 500;
+      color: #FFFFFF;
+      line-height: 30rpx;
+      position: absolute;
+      left: 164rpx;
+      top: 84rpx;
+    }
+  }
+  .supplier_tab{
+    width: 710rpx;
+    height: 180rpx;
+    background: #FFFFFF;
+    border-radius: 10rpx;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin: 20rpx 20rpx 0;
+    .supplier_tab_line{
+      width: 2rpx;
+      height: 30rpx;
+      background: #E0E0E0;
+    }
+    .supplier_tab_li{
+      flex: 1;
+      text-align: center;
+      >text{
+        display: block;
+      }
+      >text:nth-child(1){
+        font-size: 30rpx;
+        font-family: PingFang SC;
+        font-weight: 500;
+        color: #0183FA;
+        line-height: 30rpx;
+      }
+      >text:nth-child(2){
+        font-size: 30rpx;
+        font-family: PingFang SC;
+        font-weight: 500;
+        color: #333333;
+        line-height: 30rpx;
+        margin-top: 36rpx;
+      }
+    }
+  }
+  /* 列表 */
+  .for-max-box{
+    flex:1;
+    overflow-y scroll;
+    .for-big-box{
+      background:#fff;
+      border-radius:20rpx;
+      margin:20rpx;
+      .backlog{
+        height: 100rpx;
+        display: flex;
+        justify-content: flex-start;
+        align-items: center;
+        .backlog_l{
+          width: 34rpx;
+          height: 32rpx;
+          margin-left:20rpx;
+        }
+        .backlog_c{
+          font-size: 30rpx;
+          font-family: PingFang SC;
+          font-weight: 500;
+          color: #333333;
+          line-height: 30rpx;
+          margin-left:16rpx;
+        }
+        .backlog_r{
+          width: 24rpx;
+          height: 24rpx;
+          margin-left:472rpx;
+        }
+
+      }
+      .for-box:nth-child(1){
+        .for-title-box{
+          border:none;
+        }
+      }
+      .for-box{
+        overflow hidden
+        .for-title-box{
+          display:flex;
+          margin:0 26rpx 0;
+          border-top:1rpx solid #dedede;
+          padding-top:45rpx;
+          view:nth-child(1){
+            width:98rpx;
+            line-height:38rpx;
+            height:38rpx;
+            border-radius:6rpx;
+            font-size:20rpx;
+            text-align center;
+            margin-right:10rpx;
+          }
+          view:nth-child(2){
+            flex:1;
+            font-size:30rpx;
+            color:#333;
+            height:36rpx;
+            lin-height:36rpx;
+            margin-right:10rpx;
+            display:block;
+            overflow:hidden;
+            text-overflow:ellipsis;
+            white-space:nowrap;
+          }
+          view:nth-child(3){
+            font-size:30rpx;
+            color:#333;
+            height:36rpx;
+            lin-height:36rpx;
+            color:#D80000;
+          }
+          .viewColor1{
+            background #ffe6e6;
+            color:#ff5555;
+          }
+          .viewColor2{
+            background #fef2dd;
+            color:#f6a71d;
+          }
+          .viewColor3{
+            background #e0f1e2;
+            color:#30a23d;
+          }
+          .viewColor4{
+            background #f2dddd;
+            color:#a51919;
+          }
+          .viewColor5{
+            background #e2f6f8;
+            color:#3ac3d3;
+          }
+          .viewColor6{
+            background #d9edfe;
+            color:#0183fa;
+          }
+        }
+        .for-address-box{
+          display:flex;
+          margin:33rpx 26rpx 0;
+          img{
+            width:28rpx;
+            height:28rpx;
+            margin-right:20rpx;
+          }
+          view{
+            font-size:28rpx;
+            line-height:28rpx;
+            color:#666;
+          }
+        }
+        .for-time-box{
+          display:flex;
+          margin:26rpx 26rpx 0;
+          padding-bottom:32rpx;
+          img{
+            width:28rpx;
+            height:28rpx;
+            margin-right:20rpx;
+          }
+          view{
+            font-size:28rpx;
+            line-height:28rpx;
+            color:#666;
+          }
+        }
+      }
+    }
+    .null-img{
+      display block
+      width:276rpx;
+      height:321rpx;
+      position absolute
+      top:100rpx;
+      left:274rpx;
+    }
+  }
+  /* 供求回收记录 */
+  .supernatant{
+    width: 152rpx;
+    height: 152rpx;
+    position: fixed;
+    right: 0rpx;
+    bottom: 60rpx;
+  }
+}
+</style>

+ 249 - 0
pages/information/information.vue

@@ -0,0 +1,249 @@
+<!-- 消息 -->
+<template>
+	<view id="information">
+		<scroll-view scroll-y @scrolltolower="scrollGet" class="info-max-box">
+			<view class="for-info-box" v-for="(item,index) in infoList" :key="index" @click="goInfoPage(item)">
+				<img v-if='item.isApply==1' src="@/images/icon_xx_tz.png">
+				<img v-if='item.isApply==2' src="@/images/icon_xx_tz.png">
+				<img v-if='item.isApply!=1 && item.isApply!=2' src="@/images/icon_01.png">
+				<view class="right-box">
+					<view class="top-box">
+						<view>{{item.isApply==1?'准入驳回':(item.isApply==2?item.remark:
+						(item.isApply==3||item.isApply==-1?item.sendName:(item.isApply==4||item.isApply==5?item.remark:'')))}}</view>
+						<view>{{item.isApply==1?item.subName:(item.isApply==2?'':
+						(item.isApply==3||item.isApply==-1?item.deptName:(item.isApply==4||item.isApply==5?'':'')))}}</view>
+						<view>{{item.newMessageDate}}</view>
+					</view>
+					<view class="bottom">{{item.newMessage}}</view>
+				</view>
+			</view>
+			<view class="get-null-box" v-if="getData.nullDataType">暂无更多数据</view>
+		</scroll-view>
+		<tab-bar ref='infoAll'></tab-bar>
+	</view>
+</template>
+
+<script>
+    import { groupList,queryByMessage } from '@/api/index.js'
+    import { tabBar } from '@/component/tabBar.vue'
+	export default {
+        components: {
+            tabBar
+        },
+		data() {
+			return {
+				infoList:[],
+				//列表请求参数
+				getData:{
+				    page:1,
+					pageSize:20,
+                    getType:true,
+                    nullDataType:true,
+				}
+			}
+		},
+		onLoad() {
+
+		},
+		onShow(){
+
+            this.clearData();
+            this.getList();
+            this.$refs.infoAll.getTotalList();
+
+		},
+		methods: {
+            //清除
+            clearData(){
+                this.infoList = [];
+                this.getData.page = 1;
+                this.getData.getType = true;
+                this.getData.nullDataType = true;
+            },
+            //去消息详情页面
+            goInfoPage(item){
+
+				if(item.isApply==1){
+
+					uni.navigateTo({
+					    url:'/pages/information/notPassInfo?item='+encodeURIComponent(JSON.stringify(item))
+					})
+				}else if(item.isApply==2){
+					uni.navigateTo({
+					    url: '/pages_manage/workbench/receiveCasuallyPat/casuallyPatInfo?item='+encodeURIComponent(JSON.stringify(item))
+					});
+				}else if(item.isApply==3 || item.isApply == -1){
+					uni.navigateTo({
+					    url:'/pages/information/informationInfo?item='+encodeURIComponent(JSON.stringify(item))
+					})
+				}else if(item.isApply==4){
+					//记录详情-未执行  dynamicId       4
+					let obj = {
+						messageUserId:item.messageUserId,
+						recordId:item.dynamicId
+					}
+					uni.navigateTo({
+					    url:'/pages_manage/gradingControl/gradingControlDetail?item='+encodeURIComponent(JSON.stringify(obj))
+					})
+				}else if(item.isApply==5){
+					//完成控制-页面   messageContext    5
+					let obj = JSON.parse(item.messageContext);
+					this.queryByMessage(obj,item.messageUserId)
+					// obj.messageUserId = item.messageUserId
+					// uni.navigateTo({
+					//     url:'/pages/gradingControl/gradingControlAdd?obj='+encodeURIComponent(JSON.stringify(obj))
+					// })
+				}
+            },
+			async queryByMessage(obj,messageUserId){
+				const {data} = await queryByMessage(obj);
+				if(data.code == 200){
+					uni.navigateTo({
+						url:'/pages_manage/gradingControl/gradingControlAdd?item='+encodeURIComponent(JSON.stringify(data.data))+'&item2='+encodeURIComponent(JSON.stringify(data.data.detailList[0]))+'&messageUserId='+messageUserId
+					})
+				}
+			},
+            //滚动事件
+            scrollGet(){
+                if(this.getData.getType){
+                    this.getData.page += 1;
+                    this.getList();
+                }
+            },
+            //获取列表数据
+            async getList(){
+                let self = this;
+                let obj = {
+                    pageNum:this.getData.page,
+                    pageSize:this.getData.pageSize,
+                };
+                const {data} = await groupList(obj);
+                if(data.code==200){
+                    let newDataList = data.rows;
+                    for(let i=0;i<newDataList.length;i++){
+                        if(!newDataList[i].newMessageDate || newDataList[i].newMessageDate == null){
+                            newDataList[i].newMessageDate = '';
+						}else{
+                            let timeOne = (new Date(newDataList[i].newMessageDate)).getTime();
+                            newDataList[i].newMessageDate = self.formatDate(timeOne);
+                            newDataList[i].newMessage = unescape(newDataList[i].newMessage);
+                            let reg1 = RegExp(/<img/);
+                            let reg2 = RegExp(/<iframe/);
+                            if(newDataList[i].newMessage.match(reg1)){
+                                newDataList[i].newMessage = "[图片]"
+                            }if(newDataList[i].newMessage.match(reg2)){
+                                newDataList[i].newMessage = "[视频]"
+                            }else{
+                                newDataList[i].newMessage=newDataList[i].newMessage.replace(/<\/?.+?>/g,"");
+                            }
+						}
+					}
+                    if(self.page==1){
+                        if(data.rows.length > 0 && data.rows.length == self.getData.pageSize){
+                            self.infoList = data.rows;
+                        }else if(data.rows.length > 0 && data.rows.length != self.getData.pageSize){
+                            self.infoList = data.rows;
+                            self.getData.getType = false;
+                            self.getData.nullDataType = true;
+                        }else{
+                            self.getData.getType = false;
+                            self.getData.nullDataType = true;
+                        }
+                    }else{
+                        if(data.rows.length > 0 && data.rows.length == self.getData.pageSize){
+                            self.infoList = self.infoList.concat(data.rows)
+                        }else if(data.rows.length > 0 && data.rows.length != self.getData.pageSize){
+                            self.infoList = self.infoList.concat(data.rows);
+                            self.getData.getType = false;
+                            self.getData.nullDataType = true;
+                        }else{
+                            self.getData.getType = false;
+                            self.getData.nullDataType = true;
+                        }
+                    }
+                }
+            },
+            formatDate(date) {
+                let newDate = new Date(date);
+                let YY = newDate.getFullYear() + '-';
+                let MM = (newDate.getMonth() + 1 < 10 ? '0' + (newDate.getMonth() + 1) : newDate.getMonth() + 1) + '-';
+                let DD = (newDate.getDate() < 10 ? '0' + (newDate.getDate()) : newDate.getDate());
+                return YY + MM + DD;
+            },
+		}
+	}
+</script>
+
+<style lang="stylus" scoped>
+	#information{
+		height:100%;
+		display flex
+		background #fff
+		.info-max-box{
+			flex:1;
+			overflow: scroll
+			padding-bottom:100rpx;
+			background #fff
+			margin:0 20rpx;
+			.for-info-box:nth-child(1){
+				border:none;
+			}
+			.for-info-box{
+				height:150rpx;
+				border-top:1rpx solid #F5F5F5;
+				display flex
+				img{
+					border-radius:50%;
+					margin:25rpx 28rpx 25rpx 20rpx;
+					width:100rpx;
+					height:100rpx;
+				}
+				.right-box{
+					flex:1;
+					.top-box{
+						display flex
+						line-height:67rpx;
+						margin-top:7rpx;
+						view:nth-child(1){
+							font-size:30rpx;
+							color:#333333;
+							margin-right:28rpx;
+						}
+						view:nth-child(2){
+
+							font-size:24rpx;
+							color:#CCCCCC;
+							flex:1;
+							white-space:nowrap;
+							overflow:hidden;
+							text-overflow:ellipsis;
+
+
+						}
+						view:nth-child(3){
+							font-size:20rpx;
+							color:#CCCCCC;
+							text-align right;
+						}
+					}
+					.bottom{
+						width:530rpx;
+						line-height:62rpx;
+						font-size:25rpx;
+						color: #666666;
+						display block
+						overflow:hidden;
+						text-overflow:ellipsis;
+						white-space:nowrap;
+					}
+				}
+			}
+			.get-null-box{
+				height:100rpx;
+				line-height:100rpx;
+				color:#999;
+				text-align center
+			}
+		}
+	}
+</style>

+ 194 - 0
pages/information/informationInfo.vue

@@ -0,0 +1,194 @@
+<!-- 测试 -->
+<template>
+    <view id="informationInfo">
+        <scroll-view scroll-y @scrolltolower="scrollGet" class="info-max-box">
+            <view class="for-info-box" v-for="(item,index) in infoList" :key="index">
+                <view class="title-time">{{item.createTime}}</view>
+                <view class="for-min-box">
+                    <view>通知</view>
+                    <rich-text :nodes="item.meaasgeContext"></rich-text>
+                </view>
+            </view>
+			<!-- <view class="for-info-box" v-if="itemData.isApply==-1">
+			    <view class="title-time">{{itemData.deptName}}</view>
+			    <view class="for-min-box">
+			        <view>通知</view>
+			        <rich-text :nodes="itemData.newMessage"></rich-text>
+			    </view>
+			</view> -->
+            <view class="get-null-box" v-if="getData.nullDataType &&itemData.isApply!=-1">暂无更多数据</view>
+        </scroll-view>
+    </view>
+</template>
+
+<script>
+    import { groupIdList,groupListRead} from '@/api/index.js'
+    export default {
+        data() {
+            return {
+                //列表请求参数
+                getData:{
+                    page:1,
+                    pageSize:20,
+                    getType:true,
+                    nullDataType:true,
+                },
+                itemData:{},
+                infoList:[]
+            }
+        },
+        onLoad(option) {
+            this.itemData = JSON.parse(decodeURIComponent(option.item));
+			
+            //修改页面title
+            if(this.itemData.sendUserId == '-2'){
+                uni.setNavigationBarTitle({
+                    title:this.itemData.sendName
+                });
+            }else if(this.itemData.isApply==-1){
+				this.getRead()
+			}else{
+                uni.setNavigationBarTitle({
+                    title:this.itemData.sendName+'-'+this.itemData.deptName
+                });
+            }
+            this.getList();
+        },
+        methods: {
+            //清除
+            clearData(){
+                this.infoList = [];
+                this.getData.page = 1;
+                this.getData.getType = true;
+                this.getData.nullDataType = true;
+            },
+            //滚动事件
+            scrollGet(){
+                if(this.getData.getType){
+                    this.getData.page += 1;
+                    this.getList();
+                }
+            },
+			async getRead() {
+				let self = this;
+				const {data} = await groupListRead({messageId:this.itemData.messageId})
+				if(data.code==200){
+					
+				}
+			},
+            //获取列表数据
+            async getList(){
+                let self = this;
+                let obj = {
+                    pageNum:this.getData.page,
+                    pageSize:this.getData.pageSize,
+                };
+                const {data} = await groupIdList(this.itemData.sendUserId,obj);
+                if(data.code==200){
+                    let newDataList = data.rows;
+                    for(let i=0;i<newDataList.length;i++){
+                        let list = [];
+                        if(!newDataList[i].createTime || newDataList[i].createTime == null){
+                            newDataList[i].createTime = '';
+                        }else{
+                            list = newDataList[i].createTime.split(' ');
+                            newDataList[i].createTime = list[0];
+                        }
+                        newDataList[i].meaasgeContext = unescape(newDataList[i].meaasgeContext);
+						newDataList[i].meaasgeContext = newDataList[i].meaasgeContext.replace(/<p([\s\w"=\/\.:;]+)((?:(style="[^"]+")))/ig, '<p')
+														.replace(/<p>/ig, '<p style="font-size: 15px; line-height: 25px;">')
+														.replace(/<img([\s\w"-=\/\.:;]+)((?:(height="[^"]+")))/ig, '<img$1')
+														.replace(/<img([\s\w"-=\/\.:;]+)((?:(width="[^"]+")))/ig, '<img$1')
+														.replace(/<img([\s\w"-=\/\.:;]+)((?:(style="[^"]+")))/ig, '<img$1')
+														.replace(/<img([\s\w"-=\/\.:;]+)((?:(alt="[^"]+")))/ig, '<img$1')
+														.replace(/<img([\s\w"-=\/\.:;]+)/ig, '<img style="width: 100%;" $1');
+                    }
+                    if(self.page==1){
+                        if(newDataList.length > 0 && newDataList.length == self.getData.pageSize){
+                            self.infoList = newDataList;
+                        }else if(newDataList.length > 0 && newDataList.length != self.getData.pageSize){
+                            self.infoList = newDataList;
+                            self.getData.getType = false;
+                            self.getData.nullDataType = true;
+                        }else{
+                            self.getData.getType = false;
+                            self.getData.nullDataType = true;
+                        }
+                    }else{
+                        if(newDataList.length > 0 && newDataList.length == self.getData.pageSize){
+                            self.infoList = self.infoList.concat(newDataList)
+                        }else if(newDataList.length > 0 && newDataList.length != self.getData.pageSize){
+                            self.infoList = self.infoList.concat(newDataList);
+                            self.getData.getType = false;
+                            self.getData.nullDataType = true;
+                        }else{
+                            self.getData.getType = false;
+                            self.getData.nullDataType = true;
+                        }
+                    }
+                }
+            },
+            formatDate(date) {
+                let newDate = new Date(date);
+                let YY = newDate.getFullYear() + '-';
+                let MM = (newDate.getMonth() + 1 < 10 ? '0' + (newDate.getMonth() + 1) : newDate.getMonth() + 1) + '-';
+                let DD = (newDate.getDate() < 10 ? '0' + (newDate.getDate()) : newDate.getDate());
+                return YY + MM + DD;
+            },
+        }
+    }
+</script>
+
+<style lang="stylus" scoped>
+    #informationInfo{
+        height:100%;
+        display flex
+        .info-max-box{
+            flex:1;
+            overflow: scroll
+            background #f5f5f5;
+            padding-bottom:20px;
+            .for-info-box{
+                border-radius: 10rpx;
+                .title-time{
+                    line-height:94rpx;
+                    color:#CCCCCC;
+                    text-align: center;
+                    font-size: 24rpx;
+                }
+                .for-min-box{
+                    background #ffffff
+                    border-radius:10rpx;
+                    padding:20rpx;
+                    margin:0 20rpx;
+                    view:nth-child(1){
+                        line-height:44rpx;
+                        margin-bottom:13rpx;
+                        margin-left:5rpx;
+                        color: #333333;
+                        font-size: 30rpx;
+                    }
+                    view:nth-child(2){
+                        line-height:42rpx;
+                        font-size: 25rpx;
+                        color: #666;
+                    }
+                    img{
+                        width:100%;
+                        height:100%;
+						max-width 100%;
+                    }
+                    rich-text{
+                        overflow hidden
+                    }
+                }
+            }
+            .get-null-box{
+                height:100rpx;
+                line-height:100rpx;
+                color:#999;
+                text-align center
+            }
+        }
+    }
+</style>

+ 309 - 0
pages/information/notPassInfo.vue

@@ -0,0 +1,309 @@
+<!-- 申请详情 -->
+<template>
+    <view id="applicationDetails" v-if="pageType">
+		<view class="user-info-box">
+			<view class="user-info-box-min">
+				<view>实验室:</view>
+				<view>{{subjectData.labSecurityApply.subjectName}}</view>
+			</view>
+			<view class="user-info-box-min">
+				<view>申请时限:</view>
+				<view>{{subjectData.labSecurityApply.validBeginTime}}至{{subjectData.labSecurityApply.validEndTime}}</view>
+			</view>
+			<view class="user-info-box-min">
+				<view>申请备注:</view>
+				<view>{{subjectData.labSecurityApply.applyCause}}</view>
+			</view>
+		</view>
+		<view class="user-info-box">
+			<view class="user-info-box_title"><view style="color: red;">*</view>身份信息:(关联学生信息材料)</view>
+			<view class="user-info-box-min">
+				<view>申请人:</view>
+				<view>{{subjectData.sysUser.nickName}}</view>
+			</view>
+			<view class="user-info-box-min">
+				<view>联系电话:</view>
+				<view>{{subjectData.sysUser.phonenumber}}</view>
+			</view>
+			<view class="user-info-box-min" >
+				<view>学号:</view>
+				<view>{{subjectData.sysUser.userName}}</view>
+			</view>
+			<view class="user-info-box-min">
+				<view>物理卡号:</view>
+				<view>{{subjectData.sysUser.cardNum}}</view>
+			</view>
+			<view class="user-info-box-min" >
+				<view>班级:</view>
+				<view>{{subjectData.sysUser.grade}}</view>
+			</view>
+			<view class="user-info-box-min" >
+				<view>导师:</view>
+				<view>{{subjectData.sysUser.tutorUserName}}</view>
+			</view>
+
+		</view>
+		<view v-for="(item,index) in subjectData.listTemp" :key="index" style="overflow: hidden;">
+			<view class="img-box" v-if="item.materialType==2&&item.relationType==2">
+				<view class="img-title">安全考试证书</view>
+				<img v-if="subjectData.listcert[0]" class="item-img-box" :src="subjectData.listcert[0].cert_url">
+				<view v-if="!subjectData.listcert[0]" style="margin-left:40px;color:#999;font-size:14px;">暂无证书</view>
+			</view>
+			<view class="word-box" v-if="item.materialType==1">
+				<view class="word-box-title">{{item.materialName}}</view>
+				<view class="word-box-min" v-for="(minItem,minIndex) in item.upList" :key="minIndex" @click="lookItem(minItem)">
+					<img src="@/images/Version2.3/icon_pdf.png" v-if="minItem.type == 'pdf'">
+					<img src="@/images/Version2.3/icon_word.png" v-if="minItem.type == 'doc' || minItem.type == 'docx'">
+					<img :src="configUrl+minItem.url" v-if="minItem.type == 'png' || minItem.type == 'jpg' || minItem.type == 'jpeg' || minItem.type == 'gif'">
+					<view>{{minItem.name}}</view>
+				</view>
+			</view>
+		</view>
+		<view class="bottom-button-p" v-if="subjectData.labSecurityApply.auditStatus == 1" @click="bottomButtonClick">重新提交</view>
+    </view>
+</template>
+
+<script>
+    import { getDetails,groupListRead} from '@/api/index.js'
+	import { config } from '@/api/request/config.js'
+    export default {
+        data() {
+            return {
+				pageType:false,
+				//传参数据
+				infoData:{},
+				//获取数据
+				subjectData:{},
+				configUrl:config.base_url,
+            }
+        },
+        onLoad(option) {
+
+            this.infoData = JSON.parse(decodeURIComponent(option.item));
+            //修改页面title
+            uni.setNavigationBarTitle({
+                title:this.infoData.auditStatus==0?'待审核':(this.infoData.auditStatus==1?'未通过':(this.infoData.auditStatus==2?'已通过':''))
+            });
+        },
+        onShow(){
+
+            this.getRead();
+        },
+        methods: {
+			lookItem(minItem){
+				if(minItem.type == 'png' || minItem.type == 'jpg' || minItem.type == 'jpeg' || minItem.type == 'gif'){
+					//查看图片
+					wx.previewImage({
+						urls: [config.base_url+minItem.url], //需要预览的图片http链接列表,多张的时候,url直接写在后面就行了
+						current: '', // 当前显示图片的http链接,默认是第一个
+						success: function(res) {},
+						fail: function(res) {},
+						complete: function(res) {},
+					})
+				}else if(minItem.type == 'pdf' || minItem.type == 'doc' || minItem.type == 'docx'){
+					uni.showLoading({
+					    title: '下载中'
+					});
+					//下载文档
+					wx.downloadFile({
+						url: config.base_url+minItem.url,
+						header: {
+							Authorization: uni.getStorageSync('token')
+						},
+						success: function (res) {
+							const fileManager = wx.getFileSystemManager()
+							const filePath = wx.env.USER_DATA_PATH + '/' + minItem.name + '.docx'
+							fileManager.saveFile({
+								tempFilePath: res.tempFilePath,
+								filePath,
+								success: () => {
+									uni.hideLoading();
+									wx.openDocument({
+										filePath: filePath,
+										showMenu: true,
+										fileType: minItem.type
+									})
+								},
+								fail: function (res){
+									uni.hideLoading();
+									uni.showToast({
+										title: '下载失败',
+										icon:"none",
+										mask:true,
+										duration: 2000
+									});
+								}
+							})
+						},
+						fail: function (res){
+							uni.hideLoading();
+							uni.showToast({
+								title: '下载失败',
+								icon:"none",
+								mask:true,
+								duration: 2000
+							});
+						}
+					})
+				}
+			},
+			//重新提交
+			bottomButtonClick(){
+				uni.navigateTo({
+				    url:'/pages_student/workbench/safeAccess/newApplication?item='+encodeURIComponent(JSON.stringify(this.subjectData))
+				});
+			},
+			async getRead() {
+			        let self = this;
+			        const {data} = await groupListRead({messageId:this.infoData.messageId})
+			        if(data.code==200){
+						let id=data.data.applyId
+						this.getDetails(id)
+			        }
+			    },
+            //获取安全准入审批记录详细信息(用户端)
+            async getDetails(id) {
+                let self = this;
+
+                const {data} = await getDetails({id:id})
+                if(data.code==200){
+				  for(let i=0;i<data.data.listTemp.length;i++){
+					if(data.data.listTemp[i].materialType == 1) {
+            let maxList = [];
+            for (let o = 0; o < data.data.listTemp[i].listMr.length; o++) {
+              let bigList = data.data.listTemp[i].listMr[o].dataUrl.split(',');
+              for (let x = 0; x < bigList.length; x++) {
+                if (bigList[x]) {
+                  let minList = bigList[x].split(';');
+                  let minListTwo = minList[0].split('.')
+                  let obj = {
+                    name: minList[0],
+                    url: minList[1],
+                    type: minListTwo[1]
+                  };
+                  maxList.push(obj);
+                }
+              }
+            }
+            data.data.listTemp[i].upList = maxList;
+           }
+				  }
+				  this.$set(this,"subjectData",data.data);
+				  this.pageType = true;
+                }
+            }
+        }
+    }
+</script>
+
+<style lang="stylus" scoped>
+    #applicationDetails{
+        height:100%;
+        width:100%;
+        overflow-y scroll
+		.user-info-box{
+			background #fff;
+			border-radius:20rpx;
+			margin:20rpx 20rpx;
+			padding:20rpx 0;
+			.user-info-box_title{
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 30rpx;
+				margin-left: 24rpx
+				margin-bottom :10px;
+				>view{
+					display inline-block;
+				}
+			}
+			.user-info-box-min{
+				margin:0 26rpx;
+				display flex;
+				view{
+					line-height:66rpx;
+					font-size:28rpx;
+				}
+				view:nth-child(1){
+					width:140rpx;
+					color:#999;
+				}
+				view:nth-child(2){
+					flex:1;
+					text-align right;
+					color:#333;
+				}
+			}
+		}
+		.user-card-box{
+			background #fff;
+			border-radius:20rpx;
+			margin:0 20rpx 20rpx;
+			padding:20rpx 0;
+			.user-card-title{
+				padding-left:24rpx;
+				font-size:30rpx;
+				font-weight:700;
+				margin-bottom:20rpx;
+			}
+			.user-card-text{
+				line-height:66rpx;
+				font-size:28rpx;
+				color:#999;
+				padding:0 24rpx;
+			}
+		}
+		.img-box{
+			background #fff;
+			border-radius:20rpx;
+			margin:0 20rpx 20rpx;
+			padding:20rpx 0;
+			.img-title{
+				padding-left:24rpx;
+				font-size:30rpx;
+				font-weight:700;
+				margin-bottom:20rpx;
+			}
+			img{
+				display block;
+				width:640rpx;
+				margin:0 auto 10rpx;
+			}
+		}
+		.word-box{
+			background #fff;
+			border-radius:20rpx;
+			margin:0 20rpx 20rpx;
+			padding:20rpx 0;
+			.word-box-title{
+				padding-left:24rpx;
+				font-size:30rpx;
+				font-weight:700;
+				margin-bottom:20rpx;
+			}
+			.word-box-min{
+				display flex;
+				margin:0 20rpx 20rpx;
+				img{
+					height:60rpx;
+					width:60rpx;
+				}
+				view{
+					margin-left:20rpx;
+					line-height:60rpx;
+				}
+			}
+		}
+		.bottom-button-p{
+			width:650rpx;
+			height:100rpx;
+			line-height:100rpx;
+			text-align center;
+			border-radius:20rpx;
+			margin:20rpx 50rpx;
+			background: #0183fa;
+			color:#fff;
+		}
+    }
+</style>

+ 355 - 0
pages/login/login.vue

@@ -0,0 +1,355 @@
+<!-- 登录 -->
+<template>
+  <view id="login">
+    <img class="login-max-big" :src="loginBanner">
+    <view class="login-box">
+      <view class="input-max-box-one">
+        <view class="input-box">
+          <img src="@/images/basicsModules/img_log_in_account.png">
+          <input type="text" v-model="username" placeholder="请输入账号" maxlength="20">
+        </view>
+      </view>
+      <view class="input-max-box-two">
+        <view class="input-box">
+          <img src="@/images/basicsModules/img_log_in_password.png">
+          <input type="password" v-model="password" placeholder="请输入密码" maxlength="20">
+        </view>
+      </view>
+      <view class="check-max-box">
+        <view class="check-box" @click="checkboxChange">
+          <img v-if="checkedType" src="@/images/basicsModules/icon_13.png">
+          <img v-if="!checkedType" src="@/images/basicsModules/icon_12.png">
+          <view>记住我</view>
+        </view>
+        <view class="check-right-box" @click="nullPasswrod">
+          忘记密码
+        </view>
+      </view>
+      <view class="button-box" @click="login">登录</view>
+    </view>
+  </view>
+</template>
+
+<script>
+import md5 from '@/utils/md5.js'
+import { config } from '@/api/request/config.js'
+import { login,configInfo,getConfigByType,getGentleIdentifier,systemAppletRolePermission} from '@/api/basicsModules/index.js'
+import { Encrypt,Decrypt} from '@/utils/secret.js'
+export default {
+  data() {
+    return {
+      identityStatus:1,
+      username:"superadmin",
+      password:"zd123456",
+      checkedType:false,
+      loginBanner:uni.getStorageSync('loginBanner'),
+      infoList:[],//模板消息Id
+      tabText:['师生登录','供应商登录'],
+      curTab:0,
+      pageType:0,
+    }
+  },
+
+  onLoad(option) {
+    //供应商注册成功后返回到供应商注册页面
+    if(option.status){
+      this.identityStatus=2
+    }
+    if(uni.getStorageSync('userName') && uni.getStorageSync('password')){
+      this.username = uni.getStorageSync('userName');
+      this.password = uni.getStorageSync('password');
+      this.checkedType = true;
+    }
+
+
+  },
+  onShow(){
+    this.getConfigInfo();
+  },
+  methods: {
+    //顶部tab点击
+    tabClick(index) {
+      this.curTab = index;
+    },
+	//登录
+	async login() {
+	  let self = this;
+	  let obj = {
+	    account:this.username,
+	    password:md5.hex_md5(this.password),
+	  }
+	  const {data} = await login(obj)
+	  if(data.code == 200){
+	    uni.setStorageSync('token',data.data.token);
+	    uni.setStorageSync('userId',data.data.userId);
+	    uni.setStorageSync('userType',data.data.userType==0||data.data.userType==1?'1':
+		(data.data.userType==2?'2':(data.data.userType==3?'3':'none')));
+	    if(this.checkedType){
+	      uni.setStorageSync('userName',this.username)
+	      uni.setStorageSync('password',this.password)
+	    }else{
+	      uni.removeStorageSync('userName')
+	      uni.removeStorageSync('password')
+	    }
+		//获取开发配置
+		this.getConfigByType();
+		//获取权限字段
+		this.systemAppletRolePermission();
+	    //获取身份标识
+	    // this.getGentleIdentifier();
+	  }
+	},
+	//获取权限字段
+	async systemAppletRolePermission(){
+		let self = this;
+		const {data} = await systemAppletRolePermission();
+		if(data.code==200){
+			uni.setStorageSync('permissions',data.data.data)
+		}
+	},
+    //获取用户身份标识"adminGentle": false,   
+	//管理员身份 "rectifyGentle": false,   
+	//整改身份"applyGentle": false    检查者身份
+    async getGentleIdentifier(){
+      let self = this;
+      const {data} = await getGentleIdentifier();
+      if(data.code==200){
+        uni.setStorageSync('gentleIdentifierData',data.data)
+        let list=[];
+        if(data.data.adminGentle || data.data.collegeGentle){//校级管理员
+          list.push({name:'管理员',pageType:1})
+        }
+        if(data.data.applyGentle ||data.data.myApplyGentle){
+          list.push({name:'检查者',pageType:2})
+        }
+        if(data.data.rectifyGentle){
+          list.push({name:'整改者',pageType:3})
+        }
+        if(!data.data.adminGentle && !data.data.applyGentle && !data.data.myApplyGentle  && !data.data.applyGentle && !data.data.collegeGentle){
+          self.pageType='mine'
+          list.push({name:'暂无权限',pageType:'mine'})
+        }
+        uni.setStorageSync('gentleIdentifier',list)
+        if(uni.getStorageSync('saoCode')){
+          uni.redirectTo({
+            url: '/pages/saoCode/saoCode'
+          });
+        }else if(self.pageType=='mine'){
+          uni.redirectTo({
+            url: '/pages/mine/mine',
+          });
+        }else{
+          uni.redirectTo({
+            url: '/pages/home/home',
+          });
+        }
+      }
+    },
+    switchClick(){
+      if(this.identityStatus==1){
+        this.identityStatus=2;
+      }else{
+        this.identityStatus=1;
+      }
+    },
+	//查询公共配置
+	getConfigInfo(){
+		this.getCircularLogo();
+		this.getVideoCover();
+		this.getBanner();
+	},
+    async getCircularLogo(){
+      const {data} = await configInfo({ type: 1 });
+      if(data.code == 200){
+        uni.setStorageSync('circularLogo',config.base_url + data.data.circularLogo)
+      }
+    },
+    async getVideoCover(){
+      const {data} = await configInfo({ type: 2 });
+      if(data.code == 200){
+        uni.setStorageSync('videoCover',config.base_url + data.data.videoCover)
+      }
+    },
+    async getBanner(){
+      const {data} = await configInfo({ type: 4 });
+      if(data.code == 200){
+        this.loginBanner = config.base_url + data.data.loginBanner;
+        uni.setStorageSync('loginBanner',config.base_url + data.data.loginBanner)
+        uni.setStorageSync('homepageBanner',config.base_url + data.data.homepageBanner)
+      }
+    },
+    //获取开发配置
+	async getConfigByType(){
+      const {data} = await getConfigByType({ category: 2, configType: 5 });
+      if(data.code == 200){
+        let obj = JSON.parse(data.data.configValue)
+        //文件预览地址
+        uni.setStorageSync('filePreviewUrl','https://'+obj.fileExtranetUrl)
+        //摄像头代理访问地址
+        uni.setStorageSync('cameraExtranetAgent','https://'+obj.cameraExtranetAgent)
+        //摄像头地址ip段
+        uni.setStorageSync('cameraIntranetAgent',obj.cameraIntranetAgent)
+        //摄像头访问地址
+        uni.setStorageSync('cameraUrl','https://'+obj.cameraExtranetUrl)
+        //MQTT地址
+        uni.setStorageSync('mqttUrl',Decrypt(obj.mqttExtranetUrl))
+        //MQTT账号
+        uni.setStorageSync('mqttUser',Decrypt(obj.mqttExtranetUser))
+        //MQTT密码
+        uni.setStorageSync('mqttPassword',Decrypt(obj.mqttExtranetPassword))
+		uni.redirectTo({
+			url: '/pages/home/home',
+		});
+      }
+    },
+    checkboxChange() {
+      this.checkedType = !this.checkedType;
+    },
+    //点击事件
+    handleClick(doType) {
+      if(doType=='register'){//供应商注册
+        uni.redirectTo({
+          url: '/pages_supplier/register/register?pageStatus=0'
+        });
+      }else if(doType=='forget'){//忘记密码
+        uni.showModal({
+          showCancel:false,
+          confirmColor:'#0183FA',
+          content: '请您联系学校相关管理人员申请重置密码',
+          success: function (res) {
+            if (res.confirm) {
+            }
+          }
+        });
+      }
+    },
+  },
+
+}
+</script>
+
+
+<style lang="stylus" scoped>
+#login{
+  height:100%;
+  width:100%;
+  background #f5f5f5
+  position relative
+  .login-max-big{
+    width:750rpx;
+    height:1102rpx;
+    z-index:0;
+  }
+  .login-box{
+    z-index:1;
+    position: absolute
+    top:446rpx;
+    left:46rpx;
+    width:658rpx;
+    height:655rpx;
+    // background #fff
+    border-radius:20rpx;
+    .input-max-box-one{
+      .input-box{
+        display flex
+        width:600rpx;
+        height:80rpx;
+        border:1rpx solid #e0e0e0;
+        border-radius:40rpx;
+        margin:147rpx auto 0;
+        img{
+          width:28rpx;
+          height:32rpx;
+          margin:24rpx 31rpx;
+        }
+        input{
+          flex:1;
+          font-size:24rpx;
+          height:80rpx;
+          line-height:80rpx;
+          margin-right:31rpx;
+        }
+      }
+      .text-box{
+        height:59rpx;
+        line-height:59rpx;
+        color:#DC1616;
+        font-size:24rpx;
+        margin-left:102rpx;
+      }
+    }
+    .input-max-box-two{
+      margin-top:40rpx;
+      .input-box{
+        display flex
+        width:600rpx;
+        height:80rpx;
+        border:1rpx solid #e0e0e0;
+        border-radius:40rpx;
+        margin:0 auto 0;
+        img{
+          width:30rpx;
+          height:32rpx;
+          margin:24rpx 30rpx;
+        }
+        input{
+          flex:1;
+          font-size:24rpx;
+          height:80rpx;
+          line-height:80rpx;
+          margin-right:31rpx;
+        }
+      }
+      .text-box{
+        height:59rpx;
+        line-height:59rpx;
+        color:#DC1616;
+        font-size:24rpx;
+        margin-left:102rpx;
+      }
+    }
+    .check-max-box{
+      display flex;
+      .check-box{
+        margin:30rpx 0 30rpx 104rpx;
+        width:300rpx;
+        height:50rpx;
+        display:flex;
+        img{
+          margin-top:10rpx;
+          width:32rpx;
+          height:32rpx;
+          margin-right:10rpx;
+        }
+        view{
+          font-size:24rpx;
+          line-height:50rpx;
+        }
+      }
+      .check-right-box{
+        font-size:24rpx;
+        line-height:50rpx;
+        margin:30rpx 0 30rpx 30rpx;
+      }
+    }
+    .button-box{
+      width: 600rpx;
+      line-height: 80rpx;
+      background: #0183FA;
+      border-radius: 40rpx;
+      font-size: 36rpx;
+      color:#fff;
+      text-align center
+      margin:0 auto 0;
+    }
+  }
+  .top-back{
+    z-index:2;
+    position: absolute
+    top:261rpx;
+    left:375rpx;
+    height:296rpx;
+    width:366rpx;
+  }
+}
+</style>

+ 641 - 0
pages/mine/mine.vue

@@ -0,0 +1,641 @@
+<!-- 我的 -->
+<template>
+  <view id="mine">
+    <view class="top-max-big-box" v-if="pageType">
+      <!--老师-->
+      <view class="top-max-box-two" v-if="userType==1&&certification.auditStatus">
+        <view class="user-img-box" @click="selectImage">
+          <img v-if="userData.avatar" :src="userData.avatarUrl">
+          <img v-else  src="@/images/icon_01.png">
+          <view>{{userData.avatar?'编辑':'未上传'}}</view>
+        </view>
+        <view class="name-box">
+          <view>{{userData.userName}}</view>
+          <view>{{userData.professional}}丨{{userData.deptName}}</view>
+        </view>
+      </view>
+      <!--学生-->
+      <view class="user-top-max-box-one" v-if="userType==2">
+        <view class="back-posi"></view>
+        <view class="top-max-box-one">
+          <view class="user-img-box" @click="selectImage">
+            <img v-if="userData.avatar" :src="userData.avatarUrl">
+            <img v-else  src="@/images/icon_01.png">
+            <view>{{userData.avatar?'编辑':'未上传'}}</view>
+          </view>
+          <view class="name-box">
+            <view class="name-box-min">
+              <view>{{userData.userName}}</view>
+              <view :class="userData.status == 2?'view-color-one':(userData.status == 3?'view-color-two':(userData.status == 1?'view-color-tree':''))">{{userData.status == 2?'负面清单':(userData.status == 3?'黑名单':(userData.status == 1?'正常':''))}}</view>
+            </view>
+            <view class="name-box-user">{{userData.professional}}丨{{userData.deptName}}</view>
+          </view>
+        </view>
+        <view class="num-max-box">
+          <view class="min-num-box" @click="goUserPage('none')">
+            <view class="min-num-view color-one">{{creditScore}}</view>
+            <view class="bottom-min-num-view">
+              <img class="img-one" src="@/images/icon_wd_xyf.png">
+              <view>信用分</view>
+            </view>
+          </view>
+          <view class="null-p"></view>
+          <view class="min-num-box" @click="goUserPage('none')">
+            <view class="min-num-view color-two">{{bonusPoints}}</view>
+            <view class="bottom-min-num-view">
+              <img class="img-two" src="@/images/icon_wd_jlf.png">
+              <view>奖励分</view>
+            </view>
+          </view>
+          <view class="null-p"></view>
+          <view class="min-num-box" @click="goUserPage(3)">
+            <view class="min-num-view">扫一扫</view>
+            <view class="bottom-min-num-view">
+              <img class="img-two" src="@/images/icon_wd_dh.png">
+              <view>兑换礼品</view>
+            </view>
+          </view>
+        </view>
+      </view>
+      <view class="button-max-big-box">
+        <view class="button-max-box" @click="goPage('alarm')" v-if="userType==1">
+          <img class="left-img" src="@/images/icon_003.png">
+          <view>预警记录</view>
+          <view class="view-three-one" v-if="securityAlertNum>0">{{securityAlertNum}}</view>
+          <img class="right-img" src="@/images/icon_04.png">
+        </view>
+        <view class="button-max-box" @click="goPage('laboratory')" v-if="userType==1">
+          <img class="left-img" src="@/images/icon_002.png">
+          <view>我的实验室</view>
+          <view class="view-three-two" v-if="adminSubCount>0">{{adminSubCount}}</view>
+          <img class="right-img" src="@/images/icon_04.png">
+        </view>
+        <view class="button-max-box" @click="goPage('record')" v-if="userType==1">
+          <img class="left-img" src="@/images/icon_004.png">
+          <view>预案执行记录</view>
+          <view class="view-three-two" v-if="wranDoCount>0">{{wranDoCount}}</view>
+          <img class="right-img" src="@/images/icon_04.png">
+        </view>
+        <view class="button-max-box" @click="goPage('faceImage')">
+          <img class="left-img" src="@/images/icon_001.png">
+          <view>身份验证</view>
+          <view class="view-three-type" :class="!ifFaceFeature?'colorA':'marginType'">{{!ifFaceFeature?'去认证':'已认证'}}</view>
+          <img class="right-img" src="@/images/icon_04.png">
+        </view>
+        <view class="button-max-box" @click="goPage('signature')">
+          <img class="left-img" src="@/images/icon_wd_dzqm.png">
+          <view>电子签名</view>
+          <view class="view-three-type" :class="!isUpload?'colorA':'marginType'">{{!isUpload?'未上传':'已上传'}}</view>
+          <img class="right-img" src="@/images/icon_04.png">
+        </view>
+        <view class="button-max-box" @click="fingerprintClick()">
+          <img class="left-img" src="@/images/icon_wd_zw.png">
+          <view>指纹</view>
+          <view class="view-three-type" :class="Quantity>0?'marginType':'colorA'">{{Quantity>0?'已配置'+Quantity+'个':''}}</view>
+          <img class="right-img" src="@/images/icon_04.png">
+        </view>
+      </view>
+    </view>
+    <view class="out-button" @click="clickOut">退出登录</view>
+    <tab-bar></tab-bar>
+  </view>
+</template>
+
+<script>
+import { config } from '@/api/request/config.js'
+import { logout,studentinfoFacemy,simpleInfo,getSafeWarnList,getMyPointsLogInfo,querySignature,fingerprintQuantity,fingerprintQueryList} from '@/api/index.js'
+import { tabBar } from '@/component/tabBar.vue'
+export default {
+  components: {
+    tabBar
+  },
+  data() {
+    return {
+      //页面状态
+      pageType:false,
+      //认证数据
+      certification:{
+
+      },
+      userType:0,
+      userData:{
+        deptName: "",
+        professional: "",
+        userName: "",
+      },
+      securityAlertNum:0,
+      adminSubCount:0,
+      wranDoCount:0,
+      //奖励分
+      bonusPoints:0,
+      //信用分
+      creditScore:0,
+      //用户签名
+      signatureUrl:'',
+      // 人脸
+      ifFaceFeature:"",
+      //签名
+      isUpload:"",
+      Quantity:0,//指纹录取数量
+
+    }
+  },
+  onLoad() {
+
+  },
+  onShow(){
+
+    if(uni.getStorageSync('token')&&uni.getStorageSync('userId')&&uni.getStorageSync('userType')){
+      this.userType = uni.getStorageSync('userType')
+      this.studentinfoFacemy();
+      this.simpleInfo();
+      this.querySignature();
+    }else{
+      uni.removeStorageSync('token');
+      uni.removeStorageSync('userId');
+      uni.removeStorageSync('userType');
+      uni.redirectTo({
+        url: '/pages/login',
+      });
+    }
+  },
+
+  methods: {
+    //学生端-信用分/奖励分/扫一扫按钮
+    goUserPage(type){
+      let self = this;
+      if(type == 1){
+        uni.navigateTo({
+          url: '/pages_student/mine/creditPoints',
+        });
+      }else if(type == 2){
+        uni.navigateTo({
+          url: '/pages_student/mine/rewardPoints',
+        });
+      }else if(type == 3){
+        uni.scanCode({
+          onlyFromCamera: true,
+          success: function (res) {
+            uni.navigateTo({
+              url: '/pages_student/mine/codeSuccess?q='+encodeURIComponent(JSON.stringify(res.result))
+            });
+          }
+        });
+      }else if(type == 'none'){
+		  uni.showToast({
+		    title: '暂未开放',
+		    icon:"none",
+		    mask:true,
+		    duration: 2000
+		  });
+	  }
+    },
+    //获取个人信息
+    async simpleInfo(){
+      const {data} = await simpleInfo();
+      if(data.code == 200){
+        this.userData = data.data;
+        this.userData.avatar=data.data.avatar;
+
+        this.userData.avatarUrl=config.base_url+data.data.avatar;
+		console.log(config.base_url)
+		console.log(this.userData.avatarUrl)
+        if(this.userType == 1){
+          this.getSafeWarnList();
+        }else if(this.userType == 2){
+          //this.getMyPointsLogInfo();
+        }
+        if(data.data.count){
+          this.adminSubCount = data.data.count.adminSubCount;
+          this.wranDoCount = data.data.count.wranDoCount;
+        }
+        this.pageType = true;
+      }
+    },
+
+    //查询用户指纹录取数量
+    async fingerprintQuantityFun(){
+      let _this=this;
+      const {data} = await fingerprintQuantity(uni.getStorageSync('userId'));
+      if(data.code == 200){
+        _this.Quantity=data.data;
+
+      }
+    },
+    //查询用户指纹录取数据
+    async fingerprintClick(){
+      let _this=this;
+      const {data} = await fingerprintQueryList(uni.getStorageSync('userId'));
+      if(data.code == 200){
+        uni.navigateTo({
+          url: '/pages/fingerprint',//指纹信息
+        });
+      }
+    },
+    //查询用户电子签名
+    async querySignature(){
+      let _this=this;
+      const {data} = await querySignature();
+      if(data.code == 200){
+
+        _this.isUpload=data.data.isUpload;
+        _this.signatureUrl=data.data.signature;
+      }
+    },
+    //获取个人奖励分/信用分
+    async getMyPointsLogInfo(){
+      const {data} = await getMyPointsLogInfo();
+      if(data.code == 200){
+        this.bonusPoints = data.data.bonusPoints;
+        this.creditScore = data.data.creditScore;
+      }
+    },
+    //获取报警信息列表
+    async getSafeWarnList(){
+      let obj = {
+        pageNum:1,
+        pageSize:1,
+        count:0,
+        groupStatus:1,
+      };
+      const {data} = await getSafeWarnList(obj);
+      if(data.code == 200){
+        if(data.rows[0]){
+          this.securityAlertNum = data.rows[0].todayHappenCount;
+        }else{
+          this.securityAlertNum = 0;
+        }
+      }
+    },
+    //获取当前身份人脸验证状态与学生卡上传状态
+    async studentinfoFacemy(){
+      let obj = {
+        studentsId:uni.getStorageSync('userId')
+      }
+      const {data} = await studentinfoFacemy(obj)
+      if(data.code == 200){
+        this.certification = data.data;
+        this.ifFaceFeature = data.data.ifFaceFeature;
+      }
+    },
+    //退出按钮
+    clickOut(){
+      let self = this;
+      uni.showModal({
+        // title: '确认要退出吗?',
+        content: '确认要退出吗',
+        cancelColor:"#999",
+        confirmColor:"#0183FA",
+        success: function (res) {
+          if (res.confirm) {
+            self.logout();
+          } else if (res.cancel) {
+          }
+        }
+      });
+    },
+    //退出登录
+    async logout() {
+      let self = this;
+      const {data} = await logout();
+      if(data.code == 200){
+        uni.removeStorageSync('token');
+        uni.removeStorageSync('userId');
+        uni.removeStorageSync('userType');
+        uni.redirectTo({
+          url: '/pages/login',
+        });
+      }
+    },
+    //页面跳转
+    goPage(type){
+      if(type == 'pointsRecord'){//积分记录
+        uni.navigateTo({
+          url: '/pages_student/mine/pointsRecord',
+        });
+      }else if(type == 'faceImage'){//身份验证
+        uni.navigateTo({
+          url: '/pages/faceImage',
+        });
+      }else if(type == 'laboratory'){
+        uni.navigateTo({
+          url: '/pages_manage/workbench/laboratory/meLaboratory',//我的实验室
+        });
+      }else if(type == 'alarm'){
+        uni.navigateTo({
+		  url: '/pages/earlyWarningManage/earlyWarningList',//安全警报
+		});
+      }else if(type == 'record'){
+        uni.navigateTo({
+          url: '/pages_manage/workbench/plan/planList',//预案执行记录
+        });
+      }else if(type == 'signature'){
+        uni.navigateTo({
+          url: '/pages_manage/workbench/signature/signature?item='+this.signatureUrl,//电子签名
+        });
+      }
+
+
+    },
+    // 头像上传
+    selectImage() {
+      let self = this;
+      wx.chooseImage({
+        count: 1,
+        sizeType: ["original", "compressed"],
+        sourceType: ["album", "camera"],
+        success: function(res) {
+          let tempFilePaths = res.tempFilePaths[0];
+          self.uploadImg(tempFilePaths);
+        }
+      });
+    },
+    async uploadImg(tempFilePaths){
+      var self = this;
+      uni.showLoading({
+        title: '上传中',
+        mask: true
+      });
+      uni.uploadFile({
+        url: config.base_url+'/base/file/upload', //仅为示例,非真实的接口地址
+        header:{'Authorization':uni.getStorageSync('token')},
+        filePath: tempFilePaths,
+        name: 'file',
+        formData: {
+          'user': 'test'
+        },
+        success: (uploadFileRes) => {
+          let res = JSON.parse(uploadFileRes.data);
+          if(res.code == 200){
+            uni.navigateTo({
+              url: '/pages/avatar?src='+config.base_url+res.data.url,//预案执行记录
+            });
+
+
+
+          }else{
+            uni.showToast({
+              title: res.msg,
+              icon:"none",
+              mask:true,
+              duration: 2000
+            });
+          }
+        },
+        fail: err => {},
+        complete: () => {
+          uni.hideLoading()
+        }
+      });
+    },
+  },
+}
+</script>
+
+<style lang="stylus" scoped>
+#mine{
+  height:100%;
+  .top-max-big-box{
+    /*background:#ffffff;*/
+    .user-top-max-box-one{
+      overflow hidden
+      background url("@/images/img_wd_bg.png") no-repeat
+      background-size:100%;
+      height:350rpx;
+      .top-max-box-one{
+        background #fff
+        margin:40rpx 40rpx 0;
+        z-index:1;
+        height:180rpx;
+        border-top-right-radius 20rpx
+        border-top-left-radius 20rpx
+        display flex
+        overflow hidden
+        .user-img-box{
+          height:120rpx;
+          width:100rpx;
+          margin:30rpx 53rpx 0 22rpx;
+          img{
+            height:100rpx;
+            width:100rpx;
+            border-radius:50%;
+          }
+          view{
+            font-size:22rpx;
+            color:#666666;
+            text-align center
+            line-height:22rpx;
+            margin-top:10rpx;
+          }
+        }
+        .name-box{
+          margin-top:30rpx;
+          .name-box-min{
+            display flex
+            overflow hidden
+            margin-bottom:11rpx;
+            view:nth-child(1){
+              height:48rpx;
+              line-height:48rpx;
+              font-size: 30rpx;
+              color: #333;
+            }
+            view:nth-child(2){
+              height:30rpx;
+              line-height:30rpx;
+              font-size:20rpx;
+              padding:0 20rpx;
+              margin:9rpx 0 9rpx 20rpx;
+            }
+            view-color-one{
+              background #FDD255;
+            }
+            view-color-two{
+              background #A2A2A2;
+            }
+            view-color-tree{
+              background #0183FA;
+            }
+          }
+          .name-box-user{
+            line-height:41rpx;
+            font-size: 22rpx;
+            color: #333;
+          }
+        }
+
+      }
+      .num-max-box{
+        width:670rpx;
+        background #fff
+        border-bottom-right-radius 20rpx
+        border-bottom-left-radius 20rpx
+        height:130rpx;
+        margin:0 40rpx;
+        display flex
+        .min-num-box{
+          flex:1;
+          .min-num-view{
+            margin-top:30rpx;
+            height:30rpx;
+            line-height:30rpx;
+            font-size:22rpx;
+            text-align center
+          }
+          .color-one{
+            font-weight:700;
+            font-size:26rpx;
+            color:#2B99FE;
+          }
+          .color-two{
+            font-weight:700;
+            font-size:26rpx;
+            color:#FDD255;
+          }
+          .bottom-min-num-view{
+            display flex
+            margin-top:20rpx;
+            .img-one{
+              width:25rpx;
+              height:28rpx;
+              margin: 0 10rpx 0 58rpx;
+            }
+            .img-two{
+              width:28rpx;
+              height:26rpx;
+              margin: 0 10rpx 0 59rpx;
+            }
+            view{
+              font-size:22rpx;
+            }
+          }
+        }
+      }
+      .null-p{
+        background #dedede
+        height:30rpx;
+        width:2rpx;
+        margin:50rpx 0 0;
+      }
+    }
+    .top-max-box-two{
+      background url("@/images/img_wd_bg.png")
+      background-size:100%;
+      height:245rpx;
+      display flex
+      overflow hidden
+      .user-img-box{
+        height:120rpx;
+        width:100rpx;
+        margin:50rpx 53rpx 0 22rpx;
+        img{
+          height:100rpx;
+          width:100rpx;
+          border-radius:50%;
+        }
+        view{
+          font-size:22rpx;
+          color:#fff;
+          text-align center
+          line-height:22rpx;
+          margin-top:10rpx;
+        }
+      }
+      .name-box{
+        margin-top:50rpx;
+        view:nth-child(1){
+          line-height:48rpx;
+          margin-bottom:11rpx;
+          font-size: 30rpx;
+          color: #fff;
+        }
+        view:nth-child(2){
+          line-height:41rpx;
+          font-size: 22rpx;
+          color: #fff;
+        }
+      }
+
+    }
+    .button-max-big-box{
+      background #fff
+      padding:0 20rpx;
+      margin-top:30rpx;
+      .button-max-box{
+        height:100rpx;
+        display flex
+        border-top:1rpx solid #e0e0e0;
+        .left-img{
+          height:30rpx;
+          width:30rpx;
+          margin:34rpx 44rpx 0 0;
+        }
+        view{
+          line-height:100rpx;
+        }
+        view:nth-child(2){
+          flex:1;
+          color:#333333;
+          font-size: 30rpx;
+        }
+        .right-img{
+          height:24rpx;
+          width:12rpx;
+          margin:39rpx 0 0 0;
+        }
+        .colorA{
+          color:#E45656!important;
+        }
+        .marginType{
+          margin-right:12rpx;
+        }
+        .view-three-one{
+          width:30rpx;
+          height:30rpx;
+          text-align center
+          background #FF4552
+          border-radius:50%;
+          font-size:20rpx;
+          line-height:30rpx;
+          color:#fff;
+          margin:36rpx 20rpx;
+        }
+        .view-three-two{
+          width:30rpx;
+          height:30rpx;
+          text-align center
+          border-radius:50%;
+          font-size:20rpx;
+          line-height:30rpx;
+          color:#999;
+          margin:36rpx 20rpx;
+
+        }
+        .view-three-type{
+          width:120rpx;
+          text-align center;
+          color:#CCCCCC;
+          font-size: 26rpx;
+        }
+      }
+      .button-max-box:nth-child(1){
+        border:none;
+      }
+    }
+  }
+  .out-button{
+    position absolute
+    bottom:140rpx;
+    left:25rpx;
+    width:700rpx;
+    height:100rpx;
+    line-height:100rpx;
+    border-radius:10rpx;
+    text-align center
+    background #E0E0E0
+    color:#0183FA;
+    font-size: 30rpx;
+    margin:0 auto;
+  }
+}
+</style>

+ 36 - 0
pages/saoCode/hazardousChemicalsDescription.vue

@@ -0,0 +1,36 @@
+<!--危险化学品说明-->
+<template>
+    <view id="hazardousChemicalsDescription">
+        <web-view :src="baseUrl+'admin/#/codeHtml?code='+code+'&type==1'"></web-view>
+    </view>
+</template>
+
+<script>
+	import { config } from '@/api/request/config.js'
+    export default {
+        name: "hazardousChemicalsDescription",
+        data() {
+            return {
+				baseUrl:config.base_url,
+                code:"",
+            }
+        },
+
+        onLoad(option) {
+            this.code = JSON.parse(decodeURIComponent(option.code));
+        },
+        mounted(){
+
+        },
+
+        methods:{
+
+        },
+    }
+</script>
+
+<style lang="stylus" scoped>
+    #hazardousChemicalsDescription{
+        overflow scroll
+    }
+</style>

+ 36 - 0
pages/saoCode/safetyManagement.vue

@@ -0,0 +1,36 @@
+<!--安全管理制度-->
+<template>
+    <view id="safetyManagement">
+        <web-view :src="baseUrl+'admin/#/codeHtml?code='+code+'&type==2'"></web-view>
+    </view>
+</template>
+
+<script>
+	import { config } from '@/api/request/config.js'
+    export default {
+        name: "safetyManagement",
+        data() {
+            return {
+				baseUrl:config.base_url,
+                code:"",
+            }
+        },
+
+        onLoad(option) {
+            this.code = JSON.parse(decodeURIComponent(option.code));
+        },
+        mounted(){
+
+        },
+
+        methods:{
+
+        },
+    }
+</script>
+
+<style lang="stylus" scoped>
+    #safetyManagement{
+        overflow scroll
+    }
+</style>

+ 62 - 0
pages/saoCode/saoCode.vue

@@ -0,0 +1,62 @@
+<!--扫描二维码页面-->
+<template>
+    <view id="saoCode">
+        <web-view :src="baseUrl+'admin/#/codeHtml?code='+code+'&type='+type"></web-view>
+    </view>
+</template>
+
+<script>
+	import { config } from '@/api/request/config.js'
+    export default {
+		
+        name: "saoCode",
+        data() {
+            return {
+				baseUrl:config.base_url,
+                code:"",
+                type:"",
+            }
+        },
+
+        onLoad(option) {
+            let self = this;
+            if(option.q){
+                let text = decodeURIComponent(option.q)
+                let list = text.split("?")[1].split("&");
+                for(let i=0;i<list.length;i++){
+                    let newList = list[i].split("=");
+                    if(newList[0] == 'code'){
+                        self.code = newList[1];
+                    }else if(newList[0] == 'type'){
+                        self.type = newList[1];
+                    }
+                }
+                if(!uni.getStorageSync('token')){
+                    uni.setStorageSync('saoCode',this.code);
+                    uni.setStorageSync('saoType',this.type);
+                    uni.redirectTo({
+                        url: '/pages/login',
+                    });
+                }
+            }else{
+                this.code = uni.getStorageSync('saoCode');
+                this.type = uni.getStorageSync('saoType');
+                uni.removeStorageSync('saoCode');
+                uni.removeStorageSync('saoType');
+            }
+        },
+        mounted(){
+
+        },
+
+        methods:{
+
+        },
+    }
+</script>
+
+<style lang="stylus" scoped>
+    #saoCode{
+        overflow scroll
+    }
+</style>

+ 137 - 0
pages/saoCode/scan.vue

@@ -0,0 +1,137 @@
+<!-- 扫一扫 -->
+<template>
+	<view>
+		<view class="scanCode_box">
+			<view class="title">请扫描设备二维码</view>
+			<camera class='camera' mode="scanCode" @error="cameraError" @scancode='scancode'
+				frame-size='large'>
+				<cover-view class='animation' :animation="animation"></cover-view>
+			</camera>
+			<view @click="manualFun()" class="manual">手动选择设备</view>
+		</view>
+	</view>
+</template>
+<script>
+	let animation = uni.createAnimation({});
+	
+	export default {
+		data() {
+			return {
+				animation,
+				form:{},
+			}
+		},
+		onLoad(option) {
+			if(option.form){
+				this.form=JSON.parse(decodeURIComponent(option.form));
+			}
+		},
+		onShow() {
+			this.donghua()
+		},
+		methods: {
+			donghua() {
+				let that = this;
+				let scode = true
+				setInterval(function() {
+					if (scode) {
+						animation.translateY(250).step({
+							duration: 3000
+						})
+						scode = !scode;
+					} else {
+						animation.translateY(-10).step({
+							duration: 3000
+						})
+						scode = !scode;
+					}
+						that.animation = animation.export()
+					
+				}.bind(this), 3000)
+			},
+			//手动选择设备
+			manualFun(){
+				uni.redirectTo({
+				    url: '/pages_safetyExamine/examineManage/examineAddContent?form='+encodeURIComponent(JSON.stringify(this.form))+'&pageType=3'
+				});
+			},
+			scancode(e){
+				let self=this;
+			    // 扫描结果
+				let text = decodeURIComponent(e.detail.result)
+				let list = text.split("?")[1].split("&");
+				for(let i=0;i<list.length;i++){
+				    let newList = list[i].split("=");
+				    if(newList[0] == 'code'){
+				        self.code = newList[1];
+				    }else if(newList[0] == 'type'){
+				        self.type = newList[1];
+				    }
+				}
+				let joinHazardIds=[];
+				if(this.form.hazardIds){
+					joinHazardIds=this.form.hazardIds.split(',')
+					joinHazardIds.push(self.code)
+					this.form.joinHazardIds=joinHazardIds
+				}else{
+					this.form.joinHazardIds=self.code
+				}
+				uni.navigateTo({
+					url: '/pages_safetyExamine/examineManage/examineAddTow?form='+encodeURIComponent(JSON.stringify(this.form))+'&joinHazardIds='+self.code
+				});
+			  }
+		}
+	
+	}
+</script>
+<style>
+	.scanCode_box {
+		width: 100%;
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		background-color: #000000;
+		position: fixed;
+		align-items: center;
+	}
+	.title{
+		font-size: 34rpx;
+		font-family: PingFang SC-Medium, PingFang SC;
+		font-weight: 400;
+		color: #FFFFFF;
+		line-height: 48rpx;
+		margin-top: 256rpx;
+		text-align: center;
+	}
+	.camera {
+		width: 433rpx;
+		height: 434rpx;
+		border-radius: 6rpx;
+		margin: 30rpx;
+		overflow: hidden;
+	}
+	.animation {
+		position: absolute;
+		top: 10rpx;
+		left: 0rpx;
+		width: 430rpx;
+		height: 2rpx;
+		background-color: #4CD964;
+		border-radius: 50%;
+	}
+	.manual{
+		width: 300rpx;
+		height: 100rpx;
+		background: #0183FA;
+		border-radius: 60rpx 60rpx 60rpx 60rpx;
+		font-size: 34rpx;
+		font-family: PingFang SC-Medium, PingFang SC;
+		font-weight: 400;
+		color: #FFFFFF;
+		line-height: 100rpx;
+		text-align: center;
+		position: fixed;
+		bottom: 76rpx;
+		left: 226rpx;
+	}
+</style>

+ 26 - 0
styles/animation.styl

@@ -0,0 +1,26 @@
+
+vendors = official
+@keyframes rotate {
+  0% {
+    transform: rotateZ(0deg) 
+  }  
+  100% {
+    transform: rotateZ(360deg) 
+  }
+}
+@keyframes Rerotate {
+  0% {
+    transform: rotateZ(0deg) 
+  }  
+  100% {
+    transform: rotateZ(-360deg) 
+  }
+}
+@keyframes flicker {
+  0% {
+    opacity 0
+  }  
+  100% {
+    opacity 1
+  }
+}

+ 73 - 0
styles/button.styl

@@ -0,0 +1,73 @@
+@import './variable.styl'
+.btn-primary-big-radius
+	background-color $primary
+	color $color-ff
+	width 625rpx
+	line-height 104rpx
+	font-size 33rpx
+	text-align center
+	border-radius 50rpx
+	margin:0 auto;
+.btn-prohibit-big-radius
+	background-color $prohibit
+	color $color-ff
+	width 625rpx
+	line-height 104rpx
+	font-size 33rpx
+	text-align center
+	border-radius 50rpx
+	margin:0 auto;
+.btn-primary-big
+	background-color $primary
+	color $color-ff
+	width 625rpx
+	line-height 104rpx
+	font-size 33rpx
+	text-align center
+	border-radius 20rpx
+	margin:0 auto;
+.btn-prohibit-big
+	background-color $prohibit
+	color $color-ff
+	width 625rpx
+	line-height 104rpx
+	font-size 33rpx
+	text-align center
+	border-radius 20rpx
+	margin:0 auto;
+//底部边框 
+.border-bottom-f7
+	border-bottom:2rpx solid #f7f7f7;
+//主色边框
+.border-primary
+	border:2rpx solid #00b68a;
+//单行溢出省略号
+.dlc-one-row-omit
+	display block
+	overflow hidden
+	text-overflow ellipsis
+	white-space nowrap
+//双行溢出省略号
+.dlc-tow-row-omit
+	display -webkit-box
+	-webkit-box-orient vertical
+	-webkit-line-clamp 2
+	overflow hidden
+//三行溢出省略号
+.dlc-three-row-omit
+	display -webkit-box
+	-webkit-box-orient vertical
+	-webkit-line-clamp 3
+	overflow hidden
+//四行溢出省略号
+.dlc-four-row-omit
+	display -webkit-box
+	-webkit-box-orient vertical
+	-webkit-line-clamp 4
+	overflow hidden
+//文本自动换行
+.dlc-text-auto-row
+	width 456rpx
+	word-wrap break-word
+	word-break break-all
+	overflow  hidden

+ 22 - 0
styles/color.styl

@@ -0,0 +1,22 @@
+@import './variable.styl'
+//主题色
+.primary
+	color $primary !important
+.back-primary
+	background $back-primary !important
+.back-color
+	background $back-color !important
+.back-e0
+	background $back-e0 !important
+.back-ff
+	background $back-ff !important
+.color-ff
+	color $color-ff !important
+.font-color
+	color $font-color !important
+.color-33
+	color $color-33 !important
+.color-99
+	color $color-99 !important
+.color-fail
+	color $fail !important

+ 68 - 0
styles/flex.styl

@@ -0,0 +1,68 @@
+.flex
+  display flex
+  align-items: center
+.flex-column-center
+  display flex
+  flex-direction: column
+  justify-content: center
+  align-items: center
+.flex-column-between
+  display flex
+  flex-direction: column
+  justify-content: space-between
+  align-items: center
+.flex-column-around
+  display flex
+  flex-direction: column
+  justify-content: space-around
+  align-items: center
+.flex-center
+  display flex
+  justify-content: center
+  align-items: center
+.flex-between
+  display flex
+  justify-content: space-between
+  align-items: center
+.flex-around
+  display flex
+  justify-content: space-around
+  align-items: center
+.flex-wrap
+  flex-wrap:wrap
+.flex-end
+  justify-content: flex-end
+.flex-start
+  justify-content: flex-start
+.flex-column
+  flex-direction: column
+.flex-align-end
+  align-items: flex-end
+.flex-align-baseline
+  align-items: baseline
+.flex1
+  flex 1
+.flex2
+  flex 2
+.flex3
+  flex 3
+// 没有数据时的展示
+.null-data
+	width 100%
+	margin-top 30rpx
+	display flex
+	align-items center
+	flex-direction column 
+	justify-content center
+	.image
+		width 100rpx
+		height 100rpx
+	view
+		margin-top 30rpx
+		font-size 32rpx
+		color #929292
+.end-data
+	text-align center
+	font-size 32rpx
+	color #929292
+	line-height 80rpx

+ 3 - 0
styles/font.styl

@@ -0,0 +1,3 @@
+for ft in 12..50
+  .ft{ft}
+    font-size: ft * 1upx

+ 6 - 0
styles/index.styl

@@ -0,0 +1,6 @@
+@import 'font.styl'
+@import 'layout.styl'
+@import 'flex.styl'
+@import 'color.styl'
+@import 'button.styl'
+@import 'w-e-text.styl'

+ 91 - 0
styles/layout.styl

@@ -0,0 +1,91 @@
+.sticky
+  top 0
+  position sticky
+.content
+  height 100%
+.w100
+  width 100%
+.pr
+  position relative
+.pa
+  position absolute
+.pcy
+  position absolute
+  top:50%
+  transform: translateY(-50%)
+.pcx
+  position absolute
+  left:50%
+  transform: translateX(-50%)
+.pc
+  position absolute
+  top 50%
+  left 50%
+  transform translate(-50%, -50%)
+.indent
+  text-indent: 2em
+.ta
+  text-align: center
+.va
+  vertical-align: middle
+.vt
+  vertical-align: top
+.no_data
+  text-align: center
+  margin-top 40px
+.wrapper
+  position relative
+  min-width 100%
+  min-height 100%
+.eli
+  overflow: hidden;
+  text-overflow:ellipsis;
+  white-space: nowrap;
+.nowrap
+  white-space nowrap
+.mg-auto
+  margin: auto
+.radius
+  border-radius: 50%
+.radius-16
+  border-radius: 16upx
+.radius-8
+  border-radius: 8upx
+.radius-4
+  border-radius: 4upx
+for ft in 2..50
+  .pd{ft}-x
+    padding-right 1upx * ft
+    padding-left 1upx * ft
+  .pd{ft}-y
+    padding-top 1upx * ft
+    padding-bottom 1upx * ft
+  .pd{ft}
+    padding: 1upx * ft
+  .pdt{ft}
+    padding-top: 1upx * ft
+  .pdb{ft}
+    padding-bottom: 1upx * ft
+  .pdr{ft}
+    padding-right: 1upx * ft
+  .pdl{ft}
+    padding-left: 1upx * ft
+  .mg{ft}-x
+    margin-right 1upx * ft
+    margin-left 1upx * ft
+  .mg{ft}-y
+    margin-top 1upx * ft
+    margin-bottom 1upx * ft
+  .mg{ft}
+    margin: 1upx * ft
+  .mgt{ft}
+    margin-top: 1upx * ft
+  .mgb{ft}
+    margin-bottom: 1upx * ft
+  .mgr{ft}
+    margin-right: 1upx * ft
+  .mgl{ft}
+    margin-left: 1upx * ft
+
+
+

+ 19 - 0
styles/variable.styl

@@ -0,0 +1,19 @@
+
+// 主题色
+$primary = #0183FA
+$success = #FE0000
+$warn = #FE0000
+$fail = #FE0000
+$prohibit = #E0E0E0
+$back-primary = #00b68a
+$back-color = #F5F5F5
+$back-e0 = #e0e0e0
+$back-ff = #ffffff
+$color-ff = #ffffff
+$font-color = #00b68a
+$color-33 = #333333
+$color-99 = #999999
+
+
+
+

+ 256 - 0
styles/w-e-text.styl

@@ -0,0 +1,256 @@
+.w-e-toolbar,
+.w-e-text-container,
+.w-e-menu-panel {
+  padding: 0;
+  margin: 0;
+  box-sizing: border-box;
+  background-color: #fff;
+  h1 {
+    font-size: 32px !important;
+  }
+  h2 {
+    font-size: 24px !important;
+  }
+  h3 {
+    font-size: 18.72px !important;
+  }
+  h4 {
+    font-size: 16px !important;
+  }
+  h5 {
+    font-size: 13.28px !important;
+  }
+  p {
+    font-size: 16px !important;
+  }
+  /*表情菜单样式*/
+  .eleImg{
+    cursor: pointer;
+    display: inline-block;
+    font-size: 18px;
+    padding: 0 3px;
+  }
+  * {
+    padding: 0;
+    margin: 0;
+    box-sizing: border-box;
+  }
+  /*分割线样式*/
+  hr{
+    cursor: pointer;
+    display: block;
+    height: 0px;
+    border: 0;
+    border-top: 3px solid #ccc;
+    margin: 20px 0;
+  }
+}
+
+.w-e-clear-fix:after {
+  content: "";
+  display: table;
+  clear: both;
+}
+
+.w-e-drop-list-item {
+  position: relative;
+  top: 1px;
+  padding-right: 7px;
+  color: #333 !important;
+}
+
+.w-e-drop-list-tl {
+  padding-left: 10px;
+  text-align: left;
+}
+.w-e-text-container {
+  position: relative;
+  height: 100%;
+
+  .w-e-progress {
+    position: absolute;
+    background-color: #1e88e5;
+    top: 0;
+    left: 0;
+    height: 1px;
+  }
+
+  .placeholder {
+    color: #D4D4D4;
+    position: absolute;
+    font-size: 11pt;
+    line-height: 22px;
+    left: 10px;
+    top: 10px;
+    user-select: none;
+    z-index: -1;
+  }
+}
+.w-e-text {
+  //padding: 0 10px;
+  //overflow-y: auto;
+
+  p,h1,h2,h3,h4,h5,table,pre {
+    margin: 10px 0;
+    line-height: 1.5;
+  }
+
+  ul, ol {
+    margin: 10px 0 10px 20px;
+  }
+
+  blockquote {
+    display: block;
+    border-left: 8px solid #d0e5f2;
+    padding: 5px 10px;
+    margin: 10px 0;
+    line-height: 1.4;
+    font-size: 100%;
+    background-color: #f1f1f1;
+  }
+
+  code {
+    display: inline-block;
+    background-color: #f1f1f1;
+    border-radius: 3px;
+    padding: 3px 5px;
+    margin: 0 3px;
+  }
+
+  pre {
+
+    code {
+      display: block;
+    }
+  }
+
+  table {
+    border-top: 1px solid #ccc;
+    border-left: 1px solid #ccc;
+
+    td,th {
+      border-bottom: 1px solid #ccc;
+      border-right: 1px solid #ccc;
+      padding: 3px 5px;
+      min-height: 30px;
+      height: 30px;
+    }
+
+    th {
+      border-bottom: 2px solid #ccc;
+      text-align: center;
+      background-color: #f1f1f1;
+    }
+  }
+
+  &:focus {
+    outline: none;
+  }
+
+  img {
+    cursor: pointer;
+
+    &:hover {
+      box-shadow: 0 0 5px #333;
+    }
+  }
+
+  .w-e-todo {
+    margin:0 0 0 20px;
+    li {
+      list-style:none;
+      font-size: 1em;
+      span:nth-child(1) {
+        position: relative;
+        left: -18px;
+        input {
+          position: absolute;
+          margin-right:3px;
+        }
+        // 防止其他样式通过属性选择器重置input样式
+        input[type=checkbox] {
+          top: 50%;
+          margin-top: -6px;
+        }
+      }
+    }
+  }
+}
+
+.w-e-tooltip {
+  position: absolute;
+  display: flex;
+  color: #f1f1f1;
+  background-color: rgba(0,0,0,.75);
+  box-shadow: 0 2px 8px 0 rgba(0,0,0,.15);
+  border-radius: 4px;
+  padding: 4px 5px 6px;
+  justify-content: center;
+  align-items: center;
+}
+// 下箭头
+.w-e-tooltip-up::after {
+  content: "";
+  position: absolute;
+  top: 100%;
+  left: 50%;
+  margin-left: -5px;
+  border: 5px solid rgba(0,0,0,0);
+  border-top-color: rgba(0,0,0,.73);
+}
+// 上箭头
+.w-e-tooltip-down::after {
+  content: "";
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  margin-left: -5px;
+  border: 5px solid rgba(0,0,0,0);
+  border-bottom-color: rgba(0,0,0,.73);
+}
+.w-e-tooltip-item-wrapper {
+  cursor: pointer;
+  font-size: 14px;
+  margin: 0 5px;
+
+  &:hover {
+    color: #ccc;
+    text-decoration: underline;
+  }
+}
+.w-e-text-container {
+  overflow: hidden;
+}
+
+.w-e-img-drag-mask {
+  position: absolute;
+  z-index: 1;
+  border: 1px dashed #ccc;
+  box-sizing: border-box;
+
+  .w-e-img-drag-rb {
+    position: absolute;
+    right: -5px;
+    bottom: -5px;
+    width: 16px;
+    height: 16px;
+    border-radius: 50%;
+    background: #ccc;
+    cursor: se-resize;
+  }
+
+  .w-e-img-drag-show-size {
+    min-width: 110px;
+    height: 22px;
+    line-height: 22px;
+    font-size: 14px;
+    color: #999;
+    position: absolute;
+    left: 0;
+    top: 0;
+    background-color: #999;
+    color: #fff;
+    border-radius: 2px;
+    padding: 0 5px;
+  }
+}

+ 76 - 0
uni.scss

@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:24rpx;
+$uni-font-size-base:28rpx;
+$uni-font-size-lg:32rpx;
+
+/* 图片尺寸 */
+$uni-img-size-sm:40rpx;
+$uni-img-size-base:52rpx;
+$uni-img-size-lg:80rpx;
+
+/* Border Radius */
+$uni-border-radius-sm: 4rpx;
+$uni-border-radius-base: 6rpx;
+$uni-border-radius-lg: 12rpx;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 10px;
+$uni-spacing-row-base: 20rpx;
+$uni-spacing-row-lg: 30rpx;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 8rpx;
+$uni-spacing-col-base: 16rpx;
+$uni-spacing-col-lg: 24rpx;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:40rpx;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:36rpx;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:30rpx;

+ 196 - 0
uni_modules/mmmm-image-tools/index.js

@@ -0,0 +1,196 @@
+function getLocalFilePath(path) {
+    if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf('_downloads') === 0) {
+        return path
+    }
+    if (path.indexOf('file://') === 0) {
+        return path
+    }
+    if (path.indexOf('/storage/emulated/0/') === 0) {
+        return path
+    }
+    if (path.indexOf('/') === 0) {
+        var localFilePath = plus.io.convertAbsoluteFileSystem(path)
+        if (localFilePath !== path) {
+            return localFilePath
+        } else {
+            path = path.substr(1)
+        }
+    }
+    return '_www/' + path
+}
+
+function dataUrlToBase64(str) {
+    var array = str.split(',')
+    return array[array.length - 1]
+}
+
+var index = 0
+function getNewFileId() {
+    return Date.now() + String(index++)
+}
+
+function biggerThan(v1, v2) {
+    var v1Array = v1.split('.')
+    var v2Array = v2.split('.')
+    var update = false
+    for (var index = 0; index < v2Array.length; index++) {
+        var diff = v1Array[index] - v2Array[index]
+        if (diff !== 0) {
+            update = diff > 0
+            break
+        }
+    }
+    return update
+}
+
+export function pathToBase64(path) {
+    return new Promise(function(resolve, reject) {
+        if (typeof window === 'object' && 'document' in window) {
+            if (typeof FileReader === 'function') {
+                var xhr = new XMLHttpRequest()
+                xhr.open('GET', path, true)
+                xhr.responseType = 'blob'
+                xhr.onload = function() {
+                    if (this.status === 200) {
+                        let fileReader = new FileReader()
+                        fileReader.onload = function(e) {
+                            resolve(e.target.result)
+                        }
+                        fileReader.onerror = reject
+                        fileReader.readAsDataURL(this.response)
+                    }
+                }
+                xhr.onerror = reject
+                xhr.send()
+                return
+            }
+            var canvas = document.createElement('canvas')
+            var c2x = canvas.getContext('2d')
+            var img = new Image
+            img.onload = function() {
+                canvas.width = img.width
+                canvas.height = img.height
+                c2x.drawImage(img, 0, 0)
+                resolve(canvas.toDataURL())
+                canvas.height = canvas.width = 0
+            }
+            img.onerror = reject
+            img.src = path
+            return
+        }
+        if (typeof plus === 'object') {
+            plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) {
+                entry.file(function(file) {
+                    var fileReader = new plus.io.FileReader()
+                    fileReader.onload = function(data) {
+                        resolve(data.target.result)
+                    }
+                    fileReader.onerror = function(error) {
+                        reject(error)
+                    }
+                    fileReader.readAsDataURL(file)
+                }, function(error) {
+                    reject(error)
+                })
+            }, function(error) {
+                reject(error)
+            })
+            return
+        }
+        if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
+            wx.getFileSystemManager().readFile({
+                filePath: path,
+                encoding: 'base64',
+                success: function(res) {
+                    resolve('data:image/png;base64,' + res.data)
+                },
+                fail: function(error) {
+                    reject(error)
+                }
+            })
+            return
+        }
+        reject(new Error('not support'))
+    })
+}
+
+export function base64ToPath(base64) {
+    return new Promise(function(resolve, reject) {
+        if (typeof window === 'object' && 'document' in window) {
+            base64 = base64.split(',')
+            var type = base64[0].match(/:(.*?);/)[1]
+            var str = atob(base64[1])
+            var n = str.length
+            var array = new Uint8Array(n)
+            while (n--) {
+                array[n] = str.charCodeAt(n)
+            }
+            return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { type: type })))
+        }
+        var extName = base64.split(',')[0].match(/data\:\S+\/(\S+);/)
+        if (extName) {
+            extName = extName[1]
+        } else {
+            reject(new Error('base64 error'))
+        }
+        var fileName = getNewFileId() + '.' + extName
+        if (typeof plus === 'object') {
+            var basePath = '_doc'
+            var dirPath = 'uniapp_temp'
+            var filePath = basePath + '/' + dirPath + '/' + fileName
+            if (!biggerThan(plus.os.name === 'Android' ? '1.9.9.80627' : '1.9.9.80472', plus.runtime.innerVersion)) {
+                plus.io.resolveLocalFileSystemURL(basePath, function(entry) {
+                    entry.getDirectory(dirPath, {
+                        create: true,
+                        exclusive: false,
+                    }, function(entry) {
+                        entry.getFile(fileName, {
+                            create: true,
+                            exclusive: false,
+                        }, function(entry) {
+                            entry.createWriter(function(writer) {
+                                writer.onwrite = function() {
+                                    resolve(filePath)
+                                }
+                                writer.onerror = reject
+                                writer.seek(0)
+                                writer.writeAsBinary(dataUrlToBase64(base64))
+                            }, reject)
+                        }, reject)
+                    }, reject)
+                }, reject)
+                return
+            }
+            var bitmap = new plus.nativeObj.Bitmap(fileName)
+            bitmap.loadBase64Data(base64, function() {
+                bitmap.save(filePath, {}, function() {
+                    bitmap.clear()
+                    resolve(filePath)
+                }, function(error) {
+                    bitmap.clear()
+                    reject(error)
+                })
+            }, function(error) {
+                bitmap.clear()
+                reject(error)
+            })
+            return
+        }
+        if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
+            var filePath = wx.env.USER_DATA_PATH + '/' + fileName
+            wx.getFileSystemManager().writeFile({
+                filePath: filePath,
+                data: dataUrlToBase64(base64),
+                encoding: 'base64',
+                success: function() {
+                    resolve(filePath)
+                },
+                fail: function(error) {
+                    reject(error)
+                }
+            })
+            return
+        }
+        reject(new Error('not support'))
+    })
+}

+ 11 - 0
uni_modules/mmmm-image-tools/package.json

@@ -0,0 +1,11 @@
+{
+    "id": "mmmm-image-tools",
+    "name": "image-tools",
+    "version": "1.4.0",
+    "description": "图像转换工具,可用于图像和base64的转换",
+    "keywords": [
+        "base64",
+        "保存",
+        "图像"
+    ]
+}

+ 52 - 0
uni_modules/uni-data-picker/changelog.md

@@ -0,0 +1,52 @@
+## 1.0.1(2021-11-23)
+- 修复 由上个版本引发的map、v-model等属性不生效的bug
+## 1.0.0(2021-11-19)
+- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+## 0.4.9(2021-10-28)
+- 修复 VUE2 v-model 概率无效的 bug
+## 0.4.8(2021-10-27)
+- 修复 v-model 概率无效的 bug
+## 0.4.7(2021-10-25)
+- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
+- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
+## 0.4.6(2021-10-19)
+- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
+## 0.4.5(2021-09-26)
+- 新增 清除已选项的功能(通过 clearIcon 属性配置是否显示按钮),同时提供 clear 方法以供调用,二者等效
+- 修复 readonly 为 true 时报错的 bug
+## 0.4.4(2021-09-26)
+- 修复 上一版本造成的 map 属性失效的 bug
+- 新增 ellipsis 属性,支持配置 tab 选项长度过长时是否自动省略
+## 0.4.3(2021-09-24)
+- 修复 某些情况下级联未触发的 bug
+## 0.4.2(2021-09-23)
+- 新增 提供 show 和 hide 方法,开发者可以通过 ref 调用
+- 新增 选项内容过长自动添加省略号
+## 0.4.1(2021-09-15)
+- 新增 map 属性 字段映射,将 text/value 映射到数据中的其他字段
+## 0.4.0(2021-07-13)
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.3.5(2021-06-04)
+- 修复 无法加载云端数据的问题
+## 0.3.4(2021-05-28)
+- 修复 v-model 无效问题
+- 修复 loaddata 为空数据组时加载时间过长问题
+- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
+## 0.3.3(2021-05-12)
+- 新增 组件示例地址
+## 0.3.2(2021-04-22)
+- 修复 非树形数据有 where 属性查询报错的问题
+## 0.3.1(2021-04-15)
+- 修复 本地数据概率无法回显时问题
+## 0.3.0(2021-04-07)
+- 新增 支持云端非树形表结构数据
+- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
+## 0.2.0(2021-03-15)
+- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
+## 0.1.9(2021-03-09)
+- 修复 微信小程序某些情况下无法选择的问题
+## 0.1.8(2021-02-05)
+- 优化 部分样式在 nvue 上的兼容表现
+## 0.1.7(2021-02-05)
+- 调整为 uni_modules 目录规范

+ 45 - 0
uni_modules/uni-data-picker/components/uni-data-picker/keypress.js

@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+  name: 'Keypress',
+  props: {
+    disable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted () {
+    const keyNames = {
+      esc: ['Esc', 'Escape'],
+      tab: 'Tab',
+      enter: 'Enter',
+      space: [' ', 'Spacebar'],
+      up: ['Up', 'ArrowUp'],
+      left: ['Left', 'ArrowLeft'],
+      right: ['Right', 'ArrowRight'],
+      down: ['Down', 'ArrowDown'],
+      delete: ['Backspace', 'Delete', 'Del']
+    }
+    const listener = ($event) => {
+      if (this.disable) {
+        return
+      }
+      const keyName = Object.keys(keyNames).find(key => {
+        const keyName = $event.key
+        const value = keyNames[key]
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
+      })
+      if (keyName) {
+        // 避免和其他按键事件冲突
+        setTimeout(() => {
+          this.$emit(keyName, {})
+        }, 0)
+      }
+    }
+    document.addEventListener('keyup', listener)
+    this.$once('hook:beforeDestroy', () => {
+      document.removeEventListener('keyup', listener)
+    })
+  },
+	render: () => {}
+}
+// #endif

+ 546 - 0
uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue

@@ -0,0 +1,546 @@
+<template>
+	<view class="uni-data-tree">
+		<view class="uni-data-tree-input" @click="handleInput">
+			<slot :options="options" :data="inputSelected" :error="errorMessage">
+				<view class="input-value" :class="{'input-value-border': border}">
+					<text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text>
+					<view v-else-if="loading && !isOpened" class="selected-area">
+						<uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
+					</view>
+					<scroll-view v-else-if="inputSelected.length" class="selected-area" scroll-x="true">
+						<view class="selected-list">
+							<view class="selected-item" v-for="(item,index) in inputSelected" :key="index">
+								<text>{{item.text}}</text><text v-if="index<inputSelected.length-1"
+									class="input-split-line">{{split}}</text>
+							</view>
+						</view>
+					</scroll-view>
+					<text v-else class="selected-area placeholder">{{placeholder}}</text>
+					<view v-show="clearIcon && !readonly && inputSelected.length" class="icon-clear"
+						@click.stop="clear">
+						<uni-icons type="clear" color="#e1e1e1" size="14"></uni-icons>
+					</view>
+					<view class="arrow-area" v-if="(!clearIcon || !inputSelected.length) && !readonly ">
+						<view class="input-arrow"></view>
+					</view>
+				</view>
+			</slot>
+		</view>
+		<view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
+		<view class="uni-data-tree-dialog" v-if="isOpened">
+			<view class="uni-popper__arrow"></view>
+			<view class="dialog-caption">
+				<view class="title-area">
+					<text class="dialog-title">{{popupTitle}}</text>
+				</view>
+				<view class="dialog-close" @click="handleClose">
+					<view class="dialog-close-plus" data-id="close"></view>
+					<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
+				</view>
+			</view>
+			<data-picker-view class="picker-view" ref="pickerView" v-model="dataValue" :localdata="localdata"
+				:addType="addType" :addIndex="addIndex"
+				:preload="preload" :collection="collection" :field="field" :orderby="orderby" :where="where"
+				:step-searh="stepSearh" :self-field="selfField" :parent-field="parentField" :managed-mode="true"
+				:map="map" :ellipsis="ellipsis" @change="onchange" @datachange="ondatachange" @nodeclick="onnodeclick">
+			</data-picker-view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import dataPicker from "../uni-data-pickerview/uni-data-picker.js"
+	import DataPickerView from "../uni-data-pickerview/uni-data-pickerview.vue"
+
+	/**
+	 * DataPicker 级联选择
+	 * @description 支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+	 * @property {String} popup-title 弹出窗口标题
+	 * @property {Array} localdata 本地数据,参考
+	 * @property {Boolean} border = [true|false] 是否有边框
+	 * @property {Boolean} readonly = [true|false] 是否仅读
+	 * @property {Boolean} preload = [true|false] 是否预加载数据
+	 * @value true 开启预加载数据,点击弹出窗口后显示已加载数据
+	 * @value false 关闭预加载数据,点击弹出窗口后开始加载数据
+	 * @property {Boolean} step-searh = [true|false] 是否分布查询
+	 * @value true 启用分布查询,仅查询当前选中节点
+	 * @value false 关闭分布查询,一次查询出所有数据
+	 * @property {String|DBFieldString} self-field 分布查询当前字段名称
+	 * @property {String|DBFieldString} parent-field 分布查询父字段名称
+	 * @property {String|DBCollectionString} collection 表名
+	 * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
+	 * @property {String} orderby 排序字段及正序倒叙设置
+	 * @property {String|JQLString} where 查询条件
+	 * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
+	 * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
+	 */
+	export default {
+		name: 'UniDataPicker',
+		emits: ['popupopened', 'popupclosed', 'nodeclick', 'input', 'change', 'update:modelValue'],
+		mixins: [dataPicker],
+		components: {
+			DataPickerView
+		},
+		props: {
+			addType:{},
+			addIndex:{},
+			options: {
+				type: [Object, Array],
+				default () {
+					return {
+						pageType:true
+					}
+				}
+			},
+			popupTitle: {
+				type: String,
+				default: '请选择'
+			},
+			placeholder: {
+				type: String,
+				default: '请选择'
+			},
+			heightMobile: {
+				type: String,
+				default: ''
+			},
+			readonly: {
+				type: Boolean,
+				default: false
+			},
+			clearIcon: {
+				type: Boolean,
+				default: true
+			},
+			border: {
+				type: Boolean,
+				default: true
+			},
+			split: {
+				type: String,
+				default: '/'
+			},
+			ellipsis: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				isOpened: false,
+				inputSelected: []
+			}
+		},
+		created() {
+			this.form = this.getForm('uniForms')
+			this.formItem = this.getForm('uniFormsItem')
+			if (this.formItem) {
+				if (this.formItem.name) {
+					this.rename = this.formItem.name
+					this.form.inputChildrens.push(this)
+				}
+			}
+
+			this.$nextTick(() => {
+				this.load()
+			})
+		},
+		methods: {
+			pageRefresh(){
+				this.show();
+			},
+			clear() {
+				this.inputSelected.splice(0)
+				this._dispatchEvent([])
+			},
+			onPropsChange() {
+				this._treeData = []
+				this.selectedIndex = 0
+				this.load()
+			},
+			load() {
+				if (this.readonly) {
+					this._processReadonly(this.localdata, this.dataValue)
+					return
+				}
+
+				if (this.isLocaldata) {
+					this.loadData()
+					this.inputSelected = this.selected.slice(0)
+				} else if (!this.parentField && !this.selfField && this.hasValue) {
+					this.getNodeData(() => {
+						this.inputSelected = this.selected.slice(0)
+					})
+				} else if (this.hasValue) {
+					this.getTreePath(() => {
+						this.inputSelected = this.selected.slice(0)
+					})
+				}
+			},
+			getForm(name = 'uniForms') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false;
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			show() {
+				this.isOpened = true
+				this.$nextTick(() => {
+					this.$refs.pickerView.updateData({
+						treeData: this._treeData,
+						selected: this.selected,
+						selectedIndex: this.selectedIndex
+					})
+				})
+				this.$emit('popupopened')
+			},
+			hide() {
+				this.isOpened = false
+				this.$emit('popupclosed')
+			},
+			handleInput() {
+				if (this.readonly) {
+					return
+				}
+				this.show()
+			},
+			handleClose(e) {
+				this.hide()
+			},
+			onnodeclick(e) {
+				this.$emit('nodeclick', e)
+			},
+			ondatachange(e) {
+				this._treeData = this.$refs.pickerView._treeData
+			},
+			onchange(e) {
+				this.hide()
+				this.inputSelected = e
+				this._dispatchEvent(e)
+			},
+			_processReadonly(dataList, value) {
+				var isTree = dataList.findIndex((item) => {
+					return item.children
+				})
+				if (isTree > -1) {
+					let inputValue
+					if (Array.isArray(value)) {
+						inputValue = value[value.length - 1]
+						if (typeof inputValue === 'object' && inputValue.value) {
+							inputValue = inputValue.value
+						}
+					} else {
+						inputValue = value
+					}
+					this.inputSelected = this._findNodePath(inputValue, this.localdata)
+					return
+				}
+
+				if (!this.hasValue) {
+					this.inputSelected = []
+					return
+				}
+
+				let result = []
+				for (let i = 0; i < value.length; i++) {
+					var val = value[i]
+					var item = dataList.find((v) => {
+						return v.value == val
+					})
+					if (item) {
+						result.push(item)
+					}
+				}
+				if (result.length) {
+					this.inputSelected = result
+				}
+			},
+			_filterForArray(data, valueArray) {
+				var result = []
+				for (let i = 0; i < valueArray.length; i++) {
+					var value = valueArray[i]
+					var found = data.find((item) => {
+						return item.value == value
+					})
+					if (found) {
+						result.push(found)
+					}
+				}
+				return result
+			},
+			_dispatchEvent(selected) {
+				let item = {}
+				if (selected.length) {
+					var value = new Array(selected.length)
+					for (var i = 0; i < selected.length; i++) {
+						value[i] = selected[i].value
+					}
+					item = selected[selected.length - 1]
+				} else {
+					item.value = ''
+				}
+				if (this.formItem) {
+					this.formItem.setValue(item.value)
+				}
+
+				this.$emit('input', item.value)
+				this.$emit('update:modelValue', item.value)
+				this.$emit('change', {
+					detail: {
+						value: selected
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.uni-data-tree {
+		position: relative;
+		font-size: 14px;
+	}
+
+	.error-text {
+		color: #DD524D;
+	}
+
+	.input-value {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		flex-wrap: nowrap;
+		font-size: 14px;
+		line-height: 38px;
+		padding: 0 5px;
+		overflow: hidden;
+		/* #ifdef APP-NVUE */
+		height: 40px;
+		/* #endif */
+	}
+
+	.input-value-border {
+		border: 1px solid #e5e5e5;
+		border-radius: 5px;
+	}
+
+	.selected-area {
+		flex: 1;
+		overflow: hidden;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.load-more {
+		/* #ifndef APP-NVUE */
+		margin-right: auto;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		width: 40px;
+		/* #endif */
+	}
+
+	.selected-list {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex-wrap: nowrap;
+		padding: 0 5px;
+	}
+
+	.selected-item {
+		flex-direction: row;
+		padding: 0 1px;
+		/* #ifndef APP-NVUE */
+		white-space: nowrap;
+		/* #endif */
+	}
+
+	.placeholder {
+		color: grey;
+	}
+
+	.input-split-line {
+		opacity: .5;
+	}
+
+	.arrow-area {
+		position: relative;
+		width: 20px;
+		/* #ifndef APP-NVUE */
+		margin-bottom: 5px;
+		margin-left: auto;
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		transform: rotate(-45deg);
+		transform-origin: center;
+	}
+
+	.input-arrow {
+		width: 7px;
+		height: 7px;
+		border-left: 1px solid #999;
+		border-bottom: 1px solid #999;
+	}
+
+	.uni-data-tree-cover {
+		position: fixed;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		background-color: rgba(0, 0, 0, .4);
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		z-index: 100;
+	}
+
+	.uni-data-tree-dialog {
+		position: fixed;
+		left: 0;
+		/* top: 20%; */
+		top:0;
+		right: 0;
+		bottom: 0;
+		background-color: #FFFFFF;
+/* 		border-top-left-radius: 10px;
+		border-top-right-radius: 10px; */
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		z-index: 102;
+		overflow: hidden;
+		/* #ifdef APP-NVUE */
+		/* width: 750rpx; */
+		/* #endif */
+	}
+
+	.dialog-caption {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		/* border-bottom: 1px solid #f0f0f0; */
+	}
+
+	.title-area {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		/* #ifndef APP-NVUE */
+		margin: auto;
+		/* #endif */
+		padding: 0 10px;
+	}
+
+	.dialog-title {
+		/* font-weight: bold; */
+		line-height: 44px;
+	}
+
+	.dialog-close {
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		padding: 0 15px;
+	}
+
+	.dialog-close-plus {
+		width: 16px;
+		height: 2px;
+		background-color: #666;
+		border-radius: 2px;
+		transform: rotate(45deg);
+	}
+
+	.dialog-close-rotate {
+		position: absolute;
+		transform: rotate(-45deg);
+	}
+
+	.picker-view {
+		flex: 1;
+		overflow: hidden;
+	}
+
+	/* #ifdef H5 */
+	@media all and (min-width: 768px) {
+		.uni-data-tree-cover {
+			background-color: transparent;
+		}
+
+		.uni-data-tree-dialog {
+			position: absolute;
+			top: 55px;
+			height: auto;
+			min-height: 400px;
+			max-height: 50vh;
+			background-color: #fff;
+			border: 1px solid #EBEEF5;
+			box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+			border-radius: 4px;
+			overflow: unset;
+		}
+
+		.dialog-caption {
+			display: none;
+		}
+
+		.icon-clear {
+			margin-right: 5px;
+		}
+	}
+
+	/* #endif */
+
+	/* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
+	.uni-popper__arrow,
+	.uni-popper__arrow::after {
+		position: absolute;
+		display: block;
+		width: 0;
+		height: 0;
+		border-color: transparent;
+		border-style: solid;
+		border-width: 6px;
+	}
+
+	.uni-popper__arrow {
+		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+		top: -6px;
+		left: 10%;
+		margin-right: 3px;
+		border-top-width: 0;
+		border-bottom-color: #EBEEF5;
+	}
+
+	.uni-popper__arrow::after {
+		content: " ";
+		top: 1px;
+		margin-left: -6px;
+		border-top-width: 0;
+		border-bottom-color: #fff;
+	}
+	</style>

+ 563 - 0
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js

@@ -0,0 +1,563 @@
+export default {
+  props: {
+    localdata: {
+      type: [Array, Object],
+      default () {
+        return []
+      }
+    },
+    spaceInfo: {
+      type: Object,
+      default () {
+        return {}
+      }
+    },
+    collection: {
+      type: String,
+      default: ''
+    },
+    action: {
+      type: String,
+      default: ''
+    },
+    field: {
+      type: String,
+      default: ''
+    },
+    orderby: {
+      type: String,
+      default: ''
+    },
+    where: {
+      type: [String, Object],
+      default: ''
+    },
+    pageData: {
+      type: String,
+      default: 'add'
+    },
+    pageCurrent: {
+      type: Number,
+      default: 1
+    },
+    pageSize: {
+      type: Number,
+      default: 20
+    },
+    getcount: {
+      type: [Boolean, String],
+      default: false
+    },
+    getone: {
+      type: [Boolean, String],
+      default: false
+    },
+    gettree: {
+      type: [Boolean, String],
+      default: false
+    },
+    manual: {
+      type: Boolean,
+      default: false
+    },
+    value: {
+      type: [Array, String, Number],
+      default () {
+        return []
+      }
+    },
+    modelValue: {
+      type: [Array, String, Number],
+      default () {
+        return []
+      }
+    },
+    preload: {
+      type: Boolean,
+      default: false
+    },
+    stepSearh: {
+      type: Boolean,
+      default: true
+    },
+    selfField: {
+      type: String,
+      default: ''
+    },
+    parentField: {
+      type: String,
+      default: ''
+    },
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    map: {
+      type: Object,
+      default() {
+        return {
+          text: "text",
+          value: "value"
+        }
+      }
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      errorMessage: '',
+      loadMore: {
+        contentdown: '',
+        contentrefresh: '',
+        contentnomore: ''
+      },
+      dataList: [],
+      selected: [],
+      selectedIndex: 0,
+      page: {
+        current: this.pageCurrent,
+        size: this.pageSize,
+        count: 0
+      }
+    }
+  },
+  computed: {
+    isLocaldata() {
+      return !this.collection.length
+    },
+    postField() {
+      let fields = [this.field];
+      if (this.parentField) {
+        fields.push(`${this.parentField} as parent_value`);
+      }
+      return fields.join(',');
+    },
+    dataValue() {
+      let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null || this.modelValue !== undefined)
+      return isModelValue ? this.modelValue : this.value
+    },
+    hasValue() {
+      if (typeof this.dataValue === 'number') {
+        return true
+      }
+      return (this.dataValue != null) && (this.dataValue.length > 0)
+    }
+  },
+  created() {
+    this.$watch(() => {
+      var al = [];
+      ['pageCurrent',
+        'pageSize',
+        'spaceInfo',
+        'value',
+        'modelValue',
+        'localdata',
+        'collection',
+        'action',
+        'field',
+        'orderby',
+        'where',
+        'getont',
+        'getcount',
+        'gettree'
+      ].forEach(key => {
+        al.push(this[key])
+      });
+      return al
+    }, (newValue, oldValue) => {
+      let needReset = false
+      for (let i = 2; i < newValue.length; i++) {
+        if (newValue[i] != oldValue[i]) {
+          needReset = true
+          break
+        }
+      }
+      if (newValue[0] != oldValue[0]) {
+        this.page.current = this.pageCurrent
+      }
+      this.page.size = this.pageSize
+
+      this.onPropsChange()
+    })
+    this._treeData = []
+  },
+  methods: {
+    onPropsChange() {
+      this._treeData = []
+    },
+    getCommand(options = {}) {
+      /* eslint-disable no-undef */
+      let db = uniCloud.database(this.spaceInfo)
+
+      const action = options.action || this.action
+      if (action) {
+        db = db.action(action)
+      }
+
+      const collection = options.collection || this.collection
+      db = db.collection(collection)
+
+      const where = options.where || this.where
+      if (!(!where || !Object.keys(where).length)) {
+        db = db.where(where)
+      }
+
+      const field = options.field || this.field
+      if (field) {
+        db = db.field(field)
+      }
+
+      const orderby = options.orderby || this.orderby
+      if (orderby) {
+        db = db.orderBy(orderby)
+      }
+
+      const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
+      const size = options.pageSize !== undefined ? options.pageSize : this.page.size
+      const getCount = options.getcount !== undefined ? options.getcount : this.getcount
+      const getTree = options.gettree !== undefined ? options.gettree : this.gettree
+
+      const getOptions = {
+        getCount,
+        getTree
+      }
+      if (options.getTreePath) {
+        getOptions.getTreePath = options.getTreePath
+      }
+
+      db = db.skip(size * (current - 1)).limit(size).get(getOptions)
+
+      return db
+    },
+		getNodeData(callback) {
+		  if (this.loading) {
+		    return
+		  }
+		  this.loading = true
+		  this.getCommand({
+		    field: this.postField,
+				where: this._pathWhere()
+		  }).then((res) => {
+		    this.loading = false
+		    this.selected = res.result.data
+		    callback && callback()
+		  }).catch((err) => {
+		    this.loading = false
+		    this.errorMessage = err
+		  })
+		},
+    getTreePath(callback) {
+      if (this.loading) {
+        return
+      }
+      this.loading = true
+
+      this.getCommand({
+        field: this.postField,
+        getTreePath: {
+          startWith: `${this.selfField}=='${this.dataValue}'`
+        }
+      }).then((res) => {
+        this.loading = false
+        let treePath = []
+        this._extractTreePath(res.result.data, treePath)
+        this.selected = treePath
+        callback && callback()
+      }).catch((err) => {
+        this.loading = false
+        this.errorMessage = err
+      })
+    },
+    loadData() {
+      if (this.isLocaldata) {
+        this._processLocalData()
+        return
+      }
+
+      if (this.dataValue != null) {
+        this._loadNodeData((data) => {
+          this._treeData = data
+          this._updateBindData()
+          this._updateSelected()
+        })
+        return
+      }
+
+      if (this.stepSearh) {
+        this._loadNodeData((data) => {
+          this._treeData = data
+          this._updateBindData()
+        })
+      } else {
+        this._loadAllData((data) => {
+          this._treeData = []
+          this._extractTree(data, this._treeData, null)
+          this._updateBindData()
+        })
+      }
+    },
+    _loadAllData(callback) {
+      if (this.loading) {
+        return
+      }
+      this.loading = true
+
+      this.getCommand({
+        field: this.postField,
+        gettree: true,
+        startwith: `${this.selfField}=='${this.dataValue}'`
+      }).then((res) => {
+        this.loading = false
+        callback(res.result.data)
+        this.onDataChange()
+      }).catch((err) => {
+        this.loading = false
+        this.errorMessage = err
+      })
+    },
+    _loadNodeData(callback, pw) {
+      if (this.loading) {
+        return
+      }
+      this.loading = true
+
+      this.getCommand({
+        field: this.postField,
+        where: pw || this._postWhere(),
+        pageSize: 500
+      }).then((res) => {
+        this.loading = false
+        callback(res.result.data)
+        this.onDataChange()
+      }).catch((err) => {
+        this.loading = false
+        this.errorMessage = err
+      })
+    },
+    _pathWhere() {
+      let result = []
+      let where_field = this._getParentNameByField();
+      if (where_field) {
+        result.push(`${where_field} == '${this.dataValue}'`)
+      }
+
+      if (this.where) {
+        return `(${this.where}) && (${result.join(' || ')})`
+      }
+
+      return result.join(' || ')
+    },
+    _postWhere() {
+      let result = []
+      let selected = this.selected
+      let parentField = this.parentField
+      if (parentField) {
+        result.push(`${parentField} == null || ${parentField} == ""`)
+      }
+      if (selected.length) {
+        for (var i = 0; i < selected.length - 1; i++) {
+          result.push(`${parentField} == '${selected[i].value}'`)
+        }
+      }
+
+      let where = []
+      if (this.where) {
+        where.push(`(${this.where})`)
+      }
+      if (result.length) {
+        where.push(`(${result.join(' || ')})`)
+      }
+
+      return where.join(' && ')
+    },
+    _nodeWhere() {
+      let result = []
+      let selected = this.selected
+      if (selected.length) {
+        result.push(`${this.parentField} == '${selected[selected.length - 1].value}'`)
+      }
+
+      if (this.where) {
+        return `(${this.where}) && (${result.join(' || ')})`
+      }
+
+      return result.join(' || ')
+    },
+    _getParentNameByField() {
+      const fields = this.field.split(',');
+      let where_field = null;
+      for (let i = 0; i < fields.length; i++) {
+        const items = fields[i].split('as');
+        if (items.length < 2) {
+          continue;
+        }
+        if (items[1].trim() === 'value') {
+          where_field = items[0].trim();
+          break;
+        }
+      }
+      return where_field
+    },
+    _isTreeView() {
+      return (this.parentField && this.selfField)
+    },
+    _updateSelected() {
+      var dl = this.dataList
+      var sl = this.selected
+      let textField = this.map.text
+      let valueField = this.map.value
+      for (var i = 0; i < sl.length; i++) {
+        var value = sl[i].value
+        var dl2 = dl[i]
+        for (var j = 0; j < dl2.length; j++) {
+          var item2 = dl2[j]
+          if (item2[valueField] === value) {
+            sl[i].text = item2[textField]
+            break
+          }
+        }
+      }
+    },
+    _updateBindData(node) {
+      const {
+        dataList,
+        hasNodes
+      } = this._filterData(this._treeData, this.selected)
+
+      let isleaf = this._stepSearh === false && !hasNodes
+
+      if (node) {
+        node.isleaf = isleaf
+      }
+
+      this.dataList = dataList
+      this.selectedIndex = dataList.length - 1
+
+      if (!isleaf && this.selected.length < dataList.length) {
+        this.selected.push({
+          value: null,
+          text: "请选择"
+        })
+      }
+
+      return {
+        isleaf,
+        hasNodes
+      }
+    },
+    _filterData(data, paths) {
+      let dataList = []
+      let hasNodes = true
+
+      dataList.push(data.filter((item) => {
+        return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
+      }))
+      for (let i = 0; i < paths.length; i++) {
+        var value = paths[i].value
+        var nodes = data.filter((item) => {
+          return item.parent_value === value
+        })
+
+        if (nodes.length) {
+          dataList.push(nodes)
+        } else {
+          hasNodes = false
+        }
+      }
+
+      return {
+        dataList,
+        hasNodes
+      }
+    },
+    _extractTree(nodes, result, parent_value) {
+      let list = result || []
+      let valueField = this.map.value
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+
+        let child = {}
+        for (let key in node) {
+          if (key !== 'children') {
+            child[key] = node[key]
+          }
+        }
+        if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
+          child.parent_value = parent_value
+        }
+        result.push(child)
+
+        let children = node.children
+        if (children) {
+          this._extractTree(children, result, node[valueField])
+        }
+      }
+    },
+    _extractTreePath(nodes, result) {
+      let list = result || []
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+
+        let child = {}
+        for (let key in node) {
+          if (key !== 'children') {
+            child[key] = node[key]
+          }
+        }
+        result.push(child)
+
+        let children = node.children
+        if (children) {
+          this._extractTreePath(children, result)
+        }
+      }
+    },
+    _findNodePath(key, nodes, path = []) {
+      let textField = this.map.text
+      let valueField = this.map.value
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+        let children = node.children
+        let text = node[textField]
+        let value = node[valueField]
+
+        path.push({
+          value,
+          text
+        })
+
+        if (value === key) {
+          return path
+        }
+
+        if (children) {
+          const p = this._findNodePath(key, children, path)
+          if (p.length) {
+            return p
+          }
+        }
+
+        path.pop()
+      }
+      return []
+    },
+    _processLocalData() {
+      this._treeData = []
+      this._extractTree(this.localdata, this._treeData)
+
+      var inputValue = this.dataValue
+      if (inputValue === undefined) {
+        return
+      }
+
+      if (Array.isArray(inputValue)) {
+        inputValue = inputValue[inputValue.length - 1]
+        if (typeof inputValue === 'object' && inputValue[this.map.value]) {
+          inputValue = inputValue[this.map.value]
+        }
+      }
+
+      this.selected = this._findNodePath(inputValue, this.localdata)
+    }
+  }
+}

+ 385 - 0
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue

@@ -0,0 +1,385 @@
+<template>
+	<view class="uni-data-pickerview">
+		<view class="add-input-max-box" v-if="addType">
+			<view class="add-title">检查项</view>
+			<view class="add-input">
+				<input type="text" v-model="inputText" placeholder="请输入检查项目" maxlength="10">
+				<img src="@/images/icon_aqjc_ss.png" @click="searchClick">
+			</view>
+			<view class="add-button" @click="resetClick">重置</view>
+		</view>
+		<scroll-view class="selected-area" scroll-x="true" scroll-y="false" :show-scrollbar="false">
+			<view class="selected-list">
+				<template v-for="(item,index) in selected">
+					<view class="selected-item"
+						:class="{'selected-item-active':index==selectedIndex, 'selected-item-text-overflow': ellipsis}"
+						:key="index" v-if="item.text" @click="handleSelect(index)">
+						<text class="">{{item.text}}</text>
+					</view>
+				</template>
+			</view>
+		</scroll-view>
+		<view class="tab-c">
+			<template v-for="(child, i) in dataList">
+				<scroll-view class="list" :key="i" v-if="i==selectedIndex" :scroll-y="true">
+					<view class="item" :class="{'is-disabled': !!item.disable}" v-for="(item, j) in child" :key="j"
+						@click="handleNodeClick(item, i, j)">
+						<text class="item-text item-text-overflow">{{item[map.text]}}</text>
+						<view class="check" v-if="selected.length > i && item[map.value] == selected[i].value"></view>
+					</view>
+				</scroll-view>
+			</template>
+
+			<view class="loading-cover" v-if="loading">
+				<uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
+			</view>
+			<view class="error-message" v-if="errorMessage">
+				<text class="error-text">{{errorMessage}}</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import dataPicker from "./uni-data-picker.js"
+
+	/**
+	 * DataPickerview
+	 * @description uni-data-pickerview
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+	 * @property {Array} localdata 本地数据,参考
+	 * @property {Boolean} step-searh = [true|false] 是否分布查询
+	 * @value true 启用分布查询,仅查询当前选中节点
+	 * @value false 关闭分布查询,一次查询出所有数据
+	 * @property {String|DBFieldString} self-field 分布查询当前字段名称
+	 * @property {String|DBFieldString} parent-field 分布查询父字段名称
+	 * @property {String|DBCollectionString} collection 表名
+	 * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
+	 * @property {String} orderby 排序字段及正序倒叙设置
+	 * @property {String|JQLString} where 查询条件
+	 */
+	export default {
+		name: 'UniDataPickerView',
+		emits: ['nodeclick', 'change', 'datachange', 'update:modelValue'],
+		mixins: [dataPicker],
+		props: {
+			addType:{},
+			addIndex:{},
+			managedMode: {
+				type: Boolean,
+				default: false
+			},
+			ellipsis: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				inputText:"",
+			}
+		},
+		created() {
+			if (this.managedMode) {
+				return
+			}
+
+			this.$nextTick(() => {
+				this.load()
+			})
+		},
+		methods: {
+			//搜索
+			searchClick(){
+				this.$parent.$parent.searchClick(this.inputText,this.addIndex);
+			},
+			//重置
+			resetClick(){
+				this.inputText = "";
+				this.$parent.$parent.resetClick(this.addIndex);
+			},
+			onPropsChange() {
+				this._treeData = []
+				this.selectedIndex = 0
+				this.load()
+			},
+			load() {
+				if (this.isLocaldata) {
+					this.loadData()
+				} else if (this.dataValue.length) {
+					this.getTreePath((res) => {
+						this.loadData()
+					})
+				}
+			},
+			handleSelect(index) {
+				this.selectedIndex = index
+			},
+			handleNodeClick(item, i, j) {
+				if (item.disable) {
+					return
+				}
+				const node = this.dataList[i][j]
+				const text = node[this.map.text]
+				const value = node[this.map.value]
+				if (i < this.selected.length - 1) {
+					this.selected.splice(i, this.selected.length - i)
+					this.selected.push({
+						text,
+						value
+					})
+				} else if (i === this.selected.length - 1) {
+					this.selected.splice(i, 1, {
+						text,
+						value
+					})
+				}
+
+				if (node.isleaf) {
+					this.onSelectedChange(node, node.isleaf)
+					return
+				}
+
+				const {
+					isleaf,
+					hasNodes
+				} = this._updateBindData()
+
+				if (!this._isTreeView() && !hasNodes) {
+					this.onSelectedChange(node, true)
+					return
+				}
+
+				if (this.isLocaldata && (!hasNodes || isleaf)) {
+					this.onSelectedChange(node, true)
+					return
+				}
+
+				if (!isleaf && !hasNodes) {
+					this._loadNodeData((data) => {
+						if (!data.length) {
+							node.isleaf = true
+						} else {
+							this._treeData.push(...data)
+							this._updateBindData(node)
+						}
+						this.onSelectedChange(node, node.isleaf)
+					}, this._nodeWhere())
+					return
+				}
+
+				this.onSelectedChange(node, false)
+			},
+			updateData(data) {
+				this._treeData = data.treeData
+				this.selected = data.selected
+				if (!this._treeData.length) {
+					this.loadData()
+				} else {
+					//this.selected = data.selected
+					this._updateBindData()
+				}
+			},
+			onDataChange() {
+				this.$emit('datachange')
+			},
+			onSelectedChange(node, isleaf) {
+				if (isleaf) {
+					this._dispatchEvent()
+				}
+
+				if (node) {
+					this.$emit('nodeclick', node)
+				}
+			},
+			_dispatchEvent() {
+				this.$emit('change', this.selected.slice(0))
+			}
+		}
+	}
+</script>
+<style lang="stylus" scoped>
+	.add-input-max-box{
+		display: flex;
+		font-size:30rpx;
+		.add-title{
+			width:167rpx;
+			text-align center;
+			line-height:80rpx;
+		}
+		.add-input{
+			display flex;
+			width:500rpx;
+			height:80rpx;
+			border:1rpx solid #E0E0E0;
+			border-radius:10rpx;
+			input{
+				flex:1;
+				height:80rpx;
+				margin-left:20rpx;
+			}
+			img{
+				width:32rpx;
+				height:32rpx;
+				margin:25rpx 18rpx;
+			}
+		}
+		.add-button{
+			text-align center
+			width:104rpx;
+			line-height:80rpx;
+		}
+	}
+	.uni-data-pickerview {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		overflow: hidden;
+		height: 100%;
+	}
+
+	.error-text {
+		color: #DD524D;
+	}
+
+	.loading-cover {
+		position: absolute;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		background-color: rgba(255, 255, 255, .5);
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		align-items: center;
+		z-index: 1001;
+	}
+
+	.load-more {
+		/* #ifndef APP-NVUE */
+		margin: auto;
+		/* #endif */
+	}
+
+	.error-message {
+		background-color: #fff;
+		position: absolute;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		padding: 15px;
+		opacity: .9;
+		z-index: 102;
+	}
+
+	/* #ifdef APP-NVUE */
+	.selected-area {
+		width: 750rpx;
+	}
+
+	/* #endif */
+
+	.selected-list {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex-wrap: nowrap;
+		padding: 0 5px;
+		border-bottom: 1px solid #f8f8f8;
+	}
+
+	.selected-item {
+		margin-left: 10px;
+		margin-right: 10px;
+		padding: 12px 0;
+		text-align: center;
+		/* #ifndef APP-NVUE */
+		white-space: nowrap;
+		/* #endif */
+	}
+
+	.selected-item-text-overflow {
+		width: 168px;
+		/* fix nvue */
+		overflow: hidden;
+		/* #ifndef APP-NVUE */
+		width: 6em;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		-o-text-overflow: ellipsis;
+		/* #endif */
+	}
+
+	.selected-item-active {
+		border-bottom: 2px solid #007aff;
+	}
+
+	.selected-item-text {
+		color: #007aff;
+	}
+
+	.tab-c {
+		position: relative;
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		overflow: hidden;
+	}
+
+	.list {
+		flex: 1;
+	}
+
+	.item {
+		padding: 12px 15px;
+		/* border-bottom: 1px solid #f0f0f0; */
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+	}
+
+	.is-disabled {
+		opacity: .5;
+	}
+
+	.item-text {
+		/* flex: 1; */
+		color: #333333;
+	}
+
+	.item-text-overflow {
+		width: 280px;
+		/* fix nvue */
+		overflow: hidden;
+		/* #ifndef APP-NVUE */
+		width: 20em;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		-o-text-overflow: ellipsis;
+		/* #endif */
+	}
+
+	.check {
+		margin-right: 5px;
+		border: 2px solid #007aff;
+		border-left: 0;
+		border-top: 0;
+		height: 12px;
+		width: 6px;
+		transform-origin: center;
+		/* #ifndef APP-NVUE */
+		transition: all 0.3s;
+		/* #endif */
+		transform: rotate(45deg);
+	}
+</style>

+ 92 - 0
uni_modules/uni-data-picker/package.json

@@ -0,0 +1,92 @@
+{
+  "id": "uni-data-picker",
+  "displayName": "uni-data-picker 数据驱动的picker选择器",
+  "version": "1.0.1",
+  "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "picker",
+    "级联",
+    "省市区",
+    ""
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+      "uni-load-more",
+			"uni-icons",
+			"uni-scss"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 22 - 0
uni_modules/uni-data-picker/readme.md

@@ -0,0 +1,22 @@
+## DataPicker 级联选择
+> **组件名:uni-data-picker**
+> 代码块: `uDataPicker`
+> 关联组件:`uni-data-pickerview`、`uni-load-more`。
+
+
+`<uni-data-picker>` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。
+
+支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
+
+候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。
+
+`<uni-data-picker>` 组件尤其适用于地址选择、分类选择等选择类。
+
+`<uni-data-picker>` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。
+
+`<uni-data-picker>` 可以通过JQL直连uniCloud云数据库,配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema),可在schema2code中自动生成前端页面,还支持服务器端校验。
+
+在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”,这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面,会自动生成地址管理的维护页面,自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 16 - 0
uni_modules/uni-icons/changelog.md

@@ -0,0 +1,16 @@
+## 1.3.2(2021-12-01)
+- 优化 示例可复制图标名称
+## 1.3.1(2021-11-23)
+- 优化 兼容旧组件 type 值
+## 1.3.0(2021-11-19)
+- 新增 更多图标
+- 优化 自定义图标使用方式
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
+## 1.1.7(2021-11-08)
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.5(2021-05-12)
+- 新增 组件示例地址
+## 1.1.4(2021-02-05)
+- 调整为uni_modules目录规范

文件差异内容过多而无法显示
+ 1115 - 0
uni_modules/uni-icons/components/uni-icons/icons.js


+ 89 - 0
uni_modules/uni-icons/components/uni-icons/uni-icons.vue

@@ -0,0 +1,89 @@
+<template>
+	<!-- #ifdef APP-NVUE -->
+	<text :style="{ color: color, 'font-size': size + 'px' }" class="uni-icons" @click="_onClick">{{unicode}}</text>
+	<!-- #endif -->
+	<!-- #ifndef APP-NVUE -->
+	<text :style="{ color: color, 'font-size': size + 'px' }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
+	<!-- #endif -->
+</template>
+
+<script>
+	import icons from './icons.js';
+	// #ifdef APP-NVUE
+	var domModule = weex.requireModule('dom');
+	import iconUrl from './uniicons.ttf'
+	domModule.addRule('fontFace', {
+		'fontFamily': "uniicons",
+		'src': "url('"+iconUrl+"')"
+	});
+	// #endif
+
+	/**
+	 * Icons 图标
+	 * @description 用于展示 icons 图标
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=28
+	 * @property {Number} size 图标大小
+	 * @property {String} type 图标图案,参考示例
+	 * @property {String} color 图标颜色
+	 * @property {String} customPrefix 自定义图标
+	 * @event {Function} click 点击 Icon 触发事件
+	 */
+	export default {
+		name: 'UniIcons',
+		emits:['click'],
+		props: {
+			type: {
+				type: String,
+				default: ''
+			},
+			color: {
+				type: String,
+				default: '#333333'
+			},
+			size: {
+				type: [Number, String],
+				default: 16
+			},
+			customPrefix:{
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				icons: icons.glyphs
+			}
+		},
+		computed:{
+			unicode(){
+				let code = this.icons.find(v=>v.font_class === this.type)
+				if(code){
+					return unescape(`%u${code.unicode}`)
+				}
+				return ''
+			}
+		},
+		methods: {
+			_onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	/* #ifndef APP-NVUE */
+	@import './uniicons.css';
+	@font-face {
+		font-family: uniicons;
+		src: url('./uniicons.ttf') format('truetype');
+	}
+
+	/* #endif */
+	.uni-icons {
+		font-family: uniicons;
+		text-decoration: none;
+		text-align: center;
+	}
+
+</style>

+ 663 - 0
uni_modules/uni-icons/components/uni-icons/uniicons.css

@@ -0,0 +1,663 @@
+.uniui-color:before {
+  content: "\e6cf";
+}
+
+.uniui-wallet:before {
+  content: "\e6b1";
+}
+
+.uniui-settings-filled:before {
+  content: "\e6ce";
+}
+
+.uniui-auth-filled:before {
+  content: "\e6cc";
+}
+
+.uniui-shop-filled:before {
+  content: "\e6cd";
+}
+
+.uniui-staff-filled:before {
+  content: "\e6cb";
+}
+
+.uniui-vip-filled:before {
+  content: "\e6c6";
+}
+
+.uniui-plus-filled:before {
+  content: "\e6c7";
+}
+
+.uniui-folder-add-filled:before {
+  content: "\e6c8";
+}
+
+.uniui-color-filled:before {
+  content: "\e6c9";
+}
+
+.uniui-tune-filled:before {
+  content: "\e6ca";
+}
+
+.uniui-calendar-filled:before {
+  content: "\e6c0";
+}
+
+.uniui-notification-filled:before {
+  content: "\e6c1";
+}
+
+.uniui-wallet-filled:before {
+  content: "\e6c2";
+}
+
+.uniui-medal-filled:before {
+  content: "\e6c3";
+}
+
+.uniui-gift-filled:before {
+  content: "\e6c4";
+}
+
+.uniui-fire-filled:before {
+  content: "\e6c5";
+}
+
+.uniui-refreshempty:before {
+  content: "\e6bf";
+}
+
+.uniui-location-filled:before {
+  content: "\e6af";
+}
+
+.uniui-person-filled:before {
+  content: "\e69d";
+}
+
+.uniui-personadd-filled:before {
+  content: "\e698";
+}
+
+.uniui-back:before {
+  content: "\e6b9";
+}
+
+.uniui-forward:before {
+  content: "\e6ba";
+}
+
+.uniui-arrow-right:before {
+  content: "\e6bb";
+}
+
+.uniui-arrowthinright:before {
+  content: "\e6bb";
+}
+
+.uniui-arrow-left:before {
+  content: "\e6bc";
+}
+
+.uniui-arrowthinleft:before {
+  content: "\e6bc";
+}
+
+.uniui-arrow-up:before {
+  content: "\e6bd";
+}
+
+.uniui-arrowthinup:before {
+  content: "\e6bd";
+}
+
+.uniui-arrow-down:before {
+  content: "\e6be";
+}
+
+.uniui-arrowthindown:before {
+  content: "\e6be";
+}
+
+.uniui-bottom:before {
+  content: "\e6b8";
+}
+
+.uniui-arrowdown:before {
+  content: "\e6b8";
+}
+
+.uniui-right:before {
+  content: "\e6b5";
+}
+
+.uniui-arrowright:before {
+  content: "\e6b5";
+}
+
+.uniui-top:before {
+  content: "\e6b6";
+}
+
+.uniui-arrowup:before {
+  content: "\e6b6";
+}
+
+.uniui-left:before {
+  content: "\e6b7";
+}
+
+.uniui-arrowleft:before {
+  content: "\e6b7";
+}
+
+.uniui-eye:before {
+  content: "\e651";
+}
+
+.uniui-eye-filled:before {
+  content: "\e66a";
+}
+
+.uniui-eye-slash:before {
+  content: "\e6b3";
+}
+
+.uniui-eye-slash-filled:before {
+  content: "\e6b4";
+}
+
+.uniui-info-filled:before {
+  content: "\e649";
+}
+
+.uniui-reload:before {
+  content: "\e6b2";
+}
+
+.uniui-micoff-filled:before {
+  content: "\e6b0";
+}
+
+.uniui-map-pin-ellipse:before {
+  content: "\e6ac";
+}
+
+.uniui-map-pin:before {
+  content: "\e6ad";
+}
+
+.uniui-location:before {
+  content: "\e6ae";
+}
+
+.uniui-starhalf:before {
+  content: "\e683";
+}
+
+.uniui-star:before {
+  content: "\e688";
+}
+
+.uniui-star-filled:before {
+  content: "\e68f";
+}
+
+.uniui-calendar:before {
+  content: "\e6a0";
+}
+
+.uniui-fire:before {
+  content: "\e6a1";
+}
+
+.uniui-medal:before {
+  content: "\e6a2";
+}
+
+.uniui-font:before {
+  content: "\e6a3";
+}
+
+.uniui-gift:before {
+  content: "\e6a4";
+}
+
+.uniui-link:before {
+  content: "\e6a5";
+}
+
+.uniui-notification:before {
+  content: "\e6a6";
+}
+
+.uniui-staff:before {
+  content: "\e6a7";
+}
+
+.uniui-vip:before {
+  content: "\e6a8";
+}
+
+.uniui-folder-add:before {
+  content: "\e6a9";
+}
+
+.uniui-tune:before {
+  content: "\e6aa";
+}
+
+.uniui-auth:before {
+  content: "\e6ab";
+}
+
+.uniui-person:before {
+  content: "\e699";
+}
+
+.uniui-email-filled:before {
+  content: "\e69a";
+}
+
+.uniui-phone-filled:before {
+  content: "\e69b";
+}
+
+.uniui-phone:before {
+  content: "\e69c";
+}
+
+.uniui-email:before {
+  content: "\e69e";
+}
+
+.uniui-personadd:before {
+  content: "\e69f";
+}
+
+.uniui-chatboxes-filled:before {
+  content: "\e692";
+}
+
+.uniui-contact:before {
+  content: "\e693";
+}
+
+.uniui-chatbubble-filled:before {
+  content: "\e694";
+}
+
+.uniui-contact-filled:before {
+  content: "\e695";
+}
+
+.uniui-chatboxes:before {
+  content: "\e696";
+}
+
+.uniui-chatbubble:before {
+  content: "\e697";
+}
+
+.uniui-upload-filled:before {
+  content: "\e68e";
+}
+
+.uniui-upload:before {
+  content: "\e690";
+}
+
+.uniui-weixin:before {
+  content: "\e691";
+}
+
+.uniui-compose:before {
+  content: "\e67f";
+}
+
+.uniui-qq:before {
+  content: "\e680";
+}
+
+.uniui-download-filled:before {
+  content: "\e681";
+}
+
+.uniui-pyq:before {
+  content: "\e682";
+}
+
+.uniui-sound:before {
+  content: "\e684";
+}
+
+.uniui-trash-filled:before {
+  content: "\e685";
+}
+
+.uniui-sound-filled:before {
+  content: "\e686";
+}
+
+.uniui-trash:before {
+  content: "\e687";
+}
+
+.uniui-videocam-filled:before {
+  content: "\e689";
+}
+
+.uniui-spinner-cycle:before {
+  content: "\e68a";
+}
+
+.uniui-weibo:before {
+  content: "\e68b";
+}
+
+.uniui-videocam:before {
+  content: "\e68c";
+}
+
+.uniui-download:before {
+  content: "\e68d";
+}
+
+.uniui-help:before {
+  content: "\e679";
+}
+
+.uniui-navigate-filled:before {
+  content: "\e67a";
+}
+
+.uniui-plusempty:before {
+  content: "\e67b";
+}
+
+.uniui-smallcircle:before {
+  content: "\e67c";
+}
+
+.uniui-minus-filled:before {
+  content: "\e67d";
+}
+
+.uniui-micoff:before {
+  content: "\e67e";
+}
+
+.uniui-closeempty:before {
+  content: "\e66c";
+}
+
+.uniui-clear:before {
+  content: "\e66d";
+}
+
+.uniui-navigate:before {
+  content: "\e66e";
+}
+
+.uniui-minus:before {
+  content: "\e66f";
+}
+
+.uniui-image:before {
+  content: "\e670";
+}
+
+.uniui-mic:before {
+  content: "\e671";
+}
+
+.uniui-paperplane:before {
+  content: "\e672";
+}
+
+.uniui-close:before {
+  content: "\e673";
+}
+
+.uniui-help-filled:before {
+  content: "\e674";
+}
+
+.uniui-paperplane-filled:before {
+  content: "\e675";
+}
+
+.uniui-plus:before {
+  content: "\e676";
+}
+
+.uniui-mic-filled:before {
+  content: "\e677";
+}
+
+.uniui-image-filled:before {
+  content: "\e678";
+}
+
+.uniui-locked-filled:before {
+  content: "\e668";
+}
+
+.uniui-info:before {
+  content: "\e669";
+}
+
+.uniui-locked:before {
+  content: "\e66b";
+}
+
+.uniui-camera-filled:before {
+  content: "\e658";
+}
+
+.uniui-chat-filled:before {
+  content: "\e659";
+}
+
+.uniui-camera:before {
+  content: "\e65a";
+}
+
+.uniui-circle:before {
+  content: "\e65b";
+}
+
+.uniui-checkmarkempty:before {
+  content: "\e65c";
+}
+
+.uniui-chat:before {
+  content: "\e65d";
+}
+
+.uniui-circle-filled:before {
+  content: "\e65e";
+}
+
+.uniui-flag:before {
+  content: "\e65f";
+}
+
+.uniui-flag-filled:before {
+  content: "\e660";
+}
+
+.uniui-gear-filled:before {
+  content: "\e661";
+}
+
+.uniui-home:before {
+  content: "\e662";
+}
+
+.uniui-home-filled:before {
+  content: "\e663";
+}
+
+.uniui-gear:before {
+  content: "\e664";
+}
+
+.uniui-smallcircle-filled:before {
+  content: "\e665";
+}
+
+.uniui-map-filled:before {
+  content: "\e666";
+}
+
+.uniui-map:before {
+  content: "\e667";
+}
+
+.uniui-refresh-filled:before {
+  content: "\e656";
+}
+
+.uniui-refresh:before {
+  content: "\e657";
+}
+
+.uniui-cloud-upload:before {
+  content: "\e645";
+}
+
+.uniui-cloud-download-filled:before {
+  content: "\e646";
+}
+
+.uniui-cloud-download:before {
+  content: "\e647";
+}
+
+.uniui-cloud-upload-filled:before {
+  content: "\e648";
+}
+
+.uniui-redo:before {
+  content: "\e64a";
+}
+
+.uniui-images-filled:before {
+  content: "\e64b";
+}
+
+.uniui-undo-filled:before {
+  content: "\e64c";
+}
+
+.uniui-more:before {
+  content: "\e64d";
+}
+
+.uniui-more-filled:before {
+  content: "\e64e";
+}
+
+.uniui-undo:before {
+  content: "\e64f";
+}
+
+.uniui-images:before {
+  content: "\e650";
+}
+
+.uniui-paperclip:before {
+  content: "\e652";
+}
+
+.uniui-settings:before {
+  content: "\e653";
+}
+
+.uniui-search:before {
+  content: "\e654";
+}
+
+.uniui-redo-filled:before {
+  content: "\e655";
+}
+
+.uniui-list:before {
+  content: "\e644";
+}
+
+.uniui-mail-open-filled:before {
+  content: "\e63a";
+}
+
+.uniui-hand-down-filled:before {
+  content: "\e63c";
+}
+
+.uniui-hand-down:before {
+  content: "\e63d";
+}
+
+.uniui-hand-up-filled:before {
+  content: "\e63e";
+}
+
+.uniui-hand-up:before {
+  content: "\e63f";
+}
+
+.uniui-heart-filled:before {
+  content: "\e641";
+}
+
+.uniui-mail-open:before {
+  content: "\e643";
+}
+
+.uniui-heart:before {
+  content: "\e639";
+}
+
+.uniui-loop:before {
+  content: "\e633";
+}
+
+.uniui-pulldown:before {
+  content: "\e632";
+}
+
+.uniui-scan:before {
+  content: "\e62a";
+}
+
+.uniui-bars:before {
+  content: "\e627";
+}
+
+.uniui-cart-filled:before {
+  content: "\e629";
+}
+
+.uniui-checkbox:before {
+  content: "\e62b";
+}
+
+.uniui-checkbox-filled:before {
+  content: "\e62c";
+}
+
+.uniui-shop:before {
+  content: "\e62f";
+}
+
+.uniui-headphones:before {
+  content: "\e630";
+}
+
+.uniui-cart:before {
+  content: "\e631";
+}

+ 0 - 0
uni_modules/uni-icons/components/uni-icons/uniicons.ttf


部分文件因为文件数量过多而无法显示