浏览代码

第一次推送

fanghuisheng 2 年之前
当前提交
f81f040d3b
共有 78 个文件被更改,包括 9541 次插入0 次删除
  1. 26 0
      .gitignore
  2. 10 0
      README.md
  3. 41 0
      index.html
  4. 9 0
      jsconfig.json
  5. 72 0
      package.json
  6. 45 0
      src/App.vue
  7. 184 0
      src/colorui/animation.css
  8. 69 0
      src/colorui/components/cu-custom.vue
  9. 36 0
      src/colorui/icon.css
  10. 3917 0
      src/colorui/main.css
  11. 30 0
      src/common/common.js
  12. 584 0
      src/common/common.scss
  13. 171 0
      src/common/export.js
  14. 97 0
      src/common/graceChecker.js
  15. 238 0
      src/common/public.scss
  16. 188 0
      src/common/select.js
  17. 96 0
      src/common/uni-nvue.scss
  18. 116 0
      src/components/calendar/calendar.vue
  19. 20 0
      src/components/export.vue
  20. 175 0
      src/components/helang-compress/helang-compress.vue
  21. 205 0
      src/components/list-test/list-test.vue
  22. 123 0
      src/components/mpvue-echarts/src/echarts.vue
  23. 73 0
      src/components/mpvue-echarts/src/wx-canvas.js
  24. 45 0
      src/components/square/square.vue
  25. 236 0
      src/components/yealuo-select/yealuo-select.vue
  26. 120 0
      src/components/zzlb-mutiselect/zzlb-mutiselect.vue
  27. 136 0
      src/data/json.js
  28. 71 0
      src/main.js
  29. 182 0
      src/manifest.json
  30. 345 0
      src/pages.json
  31. 102 0
      src/pages/index/components/searchSelect/searchSelect.vue
  32. 548 0
      src/pages/index/index.vue
  33. 443 0
      src/pages/login/login.vue
  34. 二进制
      src/static/font/FANDOLFANG-REGULAR.OTF
  35. 二进制
      src/static/font/IMPACT.TTF
  36. 84 0
      src/static/iconfont/iconfont.css
  37. 二进制
      src/static/iconfont/iconfont.ttf
  38. 39 0
      src/static/iconfont/uciconfont/iconfont.css
  39. 二进制
      src/static/iconfont/uciconfont/iconfont.ttf
  40. 二进制
      src/static/iconfont/uciconfont/iconfont.woff
  41. 二进制
      src/static/iconfont/uciconfont/iconfont.woff2
  42. 二进制
      src/static/index/ge1.png
  43. 二进制
      src/static/index/ge2.png
  44. 二进制
      src/static/index/ge3.png
  45. 二进制
      src/static/index/ge4.png
  46. 二进制
      src/static/login-bg.png
  47. 二进制
      src/static/login-bg2.png
  48. 二进制
      src/static/logo.png
  49. 二进制
      src/static/start.png
  50. 二进制
      src/static/startUp.png
  51. 二进制
      src/static/startup.jpeg
  52. 二进制
      src/static/tabBar/analyse-selected.png
  53. 二进制
      src/static/tabBar/analyse.png
  54. 二进制
      src/static/tabBar/feiqi/analyse-selected.png
  55. 二进制
      src/static/tabBar/feiqi/analyse.png
  56. 二进制
      src/static/tabBar/feiqi/home-selected.png
  57. 二进制
      src/static/tabBar/feiqi/home.png
  58. 二进制
      src/static/tabBar/feiqi/info-selected.png
  59. 二进制
      src/static/tabBar/feiqi/info.png
  60. 二进制
      src/static/tabBar/feiqi/setting-selected.png
  61. 二进制
      src/static/tabBar/feiqi/setting.png
  62. 二进制
      src/static/tabBar/home-selected.png
  63. 二进制
      src/static/tabBar/home.png
  64. 二进制
      src/static/tabBar/info-selected.png
  65. 二进制
      src/static/tabBar/info.png
  66. 二进制
      src/static/tabBar/setting-selected.png
  67. 二进制
      src/static/tabBar/setting.png
  68. 13 0
      src/store/index.js
  69. 145 0
      src/store/modules/public.js
  70. 22 0
      src/store/modules/user.js
  71. 127 0
      src/store/modules/xunJian.js
  72. 75 0
      src/uni.scss
  73. 145 0
      src/utils/api.js
  74. 0 0
      src/utils/auth.js
  75. 52 0
      src/utils/jssdk.js
  76. 8 0
      src/utils/router/config.js
  77. 52 0
      src/utils/router/init.js
  78. 26 0
      vite.config.js

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+.DS_Store
+.history/
+.hbuilderx/
+package-lock.json
+node_modules/
+dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+**/*.log
+
+tests/**/coverage/
+tests/e2e/reports
+selenium-debug.log
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.local
+*.zip
+
+yarn.lock

+ 10 - 0
README.md

@@ -0,0 +1,10 @@
+# sass移动端
+### 文档(吉超博、詹叶俊)
+### https://docs.apipost.cn/preview/61b2861af42252f6/a453b7fa01ec4c0f?target_id=2c54712b-9b38-4642-b3a9-7205d58072ca
+
+
+### 坐标系(GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统、
+
+
+### 账号:fire_admin
+### 密码:FIRE_admin123

+ 41 - 0
index.html

@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+	<meta charset="UTF-8" />
+	<meta http-equiv="X-UA-Compatible" content="IE=edge">
+	<meta name="viewport" content="width=device-width,initial-scale=1.0">
+	<script>
+		var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
+			CSS.supports('top: constant(a)'))
+		document.write(
+			'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
+			(coverSupport ? ', viewport-fit=cover' : '') + '" />')
+	</script>
+
+	<!-- 高德地图 -->
+	<script type="text/javascript">
+		window._AMapSecurityConfig = {
+			securityJsCode: 'be916fcd16d0b33d228c49f0ff096b17',
+		}
+	</script>
+	<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=d4d73a7d572b6ff6028d5f67de62029a">
+	</script>
+
+	<!-- <script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=ffc71dfd4e576596027f8f45a1b8fb2f">
+	</script> -->
+	<!-- <script src="https://webapi.amap.com/loader.js"></script> -->
+	<!-- <script type="text/javascript" src="//webapi.amap.com/ui/1.1/main.js"></script> -->
+	<title></title>
+	<!--preload-links-->
+	<!--app-context-->
+</head>
+
+<body>
+	<div id="app">
+		<!--app-html-->
+	</div>
+	<script type="module" src="/src/main.js"></script>
+</body>
+
+</html>

+ 9 - 0
jsconfig.json

@@ -0,0 +1,9 @@
+{
+  "compilerOptions": {
+    "types": [
+      "@dcloudio/types",
+      "miniprogram-api-typings",
+      "mini-types"
+    ]
+  }
+}

+ 72 - 0
package.json

@@ -0,0 +1,72 @@
+{
+    "name": "uni-preset-vue",
+    "version": "0.0.0",
+    "scripts": {
+        "dev:app": "uni -p app",
+        "dev:custom": "uni -p",
+        "dev:h5": "uni",
+        "dev:h5:ssr": "uni --ssr",
+        "dev:mp-alipay": "uni -p mp-alipay",
+        "dev:mp-baidu": "uni -p mp-baidu",
+        "dev:mp-kuaishou": "uni -p mp-kuaishou",
+        "dev:mp-lark": "uni -p mp-lark",
+        "dev:mp-qq": "uni -p mp-qq",
+        "dev:mp-toutiao": "uni -p mp-toutiao",
+        "dev:mp-weixin": "uni -p mp-weixin",
+        "dev:quickapp-webview": "uni -p quickapp-webview",
+        "dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
+        "dev:quickapp-webview-union": "uni -p quickapp-webview-union",
+        "build:app": "uni build -p app",
+        "build:custom": "uni build -p",
+        "build:h5": "uni build",
+        "build:h5:ssr": "uni build --ssr",
+        "build:mp-alipay": "uni build -p mp-alipay",
+        "build:mp-baidu": "uni build -p mp-baidu",
+        "build:mp-kuaishou": "uni build -p mp-kuaishou",
+        "build:mp-lark": "uni build -p mp-lark",
+        "build:mp-qq": "uni build -p mp-qq",
+        "build:mp-toutiao": "uni build -p mp-toutiao",
+        "build:mp-weixin": "uni build -p mp-weixin",
+        "build:quickapp-webview": "uni build -p quickapp-webview",
+        "build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
+        "build:quickapp-webview-union": "uni build -p quickapp-webview-union",
+        "clear": "rimraf node_modules&&cnpm install"
+    },
+    "dependencies": {
+        "@amap/amap-jsapi-loader": "^1.0.1",
+        "@dcloudio/uni-app": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-app-plus": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-components": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-h5": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-mp-alipay": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-mp-baidu": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-mp-lark": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-mp-qq": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-mp-weixin": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3050320220729001",
+        "@element-plus/icons-vue": "^2.0.9",
+        "echarts": "^5.3.3",
+        "element-plus": "^2.2.12",
+        "node-sass": "^7.0.1",
+        "pinia": "^2.0.17",
+        "pinia-plugin-persistedstate": "^2.1.1",
+        "vue": "^3.2.37",
+        "vue-echarts": "^6.2.3",
+        "vue-i18n": "^9.1.9",
+        "vue-json-excel": "^0.3.0",
+        "vuex": "^4.0.2",
+        "weixin-js-sdk": "^1.6.0"
+    },
+    "devDependencies": {
+        "@dcloudio/types": "^3.0.7",
+        "@dcloudio/uni-automator": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/uni-stacktracey": "3.0.0-alpha-3050320220729001",
+        "@dcloudio/vite-plugin-uni": "3.0.0-alpha-3050320220729001",
+        "@vitejs/plugin-vue": "^2.3.3",
+        "sass": "^1.54.3",
+        "vite": "^2.9.14"
+    }
+}

+ 45 - 0
src/App.vue

@@ -0,0 +1,45 @@
+<script setup>
+import { onLoad, onShow, onHide, onLaunch } from "@dcloudio/uni-app";
+
+onLaunch(() => {
+  console.log("App Launch");
+});
+
+onShow(() => {
+  console.log("App Show");
+});
+
+onHide(() => {
+  console.log("App Hide");
+});
+</script>
+
+<style>
+/*每个页面公共css */
+@import "colorui/main.css";
+@import "colorui/icon.css";
+@import "static/iconfont/iconfont.css";
+@import "static/iconfont/uciconfont/iconfont.css";
+
+/* 解决头条小程序组件内引入字体不生效的问题 */
+/* #ifdef MP-TOUTIAO */
+@font-face {
+  font-family: uniicons;
+  src: url("/static/uni.ttf");
+}
+
+/* #endif */
+</style>
+
+<style lang="scss">
+@import "common/common.scss";
+@import "common/public.scss";
+@import "./uni_modules/uview-plus/index.scss";
+
+uni-page-body,
+uni-page-refresh {
+  height: 100%;
+}
+</style>
+
+

+ 184 - 0
src/colorui/animation.css

@@ -0,0 +1,184 @@
+/* 
+  Animation 微动画  
+  基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28
+ */
+
+/* css 滤镜 控制黑白底色gif的 */
+.gif-black{  
+  mix-blend-mode: screen;  
+}
+.gif-white{  
+  mix-blend-mode: multiply; 
+}
+
+
+/* Animation css */
+[class*=animation-] {
+    animation-duration: .5s;
+    animation-timing-function: ease-out;
+    animation-fill-mode: both
+}
+
+.animation-fade {
+    animation-name: fade;
+    animation-duration: .8s;
+    animation-timing-function: linear
+}
+
+.animation-scale-up {
+    animation-name: scale-up
+}
+
+.animation-scale-down {
+    animation-name: scale-down
+}
+
+.animation-slide-top {
+    animation-name: slide-top
+}
+
+.animation-slide-bottom {
+    animation-name: slide-bottom
+}
+
+.animation-slide-left {
+    animation-name: slide-left
+}
+
+.animation-slide-right {
+    animation-name: slide-right
+}
+
+.animation-shake {
+    animation-name: shake
+}
+
+.animation-reverse {
+    animation-direction: reverse
+}
+
+@keyframes fade {
+    0% {
+        opacity: 0
+    }
+
+    100% {
+        opacity: 1
+    }
+}
+
+@keyframes scale-up {
+    0% {
+        opacity: 0;
+        transform: scale(.2)
+    }
+
+    100% {
+        opacity: 1;
+        transform: scale(1)
+    }
+}
+
+@keyframes scale-down {
+    0% {
+        opacity: 0;
+        transform: scale(1.8)
+    }
+
+    100% {
+        opacity: 1;
+        transform: scale(1)
+    }
+}
+
+@keyframes slide-top {
+    0% {
+        opacity: 0;
+        transform: translateY(-100%)
+    }
+
+    100% {
+        opacity: 1;
+        transform: translateY(0)
+    }
+}
+
+@keyframes slide-bottom {
+    0% {
+        opacity: 0;
+        transform: translateY(100%)
+    }
+
+    100% {
+        opacity: 1;
+        transform: translateY(0)
+    }
+}
+
+@keyframes shake {
+
+    0%,
+    100% {
+        transform: translateX(0)
+    }
+
+    10% {
+        transform: translateX(-9px)
+    }
+
+    20% {
+        transform: translateX(8px)
+    }
+
+    30% {
+        transform: translateX(-7px)
+    }
+
+    40% {
+        transform: translateX(6px)
+    }
+
+    50% {
+        transform: translateX(-5px)
+    }
+
+    60% {
+        transform: translateX(4px)
+    }
+
+    70% {
+        transform: translateX(-3px)
+    }
+
+    80% {
+        transform: translateX(2px)
+    }
+
+    90% {
+        transform: translateX(-1px)
+    }
+}
+
+@keyframes slide-left {
+    0% {
+        opacity: 0;
+        transform: translateX(-100%)
+    }
+
+    100% {
+        opacity: 1;
+        transform: translateX(0)
+    }
+}
+
+@keyframes slide-right {
+    0% {
+        opacity: 0;
+        transform: translateX(100%)
+    }
+
+    100% {
+        opacity: 1;
+        transform: translateX(0)
+    }
+}

+ 69 - 0
src/colorui/components/cu-custom.vue

@@ -0,0 +1,69 @@
+<template>
+	<view>
+		<view class="cu-custom" :style="[{height:CustomBar + 'px'}]">
+			<view class="cu-bar fixed" :style="style" :class="[bgImage!=''?'none-bg text-white bg-img':'',bgColor]">
+				<view class="action" @tap="BackPage" v-if="isBack">
+					<text class="cuIcon-back"></text>
+					<slot name="backText"></slot>
+				</view>
+				<view class="content" :style="[{top:StatusBar + 'px'}]">
+					<slot name="content"></slot>
+				</view>
+				<slot name="right"></slot>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				StatusBar: this.StatusBar,
+				CustomBar: this.CustomBar
+			};
+		},
+		name: 'cu-custom',
+		computed: {
+			style() {
+				var StatusBar= this.StatusBar;
+				var CustomBar= this.CustomBar;
+				var bgImage = this.bgImage;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				if (this.bgImage) {
+					style = `${style}background-image:url(${bgImage});`;
+				}
+				return style
+			}
+		},
+		props: {
+			bgColor: {
+				type: String,
+				default: ''
+			},
+			isBack: {
+				type: [Boolean, String],
+				default: false
+			},
+			bgImage: {
+				type: String,
+				default: ''
+			},
+		},
+		methods: {
+			BackPage() {
+				if (getCurrentPages().length < 2 && 'undefined' !== typeof __wxConfig) {
+					let url = '/' + __wxConfig.pages[0]
+					return uni.redirectTo({url})
+				}
+				uni.navigateBack({
+					delta: 1
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

文件差异内容过多而无法显示
+ 36 - 0
src/colorui/icon.css


+ 3917 - 0
src/colorui/main.css

@@ -0,0 +1,3917 @@
+/*
+  ColorUi for uniApp  v2.1.6 | by 文晓港 2019-05-31 10:44:24
+  仅供学习交流,如作它用所承受的法律责任一概与作者无关  
+  
+  *使用ColorUi开发扩展与插件时,请注明基于ColorUi开发 
+  
+  (QQ交流群:240787041)
+*/
+
+/* ==================
+        初始化
+ ==================== */
+body {
+	background: rgb(241, 241, 241);
+	font-size: 28upx;
+	color: #333333;
+	font-family: Helvetica Neue, Helvetica, sans-serif;
+}
+
+view,
+scroll-view,
+swiper,
+button,
+input,
+textarea,
+label,
+navigator,
+image {
+	box-sizing: border-box;
+}
+
+.round {
+	border-radius: 5000upx;
+}
+
+.radius {
+	border-radius: 6upx;
+}
+
+/* ==================
+          图片
+ ==================== */
+
+image {
+	max-width: 100%;
+	display: inline-block;
+	position: relative;
+	z-index: 0;
+}
+
+image.loading::before {
+	content: "";
+	background-color: #f5f5f5;
+	display: block;
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	z-index: -2;
+}
+
+image.loading::after {
+	content: "\e7f1";
+	font-family: "cuIcon";
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 32upx;
+	height: 32upx;
+	line-height: 32upx;
+	right: 0;
+	bottom: 0;
+	z-index: -1;
+	font-size: 32upx;
+	margin: auto;
+	color: #ccc;
+	-webkit-animation: cuIcon-spin 2s infinite linear;
+	animation: cuIcon-spin 2s infinite linear;
+	display: block;
+}
+
+.response {
+	width: 100%;
+}
+
+/* ==================
+         开关
+ ==================== */
+
+switch,
+checkbox,
+radio {
+	position: relative;
+}
+
+switch::after,
+switch::before {
+	font-family: "cuIcon";
+	content: "\e645";
+	position: absolute;
+	color: #ffffff !important;
+	top: 0%;
+	left: 0upx;
+	font-size: 26upx;
+	line-height: 26px;
+	width: 50%;
+	text-align: center;
+	pointer-events: none;
+	transform: scale(0, 0);
+	transition: all 0.3s ease-in-out 0s;
+	z-index: 9;
+	bottom: 0;
+	height: 26px;
+	margin: auto;
+}
+
+switch::before {
+	content: "\e646";
+	right: 0;
+	transform: scale(1, 1);
+	left: auto;
+}
+
+switch[checked]::after,
+switch.checked::after {
+	transform: scale(1, 1);
+}
+
+switch[checked]::before,
+switch.checked::before {
+	transform: scale(0, 0);
+}
+
+/* #ifndef MP-ALIPAY */
+radio::before,
+checkbox::before {
+	font-family: "cuIcon";
+	content: "\e645";
+	position: absolute;
+	color: #ffffff !important;
+	top: 50%;
+	margin-top: -8px;
+	right: 5px;
+	font-size: 32upx;
+	line-height: 16px;
+	pointer-events: none;
+	transform: scale(1, 1);
+	transition: all 0.3s ease-in-out 0s;
+	z-index: 9;
+}
+
+radio .wx-radio-input,
+checkbox .wx-checkbox-input,
+radio .uni-radio-input,
+checkbox .uni-checkbox-input {
+	margin: 0;
+	width: 24px;
+	height: 24px;
+}
+
+checkbox.round .wx-checkbox-input,
+checkbox.round .uni-checkbox-input {
+	border-radius: 100upx;
+}
+
+/* #endif */
+
+switch[checked]::before {
+	transform: scale(0, 0);
+}
+
+switch .wx-switch-input,
+switch .uni-switch-input {
+	border: none;
+	padding: 0 24px;
+	width: 48px;
+	height: 26px;
+	margin: 0;
+	border-radius: 100upx;
+}
+
+switch .wx-switch-input:not([class*="bg-"]),
+switch .uni-switch-input:not([class*="bg-"]) {
+	background: #8799a3 !important;
+}
+
+switch .wx-switch-input::after,
+switch .uni-switch-input::after {
+	margin: auto;
+	width: 26px;
+	height: 26px;
+	border-radius: 100upx;
+	left: 0upx;
+	top: 0upx;
+	bottom: 0upx;
+	position: absolute;
+	transform: scale(0.9, 0.9);
+	transition: all 0.1s ease-in-out 0s;
+}
+
+switch .wx-switch-input.wx-switch-input-checked::after,
+switch .uni-switch-input.uni-switch-input-checked::after {
+	margin: auto;
+	left: 22px;
+	box-shadow: none;
+	transform: scale(0.9, 0.9);
+}
+
+radio-group {
+	display: inline-block;
+}
+
+
+
+switch.radius .wx-switch-input::after,
+switch.radius .wx-switch-input,
+switch.radius .wx-switch-input::before,
+switch.radius .uni-switch-input::after,
+switch.radius .uni-switch-input,
+switch.radius .uni-switch-input::before {
+	border-radius: 10upx;
+}
+
+switch .wx-switch-input::before,
+radio.radio::before,
+checkbox .wx-checkbox-input::before,
+radio .wx-radio-input::before,
+switch .uni-switch-input::before,
+radio.radio::before,
+checkbox .uni-checkbox-input::before,
+radio .uni-radio-input::before {
+	display: none;
+}
+
+radio.radio[checked]::after,
+radio.radio .uni-radio-input-checked::after {
+	content: "";
+	background-color: transparent;
+	display: block;
+	position: absolute;
+	width: 8px;
+	height: 8px;
+	z-index: 999;
+	top: 0upx;
+	left: 0upx;
+	right: 0;
+	bottom: 0;
+	margin: auto;
+	border-radius: 200upx;
+	/* #ifndef MP */
+	border: 7px solid #ffffff !important;
+	/* #endif */
+
+	/* #ifdef MP */
+	border: 8px solid #ffffff !important;
+	/* #endif */
+}
+
+.switch-sex::after {
+	content: "\e71c";
+}
+
+.switch-sex::before {
+	content: "\e71a";
+}
+
+.switch-sex .wx-switch-input,
+.switch-sex .uni-switch-input {
+	background: #e54d42 !important;
+	border-color: #e54d42 !important;
+}
+
+.switch-sex[checked] .wx-switch-input,
+.switch-sex.checked .uni-switch-input {
+	background: #4074E7 !important;
+	border-color: #4074E7 !important;
+}
+
+switch.red[checked] .wx-switch-input.wx-switch-input-checked,
+checkbox.red[checked] .wx-checkbox-input,
+radio.red[checked] .wx-radio-input,
+switch.red.checked .uni-switch-input.uni-switch-input-checked,
+checkbox.red.checked .uni-checkbox-input,
+radio.red.checked .uni-radio-input {
+	background-color: #e54d42 !important;
+	border-color: #e54d42 !important;
+	color: #ffffff !important;
+}
+
+switch.orange[checked] .wx-switch-input,
+checkbox.orange[checked] .wx-checkbox-input,
+radio.orange[checked] .wx-radio-input,
+switch.orange.checked .uni-switch-input,
+checkbox.orange.checked .uni-checkbox-input,
+radio.orange.checked .uni-radio-input {
+	background-color: #f37b1d !important;
+	border-color: #f37b1d !important;
+	color: #ffffff !important;
+}
+
+switch.yellow[checked] .wx-switch-input,
+checkbox.yellow[checked] .wx-checkbox-input,
+radio.yellow[checked] .wx-radio-input,
+switch.yellow.checked .uni-switch-input,
+checkbox.yellow.checked .uni-checkbox-input,
+radio.yellow.checked .uni-radio-input {
+	background-color: #fbbd08 !important;
+	border-color: #fbbd08 !important;
+	color: #333333 !important;
+}
+
+switch.olive[checked] .wx-switch-input,
+checkbox.olive[checked] .wx-checkbox-input,
+radio.olive[checked] .wx-radio-input,
+switch.olive.checked .uni-switch-input,
+checkbox.olive.checked .uni-checkbox-input,
+radio.olive.checked .uni-radio-input {
+	background-color: #8dc63f !important;
+	border-color: #8dc63f !important;
+	color: #ffffff !important;
+}
+
+switch.green[checked] .wx-switch-input,
+switch[checked] .wx-switch-input,
+checkbox.green[checked] .wx-checkbox-input,
+checkbox[checked] .wx-checkbox-input,
+radio.green[checked] .wx-radio-input,
+radio[checked] .wx-radio-input,
+switch.green.checked .uni-switch-input,
+switch.checked .uni-switch-input,
+checkbox.green.checked .uni-checkbox-input,
+checkbox.checked .uni-checkbox-input,
+radio.green.checked .uni-radio-input,
+radio.checked .uni-radio-input {
+	background-color: #39b54a !important;
+	border-color: #39b54a !important;
+	color: #ffffff !important;
+	border-color: #39B54A !important;
+}
+
+switch.cyan[checked] .wx-switch-input,
+checkbox.cyan[checked] .wx-checkbox-input,
+radio.cyan[checked] .wx-radio-input,
+switch.cyan.checked .uni-switch-input,
+checkbox.cyan.checked .uni-checkbox-input,
+radio.cyan.checked .uni-radio-input {
+	background-color: #1cbbb4 !important;
+	border-color: #1cbbb4 !important;
+	color: #ffffff !important;
+}
+
+switch.blue[checked] .wx-switch-input,
+checkbox.blue[checked] .wx-checkbox-input,
+radio.blue[checked] .wx-radio-input,
+switch.blue.checked .uni-switch-input,
+checkbox.blue.checked .uni-checkbox-input,
+radio.blue.checked .uni-radio-input {
+	background-color: #4074E7 !important;
+	border-color: #4074E7 !important;
+	color: #ffffff !important;
+}
+
+switch.purple[checked] .wx-switch-input,
+checkbox.purple[checked] .wx-checkbox-input,
+radio.purple[checked] .wx-radio-input,
+switch.purple.checked .uni-switch-input,
+checkbox.purple.checked .uni-checkbox-input,
+radio.purple.checked .uni-radio-input {
+	background-color: #6739b6 !important;
+	border-color: #6739b6 !important;
+	color: #ffffff !important;
+}
+
+switch.mauve[checked] .wx-switch-input,
+checkbox.mauve[checked] .wx-checkbox-input,
+radio.mauve[checked] .wx-radio-input,
+switch.mauve.checked .uni-switch-input,
+checkbox.mauve.checked .uni-checkbox-input,
+radio.mauve.checked .uni-radio-input {
+	background-color: #9c26b0 !important;
+	border-color: #9c26b0 !important;
+	color: #ffffff !important;
+}
+
+switch.pink[checked] .wx-switch-input,
+checkbox.pink[checked] .wx-checkbox-input,
+radio.pink[checked] .wx-radio-input,
+switch.pink.checked .uni-switch-input,
+checkbox.pink.checked .uni-checkbox-input,
+radio.pink.checked .uni-radio-input {
+	background-color: #e03997 !important;
+	border-color: #e03997 !important;
+	color: #ffffff !important;
+}
+
+switch.brown[checked] .wx-switch-input,
+checkbox.brown[checked] .wx-checkbox-input,
+radio.brown[checked] .wx-radio-input,
+switch.brown.checked .uni-switch-input,
+checkbox.brown.checked .uni-checkbox-input,
+radio.brown.checked .uni-radio-input {
+	background-color: #a5673f !important;
+	border-color: #a5673f !important;
+	color: #ffffff !important;
+}
+
+switch.grey[checked] .wx-switch-input,
+checkbox.grey[checked] .wx-checkbox-input,
+radio.grey[checked] .wx-radio-input,
+switch.grey.checked .uni-switch-input,
+checkbox.grey.checked .uni-checkbox-input,
+radio.grey.checked .uni-radio-input {
+	background-color: #8799a3 !important;
+	border-color: #8799a3 !important;
+	color: #ffffff !important;
+}
+
+switch.gray[checked] .wx-switch-input,
+checkbox.gray[checked] .wx-checkbox-input,
+radio.gray[checked] .wx-radio-input,
+switch.gray.checked .uni-switch-input,
+checkbox.gray.checked .uni-checkbox-input,
+radio.gray.checked .uni-radio-input {
+	background-color: #f0f0f0 !important;
+	border-color: #f0f0f0 !important;
+	color: #333333 !important;
+}
+
+switch.black[checked] .wx-switch-input,
+checkbox.black[checked] .wx-checkbox-input,
+radio.black[checked] .wx-radio-input,
+switch.black.checked .uni-switch-input,
+checkbox.black.checked .uni-checkbox-input,
+radio.black.checked .uni-radio-input {
+	background-color: #333333 !important;
+	border-color: #333333 !important;
+	color: #ffffff !important;
+}
+
+switch.white[checked] .wx-switch-input,
+checkbox.white[checked] .wx-checkbox-input,
+radio.white[checked] .wx-radio-input,
+switch.white.checked .uni-switch-input,
+checkbox.white.checked .uni-checkbox-input,
+radio.white.checked .uni-radio-input {
+	background-color: #ffffff !important;
+	border-color: #ffffff !important;
+	color: #333333 !important;
+}
+
+/* ==================
+          边框
+ ==================== */
+
+/* -- 实线 -- */
+
+.solid,
+.solid-top,
+.solid-right,
+.solid-bottom,
+.solid-left,
+.solids,
+.solids-top,
+.solids-right,
+.solids-bottom,
+.solids-left,
+.dashed,
+.dashed-top,
+.dashed-right,
+.dashed-bottom,
+.dashed-left {
+	position: relative;
+}
+
+.solid::after,
+.solid-top::after,
+.solid-right::after,
+.solid-bottom::after,
+.solid-left::after,
+.solids::after,
+.solids-top::after,
+.solids-right::after,
+.solids-bottom::after,
+.solids-left::after,
+.dashed::after,
+.dashed-top::after,
+.dashed-right::after,
+.dashed-bottom::after,
+.dashed-left::after {
+	content: " ";
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border-radius: inherit;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	pointer-events: none;
+	box-sizing: border-box;
+}
+
+.solid::after {
+	border: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solid-top::after {
+	border-top: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solid-right::after {
+	border-right: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solid-bottom::after {
+	border-bottom: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solid-left::after {
+	border-left: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solids::after {
+	border: 8upx solid #eee;
+}
+
+.solids-top::after {
+	border-top: 8upx solid #eee;
+}
+
+.solids-right::after {
+	border-right: 8upx solid #eee;
+}
+
+.solids-bottom::after {
+	border-bottom: 8upx solid #eee;
+}
+
+.solids-left::after {
+	border-left: 8upx solid #eee;
+}
+
+/* -- 虚线 -- */
+
+.dashed::after {
+	border: 1upx dashed #ddd;
+}
+
+.dashed-top::after {
+	border-top: 1upx dashed #ddd;
+}
+
+.dashed-right::after {
+	border-right: 1upx dashed #ddd;
+}
+
+.dashed-bottom::after {
+	border-bottom: 1upx dashed #ddd;
+}
+
+.dashed-left::after {
+	border-left: 1upx dashed #ddd;
+}
+
+/* -- 阴影 -- */
+
+.shadow[class*='white'] {
+	--ShadowSize: 0 1upx 6upx;
+}
+
+.shadow-lg {
+	--ShadowSize: 0upx 40upx 100upx 0upx;
+}
+
+.shadow-warp {
+	position: relative;
+	box-shadow: 0 0 10upx rgba(0, 0, 0, 0.1);
+}
+
+.shadow-warp:before,
+.shadow-warp:after {
+	position: absolute;
+	content: "";
+	top: 20upx;
+	bottom: 30upx;
+	left: 20upx;
+	width: 50%;
+	box-shadow: 0 30upx 20upx rgba(0, 0, 0, 0.2);
+	transform: rotate(-3deg);
+	z-index: -1;
+}
+
+.shadow-warp:after {
+	right: 20upx;
+	left: auto;
+	transform: rotate(3deg);
+}
+
+.shadow-blur {
+	position: relative;
+}
+
+.shadow-blur::before {
+	content: "";
+	display: block;
+	background: inherit;
+	filter: blur(10upx);
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	top: 10upx;
+	left: 10upx;
+	z-index: -1;
+	opacity: 0.4;
+	transform-origin: 0 0;
+	border-radius: inherit;
+	transform: scale(1, 1);
+}
+
+/* ==================
+          按钮
+ ==================== */
+
+.cu-btn {
+	position: relative;
+	border: 0upx;
+	display: inline-flex;
+	align-items: center;
+	justify-content: center;
+	box-sizing: border-box;
+	padding: 0 30upx;
+	font-size: 28upx;
+	height: 64upx;
+	line-height: 1;
+	text-align: center;
+	text-decoration: none;
+	overflow: visible;
+	margin-left: initial;
+	transform: translate(0upx, 0upx);
+	margin-right: initial;
+}
+
+.cu-btn::after {
+	display: none;
+}
+
+.cu-btn:not([class*="bg-"]) {
+	background-color: #f0f0f0;
+}
+
+.cu-btn[class*="line"] {
+	background-color: transparent;
+}
+
+.cu-btn[class*="line"]::after {
+	content: " ";
+	display: block;
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border: 1upx solid currentColor;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	box-sizing: border-box;
+	border-radius: 12upx;
+	z-index: 1;
+	pointer-events: none;
+}
+
+.cu-btn.round[class*="line"]::after {
+	border-radius: 1000upx;
+}
+
+.cu-btn[class*="lines"]::after {
+	border: 6upx solid currentColor;
+}
+
+.cu-btn[class*="bg-"]::after {
+	display: none;
+}
+
+.cu-btn.sm {
+	padding: 0 20upx;
+	font-size: 20upx;
+	height: 48upx;
+}
+
+.cu-btn.lg {
+	padding: 0 40upx;
+	font-size: 32upx;
+	height: 80upx;
+}
+
+.cu-btn.cuIcon.sm {
+	width: 48upx;
+	height: 48upx;
+}
+
+.cu-btn.cuIcon {
+	width: 64upx;
+	height: 64upx;
+	border-radius: 500upx;
+	padding: 0;
+}
+
+button.cuIcon.lg {
+	width: 80upx;
+	height: 80upx;
+}
+
+.cu-btn.shadow-blur::before {
+	top: 4upx;
+	left: 4upx;
+	filter: blur(6upx);
+	opacity: 0.6;
+}
+
+.cu-btn.button-hover {
+	transform: translate(1upx, 1upx);
+}
+
+.block {
+	display: block;
+}
+
+.cu-btn.block {
+	display: flex;
+}
+
+.cu-btn[disabled] {
+	opacity: 0.6;
+	color: #ffffff;
+}
+
+/* ==================
+          徽章
+ ==================== */
+
+.cu-tag {
+	font-size: 24upx;
+	vertical-align: middle;
+	position: relative;
+	display: inline-flex;
+	align-items: center;
+	justify-content: center;
+	box-sizing: border-box;
+	padding: 0upx 16upx;
+	height: 48upx;
+	font-family: Helvetica Neue, Helvetica, sans-serif;
+	white-space: nowrap;
+}
+
+.cu-tag:not([class*="bg"]):not([class*="line"]) {
+	background-color: #f1f1f1;
+}
+
+.cu-tag[class*="line-"]::after {
+	content: " ";
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border: 1upx solid currentColor;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	box-sizing: border-box;
+	border-radius: inherit;
+	z-index: 1;
+	pointer-events: none;
+}
+
+.cu-tag.radius[class*="line"]::after {
+	border-radius: 12upx;
+}
+
+.cu-tag.round[class*="line"]::after {
+	border-radius: 1000upx;
+}
+
+.cu-tag[class*="line-"]::after {
+	border-radius: 0;
+}
+
+.cu-tag+.cu-tag {
+	margin-left: 10upx;
+}
+
+.cu-tag.sm {
+	font-size: 20upx;
+	padding: 0upx 12upx;
+	height: 32upx;
+}
+
+.cu-capsule {
+	display: inline-flex;
+	vertical-align: middle;
+}
+
+.cu-capsule+.cu-capsule {
+	margin-left: 10upx;
+}
+
+.cu-capsule .cu-tag {
+	margin: 0;
+}
+
+.cu-capsule .cu-tag[class*="line-"]:last-child::after {
+	border-left: 0upx solid transparent;
+}
+
+.cu-capsule .cu-tag[class*="line-"]:first-child::after {
+	border-right: 0upx solid transparent;
+}
+
+.cu-capsule.radius .cu-tag:first-child {
+	border-top-left-radius: 6upx;
+	border-bottom-left-radius: 6upx;
+}
+
+.cu-capsule.radius .cu-tag:last-child::after,
+.cu-capsule.radius .cu-tag[class*="line-"] {
+	border-top-right-radius: 12upx;
+	border-bottom-right-radius: 12upx;
+}
+
+.cu-capsule.round .cu-tag:first-child {
+	border-top-left-radius: 200upx;
+	border-bottom-left-radius: 200upx;
+	text-indent: 4upx;
+}
+
+.cu-capsule.round .cu-tag:last-child::after,
+.cu-capsule.round .cu-tag:last-child {
+	border-top-right-radius: 200upx;
+	border-bottom-right-radius: 200upx;
+	text-indent: -4upx;
+}
+
+.cu-tag.badge {
+	border-radius: 200upx;
+	position: absolute;
+	top: -10upx;
+	right: -10upx;
+	font-size: 20upx;
+	padding: 0upx 10upx;
+	height: 28upx;
+	color: #ffffff;
+}
+
+.cu-tag.badge:not([class*="bg-"]) {
+	background-color: #dd514c;
+}
+
+.cu-tag:empty:not([class*="cuIcon-"]) {
+	padding: 0upx;
+	width: 16upx;
+	height: 16upx;
+	top: -4upx;
+	right: -4upx;
+}
+
+.cu-tag[class*="cuIcon-"] {
+	width: 32upx;
+	height: 32upx;
+	top: -4upx;
+	right: -4upx;
+}
+
+/* ==================
+          头像
+ ==================== */
+
+.cu-avatar {
+	font-variant: small-caps;
+	margin: 0;
+	padding: 0;
+	display: inline-flex;
+	text-align: center;
+	justify-content: center;
+	align-items: center;
+	background-color: #ccc;
+	color: #ffffff;
+	white-space: nowrap;
+	position: relative;
+	width: 64upx;
+	height: 64upx;
+	background-size: cover;
+	background-position: center;
+	vertical-align: middle;
+	font-size: 1.5em;
+}
+
+.cu-avatar.sm {
+	width: 48upx;
+	height: 48upx;
+	font-size: 1em;
+}
+
+.cu-avatar.lg {
+	width: 96upx;
+	height: 96upx;
+	font-size: 2em;
+}
+
+.cu-avatar.xl {
+	width: 128upx;
+	height: 128upx;
+	font-size: 2.5em;
+}
+
+.cu-avatar .avatar-text {
+	font-size: 0.4em;
+}
+
+.cu-avatar-group {
+	direction: rtl;
+	unicode-bidi: bidi-override;
+	padding: 0 10upx 0 40upx;
+	display: inline-block;
+}
+
+.cu-avatar-group .cu-avatar {
+	margin-left: -30upx;
+	border: 4upx solid #f1f1f1;
+	vertical-align: middle;
+}
+
+.cu-avatar-group .cu-avatar.sm {
+	margin-left: -20upx;
+	border: 1upx solid #f1f1f1;
+}
+
+/* ==================
+         进度条
+ ==================== */
+
+.cu-progress {
+	overflow: hidden;
+	height: 28upx;
+	background-color: #ebeef5;
+	display: inline-flex;
+	align-items: center;
+	width: 100%;
+}
+
+.cu-progress+view,
+.cu-progress+text {
+	line-height: 1;
+}
+
+.cu-progress.xs {
+	height: 10upx;
+}
+
+.cu-progress.sm {
+	height: 20upx;
+}
+
+.cu-progress view {
+	width: 0;
+	height: 100%;
+	align-items: center;
+	display: flex;
+	justify-items: flex-end;
+	justify-content: space-around;
+	font-size: 20upx;
+	color: #ffffff;
+	transition: width 0.6s ease;
+}
+
+.cu-progress text {
+	align-items: center;
+	display: flex;
+	font-size: 20upx;
+	color: #333333;
+	text-indent: 10upx;
+}
+
+.cu-progress.text-progress {
+	padding-right: 60upx;
+}
+
+.cu-progress.striped view {
+	background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+	background-size: 72upx 72upx;
+}
+
+.cu-progress.active view {
+	animation: progress-stripes 2s linear infinite;
+}
+
+@keyframes progress-stripes {
+	from {
+		background-position: 72upx 0;
+	}
+
+	to {
+		background-position: 0 0;
+	}
+}
+
+/* ==================
+          加载
+ ==================== */
+
+.cu-load {
+	display: block;
+	line-height: 3em;
+	text-align: center;
+}
+
+.cu-load::before {
+	font-family: "cuIcon";
+	display: inline-block;
+	margin-right: 6upx;
+}
+
+.cu-load.loading::before {
+	content: "\e67a";
+	animation: cuIcon-spin 2s infinite linear;
+}
+
+.cu-load.loading::after {
+	content: "加载中...";
+}
+
+.cu-load.over::before {
+	content: "\e64a";
+}
+
+.cu-load.over::after {
+	content: "没有更多了";
+}
+
+.cu-load.erro::before {
+	content: "\e658";
+}
+
+.cu-load.erro::after {
+	content: "加载失败";
+}
+
+.cu-load.load-cuIcon::before {
+	font-size: 32upx;
+}
+
+.cu-load.load-cuIcon::after {
+	display: none;
+}
+
+.cu-load.load-cuIcon.over {
+	display: none;
+}
+
+.cu-load.load-modal {
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 140upx;
+	left: 0;
+	margin: auto;
+	width: 260upx;
+	height: 260upx;
+	background-color: #ffffff;
+	border-radius: 10upx;
+	box-shadow: 0 0 0upx 2000upx rgba(0, 0, 0, 0.5);
+	display: flex;
+	align-items: center;
+	flex-direction: column;
+	justify-content: center;
+	font-size: 28upx;
+	z-index: 9999;
+	line-height: 2.4em;
+}
+
+.cu-load.load-modal [class*="cuIcon-"] {
+	font-size: 60upx;
+}
+
+.cu-load.load-modal image {
+	width: 70upx;
+	height: 70upx;
+}
+
+.cu-load.load-modal::after {
+	content: "";
+	position: absolute;
+	background-color: #ffffff;
+	border-radius: 50%;
+	width: 200upx;
+	height: 200upx;
+	font-size: 10px;
+	border-top: 6upx solid rgba(0, 0, 0, 0.05);
+	border-right: 6upx solid rgba(0, 0, 0, 0.05);
+	border-bottom: 6upx solid rgba(0, 0, 0, 0.05);
+	border-left: 6upx solid #f37b1d;
+	animation: cuIcon-spin 1s infinite linear;
+	z-index: -1;
+}
+
+.load-progress {
+	pointer-events: none;
+	top: 0;
+	position: fixed;
+	width: 100%;
+	left: 0;
+	z-index: 2000;
+}
+
+.load-progress.hide {
+	display: none;
+}
+
+.load-progress .load-progress-bar {
+	position: relative;
+	width: 100%;
+	height: 4upx;
+	overflow: hidden;
+	transition: all 200ms ease 0s;
+}
+
+.load-progress .load-progress-spinner {
+	position: absolute;
+	top: 10upx;
+	right: 10upx;
+	z-index: 2000;
+	display: block;
+}
+
+.load-progress .load-progress-spinner::after {
+	content: "";
+	display: block;
+	width: 24upx;
+	height: 24upx;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	border: solid 4upx transparent;
+	border-top-color: inherit;
+	border-left-color: inherit;
+	border-radius: 50%;
+	-webkit-animation: load-progress-spinner 0.4s linear infinite;
+	animation: load-progress-spinner 0.4s linear infinite;
+}
+
+@-webkit-keyframes load-progress-spinner {
+	0% {
+		-webkit-transform: rotate(0);
+		transform: rotate(0);
+	}
+
+	100% {
+		-webkit-transform: rotate(360deg);
+		transform: rotate(360deg);
+	}
+}
+
+@keyframes load-progress-spinner {
+	0% {
+		-webkit-transform: rotate(0);
+		transform: rotate(0);
+	}
+
+	100% {
+		-webkit-transform: rotate(360deg);
+		transform: rotate(360deg);
+	}
+}
+
+/* ==================
+          列表
+ ==================== */
+.grayscale {
+	filter: grayscale(1);
+}
+
+.cu-list+.cu-list {
+	margin-top: 30upx
+}
+
+.cu-list>.cu-item {
+	transition: all .6s ease-in-out 0s;
+	transform: translateX(0upx)
+}
+
+.cu-list>.cu-item.move-cur {
+	transform: translateX(-260upx)
+}
+
+.cu-list>.cu-item .move {
+	position: absolute;
+	right: 0;
+	display: flex;
+	width: 260upx;
+	height: 100%;
+	transform: translateX(100%)
+}
+
+.cu-list>.cu-item .move view {
+	display: flex;
+	flex: 1;
+	justify-content: center;
+	align-items: center
+}
+
+.cu-list.menu-avatar {
+	overflow: hidden;
+}
+
+.cu-list.menu-avatar>.cu-item {
+	position: relative;
+	display: flex;
+	padding-right: 10upx;
+	height: 140upx;
+	background-color: #ffffff;
+	justify-content: flex-end;
+	align-items: center
+}
+
+.cu-list.menu-avatar>.cu-item>.cu-avatar {
+	position: absolute;
+	left: 30upx
+}
+
+.cu-list.menu-avatar>.cu-item .flex .text-cut {
+	max-width: 510upx
+}
+
+.cu-list.menu-avatar>.cu-item .content {
+	position: absolute;
+	left: 146upx;
+	width: calc(100% - 96upx - 60upx - 120upx - 20upx);
+	line-height: 1.6em;
+}
+
+.cu-list.menu-avatar>.cu-item .content.flex-sub {
+	width: calc(100% - 96upx - 60upx - 20upx);
+}
+
+.cu-list.menu-avatar>.cu-item .content>view:first-child {
+	font-size: 30upx;
+	display: flex;
+	align-items: center
+}
+
+.cu-list.menu-avatar>.cu-item .content .cu-tag.sm {
+	display: inline-block;
+	margin-left: 10upx;
+	height: 28upx;
+	font-size: 16upx;
+	line-height: 32upx
+}
+
+.cu-list.menu-avatar>.cu-item .action {
+	width: 100upx;
+	text-align: center
+}
+
+.cu-list.menu-avatar>.cu-item .action view+view {
+	margin-top: 10upx
+}
+
+.cu-list.menu-avatar.comment .cu-item .content {
+	position: relative;
+	left: 0;
+	width: auto;
+	flex: 1;
+}
+
+.cu-list.menu-avatar.comment .cu-item {
+	padding: 30upx 30upx 30upx 120upx;
+	height: auto
+}
+
+.cu-list.menu-avatar.comment .cu-avatar {
+	align-self: flex-start
+}
+
+.cu-list.menu>.cu-item {
+	position: relative;
+	display: flex;
+	padding: 0 30upx;
+	min-height: 100upx;
+	background-color: #ffffff;
+	justify-content: space-between;
+	align-items: center
+}
+
+.cu-list.menu>.cu-item:last-child:after {
+	border: none
+}
+
+.cu-list.menu-avatar>.cu-item:after,
+.cu-list.menu>.cu-item:after {
+	position: absolute;
+	top: 0;
+	left: 0;
+	box-sizing: border-box;
+	width: 200%;
+	height: 200%;
+	border-bottom: 1upx solid #ddd;
+	border-radius: inherit;
+	content: " ";
+	transform: scale(.5);
+	transform-origin: 0 0;
+	pointer-events: none
+}
+
+.cu-list.menu>.cu-item.grayscale {
+	background-color: #f5f5f5
+}
+
+.cu-list.menu>.cu-item.cur {
+	background-color: #fcf7e9
+}
+
+.cu-list.menu>.cu-item.arrow {
+	padding-right: 90upx
+}
+
+.cu-list.menu>.cu-item.arrow:before {
+	position: absolute;
+	top: 0;
+	right: 30upx;
+	bottom: 0;
+	display: block;
+	margin: auto;
+	width: 30upx;
+	height: 30upx;
+	color: #8799a3;
+	content: "\e6a3";
+	text-align: center;
+	font-size: 34upx;
+	font-family: cuIcon;
+	line-height: 30upx
+}
+
+.cu-list.menu>.cu-item button.content {
+	padding: 0;
+	background-color: transparent;
+	justify-content: flex-start
+}
+
+.cu-list.menu>.cu-item button.content:after {
+	display: none
+}
+
+.cu-list.menu>.cu-item .cu-avatar-group .cu-avatar {
+	border-color: #ffffff
+}
+
+.cu-list.menu>.cu-item .content>view:first-child {
+	display: flex;
+	align-items: center
+}
+
+.cu-list.menu>.cu-item .content>text[class*=cuIcon] {
+	display: inline-block;
+	margin-right: 10upx;
+	width: 1.6em;
+	text-align: center
+}
+
+.cu-list.menu>.cu-item .content>image {
+	display: inline-block;
+	margin-right: 10upx;
+	width: 1.6em;
+	height: 1.6em;
+	vertical-align: middle
+}
+
+.cu-list.menu>.cu-item .content {
+	font-size: 30upx;
+	line-height: 1.6em;
+	flex: 1
+}
+
+.cu-list.menu>.cu-item .content .cu-tag.sm {
+	display: inline-block;
+	margin-left: 10upx;
+	height: 28upx;
+	font-size: 16upx;
+	line-height: 32upx
+}
+
+.cu-list.menu>.cu-item .action .cu-tag:empty {
+	right: 10upx
+}
+
+.cu-list.menu {
+	display: block;
+	overflow: hidden
+}
+
+.cu-list.menu.sm-border>.cu-item:after {
+	left: 30upx;
+	width: calc(200% - 120upx)
+}
+
+.cu-list.grid>.cu-item {
+	position: relative;
+	display: flex;
+	padding: 20upx 0 30upx;
+	transition-duration: 0s;
+	flex-direction: column
+}
+
+.cu-list.grid>.cu-item:after {
+	position: absolute;
+	top: 0;
+	left: 0;
+	box-sizing: border-box;
+	width: 200%;
+	height: 200%;
+	border-right: 1px solid rgba(0, 0, 0, .1);
+	border-bottom: 1px solid rgba(0, 0, 0, .1);
+	border-radius: inherit;
+	content: " ";
+	transform: scale(.5);
+	transform-origin: 0 0;
+	pointer-events: none
+}
+
+.cu-list.grid>.cu-item text {
+	display: block;
+	margin-top: 10upx;
+	color: #888;
+	font-size: 26upx;
+	line-height: 40upx
+}
+
+.cu-list.grid>.cu-item [class*=cuIcon] {
+	position: relative;
+	display: block;
+	margin-top: 20upx;
+	width: 100%;
+	font-size: 48upx
+}
+
+.cu-list.grid>.cu-item .cu-tag {
+	right: auto;
+	left: 50%;
+	margin-left: 20upx
+}
+
+.cu-list.grid {
+	background-color: #ffffff;
+	text-align: center
+}
+
+.cu-list.grid.no-border>.cu-item {
+	padding-top: 10upx;
+	padding-bottom: 20upx
+}
+
+.cu-list.grid.no-border>.cu-item:after {
+	border: none
+}
+
+.cu-list.grid.no-border {
+	/* padding: 20upx 10upx */
+	padding: 0upx 0upx
+}
+
+.cu-list.grid.col-3>.cu-item:nth-child(3n):after,
+.cu-list.grid.col-4>.cu-item:nth-child(4n):after,
+.cu-list.grid.col-5>.cu-item:nth-child(5n):after {
+	border-right-width: 0
+}
+
+.cu-list.card-menu {
+	overflow: hidden;
+	margin-right: 30upx;
+	margin-left: 30upx;
+	border-radius: 20upx
+}
+
+
+/* ==================
+          操作条
+ ==================== */
+
+.cu-bar {
+	display: flex;
+	position: relative;
+	align-items: center;
+	min-height: 100upx;
+	justify-content: space-between;
+}
+
+.cu-bar .action {
+	display: flex;
+	align-items: center;
+	height: 100%;
+	justify-content: center;
+	max-width: 100%;
+}
+
+.cu-bar .action.border-title {
+	position: relative;
+	top: -10upx;
+}
+
+.cu-bar .action.border-title text[class*="bg-"]:last-child {
+	position: absolute;
+	bottom: -0.5rem;
+	min-width: 2rem;
+	height: 6upx;
+	left: 0;
+}
+
+.cu-bar .action.sub-title {
+	position: relative;
+	top: -0.2rem;
+}
+
+.cu-bar .action.sub-title text {
+	position: relative;
+	z-index: 1;
+}
+
+.cu-bar .action.sub-title text[class*="bg-"]:last-child {
+	position: absolute;
+	display: inline-block;
+	bottom: -0.2rem;
+	border-radius: 6upx;
+	width: 100%;
+	height: 0.6rem;
+	left: 0.6rem;
+	opacity: 0.3;
+	z-index: 0;
+}
+
+.cu-bar .action.sub-title text[class*="text-"]:last-child {
+	position: absolute;
+	display: inline-block;
+	bottom: -0.7rem;
+	left: 0.5rem;
+	opacity: 0.2;
+	z-index: 0;
+	text-align: right;
+	font-weight: 900;
+	font-size: 36upx;
+}
+
+.cu-bar.justify-center .action.border-title text:last-child,
+.cu-bar.justify-center .action.sub-title text:last-child {
+	left: 0;
+	right: 0;
+	margin: auto;
+	text-align: center;
+}
+
+.cu-bar .action:first-child {
+	margin-left: 30upx;
+	font-size: 30upx;
+}
+
+.cu-bar .action text.text-cut {
+	text-align: left;
+	width: 100%;
+}
+
+.cu-bar .cu-avatar:first-child {
+	margin-left: 20upx;
+}
+
+.cu-bar .action:first-child>text[class*="cuIcon-"] {
+	margin-left: -0.3em;
+	margin-right: 0.3em;
+}
+
+.cu-bar .action:last-child {
+	margin-right: 30upx;
+}
+
+.cu-bar .action>text[class*="cuIcon-"],
+.cu-bar .action>view[class*="cuIcon-"] {
+	font-size: 36upx;
+}
+
+.cu-bar .action>text[class*="cuIcon-"]+text[class*="cuIcon-"] {
+	margin-left: 0.5em;
+}
+
+.cu-bar .content {
+	position: absolute;
+	text-align: center;
+	width: calc(100% - 340upx);
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: 0;
+	margin: auto;
+	height: 60upx;
+	font-size: 32upx;
+	line-height: 60upx;
+	cursor: none;
+	pointer-events: none;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+}
+
+.cu-bar.ios .content {
+	bottom: 7px;
+	height: 30px;
+	font-size: 32upx;
+	line-height: 30px;
+}
+
+.cu-bar.btn-group {
+	justify-content: space-around;
+}
+
+.cu-bar.btn-group button {
+	padding: 20upx 32upx;
+}
+
+.cu-bar.btn-group button {
+	flex: 1;
+	margin: 0 20upx;
+	max-width: 50%;
+}
+
+.cu-bar .search-form {
+	background-color: #f5f5f5;
+	line-height: 64upx;
+	height: 64upx;
+	font-size: 24upx;
+	color: #333333;
+	flex: 1;
+	display: flex;
+	align-items: center;
+	margin: 0 30upx;
+}
+
+.cu-bar .search-form+.action {
+	margin-right: 30upx;
+}
+
+.cu-bar .search-form input {
+	flex: 1;
+	padding-right: 30upx;
+	height: 64upx;
+	line-height: 64upx;
+	font-size: 26upx;
+	background-color: transparent;
+}
+
+.cu-bar .search-form [class*="cuIcon-"] {
+	margin: 0 0.5em 0 0.8em;
+}
+
+.cu-bar .search-form [class*="cuIcon-"]::before {
+	top: 0upx;
+}
+
+.cu-bar.fixed,
+.nav.fixed {
+	position: fixed;
+	width: 100%;
+	top: 0;
+	z-index: 1024;
+	box-shadow: 0 1upx 6upx rgba(0, 0, 0, 0.1);
+}
+
+.cu-bar.foot {
+	position: fixed;
+	width: 100%;
+	bottom: 0;
+	z-index: 1024;
+	box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1);
+}
+
+.cu-bar.tabbar {
+	padding: 0;
+	height: calc(100upx + env(safe-area-inset-bottom) / 2);
+	padding-bottom: calc(env(safe-area-inset-bottom) / 2);
+}
+
+.cu-tabbar-height {
+	min-height: 100upx;
+	height: calc(100upx + env(safe-area-inset-bottom) / 2);
+}
+
+.cu-bar.tabbar.shadow {
+	box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1);
+}
+
+.cu-bar.tabbar .action {
+	font-size: 22upx;
+	position: relative;
+	flex: 1;
+	text-align: center;
+	padding: 0;
+	display: block;
+	height: auto;
+	line-height: 1;
+	margin: 0;
+	background-color: inherit;
+	overflow: initial;
+}
+
+.cu-bar.tabbar.shop .action {
+	width: 140upx;
+	flex: initial;
+}
+
+.cu-bar.tabbar .action.add-action {
+	position: relative;
+	z-index: 2;
+	padding-top: 50upx;
+}
+
+.cu-bar.tabbar .action.add-action [class*="cuIcon-"] {
+	position: absolute;
+	width: 70upx;
+	z-index: 2;
+	height: 70upx;
+	border-radius: 50%;
+	line-height: 70upx;
+	font-size: 50upx;
+	top: -35upx;
+	left: 0;
+	right: 0;
+	margin: auto;
+	padding: 0;
+}
+
+.cu-bar.tabbar .action.add-action::after {
+	content: "";
+	position: absolute;
+	width: 100upx;
+	height: 100upx;
+	top: -50upx;
+	left: 0;
+	right: 0;
+	margin: auto;
+	box-shadow: 0 -3upx 8upx rgba(0, 0, 0, 0.08);
+	border-radius: 50upx;
+	background-color: inherit;
+	z-index: 0;
+}
+
+.cu-bar.tabbar .action.add-action::before {
+	content: "";
+	position: absolute;
+	width: 100upx;
+	height: 30upx;
+	bottom: 30upx;
+	left: 0;
+	right: 0;
+	margin: auto;
+	background-color: inherit;
+	z-index: 1;
+}
+
+.cu-bar.tabbar .btn-group {
+	flex: 1;
+	display: flex;
+	justify-content: space-around;
+	align-items: center;
+	padding: 0 10upx;
+}
+
+.cu-bar.tabbar button.action::after {
+	border: 0;
+}
+
+.cu-bar.tabbar .action [class*="cuIcon-"] {
+	width: 100upx;
+	position: relative;
+	display: block;
+	height: auto;
+	margin: 0 auto 10upx;
+	text-align: center;
+	font-size: 40upx;
+}
+
+.cu-bar.tabbar .action .cuIcon-cu-image {
+	margin: 0 auto;
+}
+
+.cu-bar.tabbar .action .cuIcon-cu-image image {
+	width: 50upx;
+	height: 50upx;
+	display: inline-block;
+}
+
+.cu-bar.tabbar .submit {
+	align-items: center;
+	display: flex;
+	justify-content: center;
+	text-align: center;
+	position: relative;
+	flex: 2;
+	align-self: stretch;
+}
+
+.cu-bar.tabbar .submit:last-child {
+	flex: 2.6;
+}
+
+.cu-bar.tabbar .submit+.submit {
+	flex: 2;
+}
+
+.cu-bar.tabbar.border .action::before {
+	content: " ";
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	border-right: 1upx solid rgba(0, 0, 0, 0.1);
+	z-index: 3;
+}
+
+.cu-bar.tabbar.border .action:last-child:before {
+	display: none;
+}
+
+.cu-bar.input {
+	padding-right: 20upx;
+	background-color: #ffffff;
+}
+
+.cu-bar.input input {
+	overflow: initial;
+	line-height: 64upx;
+	height: 64upx;
+	min-height: 64upx;
+	flex: 1;
+	font-size: 30upx;
+	margin: 0 20upx;
+}
+
+.cu-bar.input .action {
+	margin-left: 20upx;
+}
+
+.cu-bar.input .action [class*="cuIcon-"] {
+	font-size: 48upx;
+}
+
+.cu-bar.input input+.action {
+	margin-right: 20upx;
+	margin-left: 0upx;
+}
+
+.cu-bar.input .action:first-child [class*="cuIcon-"] {
+	margin-left: 0upx;
+}
+
+.cu-custom {
+	display: block;
+	position: relative;
+}
+
+.cu-custom .cu-bar .content {
+	width: calc(100% - 440upx);
+}
+
+/* #ifdef MP-ALIPAY */
+.cu-custom .cu-bar .action .cuIcon-back {
+	opacity: 0;
+}
+
+/* #endif */
+
+.cu-custom .cu-bar .content image {
+	height: 60upx;
+	width: 240upx;
+}
+
+.cu-custom .cu-bar {
+	min-height: 0px;
+	/* #ifdef MP-WEIXIN */
+	padding-right: 220upx;
+	/* #endif */
+	/* #ifdef MP-ALIPAY */
+	padding-right: 150upx;
+	/* #endif */
+	box-shadow: 0upx 0upx 0upx;
+	z-index: 9999;
+}
+
+.cu-custom .cu-bar .border-custom {
+	position: relative;
+	background: rgba(0, 0, 0, 0.15);
+	border-radius: 1000upx;
+	height: 30px;
+}
+
+.cu-custom .cu-bar .border-custom::after {
+	content: " ";
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border-radius: inherit;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	pointer-events: none;
+	box-sizing: border-box;
+	border: 1upx solid #ffffff;
+	opacity: 0.5;
+}
+
+.cu-custom .cu-bar .border-custom::before {
+	content: " ";
+	width: 1upx;
+	height: 110%;
+	position: absolute;
+	top: 22.5%;
+	left: 0;
+	right: 0;
+	margin: auto;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	pointer-events: none;
+	box-sizing: border-box;
+	opacity: 0.6;
+	background-color: #ffffff;
+}
+
+.cu-custom .cu-bar .border-custom text {
+	display: block;
+	flex: 1;
+	margin: auto !important;
+	text-align: center;
+	font-size: 34upx;
+}
+
+/* ==================
+         导航栏
+ ==================== */
+
+.nav {
+	white-space: nowrap;
+}
+
+::-webkit-scrollbar {
+	display: none;
+}
+
+.nav .cu-item {
+	height: 90upx;
+	display: inline-block;
+	line-height: 90upx;
+	margin: 0 10upx;
+	padding: 0 20upx;
+}
+
+.nav .cu-item.cur {
+	border-bottom: 4upx solid;
+}
+
+/* ==================
+         时间轴
+ ==================== */
+
+.cu-timeline {
+	display: block;
+	background-color: #ffffff;
+}
+
+.cu-timeline .cu-time {
+	width: 120upx;
+	text-align: center;
+	padding: 20upx 0;
+	font-size: 26upx;
+	color: #888;
+	display: block;
+}
+
+.cu-timeline>.cu-item {
+	padding: 30upx 30upx 30upx 120upx;
+	position: relative;
+	display: block;
+	z-index: 0;
+}
+
+.cu-timeline>.cu-item:not([class*="text-"]) {
+	color: #ccc;
+}
+
+.cu-timeline>.cu-item::after {
+	content: "";
+	display: block;
+	position: absolute;
+	width: 1upx;
+	background-color: #ddd;
+	left: 60upx;
+	height: 100%;
+	top: 0;
+	z-index: 8;
+}
+
+.cu-timeline>.cu-item::before {
+	font-family: "cuIcon";
+	display: block;
+	position: absolute;
+	top: 36upx;
+	z-index: 9;
+	background-color: #ffffff;
+	width: 50upx;
+	height: 50upx;
+	text-align: center;
+	border: none;
+	line-height: 50upx;
+	left: 36upx;
+}
+
+.cu-timeline>.cu-item:not([class*="cuIcon-"])::before {
+	content: "\e763";
+}
+
+.cu-timeline>.cu-item[class*="cuIcon-"]::before {
+	background-color: #ffffff;
+	width: 50upx;
+	height: 50upx;
+	text-align: center;
+	border: none;
+	line-height: 50upx;
+	left: 36upx;
+}
+
+.cu-timeline>.cu-item>.content {
+	padding: 30upx;
+	border-radius: 6upx;
+	display: block;
+	line-height: 1.6;
+}
+
+.cu-timeline>.cu-item>.content:not([class*="bg-"]) {
+	background-color: #f1f1f1;
+	color: #333333;
+}
+
+.cu-timeline>.cu-item>.content+.content {
+	margin-top: 20upx;
+}
+
+/* ==================
+         聊天
+ ==================== */
+
+.cu-chat {
+	display: flex;
+	flex-direction: column;
+}
+
+.cu-chat .cu-item {
+	display: flex;
+	padding: 30upx 30upx 70upx;
+	position: relative;
+}
+
+.cu-chat .cu-item>.cu-avatar {
+	width: 80upx;
+	height: 80upx;
+}
+
+.cu-chat .cu-item>.main {
+	max-width: calc(100% - 260upx);
+	margin: 0 40upx;
+	display: flex;
+	align-items: center;
+}
+
+.cu-chat .cu-item>image {
+	height: 320upx;
+}
+
+.cu-chat .cu-item>.main .content {
+	padding: 20upx;
+	border-radius: 6upx;
+	display: inline-flex;
+	max-width: 100%;
+	align-items: center;
+	font-size: 30upx;
+	position: relative;
+	min-height: 80upx;
+	line-height: 40upx;
+	text-align: left;
+}
+
+.cu-chat .cu-item>.main .content:not([class*="bg-"]) {
+	background-color: #ffffff;
+	color: #333333;
+}
+
+.cu-chat .cu-item .date {
+	position: absolute;
+	font-size: 24upx;
+	color: #8799a3;
+	width: calc(100% - 320upx);
+	bottom: 20upx;
+	left: 160upx;
+}
+
+.cu-chat .cu-item .action {
+	padding: 0 30upx;
+	display: flex;
+	align-items: center;
+}
+
+.cu-chat .cu-item>.main .content::after {
+	content: "";
+	top: 27upx;
+	transform: rotate(45deg);
+	position: absolute;
+	z-index: 100;
+	display: inline-block;
+	overflow: hidden;
+	width: 24upx;
+	height: 24upx;
+	left: -12upx;
+	right: initial;
+	background-color: inherit;
+}
+
+.cu-chat .cu-item.self>.main .content::after {
+	left: auto;
+	right: -12upx;
+}
+
+.cu-chat .cu-item>.main .content::before {
+	content: "";
+	top: 30upx;
+	transform: rotate(45deg);
+	position: absolute;
+	z-index: -1;
+	display: inline-block;
+	overflow: hidden;
+	width: 24upx;
+	height: 24upx;
+	left: -12upx;
+	right: initial;
+	background-color: inherit;
+	filter: blur(5upx);
+	opacity: 0.3;
+}
+
+.cu-chat .cu-item>.main .content:not([class*="bg-"])::before {
+	background-color: #333333;
+	opacity: 0.1;
+}
+
+.cu-chat .cu-item.self>.main .content::before {
+	left: auto;
+	right: -12upx;
+}
+
+.cu-chat .cu-item.self {
+	justify-content: flex-end;
+	text-align: right;
+}
+
+.cu-chat .cu-info {
+	display: inline-block;
+	margin: 20upx auto;
+	font-size: 24upx;
+	padding: 8upx 12upx;
+	background-color: rgba(0, 0, 0, 0.2);
+	border-radius: 6upx;
+	color: #ffffff;
+	max-width: 400upx;
+	line-height: 1.4;
+}
+
+/* ==================
+         卡片
+ ==================== */
+
+.cu-card {
+	display: block;
+	overflow: hidden;
+}
+
+.cu-card>.cu-item {
+	display: block;
+	background-color: #ffffff;
+	overflow: hidden;
+	border-radius: 10upx;
+	margin: 30upx;
+}
+
+.cu-card>.cu-item.shadow-blur {
+	overflow: initial;
+}
+
+.cu-card.no-card>.cu-item {
+	margin: 0upx;
+	border-radius: 0upx;
+}
+
+.cu-card .grid.grid-square {
+	margin-bottom: -20upx;
+}
+
+.cu-card.case .image {
+	position: relative;
+}
+
+.cu-card.case .image image {
+	width: 100%;
+}
+
+.cu-card.case .image .cu-tag {
+	position: absolute;
+	right: 0;
+	top: 0;
+}
+
+.cu-card.case .image .cu-bar {
+	position: absolute;
+	bottom: 0;
+	width: 100%;
+	background-color: transparent;
+	padding: 0upx 30upx;
+}
+
+.cu-card.case.no-card .image {
+	margin: 30upx 30upx 0;
+	overflow: hidden;
+	border-radius: 10upx;
+}
+
+.cu-card.dynamic {
+	display: block;
+}
+
+.cu-card.dynamic>.cu-item {
+	display: block;
+	background-color: #ffffff;
+	overflow: hidden;
+}
+
+.cu-card.dynamic>.cu-item>.text-content {
+	padding: 0 30upx 0;
+	max-height: 6.4em;
+	overflow: hidden;
+	font-size: 30upx;
+	margin-bottom: 20upx;
+}
+
+.cu-card.dynamic>.cu-item .square-img {
+	width: 100%;
+	height: 200upx;
+	border-radius: 6upx;
+}
+
+.cu-card.dynamic>.cu-item .only-img {
+	width: 100%;
+	height: 320upx;
+	border-radius: 6upx;
+}
+
+/* card.dynamic>.cu-item .comment {
+  padding: 20upx;
+  background-color: #f1f1f1;
+  margin: 0 30upx 30upx;
+  border-radius: 6upx;
+} */
+
+.cu-card.article {
+	display: block;
+}
+
+.cu-card.article>.cu-item {
+	padding-bottom: 30upx;
+}
+
+.cu-card.article>.cu-item .title {
+	font-size: 30upx;
+	font-weight: 900;
+	color: #333333;
+	line-height: 100upx;
+	padding: 0 30upx;
+}
+
+.cu-card.article>.cu-item .content {
+	display: flex;
+	padding: 0 30upx;
+}
+
+.cu-card.article>.cu-item .content>image {
+	width: 240upx;
+	height: 6.4em;
+	margin-right: 20upx;
+	border-radius: 6upx;
+}
+
+.cu-card.article>.cu-item .content .desc {
+	flex: 1;
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+}
+
+.cu-card.article>.cu-item .content .text-content {
+	font-size: 28upx;
+	color: #888;
+	height: 4.8em;
+	overflow: hidden;
+}
+
+/* ==================
+         表单
+ ==================== */
+
+.cu-form-group {
+	background-color: #ffffff;
+	padding: 1upx 30upx;
+	display: flex;
+	align-items: center;
+	min-height: 100upx;
+	justify-content: space-between;
+}
+
+.cu-form-group+.cu-form-group {
+	border-top: 1upx solid #eee;
+}
+
+.cu-form-group .title {
+	text-align: justify;
+	padding-right: 30upx;
+	font-size: 30upx;
+	position: relative;
+	height: 60upx;
+	line-height: 60upx;
+}
+
+.cu-form-group input {
+	flex: 1;
+	font-size: 30upx;
+	color: #555;
+	padding-right: 20upx;
+}
+
+.cu-form-group>text[class*="cuIcon-"] {
+	font-size: 36upx;
+	padding: 0;
+	box-sizing: border-box;
+}
+
+.cu-form-group textarea {
+	margin: 32upx 0 30upx;
+	height: 4.6em;
+	width: 100%;
+	line-height: 1.2em;
+	flex: 1;
+	font-size: 28upx;
+	padding: 0;
+}
+
+.cu-form-group.align-start .title {
+	height: 1em;
+	margin-top: 32upx;
+	line-height: 1em;
+}
+
+.cu-form-group picker {
+	flex: 1;
+	padding-right: 40upx;
+	overflow: hidden;
+	position: relative;
+}
+
+.cu-form-group picker .picker {
+	line-height: 100upx;
+	font-size: 28upx;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+	width: 100%;
+	text-align: right;
+}
+
+.cu-form-group picker::after {
+	font-family: cuIcon;
+	display: block;
+	content: "\e6a3";
+	position: absolute;
+	font-size: 34upx;
+	color: #8799a3;
+	line-height: 100upx;
+	width: 60upx;
+	text-align: center;
+	top: 0;
+	bottom: 0;
+	right: -20upx;
+	margin: auto;
+}
+
+.cu-form-group textarea[disabled],
+.cu-form-group textarea[disabled] .placeholder {
+	color: transparent;
+}
+
+/* ==================
+         模态窗口
+ ==================== */
+
+.cu-modal {
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	z-index: 1110;
+	opacity: 0;
+	outline: 0;
+	text-align: center;
+	-ms-transform: scale(1.185);
+	transform: scale(1.185);
+	backface-visibility: hidden;
+	perspective: 2000upx;
+	background: rgba(0, 0, 0, 0.6);
+	transition: all 0.3s ease-in-out 0s;
+	pointer-events: none;
+}
+
+.cu-modal::before {
+	content: "\200B";
+	display: inline-block;
+	height: 100%;
+	vertical-align: middle;
+}
+
+.cu-modal.show {
+	opacity: 1;
+	transition-duration: 0.3s;
+	-ms-transform: scale(1);
+	transform: scale(1);
+	overflow-x: hidden;
+	overflow-y: auto;
+	pointer-events: auto;
+}
+
+.cu-dialog {
+	position: relative;
+	display: inline-block;
+	vertical-align: middle;
+	margin-left: auto;
+	margin-right: auto;
+	width: 680upx;
+	max-width: 100%;
+	background-color: #f8f8f8;
+	border-radius: 10upx;
+	overflow: hidden;
+}
+
+.cu-modal.bottom-modal::before {
+	vertical-align: bottom;
+}
+
+.cu-modal.bottom-modal .cu-dialog {
+	width: 100%;
+	border-radius: 0;
+}
+
+.cu-modal.bottom-modal {
+	margin-bottom: -1000upx;
+}
+
+.cu-modal.bottom-modal.show {
+	margin-bottom: 0;
+}
+
+.cu-modal.drawer-modal {
+	transform: scale(1);
+	display: flex;
+}
+
+.cu-modal.drawer-modal .cu-dialog {
+	height: 100%;
+	min-width: 200upx;
+	border-radius: 0;
+	margin: initial;
+	transition-duration: 0.3s;
+}
+
+.cu-modal.drawer-modal.justify-start .cu-dialog {
+	transform: translateX(-100%);
+}
+
+.cu-modal.drawer-modal.justify-end .cu-dialog {
+	transform: translateX(100%);
+}
+
+.cu-modal.drawer-modal.show .cu-dialog {
+	transform: translateX(0%);
+}
+
+.cu-modal .cu-dialog>.cu-bar:first-child .action {
+	min-width: 100rpx;
+	margin-right: 0;
+	min-height: 100rpx;
+}
+
+/* ==================
+         轮播
+ ==================== */
+swiper .a-swiper-dot {
+	display: inline-block;
+	width: 16upx;
+	height: 16upx;
+	background: rgba(0, 0, 0, .3);
+	border-radius: 50%;
+	vertical-align: middle;
+}
+
+swiper[class*="-dot"] .wx-swiper-dots,
+swiper[class*="-dot"] .a-swiper-dots,
+swiper[class*="-dot"] .uni-swiper-dots {
+	display: flex;
+	align-items: center;
+	width: 100%;
+	justify-content: center;
+}
+
+swiper.square-dot .wx-swiper-dot,
+swiper.square-dot .a-swiper-dot,
+swiper.square-dot .uni-swiper-dot {
+	background-color: #ffffff;
+	opacity: 0.4;
+	width: 10upx;
+	height: 10upx;
+	border-radius: 20upx;
+	margin: 0 8upx !important;
+}
+
+swiper.square-dot .wx-swiper-dot.wx-swiper-dot-active,
+swiper.square-dot .a-swiper-dot.a-swiper-dot-active,
+swiper.square-dot .uni-swiper-dot.uni-swiper-dot-active {
+	opacity: 1;
+	width: 30upx;
+}
+
+swiper.round-dot .wx-swiper-dot,
+swiper.round-dot .a-swiper-dot,
+swiper.round-dot .uni-swiper-dot {
+	width: 10upx;
+	height: 10upx;
+	position: relative;
+	margin: 4upx 8upx !important;
+}
+
+swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active::after,
+swiper.round-dot .a-swiper-dot.a-swiper-dot-active::after,
+swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active::after {
+	content: "";
+	position: absolute;
+	width: 10upx;
+	height: 10upx;
+	top: 0upx;
+	left: 0upx;
+	right: 0;
+	bottom: 0;
+	margin: auto;
+	background-color: #ffffff;
+	border-radius: 20upx;
+}
+
+swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active,
+swiper.round-dot .a-swiper-dot.a-swiper-dot-active,
+swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active {
+	width: 18upx;
+	height: 18upx;
+}
+
+.screen-swiper {
+	min-height: 375upx;
+}
+
+.screen-swiper image,
+.screen-swiper video,
+.swiper-item image,
+.swiper-item video {
+	width: 100%;
+	display: block;
+	height: 100%;
+	margin: 0;
+	pointer-events: none;
+}
+
+.card-swiper {
+	height: 420upx !important;
+}
+
+.card-swiper swiper-item {
+	width: 610upx !important;
+	left: 70upx;
+	box-sizing: border-box;
+	padding: 40upx 0upx 70upx;
+	overflow: initial;
+}
+
+.card-swiper swiper-item .swiper-item {
+	width: 100%;
+	display: block;
+	height: 100%;
+	border-radius: 10upx;
+	transform: scale(0.9);
+	transition: all 0.2s ease-in 0s;
+	overflow: hidden;
+}
+
+.card-swiper swiper-item.cur .swiper-item {
+	transform: none;
+	transition: all 0.2s ease-in 0s;
+}
+
+
+.tower-swiper {
+	height: 420upx;
+	position: relative;
+	max-width: 750upx;
+	overflow: hidden;
+}
+
+.tower-swiper .tower-item {
+	position: absolute;
+	width: 300upx;
+	height: 380upx;
+	top: 0;
+	bottom: 0;
+	left: 50%;
+	margin: auto;
+	transition: all 0.2s ease-in 0s;
+	opacity: 1;
+}
+
+.tower-swiper .tower-item.none {
+	opacity: 0;
+}
+
+.tower-swiper .tower-item .swiper-item {
+	width: 100%;
+	height: 100%;
+	border-radius: 6upx;
+	overflow: hidden;
+}
+
+/* ==================
+          步骤条
+ ==================== */
+
+.cu-steps {
+	display: flex;
+}
+
+scroll-view.cu-steps {
+	display: block;
+	white-space: nowrap;
+}
+
+scroll-view.cu-steps .cu-item {
+	display: inline-block;
+}
+
+.cu-steps .cu-item {
+	flex: 1;
+	text-align: center;
+	position: relative;
+	min-width: 100upx;
+}
+
+.cu-steps .cu-item:not([class*="text-"]) {
+	color: #8799a3;
+}
+
+.cu-steps .cu-item [class*="cuIcon-"],
+.cu-steps .cu-item .num {
+	display: block;
+	font-size: 40upx;
+	line-height: 80upx;
+}
+
+.cu-steps .cu-item::before,
+.cu-steps .cu-item::after,
+.cu-steps.steps-arrow .cu-item::before,
+.cu-steps.steps-arrow .cu-item::after {
+	content: "";
+	display: block;
+	position: absolute;
+	height: 0px;
+	width: calc(100% - 80upx);
+	border-bottom: 1px solid #ccc;
+	left: calc(0px - (100% - 80upx) / 2);
+	top: 40upx;
+	z-index: 0;
+}
+
+.cu-steps.steps-arrow .cu-item::before,
+.cu-steps.steps-arrow .cu-item::after {
+	content: "\e6a3";
+	font-family: 'cuIcon';
+	height: 30upx;
+	border-bottom-width: 0px;
+	line-height: 30upx;
+	top: 0;
+	bottom: 0;
+	margin: auto;
+	color: #ccc;
+}
+
+.cu-steps.steps-bottom .cu-item::before,
+.cu-steps.steps-bottom .cu-item::after {
+	bottom: 40upx;
+	top: initial;
+}
+
+.cu-steps .cu-item::after {
+	border-bottom: 1px solid currentColor;
+	width: 0px;
+	transition: all 0.3s ease-in-out 0s;
+}
+
+.cu-steps .cu-item[class*="text-"]::after {
+	width: calc(100% - 80upx);
+	color: currentColor;
+}
+
+.cu-steps .cu-item:first-child::before,
+.cu-steps .cu-item:first-child::after {
+	display: none;
+}
+
+.cu-steps .cu-item .num {
+	width: 40upx;
+	height: 40upx;
+	border-radius: 50%;
+	line-height: 40upx;
+	margin: 20upx auto;
+	font-size: 24upx;
+	border: 1px solid currentColor;
+	position: relative;
+	overflow: hidden;
+}
+
+.cu-steps .cu-item[class*="text-"] .num {
+	background-color: currentColor;
+}
+
+.cu-steps .cu-item .num::before,
+.cu-steps .cu-item .num::after {
+	content: attr(data-index);
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	margin: auto;
+	transition: all 0.3s ease-in-out 0s;
+	transform: translateY(0upx);
+}
+
+.cu-steps .cu-item[class*="text-"] .num::before {
+	transform: translateY(-40upx);
+	color: #ffffff;
+}
+
+.cu-steps .cu-item .num::after {
+	transform: translateY(40upx);
+	color: #ffffff;
+	transition: all 0.3s ease-in-out 0s;
+}
+
+.cu-steps .cu-item[class*="text-"] .num::after {
+	content: "\e645";
+	font-family: 'cuIcon';
+	color: #ffffff;
+	transform: translateY(0upx);
+}
+
+.cu-steps .cu-item[class*="text-"] .num.err::after {
+	content: "\e646";
+}
+
+/* ==================
+          布局
+ ==================== */
+
+/*  -- flex弹性布局 -- */
+
+.flex {
+	display: flex;
+}
+
+.basis-xs {
+	flex-basis: 20%;
+}
+
+.basis-sm {
+	flex-basis: 40%;
+}
+
+.basis-df {
+	flex-basis: 50%;
+}
+
+.basis-lg {
+	flex-basis: 60%;
+}
+
+.basis-xl {
+	flex-basis: 80%;
+}
+
+.flex-sub {
+	flex: 1;
+}
+
+.flex-twice {
+	flex: 2;
+}
+
+.flex-treble {
+	flex: 3;
+}
+
+.flex-direction {
+	flex-direction: column;
+}
+
+.flex-wrap {
+	flex-wrap: wrap;
+}
+
+.align-start {
+	align-items: flex-start;
+}
+
+.align-end {
+	align-items: flex-end;
+}
+
+.align-center {
+	align-items: center;
+}
+
+.align-stretch {
+	align-items: stretch;
+}
+
+.self-start {
+	align-self: flex-start;
+}
+
+.self-center {
+	align-self: flex-center;
+}
+
+.self-end {
+	align-self: flex-end;
+}
+
+.self-stretch {
+	align-self: stretch;
+}
+
+.align-stretch {
+	align-items: stretch;
+}
+
+.justify-start {
+	justify-content: flex-start;
+}
+
+.justify-end {
+	justify-content: flex-end;
+}
+
+.justify-center {
+	justify-content: center;
+}
+
+.justify-between {
+	justify-content: space-between;
+}
+
+.justify-around {
+	justify-content: space-around;
+}
+
+/* grid布局 */
+
+.grid {
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.grid.grid-square {
+	overflow: hidden;
+}
+
+.grid.grid-square .cu-tag {
+	position: absolute;
+	right: 0;
+	top: 0;
+	border-bottom-left-radius: 6upx;
+	padding: 6upx 12upx;
+	height: auto;
+	background-color: rgba(0, 0, 0, 0.5);
+}
+
+.grid.grid-square>view>text[class*="cuIcon-"] {
+	font-size: 52upx;
+	position: absolute;
+	color: #8799a3;
+	margin: auto;
+	top: 0;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	flex-direction: column;
+}
+
+.grid.grid-square>view {
+	margin-right: 20upx;
+	margin-bottom: 20upx;
+	border-radius: 6upx;
+	position: relative;
+	overflow: hidden;
+}
+
+.grid.grid-square>view.bg-img image {
+	width: 100%;
+	height: 100%;
+	position: absolute;
+}
+
+.grid.col-1.grid-square>view {
+	padding-bottom: 100%;
+	height: 0;
+	margin-right: 0;
+}
+
+.grid.col-2.grid-square>view {
+	padding-bottom: calc((100% - 20upx)/2);
+	height: 0;
+	width: calc((100% - 20upx)/2);
+}
+
+.grid.col-3.grid-square>view {
+	padding-bottom: calc((100% - 40upx)/3);
+	height: 0;
+	width: calc((100% - 40upx)/3);
+}
+
+.grid.col-4.grid-square>view {
+	padding-bottom: calc((100% - 60upx)/4);
+	height: 0;
+	width: calc((100% - 60upx)/4);
+}
+
+.grid.col-5.grid-square>view {
+	padding-bottom: calc((100% - 80upx)/5);
+	height: 0;
+	width: calc((100% - 80upx)/5);
+}
+
+.grid.col-2.grid-square>view:nth-child(2n),
+.grid.col-3.grid-square>view:nth-child(3n),
+.grid.col-4.grid-square>view:nth-child(4n),
+.grid.col-5.grid-square>view:nth-child(5n) {
+	margin-right: 0;
+}
+
+.grid.col-1>view {
+	width: 100%;
+}
+
+.grid.col-2>view {
+	width: 50%;
+}
+
+.grid.col-3>view {
+	width: 33.33%;
+}
+
+.grid.col-4>view {
+	width: 25%;
+}
+
+.grid.col-5>view {
+	width: 20%;
+}
+
+/*  -- 内外边距 -- */
+
+.margin-0 {
+	margin: 0;
+}
+
+.margin-xs {
+	margin: 10upx;
+}
+
+.margin-sm {
+	margin: 20upx;
+}
+
+.margin {
+	margin: 30upx;
+}
+
+.margin-lg {
+	margin: 40upx;
+}
+
+.margin-xl {
+	margin: 50upx;
+}
+
+.margin-top-xs {
+	margin-top: 10upx;
+}
+
+.margin-top-sm {
+	margin-top: 20upx;
+}
+
+.margin-top {
+	margin-top: 30upx;
+}
+
+.margin-top-lg {
+	margin-top: 40upx;
+}
+
+.margin-top-xl {
+	margin-top: 50upx;
+}
+
+.margin-right-xs {
+	margin-right: 10upx;
+}
+
+.margin-right-sm {
+	margin-right: 20upx;
+}
+
+.margin-right {
+	margin-right: 30upx;
+}
+
+.margin-right-lg {
+	margin-right: 40upx;
+}
+
+.margin-right-xl {
+	margin-right: 50upx;
+}
+
+.margin-bottom-xs {
+	margin-bottom: 10upx;
+}
+
+.margin-bottom-sm {
+	margin-bottom: 20upx;
+}
+
+.margin-bottom {
+	margin-bottom: 30upx;
+}
+
+.margin-bottom-lg {
+	margin-bottom: 40upx;
+}
+
+.margin-bottom-xl {
+	margin-bottom: 50upx;
+}
+
+.margin-left-xs {
+	margin-left: 10upx;
+}
+
+.margin-left-sm {
+	margin-left: 20upx;
+}
+
+.margin-left {
+	margin-left: 30upx;
+}
+
+.margin-left-lg {
+	margin-left: 40upx;
+}
+
+.margin-left-xl {
+	margin-left: 50upx;
+}
+
+.margin-lr-xs {
+	margin-left: 10upx;
+	margin-right: 10upx;
+}
+
+.margin-lr-sm {
+	margin-left: 20upx;
+	margin-right: 20upx;
+}
+
+.margin-lr {
+	margin-left: 30upx;
+	margin-right: 30upx;
+}
+
+.margin-lr-lg {
+	margin-left: 40upx;
+	margin-right: 40upx;
+}
+
+.margin-lr-xl {
+	margin-left: 50upx;
+	margin-right: 50upx;
+}
+
+.margin-tb-xs {
+	margin-top: 10upx;
+	margin-bottom: 10upx;
+}
+
+.margin-tb-sm {
+	margin-top: 20upx;
+	margin-bottom: 20upx;
+}
+
+.margin-tb {
+	margin-top: 30upx;
+	margin-bottom: 30upx;
+}
+
+.margin-tb-lg {
+	margin-top: 40upx;
+	margin-bottom: 40upx;
+}
+
+.margin-tb-xl {
+	margin-top: 50upx;
+	margin-bottom: 50upx;
+}
+
+.padding-0 {
+	padding: 0;
+}
+
+.padding-xs {
+	padding: 10upx;
+}
+
+.padding-sm {
+	padding: 20upx;
+}
+
+.padding {
+	padding: 30upx;
+}
+
+.padding-lg {
+	padding: 40upx;
+}
+
+.padding-xl {
+	padding: 50upx;
+}
+
+.padding-top-xs {
+	padding-top: 10upx;
+}
+
+.padding-top-sm {
+	padding-top: 20upx;
+}
+
+.padding-top {
+	padding-top: 30upx;
+}
+
+.padding-top-lg {
+	padding-top: 40upx;
+}
+
+.padding-top-xl {
+	padding-top: 50upx;
+}
+
+.padding-right-xs {
+	padding-right: 10upx;
+}
+
+.padding-right-sm {
+	padding-right: 20upx;
+}
+
+.padding-right {
+	padding-right: 30upx;
+}
+
+.padding-right-lg {
+	padding-right: 40upx;
+}
+
+.padding-right-xl {
+	padding-right: 50upx;
+}
+
+.padding-bottom-xs {
+	padding-bottom: 10upx;
+}
+
+.padding-bottom-sm {
+	padding-bottom: 20upx;
+}
+
+.padding-bottom {
+	padding-bottom: 30upx;
+}
+
+.padding-bottom-lg {
+	padding-bottom: 40upx;
+}
+
+.padding-bottom-xl {
+	padding-bottom: 50upx;
+}
+
+.padding-left-xs {
+	padding-left: 10upx;
+}
+
+.padding-left-sm {
+	padding-left: 20upx;
+}
+
+.padding-left {
+	padding-left: 30upx;
+}
+
+.padding-left-lg {
+	padding-left: 40upx;
+}
+
+.padding-left-xl {
+	padding-left: 50upx;
+}
+
+.padding-lr-xs {
+	padding-left: 10upx;
+	padding-right: 10upx;
+}
+
+.padding-lr-sm {
+	padding-left: 20upx;
+	padding-right: 20upx;
+}
+
+.padding-lr {
+	padding-left: 30upx;
+	padding-right: 30upx;
+}
+
+.padding-lr-lg {
+	padding-left: 40upx;
+	padding-right: 40upx;
+}
+
+.padding-lr-xl {
+	padding-left: 50upx;
+	padding-right: 50upx;
+}
+
+.padding-tb-xs {
+	padding-top: 10upx;
+	padding-bottom: 10upx;
+}
+
+.padding-tb-sm {
+	padding-top: 20upx;
+	padding-bottom: 20upx;
+}
+
+.padding-tb {
+	padding-top: 30upx;
+	padding-bottom: 30upx;
+}
+
+.padding-tb-lg {
+	padding-top: 40upx;
+	padding-bottom: 40upx;
+}
+
+.padding-tb-xl {
+	padding-top: 50upx;
+	padding-bottom: 50upx;
+}
+
+/* -- 浮动 --  */
+
+.cf::after,
+.cf::before {
+	content: " ";
+	display: table;
+}
+
+.cf::after {
+	clear: both;
+}
+
+.fl {
+	float: left;
+}
+
+.fr {
+	float: right;
+}
+
+/* ==================
+          背景
+ ==================== */
+
+.line-red::after,
+.lines-red::after {
+	border-color: #e54d42;
+}
+
+.line-orange::after,
+.lines-orange::after {
+	border-color: #f37b1d;
+}
+
+.line-yellow::after,
+.lines-yellow::after {
+	border-color: #EFEF04;
+}
+
+.line-olive::after,
+.lines-olive::after {
+	border-color: #8dc63f;
+}
+
+.line-green::after,
+.lines-green::after {
+	border-color: #39b54a;
+}
+
+.line-cyan::after,
+.lines-cyan::after {
+	border-color: #1cbbb4;
+}
+
+.line-blue::after,
+.lines-blue::after {
+	border-color: #4074E7;
+}
+
+.line-purple::after,
+.lines-purple::after {
+	border-color: #6739b6;
+}
+
+.line-mauve::after,
+.lines-mauve::after {
+	border-color: #9c26b0;
+}
+
+.line-pink::after,
+.lines-pink::after {
+	border-color: #e03997;
+}
+
+.line-brown::after,
+.lines-brown::after {
+	border-color: #a5673f;
+}
+
+.line-grey::after,
+.lines-grey::after {
+	border-color: #8799a3;
+}
+
+.line-gray::after,
+.lines-gray::after {
+	border-color: #aaaaaa;
+}
+
+.line-black::after,
+.lines-black::after {
+	border-color: #333333;
+}
+
+.line-white::after,
+.lines-white::after {
+	border-color: #ffffff;
+}
+
+.bg-red {
+	background-color: #e54d42;
+	color: #ffffff;
+}
+
+.bg-orange {
+	background-color: #f37b1d;
+	color: #ffffff;
+}
+
+.bg-yellow {
+	background-color: #EFEF04;
+	color: #333333;
+}
+
+.bg-olive {
+	background-color: #8dc63f;
+	color: #ffffff;
+}
+
+.bg-green {
+	background-color: #39b54a;
+	color: #ffffff;
+}
+
+.bg-cyan {
+	background-color: #1cbbb4;
+	color: #ffffff;
+}
+
+.bg-blue {
+	background-color: #4074E7;
+	color: #ffffff;
+}
+
+.bg-purple {
+	background-color: #6739b6;
+	color: #ffffff;
+}
+
+.bg-mauve {
+	background-color: #9c26b0;
+	color: #ffffff;
+}
+
+.bg-pink {
+	background-color: #e03997;
+	color: #ffffff;
+}
+
+.bg-brown {
+	background-color: #a5673f;
+	color: #ffffff;
+}
+
+.bg-grey {
+	background-color: #8799a3;
+	color: #ffffff;
+}
+
+.bg-gray {
+	background-color: #f0f0f0;
+	color: #333333;
+}
+
+.bg-black {
+	background-color: #333333;
+	color: #ffffff;
+}
+
+.bg-white {
+	background-color: #ffffff;
+	color: #666666;
+}
+
+.bg-shadeTop {
+	background-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.01));
+	color: #ffffff;
+}
+
+.bg-shadeBottom {
+	background-image: linear-gradient(rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 1));
+	color: #ffffff;
+}
+
+.bg-red.light {
+	color: #e54d42;
+	background-color: #fadbd9;
+}
+
+.bg-orange.light {
+	color: #f37b1d;
+	background-color: #fde6d2;
+}
+
+.bg-yellow.light {
+	color: #EFEF04;
+	background-color: #fef2ced2;
+}
+
+.bg-olive.light {
+	color: #8dc63f;
+	background-color: #e8f4d9;
+}
+
+.bg-green.light {
+	color: #39b54a;
+	background-color: #d7f0dbff;
+}
+
+.bg-cyan.light {
+	color: #1cbbb4;
+	background-color: #d2f1f0;
+}
+
+.bg-blue.light {
+	color: #4074E7;
+	background-color: #cce6ff;
+}
+
+.bg-purple.light {
+	color: #6739b6;
+	background-color: #e1d7f0;
+}
+
+.bg-mauve.light {
+	color: #9c26b0;
+	background-color: #ebd4ef;
+}
+
+.bg-pink.light {
+	color: #e03997;
+	background-color: #f9d7ea;
+}
+
+.bg-brown.light {
+	color: #a5673f;
+	background-color: #ede1d9;
+}
+
+.bg-grey.light {
+	color: #8799a3;
+	background-color: #e7ebed;
+}
+
+.bg-gradual-red {
+	background-image: linear-gradient(45deg, #f43f3b, #ec008c);
+	color: #ffffff;
+}
+
+.bg-gradual-orange {
+	background-image: linear-gradient(45deg, #ff9700, #ed1c24);
+	color: #ffffff;
+}
+
+.bg-gradual-green {
+	background-image: linear-gradient(45deg, #39b54a, #8dc63f);
+	color: #ffffff;
+}
+
+.bg-gradual-purple {
+	background-image: linear-gradient(45deg, #9000ff, #5e00ff);
+	color: #ffffff;
+}
+
+.bg-gradual-pink {
+	background-image: linear-gradient(45deg, #ec008c, #6739b6);
+	color: #ffffff;
+}
+
+.bg-gradual-blue {
+	background-image: linear-gradient(45deg, #4074E7, #1cbbb4);
+	color: #ffffff;
+}
+
+.shadow[class*="-red"] {
+	box-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2);
+}
+
+.shadow[class*="-orange"] {
+	box-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2);
+}
+
+.shadow[class*="-yellow"] {
+	box-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2);
+}
+
+.shadow[class*="-olive"] {
+	box-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2);
+}
+
+.shadow[class*="-green"] {
+	box-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2);
+}
+
+.shadow[class*="-cyan"] {
+	box-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2);
+}
+
+.shadow[class*="-blue"] {
+	box-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2);
+}
+
+.shadow[class*="-purple"] {
+	box-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2);
+}
+
+.shadow[class*="-mauve"] {
+	box-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2);
+}
+
+.shadow[class*="-pink"] {
+	box-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2);
+}
+
+.shadow[class*="-brown"] {
+	box-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2);
+}
+
+.shadow[class*="-grey"] {
+	box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
+}
+
+.shadow[class*="-gray"] {
+	box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
+}
+
+.shadow[class*="-black"] {
+	box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
+}
+
+.shadow[class*="-white"] {
+	box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
+}
+
+.text-shadow[class*="-red"] {
+	text-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2);
+}
+
+.text-shadow[class*="-orange"] {
+	text-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2);
+}
+
+.text-shadow[class*="-yellow"] {
+	text-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2);
+}
+
+.text-shadow[class*="-olive"] {
+	text-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2);
+}
+
+.text-shadow[class*="-green"] {
+	text-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2);
+}
+
+.text-shadow[class*="-cyan"] {
+	text-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2);
+}
+
+.text-shadow[class*="-blue"] {
+	text-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2);
+}
+
+.text-shadow[class*="-purple"] {
+	text-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2);
+}
+
+.text-shadow[class*="-mauve"] {
+	text-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2);
+}
+
+.text-shadow[class*="-pink"] {
+	text-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2);
+}
+
+.text-shadow[class*="-brown"] {
+	text-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2);
+}
+
+.text-shadow[class*="-grey"] {
+	text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
+}
+
+.text-shadow[class*="-gray"] {
+	text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
+}
+
+.text-shadow[class*="-black"] {
+	text-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
+}
+
+.bg-img {
+	background-size: cover;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+
+.bg-mask {
+	background-color: #333333;
+	position: relative;
+}
+
+.bg-mask::after {
+	content: "";
+	border-radius: inherit;
+	width: 100%;
+	height: 100%;
+	display: block;
+	background-color: rgba(0, 0, 0, 0.4);
+	position: absolute;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: 0;
+}
+
+.bg-mask view,
+.bg-mask cover-view {
+	z-index: 5;
+	position: relative;
+}
+
+.bg-video {
+	position: relative;
+}
+
+.bg-video video {
+	display: block;
+	height: 100%;
+	width: 100%;
+	-o-object-fit: cover;
+	object-fit: cover;
+	position: absolute;
+	top: 0;
+	z-index: 0;
+	pointer-events: none;
+}
+
+/* ==================
+          文本
+ ==================== */
+
+.text-xs {
+	font-size: 20upx;
+}
+
+.text-sm {
+	font-size: 24upx;
+}
+
+.text-df {
+	font-size: 28upx;
+}
+
+.text-lg {
+	font-size: 32upx;
+}
+
+.text-xl {
+	font-size: 36upx;
+}
+
+.text-xxl {
+	font-size: 44upx;
+}
+
+.text-sl {
+	font-size: 80upx;
+}
+
+.text-xsl {
+	font-size: 120upx;
+}
+
+.text-Abc {
+	text-transform: Capitalize;
+}
+
+.text-ABC {
+	text-transform: Uppercase;
+}
+
+.text-abc {
+	text-transform: Lowercase;
+}
+
+.text-price::before {
+	content: "¥";
+	font-size: 80%;
+	margin-right: 4upx;
+}
+
+.text-cut {
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+}
+
+.text-bold {
+	font-weight: bold;
+}
+
+.text-center {
+	text-align: center;
+}
+
+.text-content {
+	line-height: 1.6;
+}
+
+.text-left {
+	text-align: left;
+}
+
+.text-right {
+	text-align: right;
+}
+
+.text-red,
+.line-red,
+.lines-red {
+	color: #e54d42;
+}
+
+.text-orange,
+.line-orange,
+.lines-orange {
+	color: #f37b1d;
+}
+
+.text-yellow,
+.line-yellow,
+.lines-yellow {
+	color: #EFEF04;
+}
+
+.text-olive,
+.line-olive,
+.lines-olive {
+	color: #8dc63f;
+}
+
+.text-green,
+.line-green,
+.lines-green {
+	color: #39b54a;
+}
+
+.text-cyan,
+.line-cyan,
+.lines-cyan {
+	color: #1cbbb4;
+}
+
+.text-blue,
+.line-blue,
+.lines-blue {
+	color: #4074E7;
+}
+
+.text-purple,
+.line-purple,
+.lines-purple {
+	color: #6739b6;
+}
+
+.text-mauve,
+.line-mauve,
+.lines-mauve {
+	color: #9c26b0;
+}
+
+.text-pink,
+.line-pink,
+.lines-pink {
+	color: #e03997;
+}
+
+.text-brown,
+.line-brown,
+.lines-brown {
+	color: #a5673f;
+}
+
+.text-grey,
+.line-grey,
+.lines-grey {
+	color: #8799a3;
+}
+
+.text-gray,
+.line-gray,
+.lines-gray {
+	color: #aaaaaa;
+}
+
+.text-black,
+.line-black,
+.lines-black {
+	color: #333333;
+}
+
+.text-white,
+.line-white,
+.lines-white {
+	color: #ffffff;
+}

+ 30 - 0
src/common/common.js

@@ -0,0 +1,30 @@
+// 处理多次点击
+function noMultipleClicks(methods,params) {
+    let that = this;
+    
+    if (that.noClick) {
+		console.log(1)
+        that.noClick= false;
+        methods(params);
+        setTimeout(function () {
+            that.noClick= true;
+        }, 2000)
+    } else {
+		console.log(2)
+        uni.showToast({
+            title: '请勿重复点击',
+            duration: 2000,
+            icon: 'none'
+        })
+    }
+}
+
+// const websiteUrl = 'https://qhome.usky.cn';  
+// const BASE_URL = 'https://qhome.usky.cn/USKYZHAF/USKYZHAF.php/Home/'
+
+//导出
+export default {
+    noMultipleClicks,//禁止多次点击
+	// websiteUrl,
+	// BASE_URL
+}

+ 584 - 0
src/common/common.scss

@@ -0,0 +1,584 @@
+/* common */
+
+* {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+body .uni-input-input,
+body .uni-textarea-textarea {
+  -webkit-touch-callout: initial !important;
+  -webkit-user-select: initial !important;
+  -khtml-user-select: initial !important;
+  -moz-user-select: initial !important;
+  -ms-user-select: initial !important;
+  user-select: initial !important;
+}
+
+body .el-input,
+body .el-input__inner {
+  -webkit-touch-callout: initial !important;
+  -webkit-user-select: initial !important;
+  -khtml-user-select: initial !important;
+  -moz-user-select: initial !important;
+  -ms-user-select: initial !important;
+  user-select: initial !important;
+}
+
+body {
+  font-size: 32rpx;
+}
+
+.cut {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.text-cut {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  width: 85%;
+}
+
+radio,
+checkbox {
+  transform: scale(0.7);
+}
+
+/* 修改placeholder颜色 */
+.uni-input-placeholder {
+  color: #999;
+}
+
+table {
+  border-collapse: collapse;
+  width: 100%;
+  text-align: left;
+}
+
+table,
+tr,
+td,
+th {
+  border: 1px solid #e2e2e2;
+}
+
+td,
+th {
+  padding: 14rpx 10rpx;
+  font-size: 26rpx;
+}
+
+.imgPic image {
+  width: 100%;
+}
+
+/* 一行显示*/
+.inOneLine {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+/* 画面监控引入特殊字体 */
+@font-face {
+  font-family: "FANDOLFANG-REGULAR";
+  /* project id 2394829 */
+  src: url("static/font/FANDOLFANG-REGULAR.OTF");
+}
+
+/* 巡检计划图表入特殊字体 */
+@font-face {
+  font-family: "IMPACT";
+  /* project id 2394829 */
+  src: url("static/font/IMPACT.TTF");
+}
+
+.cu-bar .search-form uni-input {
+  padding: 0 30rpx;
+}
+
+.searchSelect {
+  position: -webkit-fixed;
+  position: fixed;
+  // top: 88rpx;
+  left: 0;
+  bottom: 50px;
+  top: var(--window-top);
+  z-index: 999;
+  -webkit-box-flex: 1;
+  -webkit-flex: 1;
+  flex: 1;
+  -webkit-box-orient: vertical;
+  -webkit-box-direction: normal;
+  -webkit-flex-direction: column;
+  flex-direction: column;
+  overflow: hidden;
+  background-color: #fff;
+  width: 254rpx;
+
+  .search {
+    min-height: 80rpx;
+  }
+
+  .search-form {
+    border: 1px solid #e9e9e9;
+    height: 50rpx;
+    line-height: 50rpx;
+
+    .cuIcon-search {
+      color: #4074e7;
+    }
+
+    input {
+      padding-left: 20rpx;
+      padding-right: 0rpx;
+    }
+  }
+
+  .select-item {
+    padding: 12rpx 32rpx;
+    text-align: center;
+    border-top: 1px solid #e9e9e9;
+    font-size: 28rpx;
+  }
+}
+
+/* 九宫格样式 */
+.cu-list.grid > .cu-item uni-text {
+  color: #333;
+  font-size: 30rpx;
+  margin-top: 14rpx;
+}
+
+.cu-list.menu-avatar > .cu-item > .cu-avatar {
+  left: 24rpx;
+  background-color: rgba(0, 0, 0, 0);
+}
+
+.cu-list.menu-avatar > .cu-item .action {
+  width: 132rpx;
+}
+
+.iconfont.phone {
+  color: #08be04 !important;
+  font-size: 45rpx;
+  position: relative;
+  top: 6rpx;
+  left: 10rpx;
+}
+
+.iconfont.map {
+  color: #4074e7 !important;
+  font-size: 38rpx;
+}
+
+/* 列列表公共样式 */
+.processWrapper .cu-avatar {
+  background-repeat: no-repeat;
+  background-size: cover;
+  background-color: #fff;
+}
+
+.cu-avatar.lg {
+  width: 90rpx;
+  height: 90rpx;
+}
+
+.cu-list.menu-avatar > .cu-item > .cu-avatar {
+  left: 0;
+}
+
+.cu-list.menu-avatar > .cu-item .content {
+  left: 120rpx;
+  width: 580rpx;
+}
+
+// 底部操作样式 (分享  设备注册)
+.share {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  background: #f4f5f7;
+  border: 1px solid #e6e6e6;
+
+  .share-item {
+    padding: 20rpx;
+  }
+
+  .share-item:nth-child(2) {
+    border-left: 1px solid #e6e6e6;
+    border-right: 1px solid #e6e6e6;
+  }
+}
+
+/* 页面样式 */
+
+/* 站点列表页 */
+/* 筛选框 */
+.filter-section {
+  /* position: fixed; */
+  /* top: 88rpx; */
+  width: 100%;
+  z-index: 9;
+}
+
+.cu-bar .search-form {
+  background: #fff;
+}
+
+.cu-btn {
+  padding: 0 46rpx;
+}
+
+/* 站点列表 */
+.site-items {
+  margin-top: 100rpx;
+  width: 100%;
+  height: calc(100% - 100rpx);
+  // overflow: scroll
+}
+
+.site-items .site-tit {
+  font-size: 32rpx;
+  color: #333;
+  justify-content: space-between;
+}
+
+.site-items .cu-avatar {
+}
+
+/* 新增按钮 */
+.site-wrapper .plus {
+  position: fixed;
+  bottom: 20rpx;
+  right: 20rpx;
+}
+
+/* 已处理未处理列表 */
+.processList .cu-list.menu-avatar .cu-item {
+  height: 180rpx;
+}
+
+.pro-title {
+  color: #333;
+}
+
+.pro-des,
+.pro-date {
+  font-size: 28rpx;
+  color: #666;
+}
+
+.processList {
+  width: 100%;
+  height: calc(100% - 90rpx);
+  overflow-y: scroll;
+}
+
+.fireBashWrapper.pushListWrapper {
+  margin-top: 0rpx;
+}
+
+.share-item.active {
+  color: red;
+}
+
+/* 已处理未处理详情页样式 */
+.timeBox {
+  height: 88rpx;
+  background: #eff4ff;
+  line-height: 88rpx;
+
+  .time {
+    color: #333;
+  }
+}
+
+.info-tit {
+  color: #4074e7;
+  line-height: 90rpx;
+  height: 90rpx;
+}
+
+/* // 基本信息 */
+.info-content > view {
+  margin-left: 24rpx;
+  border-bottom: 1px solid #ededed;
+  line-height: 92rpx;
+  color: #666;
+
+  .checkMore {
+    color: #4074e7 !important;
+  }
+}
+
+.info-content view text:first-child {
+  width: auto !important;
+  display: inline-block;
+}
+
+//分析页面
+.analyse-wrapper {
+  .cu-list.menu-avatar .cu-item {
+    border-radius: 5px;
+    padding: 30rpx 0;
+    box-shadow: 1px 1px 4px rgb(26 26 26 / 10%);
+    .cu-avatar {
+      background-color: rgba(0, 0, 0, 0);
+      left: 26rpx;
+    }
+
+    .content {
+      left: 130rpx;
+      font-size: 32rpx;
+    }
+  }
+}
+
+//消息页面
+.image-bg {
+  width: 100%;
+  height: 100%;
+}
+
+.info-wrapper {
+  .top-banner {
+    background: none;
+    background-size: cover;
+    position: relative;
+  }
+}
+
+.submitBottomBtn {
+  position: fixed;
+  width: 100%;
+  left: 0;
+  bottom: 44rpx;
+  z-index: 9;
+  // background-color: #ffffff;
+}
+
+// 离线设备
+
+.ding {
+  position: fixed;
+  width: 100%;
+  top: var(--window-top);
+  // position: sticky;
+  /* #ifdef H5 */
+  // top: 44px;
+  /* #endif */
+  /* #ifndef H5 */
+  // top: 0;
+  /* #endif */
+  z-index: 999;
+  flex: 1;
+  flex-direction: column;
+  overflow: hidden;
+  background-color: #ffffff;
+}
+
+.cu-bar {
+  min-height: 0rpx;
+}
+
+.cu-bar .search-form {
+  margin: 26rpx 24rpx 0;
+}
+
+uni-textarea {
+  width: 500rpx;
+}
+
+uni-label uni-text {
+  position: relative;
+  top: 2px;
+}
+
+.processStatus {
+  textarea {
+    background: #f5f5f5;
+    color: #999999;
+    padding: 20rpx;
+  }
+}
+
+// 设备类型
+.cu-list.menu-avatar .deviceTypeItem.cu-item {
+  height: 110rpx;
+
+  .content {
+    left: 100rpx !important;
+  }
+
+  .cu-avatar.round {
+    width: 70rpx;
+    height: 70rpx;
+  }
+
+  .title {
+    font-size: 32rpx !important;
+  }
+
+  .num {
+    color: #666;
+  }
+}
+
+.form-item label text {
+  position: relative;
+  top: 2rpx;
+}
+
+.form-item.selectBox {
+  select {
+    background: rgba(0, 0, 0, 0);
+  }
+}
+
+.form-item {
+  margin: 0 40rpx;
+  display: flex;
+  align-items: top;
+  margin-bottom: 20rpx;
+  line-height: 70rpx;
+
+  .title {
+    width: 200rpx;
+    position: relative;
+
+    .necessary {
+      color: red;
+      display: inline-block;
+      position: absolute;
+      top: -2rpx;
+      left: -20rpx;
+      font-size: 40rpx;
+    }
+  }
+
+  input,
+  select {
+    width: calc(100% - 200rpx);
+    font-size: 28rpx;
+  }
+}
+
+.cu-list.menu-avatar > .cu-item.qa-tit {
+  height: auto;
+
+  .cu-avatar {
+    width: 32rpx;
+    height: 32rpx;
+  }
+
+  .content {
+    left: 50rpx;
+  }
+}
+
+.messagePush {
+  .uni-checkbox .uni-checkbox-input {
+    width: 40rpx;
+    height: 40rpx;
+  }
+}
+
+.fireBashWrapper {
+  .cu-avatar {
+    width: 120rpx;
+    height: 100rpx;
+  }
+
+  .cu-list.menu-avatar > .cu-item .content {
+    left: 140rpx;
+
+    .pro-date {
+      position: absolute;
+      right: 20rpx;
+      bottom: 0;
+    }
+  }
+}
+
+// 消防知识库详情页
+.fireBashDetailWrapper {
+  font-size: 28rpx;
+
+  .cu-avatar {
+    width: 50rpx;
+    height: 50rpx;
+  }
+
+  .fireD-content {
+    position: relative;
+  }
+
+  .fireD-content:before {
+    position: absolute;
+    top: -8px;
+    left: -15px;
+    box-sizing: border-box;
+    width: calc(100% + 30px);
+    height: 1px;
+    background: #ededed;
+    content: " ";
+  }
+
+  .fireD-content view {
+    line-height: 1.5;
+    // text-indent:56rpx;
+  }
+}
+
+.fireD-tit {
+  font-size: 32rpx;
+  font-weight: bold;
+}
+
+.preAndNext {
+  color: #4074e7;
+  margin: 30rpx 0 80rpx;
+}
+
+// 导出页面
+.uni-date-x--border,
+.uni-date-x {
+  border-radius: 25rpx !important;
+}
+
+.uni-date__x-input {
+  line-height: 72rpx;
+}
+
+.example-body {
+  margin: 20rpx 20rpx;
+
+  uni-input,
+  select,
+  option {
+    border: none !important;
+  }
+}
+
+.info-one-info {
+  display: flex;
+  line-height: 26px !important;
+  padding: 10px 0;
+}
+
+.info-content uni-view uni-text:first-child {
+  width: 88px !important;
+}
+
+.info-content uni-view uni-text:last-child {
+  width: 75%;
+}

+ 171 - 0
src/common/export.js

@@ -0,0 +1,171 @@
+//日期转时间戳
+function getUnixTime(dateStr){
+    var newstr = dateStr.replace(/-/g,'/'); 
+    var date =  new Date(newstr); 
+    var time_str = date.getTime().toString();
+    return time_str.substr(0, 10);
+}
+
+//时间戳转日期,falg:true表示只要年月日,part: year month date
+function toDate(number,flag,part) {
+  var n = number;
+  var date = new Date(parseInt(n) * 1000);
+  var y = date.getFullYear();
+  var m = date.getMonth() + 1;
+  m = m < 10 ? ('0' + m) : m;
+  var d = date.getDate();
+  d = d < 10 ? ('0' + d) : d;
+  var h = date.getHours();
+  h = h < 10 ? ('0' + h) : h;
+  var minute = date.getMinutes();
+  var second = date.getSeconds();
+  minute = minute < 10 ? ('0' + minute) : minute;
+  second = second < 10 ? ('0' + second) : second;
+  if(flag){
+      if(part == "year"){
+          return y;
+      }else if(part == "month"){
+          return m;
+      }else if(part == "date"){
+          return n;
+      }
+      return y + '-' + m + '-' + d;
+  }
+  return y + '-' + m + '-' + d + ' ' + h + ':' + minute+':' + second;
+}
+
+//判断两个日期时间戳相差多少天,参数为时间戳
+function dateCompare(dateTimeStamp1,dateTimeStamp2){
+    var dayNum = 0;
+    if(dateTimeStamp1 > dateTimeStamp2){
+        dayNum = Math.floor((dateTimeStamp1 - dateTimeStamp2) / 86400);
+    }else{
+        dayNum = Math.floor((dateTimeStamp2 - dateTimeStamp1) / 86400);
+    }
+    return dayNum;
+}
+
+//判断过去某个时间点到当前时间是否达到多少天,可以用来定期清理缓存
+function datePassDays(dateTimeStamp,days){
+    var now = getUnixTime(formatDateThis(new Date()));
+    var diffValue = now - dateTimeStamp;
+    var limitTime = days * 86400;
+    if(diffValue >= limitTime){
+        return true;
+    }
+    return false;
+}
+
+//当前日期加减天数,falg:true表示只要年月日
+function mathChangeDate(date,method,days,flag){
+  //method:'+' || '-'
+  //ios不解析带'-'的日期格式,要转成'/',不然Nan,切记
+  var dateVal = date.replace(/-/g, '/');
+  var timestamp = Date.parse(dateVal);
+  if(method == '+'){
+    timestamp = timestamp / 1000 + 24 * 60 * 60 * days;
+  } else if (method == '-'){
+    timestamp = timestamp / 1000 - 24 * 60 * 60 * days;
+  }
+  return toDate(timestamp,flag);
+}
+
+//时间戳转换具体时间描述(传入数值型时间戳)
+function getDateDiff(dateTimeStamp) {
+  var result = '';
+  var minute = 1 * 60;
+  var hour = minute * 60;
+  var day = hour * 24;
+  var halfamonth = day * 15;
+  var month = day * 30;
+  var now = getUnixTime(formatDateThis(new Date()));//有些特殊 不能使用 new Date()
+  var diffValue = now - dateTimeStamp;
+  if (diffValue < 0) { return; }
+  var monthC = diffValue / month;
+  var weekC = diffValue / (7 * day);
+  var dayC = diffValue / day;
+  var hourC = diffValue / hour;
+  var minC = diffValue / minute;
+  
+  if (monthC >= 1) {
+    result = "" + parseInt(monthC) + "月前";
+  }
+  else if (weekC >= 1) {
+    result = "" + parseInt(weekC) + "周前";
+  }
+  else if (dayC >= 1) {
+    result = "" + parseInt(dayC) + "天前";
+  }
+  else if (hourC >= 1) {
+    result = "" + parseInt(hourC) + "小时前";
+  }
+  else if (minC >= 1) {
+    result = "" + parseInt(minC) + "分钟前";
+  } else
+    result = "刚刚";
+  return result;
+};
+
+//获取当前年份,月份, 例: getCurrentTime("year")
+const getCurrentTime = (method,date=new Date()) => {
+    if(method == "year"){
+        return date.getFullYear();
+    }else if(method == "month"){
+        return date.getMonth() + 1;
+    }
+    return date;
+}
+
+//获取当前服务器时间,参数直接用 new Date() 就可以了
+const formatDateThis = (date,lab='-') => {
+  const year = date.getFullYear();
+  const month = date.getMonth() + 1;
+  const day = date.getDate();
+  const hour = date.getHours();
+  const minute = date.getMinutes();
+  const second = date.getSeconds();
+  return [year, month, day].map(formatNumber).join(lab) +' '+ [hour, minute, second].map(formatNumber).join(':');
+}
+
+const formatTime = (date,lab='-') => {
+  const year = date.getFullYear();
+  const month = date.getMonth() + 1;
+  const day = date.getDate();
+  return [year, month, day].map(formatNumber).join(lab);
+}
+const formatTimes = time => {
+  const hour = time.getHours();
+  const minute = time.getMinutes();
+  const second = time.getSeconds();
+  return [hour, minute,second].map(formatNumber).join(':');
+}
+//补0
+const formatNumber = n => {
+  n = n.toString();
+  return n[1] ? n : '0' + n;
+}
+
+//比较两个时间大小(格式参考yyyy-mm-dd hh:mm:ss)
+function compareTime(startTime,endTime){
+  //结束时间大于开始时间就是true  , 反之则为 false
+  var sn = getUnixTime(startTime) * 1;
+  var en = getUnixTime(endTime) * 1;
+  if(en > sn){
+    return true;
+  }
+  return false;
+}
+
+module.exports = {
+  dateCompare:dateCompare,
+  getCurrentTime:getCurrentTime,
+  getUnixTime:getUnixTime,
+  formatDateThis:formatDateThis,
+  formatTime: formatTime,
+  formatTimes: formatTimes,
+  toDate: toDate,
+  getDateDiff: getDateDiff,
+  mathChangeDate: mathChangeDate,
+  compareTime: compareTime,
+  datePassDays:datePassDays
+}

+ 97 - 0
src/common/graceChecker.js

@@ -0,0 +1,97 @@
+/**
+数据验证(表单验证)
+来自 grace.hcoder.net 
+作者 hcoder 深海
+*/
+module.exports = {
+	error:'',
+	check : function (data, rule){
+		for(var i = 0; i < rule.length; i++){
+			if (!rule[i].checkType){return true;}
+			if (!rule[i].name) {return true;}
+			if (!rule[i].errorMsg) {return true;}
+			if (!data[rule[i].name]) {this.error = rule[i].errorMsg; return false;}
+			switch (rule[i].checkType){
+				case 'string':
+					var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
+					if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
+				break;
+				case 'int':
+					var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
+					if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
+					break;
+				break;
+				case 'between':
+					if (!this.isNumber(data[rule[i].name])){
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'betweenD':
+					var reg = /^-?[1-9][0-9]?$/;
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'betweenF': 
+					var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
+					if (!reg.test(data[rule[i].name])){this.error = rule[i].errorMsg; return false;}
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'same':
+					if (data[rule[i].name] != rule[i].checkRule) { this.error = rule[i].errorMsg; return false;}
+				break;
+				case 'notsame':
+					if (data[rule[i].name] == rule[i].checkRule) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'email':
+					var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'phoneno':
+					var reg = /^1[0-9]{10,10}$/;
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'zipcode':
+					var reg = /^[0-9]{6}$/;
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'reg':
+					var reg = new RegExp(rule[i].checkRule);
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'in':
+					if(rule[i].checkRule.indexOf(data[rule[i].name]) == -1){
+						this.error = rule[i].errorMsg; return false;
+					}
+				break;
+				case 'notnull':
+					if(data[rule[i].name] == null || data[rule[i].name].length < 1){this.error = rule[i].errorMsg; return false;}
+				break;
+			}
+		}
+		return true;
+	},
+	isNumber : function (checkVal){
+		var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
+		return reg.test(checkVal);
+	}
+}

+ 238 - 0
src/common/public.scss

@@ -0,0 +1,238 @@
+/*
+ * @日期选择器样式 开始
+ */
+.el-calendar-table,
+tr,
+td,
+th {
+  border: 0px !important;
+}
+
+.el-calendar__body {
+  padding: 0 !important;
+}
+
+.el-calendar-table .el-calendar-day {
+  text-align: center;
+  height: auto !important;
+}
+
+.el-calendar-table thead > th {
+  text-align: center;
+}
+
+#calendar .filter {
+  width: 5px;
+  height: 5px;
+  border: 1px #1989fa solid;
+  border-radius: 100%;
+  text-align: center;
+  margin: auto;
+  margin-top: 5px;
+  background-color: #1989fa;
+}
+
+/*
+ * @日期选择器样式 结束
+ */
+
+/*
+ * @时间线样式 开始
+ */
+#planTimeline {
+  padding: 0px 15px;
+}
+
+#planTimeline1 {
+  padding: 0px 15px;
+
+  .u-steps-item__wrapper {
+    background-color: #f1f1f1;
+  }
+}
+
+/*
+ * @时间线样式 结束
+ */
+
+/*
+ * @抽屉样式 开始
+ */
+.el-drawer__header {
+  margin-bottom: 0px !important;
+}
+
+/*
+ * @抽屉样式 结束
+ */
+
+/*
+ * @图片上传样式 开始
+ */
+.el-upload-list {
+  display: flex !important;
+}
+
+.el-upload-list li,
+.el-upload-list .el-upload {
+  width: calc(33% - 10px) !important;
+  height: 110px !important;
+  margin: 0 15px 15px 0 !important;
+}
+
+.el-upload-list li:nth-child(3n),
+.el-upload-list .el-upload:nth-child(3n) {
+  margin: 0 !important;
+}
+
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: #409eff;
+}
+
+/*
+ * @图片上传样式 结束
+ */
+
+/*
+ * @消息弹出框样式 开始
+ */
+.el-message-box {
+  margin-top: 70%;
+}
+
+/*
+ * @消息弹出框样式 结束
+ */
+
+/*
+ * @uni-textarea 文本域样式 开始
+ */
+
+uni-textarea {
+  border: 0px solid #ededed;
+  padding: 0;
+}
+
+/*
+ * @uni-textarea 文本域样式 结束
+ */
+
+/*
+ * @全局input样式 开始
+ */
+uni-input {
+  background-color: transparent;
+}
+
+/*
+ * @全局input样式 结束
+ */
+
+/*
+ * @login input样式 开始
+ */
+#login-input {
+  .u-input {
+    height: 48px;
+    border-radius: 24px;
+    padding: 5px 12px !important;
+    background-color: rgba(255, 255, 255, 0.1) !important;
+  }
+
+  .uni-input-wrapper {
+    font-size: 18px;
+  }
+
+  uni-input {
+    color: #fff !important;
+    background-color: rgba(255, 255, 255, 0) !important;
+    border: 0px solid #ededed !important;
+    padding-left: 0 !important;
+  }
+
+  .u-icon__icon {
+    font-size: 24px !important;
+    line-height: 24px !important;
+    color: #a8abb2 !important;
+  }
+
+  .iconfont {
+    color: #a8abb2 !important;
+  }
+
+  .u-button {
+    width: 35%;
+    height: 48px;
+    line-height: 48px;
+    color: #fff;
+    border-radius: 24px;
+    margin: 0 0 0 5%;
+    font-size: 17px !important;
+    white-space: nowrap;
+    background-color: rgba(255, 255, 255, 0.1) !important;
+  }
+
+  :-webkit-autofill {
+    caret-color: #fff; // 设置光标颜色
+    -webkit-text-fill-color: #ededed !important;
+    -webkit-box-shadow: 0 0 0px 1000px transparent inset !important;
+    background-color: transparent;
+    background-image: none;
+    transition: background-color 50000s ease-in-out 0s; //背景色透明  生效时长  过渡效果  启用时延迟的时间
+  }
+}
+
+/*
+ * @login input样式 结束
+ */
+
+//折叠面板样式 开始
+.u-cell__body {
+  padding: 10px 10px !important;
+}
+//折叠面板样式 结束
+
+/*
+ * 页面样式 开始
+ * @/pages/xunJian/plan/components/siteDetails.vue
+ * @/pages/xunJian/plan/components/content.vue
+ */
+
+.siteHeader {
+  .u-icon__icon {
+    font-size: 14px !important;
+    line-height: 14px !important;
+    margin: auto !important;
+  }
+
+  .uni-section .uni-section-header {
+    padding: 0 !important;
+
+    .uni-section-header__decoration {
+      height: 14px !important;
+      background-color: #149eff;
+    }
+
+    .uni-section-header__content {
+      uni-text {
+        font-size: 15px !important;
+        color: #149eff !important;
+        font-weight: 600 !important;
+      }
+    }
+  }
+}
+
+/*
+ * 页面样式 结束
+ * @/pages/xunJian/plan/components/siteDetails.vue
+ * @/pages/xunJian/plan/components/content.vue
+ */

+ 188 - 0
src/common/select.js

@@ -0,0 +1,188 @@
+var legp = function(ele) {
+	return ({
+		that: Array.prototype.slice.call(document.querySelectorAll(ele), 0),
+		stopPropagation: function(e) {
+			e = e || window.event;
+			if (e.stopPropagation) { //W3C阻止冒泡方法  
+				e.stopPropagation();
+			} else {
+				e.cancelBubble = true; //IE阻止冒泡方法  
+			}
+		},
+		hide: function() {
+			legp(ele).that.forEach(function(item) {
+				item.style.cssText += "display:none;";
+			});
+		},
+		show: function() {
+			legp(ele).that.forEach(function(item) {
+				item.style.cssText += "display:block;";
+			});
+		},
+		legp_searchList: function(name) {
+			let arr = [];
+			legp("input[name=" + name + "]").that.forEach(item => {
+				arr.push(item.value)
+			});
+			return arr;
+		},
+		legp_search: function(name, tagData) {
+			var domId = legp(ele).that[0];
+			var html =
+				"\n<div>\n<div class=\"selectId\">\n<input type=\"text\" placeholder=\"\u8F93\u5165\u6216\u9009\u62E9\" autocomplete=\"off\">\n<dl style=\"display: none;\">\n</dl>\n</div>\n</div>\n<div>\n<label style=\"line-height:30px\">已选择:</label>\n<div class=\"AD\">\n</div>\n</div>";
+			domId.innerHTML = html;
+			// domId.appendChild(dom);
+			legp(".AD").that[0].parentNode.style.cssText += "display:none;";
+			//获取当前广告
+			function myClick() {
+				legp(".selectId dl dd").that.forEach(function(item) {
+					item.onclick = function(e) {
+						var id = this.attributes.value.value;
+						if (id != '') {
+							legp(".AD").that[0].innerHTML += "<a href=\"javascript:;\" class=\"label\"><span>" + this.innerHTML +
+								"</span><input type=\"hidden\" name=\"" + name + "\" id=\"" + id + "\" value=\"" + id +
+								"\"/><span class=\"close\">x</span></a>";
+							legp(".AD").that[0].parentNode.style.cssText += "display:block;";
+							for (var i = 0; i < tagData.length; i++) {
+								if (tagData[i].id == id) {
+									tagData.splice(i, 1);
+									i = tagData.length;
+								}
+							}
+							removeAdvertising();
+						}
+						legp(".selectId dl").hide();
+						legp(".selectId input").that[0].value = '';
+						e.stopPropagation();
+					};
+				});
+			}
+			var ddRemove = function(dd) {
+				var temp = dd.nextElementSibling;
+				dd.remove();
+				if (temp != null && temp.nodeName == 'DD') {
+					ddRemove(temp);
+				}
+			};
+			//筛选
+			legp(".selectId input").that[0].oninput = function() {
+				var val = this.value; //获取input值
+				var dd = legp(".selectId dl dd").that[0];
+				if (dd == "DD") {
+					ddRemove(dd);
+				}
+				legp(".selectId dl").hide();
+				if (tagData.length > 0) {
+					legp(".selectId dl").show();
+					var sear_1 = new RegExp(val);
+					var judge_1 = false;
+					legp(".selectId dl").that[0].innerHTML = "";
+					tagData.forEach(function(item) {
+						if (sear_1.test(item.name)) {
+							judge_1 = true;
+							legp(".selectId dl").that[0].innerHTML += "<dd value=\"" + item.id + "\">" + item.name + "</dd>";
+						}
+					});
+					if (!judge_1) {
+						legp(".selectId dl").that[0].innerHTML = "<dd>\u6682\u65E0\u6570\u636E</dd>";
+					}
+					myClick();
+				}
+			};
+			//显示没被选择的
+			legp(".selectId input").that[0].onclick = function(e) {
+				var dd = legp(".selectId dl dd").that[0];
+				if (dd == "DD") {
+					ddRemove(dd);
+				}
+				if (tagData.length == 0) {
+					this.innerHTML = "暂无数据";
+				} else {
+					legp(".selectId dl").show();
+				}
+				legp(".selectId dl").that[0].innerHTML = "";
+				tagData.sort(function(a, b) {
+					return a.id - b.id;
+				});
+				tagData.forEach(function(item) {
+					legp(".selectId dl").that[0].innerHTML += "<dd value=\"" + item.id + "\">" + item.name + "</dd>";
+				});
+				myClick();
+				e.stopPropagation();
+			};
+			var AD = /** @class */ (function() {
+				function AD(name, id) {
+					this.name = name;
+					this.id = id;
+				}
+				return AD;
+			}());
+			//删除当前广告
+			function removeAdvertising() {
+				legp(".close").that.forEach(function(item) {
+					item.onclick = function() {
+						ddRemove(this.parentNode);
+						var id = this.parentNode.children[1].id;
+						var text = this.parentNode.children[0].innerHTML;
+						tagData.push(new AD(text, id));
+						if (legp(".close").that.length == 0) {
+							legp(".AD").that[0].parentNode.style.cssText += "display:none;";
+						}
+					};
+				});
+			}
+			// //封装
+			// function clickoutSide(nameClass, callback) {
+			// 	// 全局注册点击事件
+			// 	document.onclick = function (e) {
+			// 		//若点击元素为目标元素则返回
+			// 		if (e.target.className === nameClass) return
+			// 		//否则执行回调函数
+			// 		callback()
+			// 	}
+			// }
+			//隐藏
+			document.onclick = function(e) {
+				legp(".selectId dl").hide();
+				legp(".selectId input").that[0].value = "";
+			};
+		}
+	});
+};
+(function() {
+	var tagData = [{
+		"name": "站点1",
+		"id": 64
+	}, {
+		"name": "站点2",
+		"id": 65
+	}, {
+		"name": "站点3",
+		"id": 5
+	}, {
+		"name": "站点4",
+		"id": 6
+	}, {
+		"name": "站点5",
+		"id": 7
+	}, {
+		"name": "站点6",
+		"id": 8
+	}, {
+		"name": "站点7",
+		"id": 10
+	}, {
+		"name": "站点8",
+		"id": 111
+	}, {
+		"name": "站点9",
+		"id": 112
+	}, {
+		"name": "站点10",
+		"id": 113
+	}];
+
+	legp(".qwe").legp_search("fileId", tagData)
+
+
+})()

+ 96 - 0
src/common/uni-nvue.scss

@@ -0,0 +1,96 @@
+/* 头条小程序组件内不能引入字体 */
+/* #ifdef MP-TOUTIAO */
+@font-face {
+	font-family: uniicons;
+	font-weight: normal;
+	font-style: normal;
+	src: url('~@/static/uni.ttf') format('truetype');
+}
+/* #endif */
+
+/* #ifndef APP-NVUE */
+page {
+	display: flex;
+	flex-direction: column;
+	box-sizing: border-box;
+	background-color: #efeff4;
+	min-height: 100%;
+	height: auto;
+}
+
+view {
+	font-size: 14px;
+	line-height: inherit;
+}
+
+.example {
+	padding: 0 15px 15px;
+}
+
+.example-info {
+	padding: 15px;
+	color: #3b4144;
+	background: #ffffff;
+}
+
+.example-body {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: row;
+	flex-wrap: wrap;
+	justify-content: center;
+	padding: 0;
+	font-size: 14px;
+	background-color: #ffffff;
+}
+/* #endif */
+.example {
+	padding: 0 15px;
+}
+
+.example-info {
+	/* #ifndef APP-NVUE */
+	display: block;
+	/* #endif */
+	padding: 15px;
+	color: #3b4144;
+	background-color: #ffffff;
+	font-size: 14px;
+	line-height: 20px;
+}
+
+.example-info-text {
+    font-size: 14px;
+    line-height: 20px;
+	color: #3b4144;
+}
+
+
+.example-body {
+  flex-direction: column;
+  padding: 15px;
+  background-color: #ffffff;
+}
+
+.word-btn-white{
+	font-size: 18px;
+  color:#FFFFFF;
+}
+
+.word-btn {
+  /* #ifndef APP-NVUE */
+  display: flex;
+  /* #endif */
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  border-radius: 6px;
+  height: 48px;
+  margin: 15px;
+  background-color: #007AFF;
+}
+
+.word-btn--hover {
+  background-color: #4ca2ff;
+}

+ 116 - 0
src/components/calendar/calendar.vue

@@ -0,0 +1,116 @@
+<template>
+  <view class="leave_cont">
+    <view class="ul">
+      <view class="li">
+        <view class="flex1">
+          <picker
+            mode="date"
+            :value="start_date"
+            :start="start_date"
+            :end="other"
+            @change="bindDateChange"
+          >
+            <view class="date">{{ start_date }}</view>
+          </picker>
+        </view>
+      </view>
+      ~
+      <view class="li">
+        <view class="flex1">
+          <picker
+            mode="date"
+            :value="start_date"
+            :start="start_date"
+            @change="bindDateChange2"
+          >
+            <view class="date">{{ end_date }}</view>
+          </picker>
+        </view>
+      </view>
+      <image class="canlendar-icon" src="@/static/images/calendar.png"></image>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    const currentDate = this.getDate({
+      format: true,
+    });
+    return {
+      start_date: "请选择开始日期",
+      end_date: "请选择结束日期",
+      other: "请输入",
+    };
+  },
+  computed: {},
+  methods: {
+    // 选择日期
+    bindDateChange: function (e) {
+      this.start_date = e.target.value;
+    },
+    bindDateChange2: function (e) {
+      this.end_date = e.target.value;
+      this.other = this.end_date;
+    },
+    // 获取当前时间
+    getDate(type) {
+      const date = new Date();
+      let year = date.getFullYear();
+      let month = date.getMonth() + 1;
+      let day = date.getDate();
+
+      if (type === "start") {
+        year = year - 60;
+      } else if (type === "end") {
+        year = year + 2;
+      }
+      month = month > 9 ? month : "0" + month;
+      day = day > 9 ? day : "0" + day;
+      return `${year}-${month}-${day}`;
+    },
+  },
+};
+</script>
+
+<style>
+.leave_cont .ul {
+  border: 1px solid red;
+  margin: 24rpx 24rpx;
+  border: 1px solid #e8f1ff;
+  border-radius: 36rpx;
+  line-height: 70rpx;
+  position: relative;
+}
+
+.leave_cont .ul .li {
+  display: inline-block;
+  text-align: center;
+  width: 35%;
+}
+
+.leave_cont .ul .li text {
+  padding: 40rpx 0;
+  font-size: 30rpx;
+  color: #666666;
+  text-align: center;
+}
+
+.leave_cont .ul .li .flex1 {
+  flex: 1;
+  color: #999999;
+  font-size: 32rpx;
+}
+
+.date {
+  height: 42rpx;
+}
+.canlendar-icon {
+  width: 36rpx;
+  height: 36rpx;
+  position: absolute;
+  right: 30rpx;
+  top: 16rpx;
+}
+</style>

+ 20 - 0
src/components/export.vue

@@ -0,0 +1,20 @@
+<template>
+	<view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"export",
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 175 - 0
src/components/helang-compress/helang-compress.vue

@@ -0,0 +1,175 @@
+<template>
+	<view class="compress">
+		<canvas :style="{ width: canvasSize.width,height: canvasSize.height}" canvas-id="myCanvas"></canvas>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				pic:'',
+				canvasSize: {
+					width: 0,
+					height: 0
+				}
+			}
+		},
+		methods: {
+			// 压缩
+			compress(params) {
+				return new Promise(async (resolve, reject) => {
+					// 等待图片信息
+					let info = await this.getImageInfo(params.src).then(info=>info).catch(err=>err);
+					
+					if(!info){
+						reject('获取图片信息异常');
+						return;
+					}
+					
+					// 设置最大 & 最小 尺寸
+					const maxSize = params.maxSize || 1080;
+					const minSize = params.minSize || 640;
+					
+					// 当前图片尺寸
+					let {width,height} = info;
+					
+					// 非 H5 平台进行最小尺寸校验
+					// #ifndef H5
+					if(width <= minSize && height <= minSize){
+						resolve(params.src);
+						return;
+					}
+					// #endif
+					
+					// 最大尺寸计算
+					if (width > maxSize || height > maxSize) {
+						if (width > height) {
+							height = Math.floor(height / (width / maxSize));
+							width = maxSize;
+						} else {
+							width = Math.floor(width / (height / maxSize));
+							height = maxSize;
+						}
+					}
+
+					// 设置画布尺寸
+					this.$set(this,"canvasSize",{
+						width: `${width}rpx`,
+						height: `${height}rpx`
+					});
+					
+					// Vue.nextTick 回调在 App 有异常,则使用 setTimeout 等待DOM更新
+					setTimeout(() => {
+						const ctx = uni.createCanvasContext('myCanvas', this);
+						ctx.clearRect(0,0,width, height)
+						ctx.drawImage(info.path, 0, 0, uni.upx2px(width), uni.upx2px(height));
+						ctx.draw(false, () => {
+							uni.canvasToTempFilePath({
+								x: 0,
+								y: 0,
+								width: uni.upx2px(width),
+								height: uni.upx2px(height),
+								destWidth: width,
+								destHeight: height,
+								canvasId: 'myCanvas',
+								fileType: params.fileType || 'png',
+								quality: params.quality || 0.9,
+								success: (res) => {
+									// 在H5平台下,tempFilePath 为 base64
+									resolve(res.tempFilePath);
+								},
+								fail:(err)=>{
+									reject(null);
+								}
+							},this);
+						});
+					}, 300);
+				});
+			},
+			// 获取图片信息
+			getImageInfo(src){
+				return new Promise((resolve, reject)=>{
+					uni.getImageInfo({
+						src,
+						success: (info)=> {
+							resolve(info);
+						},
+						fail: () => {
+							reject(null);
+						}
+					});
+				});
+			},
+			// 批量压缩
+			batchCompress(params){
+				// index:进度,done:成功,fail:失败
+				let [index,done,fail] = [0,0,0];
+				// 压缩完成的路径集合
+				let paths = [];
+				// 批量压缩方法
+				let batch = ()=>{
+					return new Promise((resolve, reject)=>{
+						// 开始
+						let start = async ()=>{
+							params.progress && params.progress({
+								done,
+								fail,
+								count:params.batchSrc.length
+							});
+							// 等待图片压缩方法返回
+							let path = await next();
+							if(path){
+								done++;
+								paths.push(path);
+							}else{
+								fail++;
+							}
+							
+							index++;
+							// 压缩完成
+							if(index >= params.batchSrc.length){
+								resolve(true);
+							}else{
+								start();
+							}
+						}
+						start();
+					});
+				}
+				// 依次调用压缩方法
+				let next = ()=>{
+					return this.compress({
+						src:params.batchSrc[index],
+						maxSize:params.maxSize,
+						fileType:params.fileType,
+						quality:params.quality,
+						minSize:params.minSize
+					})
+				}
+				
+				// 全部压缩完成后调用
+				return new Promise(async (resolve, reject)=>{
+					// 批量压缩方法回调
+					let res = await batch();
+					if(res){
+						resolve(paths);
+					}else{
+						reject(null);
+					}
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.compress{
+		position: fixed;
+		width: 12px;
+		height: 12px;
+		overflow: hidden;
+		top: -99999px;
+		left: 0;
+	}
+</style>

+ 205 - 0
src/components/list-test/list-test.vue

@@ -0,0 +1,205 @@
+<template>
+	<view  class="site-wrapper" ref="contentWrapper">
+		
+		<!-- 筛选框start -->
+		<view class="ding">
+			<view class="cu-bar search bg-gray filter-section">
+				<view class="search-form round bg-white">
+					<text class="cuIcon-search"></text>
+					<input class="" @focus="InputFocus" @blur="InputBlur" :adjust-position="false" type="text" placeholder="请输入站点名称"
+					 confirm-type="search" v-model="nowSiteName"></input>
+				</view>
+				<view class="action">
+					<button class="cu-btn bg-blue round" @click="searchData">查询</button>
+				</view>
+			</view>
+		</view>
+		<!-- 筛选框end -->
+		
+		<!-- 站点列表start -->
+		<view class="site-items">
+			<view class="cu-list menu-avatar">
+				<view class="cu-item" :class="modalName=='move-box-'+ index?'move-cur':''" v-for="(item,index) in bindData"
+				 :key="index" :data-target="'move-box-' + index">
+					<view class="cu-avatar round lg"  v-bind:style="{ 'background-image': 'url(' + nowIcon+ ')' }"></view>
+					
+					
+					<view class="content" v-if="nowType==1"  @tap="goNowUrl(item)" >
+						<view class="text-grey site-tit">
+							<text style="width:260rpx;" class="inOneLine">{{item.siteName}}</text>
+							
+							<text style="font-size:28rpx;text-align:right"> 
+							   ( 共{{item.siteAlarmCount}}个未处理告警 )
+							</text>
+						</view>
+					</view>
+					
+					<view class="content" v-else  @tap="goNowUrl" @longpress="showDetail(item)">
+						<view class="text-grey site-tit">
+							{{item.siteName}}
+							<text>(共3个设备)</text>
+						</view>
+						<view class="showDetail" v-if="item.isShow" @tap.stop="goNowDetailUrl" >查看详情</view>
+					</view>
+					
+					
+					
+					
+					<view class="nav-right num">
+						<view class="text-grey">
+							<text class="icon iconfont margin-right-xs margin-left-lg">&#xe629;</text>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- 站点列表end -->
+	
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		// name: 'listTest',
+		props:{
+			bindType:{
+				type:Number,
+				default: ''
+			},
+			bindData:{
+				type:Array,
+				default: ''
+			},
+			bindUrl:{
+				type:String,
+				default: ''
+			},
+			bindDetailUrl:{
+				type:String,
+				default: ''
+			},
+			bindIcon:{
+				type:String,
+				default: ''
+			},
+			bindNum:{
+				type:String,
+				default: ''
+			},
+			bindSiteName:{
+				type:String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				modalName: null,
+				nowData:this.bindData,
+				nowUrl:this.bindUrl,
+				nowDetailUrl:this.bindDetailUrl,
+				nowIcon:this.bindIcon,
+				nowNum:this.bindNum,
+				nowType:this.bindType,
+				nowSiteName:this.bindSiteName,
+				
+			};
+		},
+		onPullDownRefresh() {
+			console.log('refresh');
+			setTimeout(function() {
+				uni.stopPullDownRefresh();
+			}, 1000);
+		},
+		
+		computed: {
+			newSiteListData() {
+				return this.nowData.map(item => {
+					this.$set(item, "isShow", false)
+					return item
+				})
+			}
+		
+		},
+		
+		mounted() {
+			document.addEventListener('click', (e) => {
+				if (e.target.className != 'showDetail') {
+					this.nowData.forEach(item => {
+						item.isShow = false
+					})
+				}
+			})
+		},
+		methods:{
+			
+			searchData(){
+				// console.log("a: "+val, oldVal);
+				this.$parent.getDataList({
+					"siteName":this.nowSiteName
+				})
+			},
+			
+			
+			// 隐藏显示
+			showDetail(e) {
+				// alert(1);
+				// 存储点击那一项的状态
+				const nowStatu = e.isShow;
+				// 将每一项列表的isShow设置为false,让所有的列表都隐藏
+				this.nowData.forEach(item => {
+					item.isShow = false
+				})
+				// 用于再次点击该项的取反
+				e.isShow = !nowStatu
+			},
+			
+			
+			
+			// 页面跳转
+			goNowUrl(item) {
+				if(item.siteAlarmCount){
+					uni.navigateTo({
+						url: this.nowUrl+'?companyCode='+item.companyCode,
+						success: res => {},
+						fail: () => {},
+						complete: () => {}
+					});
+				}
+				
+			},
+			
+			goNowDetailUrl() {
+				uni.navigateTo({
+					url: this.nowDetailUrl,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			InputFocus(e) {
+				this.InputBottom = e.detail.height
+			},
+			InputBlur(e) {
+				this.InputBottom = 0
+			},
+		}
+	}
+</script>
+
+<style>
+	
+	.showDetail {
+		position: absolute;
+		background: #fff;
+		box-shadow: 0 1px 6px 0 rgb(32 33 36 / 28%);
+		padding: 0rpx 32rpx;
+		border-radius: 10rpx;
+		top: 42rpx;
+		right: 0%;
+		z-index: 3000000;
+		font-size: 28rpx;
+	
+	}
+
+</style>

+ 123 - 0
src/components/mpvue-echarts/src/echarts.vue

@@ -0,0 +1,123 @@
+<template>
+	<canvas v-if="canvasId" class="ec-canvas" :id="canvasId" :canvasId="canvasId" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error"></canvas>
+</template>
+
+<script>
+import WxCanvas from './wx-canvas';
+
+export default {
+	props: {
+		canvasId: {
+			type: String,
+			default: 'ec-canvas'
+		},
+		lazyLoad: {
+			type: Boolean,
+			default: false
+		},
+		disableTouch: {
+			type: Boolean,
+			default: false
+		},
+		throttleTouch: {
+			type: Boolean,
+			default: false
+		}
+	},
+	// #ifdef H5
+	mounted() {
+		if (!this.lazyLoad) this.init();
+	},
+	// #endif
+	// #ifndef H5
+	onReady() {
+		if (!this.lazyLoad) this.init();
+	},
+	// #endif
+	methods: {
+		setChart(chart){
+			this.chart = chart
+		},
+		init() {
+			const { canvasId } = this;
+			this.ctx = wx.createCanvasContext(canvasId, this);
+
+			this.canvas = new WxCanvas(this.ctx, canvasId);
+
+			const query = wx.createSelectorQuery().in(this);
+			query
+				.select(`#${canvasId}`)
+				.boundingClientRect(res => {
+					if (!res) {
+						setTimeout(() => this.init(), 50);
+						return;
+					}
+					this.$emit('onInit', {
+						width: res.width,
+						height: res.height
+					});
+				})
+				.exec();
+		},
+		canvasToTempFilePath(opt) {
+			const { canvasId } = this;
+			this.ctx.draw(true, () => {
+				wx.canvasToTempFilePath({
+					canvasId,
+					...opt
+				});
+			});
+		},
+		touchStart(e) {
+			const { disableTouch, chart } = this;
+			if (disableTouch || !chart || !e.mp.touches.length) return;
+			const touch = e.mp.touches[0];
+			chart._zr.handler.dispatch('mousedown', {
+				zrX: touch.x,
+				zrY: touch.y
+			});
+			chart._zr.handler.dispatch('mousemove', {
+				zrX: touch.x,
+				zrY: touch.y
+			});
+		},
+		touchMove(e) {
+			const { disableTouch, throttleTouch, chart, lastMoveTime } = this;
+			if (disableTouch || !chart || !e.mp.touches.length) return;
+
+			if (throttleTouch) {
+				const currMoveTime = Date.now();
+				if (currMoveTime - lastMoveTime < 240) return;
+				this.lastMoveTime = currMoveTime;
+			}
+
+			const touch = e.mp.touches[0];
+			chart._zr.handler.dispatch('mousemove', {
+				zrX: touch.x,
+				zrY: touch.y
+			});
+		},
+		touchEnd(e) {
+			const { disableTouch, chart } = this;
+			if (disableTouch || !chart) return;
+			const touch = e.mp.changedTouches ? e.mp.changedTouches[0] : {};
+			chart._zr.handler.dispatch('mouseup', {
+				zrX: touch.x,
+				zrY: touch.y
+			});
+			chart._zr.handler.dispatch('click', {
+				zrX: touch.x,
+				zrY: touch.y
+			});
+		}
+	}
+};
+</script>
+
+<style scoped>
+.ec-canvas {
+	width: 100%;
+	height: 100%;
+	flex: 1;
+}
+</style>

+ 73 - 0
src/components/mpvue-echarts/src/wx-canvas.js

@@ -0,0 +1,73 @@
+export default class WxCanvas {
+  constructor(ctx, canvasId) {
+    this.ctx = ctx;
+    this.canvasId = canvasId;
+    this.chart = null;
+
+    WxCanvas.initStyle(ctx);
+    this.initEvent();
+  }
+
+  getContext(contextType) {
+    return contextType === '2d' ? this.ctx : null;
+  }
+
+  setChart(chart) {
+    this.chart = chart;
+  }
+
+  attachEvent() {
+    // noop
+  }
+
+  detachEvent() {
+    // noop
+  }
+
+  static initStyle(ctx) {
+    const styles = ['fillStyle', 'strokeStyle', 'globalAlpha',
+      'textAlign', 'textBaseAlign', 'shadow', 'lineWidth',
+      'lineCap', 'lineJoin', 'lineDash', 'miterLimit', 'fontSize'];
+
+    styles.forEach((style) => {
+      Object.defineProperty(ctx, style, {
+        set: (value) => {
+          if ((style !== 'fillStyle' && style !== 'strokeStyle')
+            || (value !== 'none' && value !== null)
+          ) {
+            ctx[`set${style.charAt(0).toUpperCase()}${style.slice(1)}`](value);
+          }
+        },
+      });
+    });
+
+    ctx.createRadialGradient = () => ctx.createCircularGradient(arguments);
+  }
+
+  initEvent() {
+    this.event = {};
+    const eventNames = [{
+      wxName: 'touchStart',
+      ecName: 'mousedown',
+    }, {
+      wxName: 'touchMove',
+      ecName: 'mousemove',
+    }, {
+      wxName: 'touchEnd',
+      ecName: 'mouseup',
+    }, {
+      wxName: 'touchEnd',
+      ecName: 'click',
+    }];
+
+    eventNames.forEach((name) => {
+      this.event[name.wxName] = (e) => {
+        const touch = e.mp.touches[0];
+        this.chart._zr.handler.dispatch(name.ecName, {
+          zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
+          zrY: name.wxName === 'tap' ? touch.clientY : touch.y,
+        });
+      };
+    });
+  }
+}

+ 45 - 0
src/components/square/square.vue

@@ -0,0 +1,45 @@
+<template>
+	<view>
+		<view class="section2 section  bg-white margin-top-sm">
+			<view class="cu-list grid col-3 no-border">
+				<view class="cu-item justify-center align-center" @tap="goSiteList(item.redirectUrl)"  v-for="(item,index) in cuIconList" :key="index">
+					<image :src="`${item.imgUrl}`" style="width:100rpx;height:100rpx"></image>
+					<view class="cu-tag badge" v-if="item.badge!=0">
+						<block class="cu-tag badge" v-if="item.badge!=1">{{item.badge>99?'99+':item.badge}}</block>
+					</view>
+					<text>{{item.name}}</text>
+				</view>
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		props:[ 'cuIconList'] ,  //接收外界传过来的数据
+		data() {
+			return {
+
+			}
+		},
+		methods: {
+			goSiteList(url) {
+				 // console.log(url);
+				uni.navigateTo({
+					url: url,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+	.cu-list.grid.no-border{
+		padding:30rpx 10rpx
+	}
+
+</style>

+ 236 - 0
src/components/yealuo-select/yealuo-select.vue

@@ -0,0 +1,236 @@
+<template>
+	<view class="yealuo-select" >
+		<view class="yealuo-background" @tap="isShow=false" v-show="isShow"></view>
+		<view class="yealuo-con" :style="inputStyle" @tap='isShow=isShow?false:nowData.length'>
+			<slot name='left'></slot>
+			<input :disabled="theDisabled" :placeholder="placeholder" v-model="theValue" @input="theInput"  @focus="theFocus" @blur="theBlur" autocomplete="off" />
+			<slot name='right' v-if="selectIco">
+				<svg class="icon" v-if="!isShow" style="width: 1.5em; height: 1.5em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="530"><path d="M512 714.666667c-8.533333 0-17.066667-2.133333-23.466667-8.533334l-341.333333-341.333333c-12.8-12.8-12.8-32 0-44.8 12.8-12.8 32-12.8 44.8 0l320 317.866667 317.866667-320c12.8-12.8 32-12.8 44.8 0 12.8 12.8 12.8 32 0 44.8L533.333333 704c-4.266667 8.533333-12.8 10.666667-21.333333 10.666667z" p-id="531"></path></svg>
+				<svg class="icon" v-else style="width: 1.5em; height: 1.5em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1927"><path d="M904.533333 674.133333l-362.666666-362.666666c-17.066667-17.066667-42.666667-17.066667-59.733334 0l-362.666666 362.666666c-17.066667 17.066667-17.066667 42.666667 0 59.733334 17.066667 17.066667 42.666667 17.066667 59.733333 0L512 401.066667l332.8 332.8c8.533333 8.533333 19.2 12.8 29.866667 12.8s21.333333-4.266667 29.866666-12.8c17.066667-17.066667 17.066667-42.666667 0-59.733334z" p-id="1928"></path></svg>
+			</slot>
+		</view>
+		<view class="yealuo-select" v-show="show" :style="selectStyle">
+			<view class="data">
+				<radio-group v-if="checkType=='radio'"  @change="selectCheckbox">
+				<view class="select-item" :class="'item-'+overflow" v-for="(item, index) in nowData" :key="index" >
+					<label class="item-text" :class="{active: theValue==item.value}">
+					<radio name="name1" checked v-if="theValue==item.value" :value="item.value+'|'+item.id"></radio>
+					<radio name="name1" v-else :value="item.value+'|'+item.id"></radio>
+					{{item.value}}
+					</label>
+				</view>
+				</radio-group>
+				<checkbox-group v-else-if="checkType=='checkbox'" @change="selectCheckbox">
+				<view class="select-item" :class="'item-'+overflow" v-for="(item, index) in nowData" :key="index" >
+					<label class="item-text" :class="{active: theValue.indexOf(item.value)!=-1 }">
+					<checkbox name="name1" checked v-if="theValue.indexOf(item.value)!=-1 " :value="item.value+'|'+item.id"></checkbox>
+					<checkbox name="name1" v-else :value="item.value+'|'+item.id"></checkbox>
+					{{item.value}}
+					</label>
+				</view>
+				</checkbox-group>
+				<radio-group v-else  @change="selectCheckbox">
+				<view class="select-item" :class="'item-'+overflow" v-for="(item, index) in nowData" :key="index" >
+					<label class="item-text" :class="{active: theValue==item.value}">
+					<radio name="name1" style="display: none;" checked v-if="theValue==item.value" :value="item.value+'|'+item.id"></radio>
+					<radio name="name1" style="display: none;" v-else :value="item.value+'|'+item.id"></radio>
+					{{item.value}}
+					</label>
+				</view>
+				</radio-group>
+			</view>
+			<view class="item-close" @tap="isShow=false">收起</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * v1.0.3
+	 * 最后修改: 2021.02.02
+	 * 创建: 2020.9.30
+	 * Author:yealuo.com
+	 * contact:470797533@qq.com
+	 */
+	let fontUnit = 'upx'
+	// #ifdef MP-WEIXIN
+	fontUnit = 'rpx'
+	// #endif
+	export default {
+		name: 'yealuoInputs',
+		props: {
+			placeholder: {
+				type: String,
+				default: ''
+			},
+			value: {
+				type: String,
+				default: ''
+			},
+			checkType: {
+				type: String,
+				default: ''
+			},
+			itemKey: {
+				type: String,
+				default: ''
+			},
+			width: {
+				type: String,
+				default: '600'
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			inputStyle: {
+				type: String,
+				default: ''
+			},
+			selectStyle: {
+				type: String,
+				default: ''
+			},
+			overflow: {
+				type: String,
+				default: 'auto'
+			},
+			tags: {
+				type: String,
+				default: ''
+			},
+			
+			binData:{
+				type:Array,
+				default: ''
+			},
+			selectIco:{
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				odData:this.binData,
+				nowData:this.binData,
+				isShow: false,
+				theValue: this.value,
+				theDisabled: this.disabled
+			}
+		},
+		watch: {
+			value(val){
+				this.theValue = val;
+			},
+			//监听数据变化
+			nowData:{
+				handler:function(){
+				 this.nowData=this.binData;
+				},
+				deep:true
+			}
+			
+		},
+		computed: {
+			show(){
+				return this.isShow && this.nowData.length
+			}
+			
+		},
+		methods: {
+			//获取焦点
+			theFocus(e){
+				this.nowData=this.odData;
+			},
+			//失去焦点
+			theBlur(e){
+				this.$emit('blur',e)
+			},
+			//获取输入值
+			theInput(e) {
+				var val=e.detail.value;
+				let data = [];
+				var odData=this.odData;
+				for(var i=0;i<odData.length;i++){
+					var isHas=false;
+					if(odData[i].value.indexOf(val)!=-1){
+						data.push(odData[i])
+						if(odData[i].value==val){
+							isHas=true;
+							var arr=[];
+							arr.push(odData[i].value+"|"+odData[i].id)
+						  this.$emit('getBackVal',arr);
+						}
+					}
+					if(!isHas){
+						var arr=[];
+						arr.push(val)
+						 this.$emit('getBackVal',arr);
+					}
+				}
+				this.nowData=data;
+			},
+			//下拉选中
+			selectCheckbox(e){
+				var val=e.target.value;
+				var str=val;
+				if(typeof(str)!="string"){
+					str="";
+					for(var i=0;i<val.length;i++){
+						var vt=val[i].split("|");
+						str+=i>0?","+vt[0]:vt[0];
+					}
+				}
+				else{
+					this.isShow = false;
+					str=str.split("|")[0];
+				}
+				this.$emit('getBackVal',val+"|"+this.tags)
+				this.theValue = str;
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+.yealuo-select{
+	max-width: 100%;
+	position: relative;
+	.yealuo-background{position: fixed;top:0;left:0;width: 750upx;height: 100%;}
+	.yealuo-con{display: flex;align-items: center;justify-content: center;
+		input{flex: 1;margin: 0 6upx;}
+	}
+	
+	.yealuo-select {
+		border: 1px solid #f3f3f4;
+		position: absolute;
+		z-index: 999;
+		background: #fff;
+		width: 100%;
+		.data{
+			max-height: 600upx;
+			padding: 10upx;
+			overflow: auto;
+			.select-item {width: 100%;color:#666;
+				.item-text{ width:100%; display:block;}
+				.active{font-weight: bold;}
+			}
+			.item-auto{overflow: auto;
+				.item-text{width: max-content;}
+			}
+			.item-hide .item-text{
+				overflow: hidden;
+				text-overflow:ellipsis;
+				white-space: nowrap;
+			}
+		}
+		.item-close {
+			padding: 20upx;
+			text-align: center;
+			font-size: 32upx;
+			border-top: 1px solid #f3f3f4;
+			color:#8F8F94;
+		}
+	}
+}
+</style>

+ 120 - 0
src/components/zzlb-mutiselect/zzlb-mutiselect.vue

@@ -0,0 +1,120 @@
+<template>
+  <view class="" style="width: 100%;">
+    <view class=" flex flex-wrap">
+      <view v-for="(item, index) in items" class="cu-tag bg-cyan radius">
+        <slot name="default" v-bind:item="item">{{ item }}</slot>
+        <text class="margin-left line-blue cuIcon-close round bg-red" @click="onremove(index)"></text>
+      </view>
+      <view class="flex ">
+        <input style1="width: 60px;" placeholder="输入..." type="text" v-model="query" @input="onshuru" @click="onquery" @keyup="onquery" />
+        <text
+          v-if="query"
+          class=" cuIcon-close "
+          @click="
+            query = '';
+            onquery();
+          "
+        ></text>
+        <text v-if="visible" class="cu-btn sm" @click="onqueren">确认</text>
+      </view>
+    </view>
+    <view v-if="visible" class="fixed bg-white">
+      <!-- <view class="flex justify-between ">
+        <button class="cu-btn " @click="visible = 0">取消</button>
+        <button class="cu-btn " @click="onqueren">确认</button>
+      </view> -->
+      <picker-view
+        class="picker-view"
+        @change="e => (pvvalue = mlist[e.detail.value[0]])"
+        indicator-style1="height:40px"
+        :style1="{ height: (mlist.length > 6 ? 6 : mlist.length / 2) * 34 + 'px' }"
+      >
+        <picker-view-column>
+          <view class="item" v-for="(item, index) in mlist" :key="index">
+            <slot name="option" v-bind:item="item">{{ item }}</slot>
+          </view>
+        </picker-view-column>
+      </picker-view>
+    </view>
+  </view>
+</template>
+<script>
+export default {
+  props: {
+    url: { type: String, default: '' },
+    list: {
+      type: Array,
+      default: function() {
+        return [];
+      }
+    },
+    value: {
+      type: Array,
+      default: function() {
+        return [];
+      }
+    }
+  },
+  data() {
+    return {
+      visible: 0,
+      items: [],
+      query: '',
+      mlist: [],
+      pvvalue: []
+    };
+  },
+  computed: {},
+  watch: {
+    value() {
+      this.items = this.value || [];
+    }
+  },
+  methods: {
+    onquery() {
+      console.log(this.query);
+      this.visible = 1;
+      this.pvvalue = this.mlist[0];
+
+      if (this.list && this.list.length > 0) {
+        const l = this.list.filter(f => f.indexOf(this.query) > -1);
+        if (l.indexOf(this.pvvalue) === -1) {
+          this.pvvalue = l[0];
+        }
+        this.mlist = l;
+        return;
+      }
+      this.$http.get(this.url, { params: { title: this.query } }).then(r => {
+        r.data.list;
+        this.mlist = r.data.list;
+        this.pvvalue = this.mlist[0];
+      });
+    },
+    onremove(index) {
+      this.items.splice(index, 1);
+      this.$emit('input', this.items);
+    },
+    onshuru() {
+      this.visible = 1;
+    },
+    onqueren() {
+      this.visible = 0;
+      if (this.pvvalue) this.items.push(this.pvvalue);
+      this.$emit('input', this.items);
+    }
+  }
+};
+</script>
+<style>
+.picker-view {
+  width: 100%;
+  height: 100px;
+  /* margin-top: 20rpx; */
+}
+.item {
+  /* height: 50px; */
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+}
+</style>

+ 136 - 0
src/data/json.js

@@ -0,0 +1,136 @@
+// 本地模拟json数据
+// 首页九宫格
+let cuIconList = [
+  {
+    imgUrl: "/static/index/ge1.png",
+    badge: 0,
+    name: "巡检",
+    redirectUrl: "/pages/business/mhxf/xunJian/xunJian",
+  },
+  {
+    imgUrl: "/static/index/ge2.png",
+    badge: 0,
+    name: "信息查询",
+    redirectUrl: "/pages/business/mhxf/informationSelect/index",
+  },
+  {
+    imgUrl: "/static/index/ge3.png",
+    badge: 0,
+    name: "设备管理",
+    redirectUrl: "/pages/business/mhxf/deviceManage/index",
+  },
+  {
+    imgUrl: "/static/index/ge4.png",
+    badge: 0,
+    name: "协同作战",
+    redirectUrl: "/pages/business/mhxf/coordination/index",
+  },
+  // {
+  //   imgUrl: "/static/images/square/square-xf.png",
+  //   badge: 0,
+  //   name: "未开发",
+  //   redirectUrl: "",
+  // },
+];
+
+// 首页报警数据
+let staticData = {
+  msg: "\u64cd\u4f5c\u6210\u529f",
+  flag: true,
+  companyCode: "1,2,3,4,5,6,7,8,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39",
+  data: [
+    {
+      statisticalPeriod: "2021-03-16~2021-04-16",
+      smartElectricityCount: "178",
+      videoMonitoringCount: "12456",
+      alarmCount: 12627,
+      eventCount: 2,
+      hiddenDangerCount: 4,
+      offlineCount: 20,
+      faultCount: 30,
+      earlyWarningCount: 100,
+      otherCount: 99,
+      normalCount: 66,
+      integratedAlarmCount: 12627,
+      unprocessedCount: 0,
+    },
+  ],
+};
+
+// 巡检模块 开始
+let xunJianList = [
+  {
+    id: 1,
+    title: "巡检任务",
+    num: "0",
+    imgUrl: "/static/images/xunjian/xunJian-icon1.png",
+    redirectUrl: "/pages/business/mhxf/xunJian/plan/index",
+  },
+  {
+    id: 2,
+    title: "巡检记录",
+    num: "0",
+    imgUrl: "/static/images/xunjian/xunJian-icon2.png",
+    redirectUrl: "/pages/business/mhxf/xunJian/plan/index",
+  },
+  {
+    id: 3,
+    title: "巡检采集",
+    num: "0",
+    imgUrl: "/static/images/xunjian/xunJian-icon3.png",
+    redirectUrl: "/pages/business/mhxf/xunJian/collect/index",
+  },
+];
+
+let xunJianRecord = [
+  {
+    id: "561",
+    title: "计划:巡检计划1",
+    des: "点位:巡检点位01",
+    time: "2021-01-20 15:23:43",
+    status: 0,
+  },
+  {
+    id: "561",
+    title: "计划:巡检计划1",
+    des: "点位:巡检点位01",
+    time: "2021-01-20 15:23:43",
+    status: 1,
+  },
+  {
+    id: "561",
+    title: "计划:巡检计划1",
+    des: "点位:巡检点位01",
+    time: "2021-01-20 15:23:43",
+    status: 1,
+  },
+];
+
+let xunJianPlan = [
+  {
+    id: "561",
+    title: "虹泾总部园巡检点位1",
+    status: 0,
+  },
+  {
+    id: "561",
+    title: "虹泾总部园巡检点位2",
+    status: 0,
+  },
+  {
+    id: "561",
+    title: "虹泾总部园巡检点位3",
+    status: 1,
+  },
+];
+// 巡检模块 结束
+
+// 定义数据出口
+export default {
+  staticData: staticData,
+  cuIconList: cuIconList,
+
+  xunJianList: xunJianList,
+  xunJianRecord: xunJianRecord,
+  xunJianPlan: xunJianPlan,
+};

+ 71 - 0
src/main.js

@@ -0,0 +1,71 @@
+import { createSSRApp } from "vue";
+
+import App from "./App.vue";
+import store from "./store";
+import publicStore from "@/store/modules/public";
+
+// 引入全局api
+import api from "@/utils/api.js";
+
+// 引入全局router路由拦截
+import initApp from "@/utils/router/init.js";
+
+// 引入colorui组件
+import cuCustom from "@/colorui/components/cu-custom.vue";
+
+//配置公共方法
+import common from "@/common/common.js";
+
+// 引入json导出组件
+import JsonExcel from "vue-json-excel";
+
+// 引入微信js-sdk
+// import jweixin from 'weixin-js-sdk'
+
+import uviewPlus from "./uni_modules/uview-plus";
+
+// 引入ElementPlus
+import ElementPlus from "element-plus";
+import locale from "element-plus/lib/locale/lang/zh-cn"; // 中文语言
+import "element-plus/theme-chalk/index.css";
+import * as Elicons from "@element-plus/icons-vue";
+
+export function createApp() {
+  const app = createSSRApp(App);
+
+  // 挂载colorui组件
+  app.component("cu-custom", cuCustom);
+
+  // 挂载json导出
+  app.component("downloadExcel", JsonExcel);
+
+  // 挂宅icons-vue组件icon
+  for (const name in Elicons) {
+    app.component(name, Elicons[name]);
+  }
+
+  // 添加全局变量
+  app.provide("$myRequest", api.myRequest);
+  app.provide("$sendUploadFile", api.sendUploadFile);
+  app.provide("$BASE_URL", api.BASE_URL);
+  app.config.globalProperties.$myRequest = api.myRequest;
+  app.config.globalProperties.$BASE_URL = api.BASE_URL;
+  app.config.globalProperties.$websiteUrl = api.websiteUrl;
+  // 添加全局变量 (禁止重复点击)
+  app.config.globalProperties.$noMultipleClicks = common.noMultipleClicks;
+  // 添加全局变量 微信js-sdk
+  // app.config.globalProperties.$wx = jweixin
+
+  // 使用element-plus
+  app
+    .use(ElementPlus, {
+      locale: locale,
+    })
+    .use(store)
+    .use(initApp)
+    .use(uviewPlus);
+
+  return {
+    app,
+  };
+}

+ 182 - 0
src/manifest.json

@@ -0,0 +1,182 @@
+{
+    "name" : "智慧消防",
+    "appid" : "__UNI__36DE3A0",
+    "description" : "智慧消防",
+    "versionName" : "2.0",
+    "versionCode" : 2,
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "compatible" : {
+            "ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持
+        },
+        "kernel" : {
+            "ios" : "WKWebview" //或者 "WKWebview"
+        },
+        "usingComponents" : true,
+        "nvueStyleCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {
+            "VideoPlayer" : {},
+            "iBeacon" : {},
+            "Geolocation" : {},
+            "Maps" : {}
+        },
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>"
+                ]
+            },
+            /* ios打包配置 */
+            "ios" : {
+                "dSYMs" : false
+            },
+            /* SDK配置 */
+            "sdkConfigs" : {
+                "ad" : {},
+                "maps" : {
+                    "amap" : {
+                        "appkey_ios" : "",
+                        "appkey_android" : "ffc71dfd4e576596027f8f45a1b8fb2f"
+                    }
+                },
+                "geolocation" : {
+                    "system" : {
+                        "__platform__" : [ "android" ]
+                    },
+                    "amap" : {
+                        "__platform__" : [ "android" ],
+                        "appkey_ios" : "",
+                        "appkey_android" : "ffc71dfd4e576596027f8f45a1b8fb2f"
+                    }
+                }
+            },
+            "icons" : {
+                "android" : {
+                    "hdpi" : "unpackage/res/icons/72x72.png",
+                    "xhdpi" : "unpackage/res/icons/96x96.png",
+                    "xxhdpi" : "unpackage/res/icons/144x144.png",
+                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
+                },
+                "ios" : {
+                    "appstore" : "unpackage/res/icons/1024x1024.png",
+                    "ipad" : {
+                        "app" : "unpackage/res/icons/76x76.png",
+                        "app@2x" : "unpackage/res/icons/152x152.png",
+                        "notification" : "unpackage/res/icons/20x20.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "proapp@2x" : "unpackage/res/icons/167x167.png",
+                        "settings" : "unpackage/res/icons/29x29.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "spotlight" : "unpackage/res/icons/40x40.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
+                    },
+                    "iphone" : {
+                        "app@2x" : "unpackage/res/icons/120x120.png",
+                        "app@3x" : "unpackage/res/icons/180x180.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "notification@3x" : "unpackage/res/icons/60x60.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "settings@3x" : "unpackage/res/icons/87x87.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
+                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
+                    }
+                }
+            },
+            "splashscreen" : {
+                "androidStyle" : "default",
+                "android" : {
+                    "hdpi" : "src/static/images/wt/bg.png"
+                }
+            }
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false,
+            "checkSiteMap" : false
+        },
+        "usingComponents" : true
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "h5" : {
+        "publicPath" : "./",
+        "title" : "智慧消防",
+        "router" : {
+            "mode" : "hash",
+            "base" : "./"
+        },
+        "devServer" : {
+            "https" : false,
+            "proxy" : {
+                "/web" : {
+                    "target" : "https://wx.ewoogi.com/wx",
+                    "changeOrigin" : true,
+                    "secure" : false,
+                    "pathRewrite" : {
+                        "^/web" : "/"
+                    }
+                }
+            }
+        },
+        "domain" : "https://qhome.usky.cn/",
+        "sdkConfigs" : {
+            "maps" : {
+                "qqmap" : {
+                    "key" : "IQ5BZ-UN7KP-VBDDO-LHYJA-LZSPQ-6KFNJ"
+                }
+            }
+        },
+        "optimization" : {
+            "treeShaking" : {
+                "enable" : true
+            }
+        },
+        "template" : "index.html"
+    },
+    "vueVersion" : "3",
+    "locale" : "zh-Hans"
+}

+ 345 - 0
src/pages.json

@@ -0,0 +1,345 @@
+{
+  "pages": [
+    //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+    {
+      "path": "pages/login/login",
+      "style": {
+        "navigationBarTitleText": "登录",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/index/index",
+      "style": {
+        "navigationBarTitleText": "",
+        "app-plus": {
+          "titleNView": {
+            "buttons": [
+              {
+                "text": "\ue607",
+                "fontSize": "18px",
+                // "redDot": true,
+                "float": "right",
+                "fontSrc": "/static/iconfont/iconfont.ttf",
+                "width": "auto"
+              }
+              // {
+              //     "text": "\ue63d",
+              //     "fontSize": "18px",
+              //     "float": "left",
+              //     "fontSrc": "/static/iconfont/iconfont.ttf",
+              //     "width": "auto"
+              // }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "path": "pages/index/components/searchSelect/searchSelect",
+      "style": {
+        "navigationBarTitleText": "",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/export/export",
+      "style": {
+        "navigationBarTitleText": "导出",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "components/square/square",
+      "style": {
+        "navigationBarTitleText": "",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/authority/authority",
+      "style": {
+        "navigationBarTitleText": "授权",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/test/test",
+      "style": {
+        "navigationBarTitleText": "",
+        "enablePullDownRefresh": false
+      }
+    },
+    //消防督察单模块 开始
+
+    //消防督察单模块 结束
+
+    //巡检模块 开始
+    {
+      "path": "pages/business/mhxf/xunJian/xunJian",
+      "style": {
+        "navigationBarTitleText": "巡检",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/plan/index",
+      "style": {
+        "navigationBarTitleText": "巡检计划",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/plan/components/siteDetails",
+      "style": {
+        "navigationBarTitleText": "站点详情",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/plan/components/content",
+      "style": {
+        "navigationBarTitleText": "巡检内容",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/plan/components/report",
+      "style": {
+        "navigationBarTitleText": "巡检上报",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/record/record",
+      "style": {
+        "navigationBarTitleText": "巡检记录",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/record/recordDetail/index",
+      "style": {
+        "navigationBarTitleText": "巡检记录详情",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/collect/index",
+      "style": {
+        "navigationBarTitleText": "点位采集",
+        "enablePullDownRefresh": false,
+        "app-plus": {
+          "titleNView": {
+            "buttons": [
+              {
+                "text": "采集记录",
+                "fontSize": "12px",
+                // "redDot": true,
+                "float": "right",
+                "fontSrc": "/static/iconfont/iconfont.ttf",
+                "width": "auto"
+              }
+            ]
+          }
+        }
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/collect/components/collectDetail",
+      "style": {
+        "navigationBarTitleText": "采集上报",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/business/mhxf/xunJian/collect/components/collectRecord",
+      "style": {
+        "navigationBarTitleText": "采集记录",
+        "enablePullDownRefresh": false,
+        "app-plus": {
+          "titleNView": {
+            "buttons": [
+              {
+                "text": "\ue7c7",
+                "fontSize": "18px",
+                // "redDot": true,
+                "float": "right",
+                "fontSrc": "/static/iconfont/uciconfont/iconfont.ttf",
+                "width": "auto"
+              }
+            ]
+          }
+        }
+      }
+    },
+    //巡检模块 结束
+
+    //信息查询 开始
+    {
+      "path": "pages/business/mhxf/informationSelect/index",
+      "style": {
+        "navigationBarTitleText": "信息查询",
+        "enablePullDownRefresh": false
+      }
+    },
+    //信息查询 结束
+
+    //设备管理 开始
+    {
+      "path": "pages/business/mhxf/deviceManage/index",
+      "style": {
+        "navigationBarTitleText": "设备管理",
+        "enablePullDownRefresh": false
+      }
+    },
+    //设备管理 结束
+
+    //协同作战地图 开始
+    {
+      "path": "pages/business/mhxf/coordination/index",
+      "style": {
+        "navigationBarTitleText": "协同作战地图",
+        "enablePullDownRefresh": false
+      }
+    },
+    //协同作战地图 结束
+
+    /**
+     * @消息 开始
+     */
+    {
+      "path": "pages/info/info",
+      "style": {
+        "navigationBarTitleText": "消息",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/info/fireBase/fireBase",
+      "style": {
+        "navigationBarTitleText": "消防知识库",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/info/pushList/pushList",
+      "style": {
+        "navigationBarTitleText": "消息推送",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/info/fireBashDetail/fireBashDetail",
+      "style": {
+        "navigationBarTitleText": "火灾逃生十大要诀",
+        "enablePullDownRefresh": false
+      }
+    },
+    /**
+     * @消息 结束
+     */
+    /**
+     * @分析 开始
+     */
+    {
+      "path": "pages/analyse/analyse",
+      "style": {
+        "navigationBarTitleText": "分析"
+      }
+    },
+    /**
+     * @分析 结束
+     */
+    /**
+     * @设置 开始
+     */
+    {
+      "path": "pages/setting/setting",
+      "style": {
+        "navigationBarTitleText": "设置"
+      }
+    },
+    {
+      "path": "pages/setting/messagePush/messagePush",
+      "style": {
+        "navigationBarTitleText": "消息推送设置",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/setting/building/building",
+      "style": {
+        "navigationBarTitleText": "建筑管理",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/setting/funReport/funReport",
+      "style": {
+        "navigationBarTitleText": "功能报备",
+        "enablePullDownRefresh": false,
+        "onReachBottomDistance": 100 //距离底部多远时触发 单位px
+      }
+    },
+    {
+      "path": "pages/setting/funReport/funcAdd/funcAdd",
+      "style": {
+        "navigationBarTitleText": "功能报备新增",
+        "enablePullDownRefresh": false
+      }
+    }
+    /**
+     * @设置 结束
+     */
+  ],
+  "globalStyle": {
+    "navigationBarTextStyle": "white",
+    "navigationBarTitleText": "uni-app",
+    "navigationBarBackgroundColor": "#149EFF",
+    "backgroundColor": "#F8F8F8"
+    // "enablePullDownRefresh": true
+  },
+  "tabBar": {
+    "color": "#a9a9a9",
+    "selectedColor": "#000000",
+    "borderStyle": "white",
+    "list": [
+      {
+        "pagePath": "pages/index/index",
+        "iconPath": "static/tabBar/home.png",
+        "selectedIconPath": "static/tabBar/home-selected.png",
+        "text": "主页"
+      },
+      {
+        "pagePath": "pages/analyse/analyse",
+        "iconPath": "static/tabBar/analyse.png",
+        "selectedIconPath": "static/tabBar/analyse-selected.png",
+        "text": "分析"
+      },
+      {
+        "pagePath": "pages/info/info",
+        "iconPath": "static/tabBar/info.png",
+        "selectedIconPath": "static/tabBar/info-selected.png",
+        "text": "消息"
+      },
+      {
+        "pagePath": "pages/setting/setting",
+        "iconPath": "static/tabBar/setting.png",
+        "selectedIconPath": "static/tabBar/setting-selected.png",
+        "text": "我的"
+      }
+    ]
+  },
+  "condition": {
+    //模式配置,仅开发期间生效
+    "current": 0, //当前激活的模式(list 的索引项)
+    "list": [
+      {
+        "name": "", //模式名称
+        "path": "pages/index/index", //启动页面,必选
+        "query": "" //启动参数,在页面的onLoad函数里面得到
+      }
+    ]
+  }
+}

+ 102 - 0
src/pages/index/components/searchSelect/searchSelect.vue

@@ -0,0 +1,102 @@
+<template>
+  <view>
+    <view class="searchSelect shadow" v-if="flag">
+      <view class="cu-bar search bg-white">
+        <view class="search-form round" style="margin-top: 0">
+          <input
+            @focus="InputFocus"
+            @blur="InputBlur"
+            @input="handleInput()"
+            v-model="searchInput"
+            :adjust-position="false"
+            type="text"
+            placeholder=""
+            confirm-type="search"
+            style="border: none"
+          />
+          <text class="cuIcon-search"></text>
+        </view>
+      </view>
+      <view class="select-items">
+        <view
+          class="select-item"
+          v-for="(item, index) in searchList"
+          @click="clickSelectItem(item, index)"
+          :key="index"
+          >{{ item }}</view
+        >
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  name: "searchSelect",
+  props: {
+    flag: {
+      type: Boolean,
+      default: false,
+    },
+    searchList: {
+      type: Array,
+      // default: []
+    },
+    searchList2: {
+      type: Array,
+      // default: []
+    },
+  },
+  data() {
+    return {
+      searchInput: "",
+      // flag: false,
+      // searchList: [],
+      // searchList2: [],
+    };
+  },
+  onload() {
+    this.getSearchList();
+  },
+  methods: {
+    //请求
+    async getSearchList(ming = {}) {
+      const res = await this.$myRequest({
+        url: "Index/getSiteDropDownBox",
+        data: ming,
+      });
+      res.data.data.forEach((item) => {
+        this.searchList.push(item.siteName);
+        this.searchList2.push(item.siteName);
+      });
+    },
+    // 下拉选择
+    clickSelectItem(item, index) {
+      this.getSearchList({
+        siteName: item,
+      });
+      this.flag = false;
+    },
+    handleInput() {
+      var newlist = this.searchList2.filter(
+        (item) => item.indexOf(this.searchInput) > -1
+      );
+      this.searchList = newlist;
+    },
+
+    InputFocus(e) {
+      this.InputBottom = e.detail.height;
+    },
+    InputBlur(e) {
+      this.InputBottom = 0;
+    },
+
+    changeTab(Inv) {
+      that.navIdx = Inv;
+    },
+  },
+};
+</script>
+
+<style>
+</style>

+ 548 - 0
src/pages/index/index.vue

@@ -0,0 +1,548 @@
+<template>
+	<!-- <u-sticky bgColor="#fff"> </u-sticky> -->
+
+	<scroll-view scroll-x>
+		<view>
+			<!-- 下拉选择 -->
+			<!-- <view class="searchSelect shadow" v-if="flag">
+        <view class="cu-bar search bg-white">
+          <view class="search-form round" style="margin-top: 0">
+            <input
+              @focus="InputFocus"
+              @blur="InputBlur"
+              @input="handleInput()"
+              v-model="searchInput"
+              :adjust-position="false"
+              type="text"
+              placeholder=""
+              confirm-type="search"
+              style="border: none !important"
+            />
+            <text class="cuIcon-search"></text>
+          </view>
+        </view>
+        <view class="select-items">
+          <view
+            class="site-item"
+            v-if="!searchList.length"
+            style="text-align: center"
+            >暂无结果</view
+          >
+          <view
+            class="select-item"
+            v-for="(item, index) in searchList"
+            @click="clickSelectItem(item, index)"
+            :key="index"
+            >{{ item.owner_name }}</view
+          >
+        </view>
+      </view> -->
+			<!-- 下拉选择 end -->
+
+			<!-- 图表 -->
+			<!-- <view class="section1 section bg-white padding-xs">
+        <view
+          class="
+            static-tabs
+            grid
+            margin-bottom
+            text-center
+            col-3
+            margin-top-sm margin-bottom-sm
+          "
+        >
+          <view
+            :class="['padding-sm ', Inv == 0 ? 'active' : '']"
+            @click="Inv = 0"
+            >报警信息统计</view
+          >
+          <view
+            :class="['padding-sm ', Inv == 1 ? 'active' : '']"
+            @click="Inv = 1"
+            >数据等级统计</view
+          >
+          <view
+            :class="['padding-sm ', Inv == 2 ? 'active' : '']"
+            @click="Inv = 2"
+            >设备运行状态</view
+          >
+        </view>
+        <view class="time text-center"
+          >统计时段:{{ staticData.statisticalPeriod }}
+        </view>
+        <view style="height: 570rpx">
+          <view v-if="Inv == 0"> </view>
+          <view v-if="Inv == 1"> </view>
+          <view v-if="Inv == 2" class="chart3-box">
+            <ul class="chart3-icon">
+              <li>
+                <image
+                  src="@/static/index/chart3-1.png"
+                  style="width: 64rpx; height: 64rpx"
+                ></image>
+              </li>
+              <li>
+                <image
+                  src="@/static/index/chart3-2.png"
+                  style="width: 64rpx; height: 64rpx"
+                ></image>
+              </li>
+              <li>
+                <image
+                  src="@/static/index/chart3-3.png"
+                  style="width: 64rpx; height: 64rpx"
+                ></image>
+              </li>
+              <li>
+                <image
+                  src="@/static/index/chart3-4.png"
+                  style="width: 64rpx; height: 64rpx"
+                ></image>
+              </li>
+              <li>
+                <image
+                  src="@/static/index/chart3-5.png"
+                  style="width: 64rpx; height: 64rpx"
+                ></image>
+              </li>
+            </ul>
+          </view>
+        </view>
+      </view> -->
+			<!-- 图表 end-->
+
+			<!-- 轮播图 开始 -->
+			<u-swiper :list="arrayList.swiperList" indicator indicatorMode="line" radius="0" height="160" circular>
+			</u-swiper>
+			<!-- 轮播图 结束 -->
+
+			<!-- 宫格列表 -->
+			<view class="section2 section bg-white" style="margin-bottom: 10px"
+				v-if="arrayList.recentlyUsed.length > 0">
+				<view style="color: #000000; font-size: 16px; padding: 10px 10px 5px 10px">最近使用</view>
+				<view class="cu-list grid col-5 no-border">
+					<view class="cu-item justify-center align-center" @tap="navItemClick(item)"
+						v-for="(item, index) in arrayList.recentlyUsed" :key="index">
+						<image :src="item.imgUrl" style="width: 40px; height: 40px"></image>
+						<view class="cu-tag badge" v-if="item.badge != 0">
+							<block v-if="item.badge != 0">{{ item.badge > 99 ? "99+" : item.badge }}</block>
+						</view>
+						<text style="font-size: 14px">{{ item.name }}</text>
+					</view>
+				</view>
+			</view>
+			<!-- 宫格列表 end -->
+
+			<!-- 宫格列表 -->
+			<view class="section2 section bg-white">
+				<view style="color: #000000; font-size: 16px; padding: 10px 10px 5px 10px">常用功能</view>
+				<view class="cu-list grid col-5 no-border">
+					<view class="cu-item justify-center align-center" @tap="navItemClick(item)"
+						v-for="(item, index) in arrayList.cuIconList" :key="index">
+						<image :src="item.imgUrl" style="width: 40px; height: 40px"></image>
+						<view class="cu-tag badge" v-if="item.badge != 0">
+							<block v-if="item.badge != 0">{{ item.badge > 99 ? "99+" : item.badge }}</block>
+						</view>
+						<text style="font-size: 14px">{{ item.name }}</text>
+					</view>
+				</view>
+			</view>
+			<!-- 宫格列表 end -->
+		</view>
+	</scroll-view>
+</template>
+
+<script setup>
+	import searchSelect from "./components/searchSelect/searchSelect.vue";
+
+	import json from "@/data/json.js"; //引入api请求封装方法
+	import * as jwx from "@/utils/jssdk.js"; //引入js sdk的封装
+
+	import {
+		onReady,
+		onLoad,
+		onShow,
+		onNavigationBarButtonTap
+	} from "@dcloudio/uni-app";
+	import {
+		ref,
+		onMounted,
+		inject,
+		shallowRef,
+		reactive
+	} from "vue";
+	import useXunJianStore from "@/store/modules/xunJian.js";
+
+	const myRequest = inject("$myRequest"); //全局接口请求
+	const settingsStore = useXunJianStore(); //全局变量值Store
+	const BASE_URL = inject("$BASE_URL");
+
+	const arrayList = reactive({
+		InputBottom: 0,
+		staticData: "",
+		indicator: [],
+		datavalue: [],
+		dataname: [],
+		Inv: 0,
+		flag: false,
+		searchList: [],
+		searchList2: [],
+		searchInput: "",
+		selectedCode: 10012,
+		codeResult: "",
+
+		swiperList: ["../../static/index/banner1.png", "../../static/index/banner2.jpg",
+			"../../static/index/banner3.jpg"
+		],
+		cuIconList: json.cuIconList,
+		recentlyUsed: [],
+	});
+
+	onLoad((option) => {
+		//获取首页标题
+		if (uni.getStorageSync("homeTitle")) {
+			uni.setNavigationBarTitle({
+				title: uni.getStorageSync("homeTitle"),
+			});
+		} else {
+			uni.setNavigationBarTitle({
+				title: "首页",
+			});
+		}
+
+		if (uni.getStorageSync("recentlyUsed")) {
+			arrayList.recentlyUsed = uni.getStorageSync("recentlyUsed");
+		}
+
+		// var res = uni.getStorageSync("selectedCode");
+		// var res2 = uni.getStorageSync("selectedName");
+		// if (res) {
+		//   uni.setNavigationBarTitle({
+		//     title: res2,
+		//   });
+		// }
+
+		// // 图表切换渲染
+		// this.hackReset = false;
+		// this.$nextTick(() => {
+		//   this.hackReset = true;
+		// });
+	});
+
+	//登录请求
+	async function getLogin() {
+		const res = await myRequest({
+			url: "/system/appLogin",
+			header: {
+				"Content-Type": "application/json;charset=utf-8",
+			},
+			method: "POST",
+			data: {
+				username: "fire_admin",
+				password: "fire_admin",
+				tenantId: 1002,
+			},
+		});
+
+		uni.setStorageSync("Authorization", res.data.data.access_token);
+		if (res.data.status == "SUCCESS") {
+			uni.switchTab({
+				url: "/pages/index/index",
+			});
+		} else {}
+	}
+
+	async function init() {
+		window.location.href = BASE_URL + "Com/getPageAuthorization1";
+	}
+	//扫码
+	function scanQRCode() {
+		// console.log(1);
+		// this.scanCode();
+		// 将this赋值给that
+		let that = this;
+		// 微信公众号获取位置
+		jwx.configWeiXin((jweixin) => {
+			jweixin.scanQRCode({
+				needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
+				scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
+				success: function(res) {
+					setTimeout(function() {
+						/* 放1000ms后执行的代码 */
+						alert(res.resultStr);
+						that.getCodeResult({
+							ercode: res.resultStr,
+						});
+					}, 1000);
+				},
+			});
+		});
+	}
+
+	function scanCode() {
+		uni.scanCode({
+			scanType: ["qrCode"],
+			success: (res) => {
+				console.log("扫码成功", res);
+			},
+			fail: (err) => {
+				console.log("扫码失败", err);
+			},
+			complete: () => {
+				console.log("扫码结束");
+			},
+		});
+	}
+
+	// 扫码成功后请求
+	async function getCodeResult(param = {}) {
+		const res = await myRequest({
+			url: "ScanPush/scan_push",
+			data: param,
+		});
+		if (res.data.flag) {
+			uni.showToast({
+				title: "扫码成功",
+				icon: "none",
+			});
+		}
+	}
+
+	//获取地理位置
+	function getLocation() {
+		alert(2);
+		// 将this赋值给that
+		let that = this;
+		// 微信公众号获取位置
+		jwx.configWeiXin((jweixin) => {
+			alert(22);
+			jweixin.getLocation({
+				type: "gcj02", // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
+				success: function(res) {
+					alert(res.longitude);
+				},
+			});
+		});
+	}
+
+	// 九宫格页面跳转
+	function navItemClick(item) {
+		if (item.redirectUrl) {
+			item.sort = 0;
+
+			arrayList.recentlyUsed.push(item);
+
+			if (arrayList.recentlyUsed.length > 0) {
+				arrayList.recentlyUsed = arrayList.recentlyUsed.filter((currentValue, currentIndex, selfArr) => {
+					return selfArr.findIndex((x) => x.redirectUrl === currentValue.redirectUrl) === currentIndex;
+				});
+
+				arrayList.recentlyUsed.filter((el) => {
+					if (el.redirectUrl === item.redirectUrl) {
+						el.sort++;
+					}
+				});
+			}
+
+			arrayList.recentlyUsed = settingsStore.sortEvent(arrayList.recentlyUsed, 1);
+
+			uni.setStorageSync("recentlyUsed", arrayList.recentlyUsed);
+
+			uni.navigateTo({
+				url: item.redirectUrl,
+			});
+		} else {
+			uni.showModal({
+				title: "Tips",
+				content: "此模块开发中~",
+				showCancel: false,
+				success: function(res) {
+					if (res.confirm) {} else if (res.cancel) {}
+				},
+			});
+		}
+	}
+
+	function showTag() {
+		arrayList.flag = !arrayList.flag;
+	}
+	// 下拉选择
+	function clickSelectItem(item, index) {
+		arrayList.staticData = "";
+		arrayList.selectedCode = item.owner_code;
+		uni.setStorageSync("selectedCode", item.owner_code);
+		uni.setStorageSync("selectedName", item.owner_name);
+		arrayList.searchInput = item.owner_name;
+		uni.setNavigationBarTitle({
+			title: arrayList.searchInput,
+		});
+
+		getHomeData({
+			company_code: uni.getStorageSync("selectedCode"),
+		});
+		getHandleData({
+			company_code: uni.getStorageSync("selectedCode"),
+		});
+
+		arrayList.flag = false;
+	}
+
+	function handleInput() {
+		var newlist = arrayList.searchList2.filter((item) => item.owner_name.indexOf(arrayList.searchInput) > -1);
+		arrayList.searchList = newlist;
+	}
+
+	function InputFocus(e) {
+		arrayList.InputBottom = e.detail.height;
+	}
+
+	function InputBlur(e) {
+		arrayList.InputBottom = 0;
+	}
+	//echarts图表请求
+	async function getHomeData(param = {}) {
+		const res = await myRequest({
+			url: "Index/getHomePageData",
+			data: param,
+		});
+		// console.log('首页请求staticData')
+		// console.log(res.data.data[0])
+		arrayList.staticData = res.data.data[0];
+
+		// var data = res.data.data[0]
+
+		var datavalue = [
+			arrayList.staticData.fire_water_count,
+			arrayList.staticData.alarm_host_count,
+			arrayList.staticData.electrical_fire_count,
+			arrayList.staticData.other_count,
+			arrayList.staticData.video_monitoring_count,
+		];
+		var dataname = ["消防水系统", "报警主机", "电气火灾", "其他", "监控视频"];
+		var color = ["#3C8BF0", "#06CDF8", "#0ECB70", "#6744EF", "#FFD803"];
+
+		var aa = [
+			arrayList.staticData.fire_water_count,
+			arrayList.staticData.alarm_host_count,
+			arrayList.staticData.electrical_fire_count,
+			arrayList.staticData.other_count,
+			arrayList.staticData.video_monitoring_count,
+		];
+		aa.sort(function(a, b) {
+			return a - b;
+		});
+		aa = aa.pop();
+		var datamax = [aa, aa, aa, aa, aa];
+
+		arrayList.datavalue = datavalue;
+		arrayList.dataname = dataname;
+
+		dataname.map((val, ind) => {
+			arrayList.indicator.push({
+				name: val,
+				max: datamax[ind],
+				color: color[ind],
+			});
+		});
+		arrayList.indicator = arrayList.indicator.slice(-5);
+	}
+	// 未处理告警请求
+	async function getHandleData(param = {}) {
+		const res = await myRequest({
+			url: "Index/getFunctionalModuleStatistics",
+			showLoading: true,
+			data: param,
+		});
+		arrayList.cuIconList[0].badge = res.data.data[0].comprehensive_alarm_count;
+		arrayList.cuIconList[2].badge = res.data.data[0].fire_brigade_inspector_count;
+	}
+
+	// 自定义导航事件
+	onNavigationBarButtonTap((e) => {
+		if (e.float == "right") {
+			// alert("你点击了扫一扫");
+			this.scanQRCode();
+		} else {
+			// alert("你点击了获取位置");
+			// this.getLocation()
+			this.showTag();
+		}
+	});
+</script>
+
+<style>
+	.select-items {
+		overflow: auto;
+		height: 80vh;
+	}
+
+	.static-tabs {
+		border-radius: 50rpx;
+		border: 1rpx solid #4074e7;
+	}
+
+	.static-tabs>view {
+		color: #4074e7;
+		font-size: 30rpx;
+	}
+
+	.static-tabs>view.active {
+		color: #fff;
+		background: #4074e7;
+	}
+
+	.static-tabs>view:first-child {
+		border-top-left-radius: 50rpx;
+		border-bottom-left-radius: 50rpx;
+	}
+
+	.static-tabs>view:nth-child(2) {
+		border-left: 1px solid #4074e7;
+		border-right: 1px solid #4074e7;
+	}
+
+	.static-tabs>view:last-child {
+		border-top-right-radius: 50rpx;
+		border-bottom-right-radius: 50rpx;
+	}
+
+	/* 检测时间 */
+	.time {
+		border-radius: 50rpx;
+		background: #fafcff;
+		border: 1px solid #e8f1ff;
+		padding: 20rpx;
+		color: #666666;
+		font-size: 30rpx;
+	}
+
+	.chart3-box {
+		position: relative;
+	}
+
+	.chart3-icon {
+		width: 90%;
+		position: absolute;
+		top: 60rpx;
+		left: 30rpx;
+		z-index: 1;
+	}
+
+	.chart3-icon li {
+		padding-top: 25rpx;
+	}
+
+	ul,
+	li {
+		padding: 0;
+		margin: 0;
+		list-style: none;
+	}
+</style>
+
+<style scoped>
+	uni-page-body,
+	uni-page-refresh {
+		background: rgb(241, 241, 241);
+	}
+</style>

+ 443 - 0
src/pages/login/login.vue

@@ -0,0 +1,443 @@
+<template>
+  <view class="section">
+    <view class="bg">
+      <image class="bgImage" :src="bg" v-if="bg" />
+      <image class="bgImage" src="@/static/images/wt/bg.png" v-if="!bg" />
+    </view>
+    <view class="top">
+      <image class="logo" :src="logo" mode="widthFix" v-if="logo" />
+      <text class="title">{{ title }}</text>
+    </view>
+    <view class="middle login">
+      <view id="login-input" style="margin-top: 20px" v-if="switchText == '账号密码登录'">
+        <u-input v-model="phone" prefixIcon="phone" placeholder="请输入手机号码" />
+      </view>
+
+      <view id="login-input" style="display: flex; margin-top: 20px" v-if="switchText == '账号密码登录'">
+        <u-input style="width: 60%" v-model="verify" prefixIcon="search" placeholder="请输入验证码" />
+
+        <u-button @click="getVerifyCode">{{ !codeTime ? "获取验证码" : codeTime + "s" }}</u-button>
+      </view>
+
+      <view id="login-input" style="margin-top: 20px" v-if="switchText == '验证码登录'">
+        <u-input type="text" v-model="username" prefixIcon="lock" placeholder="请输入账号" />
+
+        <u-input style="margin-top: 20px" v-model="password" prefixIcon="search" placeholder="请输入密码" :password="inputIconBool">
+          <template #suffix>
+            <text class="iconfont ucicon-eye" @click="inputIcon()" v-if="!inputIconBool"></text>
+            <text class="iconfont ucicon-eye-close" @click="inputIcon()" v-if="inputIconBool"></text>
+          </template>
+        </u-input>
+      </view>
+
+      <!--  -->
+
+      <view class="switchText" @click="switchMode">
+        <text>{{ switchText }}</text>
+      </view>
+      <button class="submit" @click="submitRes">登 录</button>
+    </view>
+    <view class="bottom">
+      <div class="title">{{ bottomTitle }}</div>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { onLoad, onShow, onHide, onLaunch } from "@dcloudio/uni-app";
+import { reactive, toRefs, inject } from "vue";
+import { Lock, User, Cellphone } from "@element-plus/icons-vue";
+
+import useStores from "@/store/modules/user.js";
+const useStore = useStores();
+
+const myRequest = inject("$myRequest"); //api请求方法
+const data = reactive({
+  /** saas数据 */
+  bg: "/static/images/wt/bg.png",
+  logo: undefined,
+  title: undefined,
+  bottomTitle: undefined,
+  /** login数据 */
+  phone: undefined,
+  verify: undefined,
+  codeTime: 0,
+  switchText: "验证码登录",
+  tenantId: undefined,
+  username: undefined,
+  password: undefined,
+  inputIconBool: true,
+
+  // VerificationCodeOne
+});
+
+const { title, bg, bottomTitle, logo, phone, verify, codeTime, switchText, username, password, tenantId, inputIconBool } = toRefs(data);
+/**登录方式切换 */
+function switchMode() {
+  if (switchText.value == "验证码登录") {
+    switchText.value = "账号密码登录";
+  } else {
+    switchText.value = "验证码登录";
+  }
+}
+/** 点击发送验证码 */
+function getVerifyCode() {
+  if (!phone.value) {
+    uni.showToast({
+      title: "请输入手机号码...",
+      icon: "none",
+    });
+    return;
+  }
+  if (!/^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/.test(phone.value)) {
+    uni.showToast({
+      title: "请输入正确的手机号码...",
+      icon: "none",
+    });
+    return;
+  }
+  verify.value = undefined;
+  getSendSms({
+    phone: phone.value,
+  });
+  //
+  if (codeTime.value > 0) {
+    uni.showToast({
+      title: "不能重复获取",
+      icon: "none",
+    });
+    return;
+  } else {
+    codeTime.value = 60;
+    let timer = setInterval(() => {
+      codeTime.value--;
+      if (codeTime.value < 1) {
+        clearInterval(timer);
+        codeTime.value = 0;
+      }
+    }, 1000);
+  }
+}
+/** 获取验证码 */
+async function getSendSms(params) {
+  const res = await myRequest({
+    url: "/system/SendSms/noteSending",
+    header: {
+      "Content-Type": "application/json;charset=utf-8",
+    },
+    method: "GET",
+    data: params,
+    showLoading: true,
+  });
+}
+/** 获取登录页数据 */
+async function getMobileTenantConfig(params) {
+  const res = await myRequest({
+    url: "/system/sysMobileTenantConfig/getMobileTenantConfig",
+    header: {
+      "Content-Type": "application/json;charset=utf-8",
+    },
+    method: "GET",
+    data: params,
+    showLoading: true,
+  });
+  if (res.data.data.length > 0) {
+    let data = res.data.data[0];
+    bg.value = data.loginBackUrl;
+    title.value = data.loginTitle;
+
+    bottomTitle.value = data.loginFooter;
+    tenantId.value = data.tenantId;
+    uni.setStorageSync("homeTitle", data.loginTitle);
+  }
+}
+/**
+ * 判断运行环境
+ */
+function env() {
+  // const u = navigator.userAgent
+  // //https://blog.csdn.net/weixin_42659644/article/details/126294231
+  // if(u.indexOf('saas')>-1){ //指定app内 获取app识别号
+  // }else{
+
+  // }
+
+  let port = uni.getSystemInfoSync().platform;
+  switch (port) {
+    case "android":
+      console.log("Android"); //android
+      break;
+    case "ios":
+      console.log("iOS"); //ios
+      break;
+    case "windows":
+      // console.log("H5"); //H5
+      //getMobileTenantConfig({ url: "172.16.1.47:3000" })
+      getMobileTenantConfig({ url: window.location.host });
+      break;
+    default: //devtools
+      console.log("小程序");
+      break;
+  }
+}
+// env();
+//getMobileTenantConfig({ url: "172.16.1.47:3000" }) // 测试
+/** 点击提交按钮 */
+async function submitRes() {
+  if (switchText.value == "账号密码登录") {
+    if (!phone.value) {
+      uni.showToast({
+        title: "请输入手机号码...",
+        icon: "none",
+      });
+      return;
+    }
+    if (!/^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/.test(phone.value)) {
+      uni.showToast({
+        title: "请输入正确的手机号码...",
+        icon: "none",
+      });
+      return;
+    }
+    if (!verify.value) {
+      uni.showToast({
+        title: "请输入验证码...",
+        icon: "none",
+      });
+      return;
+    }
+    login({
+      phone: phone.value,
+      verify: verify.value,
+      tenantId: tenantId.value,
+    });
+  } else {
+    if (!username.value) {
+      uni.showToast({
+        title: "请输入账户",
+        icon: "none",
+      });
+      return;
+    }
+    if (!password.value) {
+      uni.showToast({
+        title: "请输入密码",
+        icon: "none",
+      });
+      return;
+    }
+    login({
+      username: username.value,
+      password: password.value,
+      tenantId: tenantId.value,
+    });
+  }
+}
+
+/** 获取登录数据 */
+async function login(data) {
+  const res = await myRequest({
+    url: "/system/appLogin",
+    header: {
+      "Content-Type": "application/json;charset=utf-8",
+    },
+    method: "post",
+    data: data,
+    showLoading: true,
+  });
+  uni.setStorageSync("Authorization", res.data.data.access_token);
+  uni.switchTab({
+    url: "/pages/index/index",
+  });
+
+  info(); //调用用户信息方法
+}
+
+/** 获取用户信息 */
+async function info() {
+  const res = await myRequest({
+    url: "/system/getInfo",
+    header: {
+      "Content-Type": "application/json;charset=utf-8",
+    },
+    method: "GET",
+    showLoading: true,
+  });
+
+  useStore.$state.userName = res.data.data.user.userName;
+}
+
+/**
+ * @密码显示隐藏icon图标事件
+ * @icon点击事件
+ */
+function inputIcon() {
+  inputIconBool.value = !inputIconBool.value;
+}
+
+/**
+ * @onLoad
+ */
+onLoad(() => {
+  const token = uni.getStorageSync("Authorization");
+  //需要登录
+  if (token) {
+    uni.switchTab({
+      url: "/pages/index/index",
+    });
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.section {
+  position: fixed;
+  height: 100%;
+  width: 100%;
+  overflow: hidden;
+  .bg {
+    width: 100%;
+    height: 100%;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    z-index: 0;
+    background: #000;
+    .bgImage {
+      width: 100%;
+      height: 100%;
+    }
+  }
+  .top {
+    margin: 90px auto 0px;
+    .logo {
+      width: 110px;
+      margin: 0 auto 44px;
+      display: block;
+    }
+    .title {
+      width: 100%;
+      position: absolute;
+      z-index: 1;
+      font-size: 20px;
+      text-align: center;
+      color: #fff;
+      font-weight: 700;
+    }
+  }
+  .middle {
+    position: absolute;
+    z-index: 1;
+    width: calc(100% - 64px);
+    margin: 40px 32px 0;
+    .switchText {
+      color: #fff;
+      font-size: 18px;
+      margin-top: 19px;
+      width: 100%;
+      display: block;
+    }
+    .submit {
+      height: 48px;
+      line-height: 48px;
+      border-radius: 24px;
+      background: #2a98ff;
+      color: #fff;
+      margin-top: 45px;
+    }
+  }
+  .bottom {
+    position: absolute;
+    width: 100%;
+    bottom: 10px;
+    .title {
+      text-align: center;
+      color: #fff;
+      font-size: 14px;
+    }
+  }
+}
+
+.content {
+  height: 434rpx;
+  text-align: center;
+  position: relative;
+}
+
+.login-box {
+  height: 600rpx;
+  position: relative;
+  top: -150rpx;
+  background: #fff;
+  border-radius: 30rpx;
+  padding: 100rpx 20rpx;
+}
+
+.shadow {
+  box-shadow: 0px 2px 4px rgb(26 26 26 / 10%);
+}
+
+.title {
+  position: absolute;
+  color: #fff;
+  font-size: 60rpx;
+  bottom: 180rpx;
+  display: block;
+  width: 100%;
+}
+
+input,
+button {
+  width: 100%;
+  height: 100rpx;
+  line-height: 100rpx;
+  opacity: 1;
+  border: 1px solid #dbdbdb;
+  border-radius: 100rpx;
+  background: #fff;
+  color: #333;
+  margin: 40rpx 0;
+  font-size: 34rpx;
+}
+
+input {
+  text-indent: 100rpx;
+}
+.submit {
+  background: #4074e7;
+  color: #fff;
+}
+.phone-box,
+.password-box {
+  position: relative;
+}
+.password-box .verify {
+  font-size: 30rpx;
+  color: #999999;
+}
+.left-icon {
+  position: absolute;
+  left: 48rpx;
+  top: 50%;
+  margin-top: -20rpx;
+  line-height: 100%;
+  font-size: 40rpx;
+  color: #7a7a7a;
+}
+.right-icon {
+  position: absolute;
+  right: 48rpx;
+  top: 50%;
+  margin-top: -20rpx;
+  line-height: 100%;
+  font-size: 40rpx;
+}
+.right-icon.verify {
+  margin-top: -10rpx;
+  color: #4074e7;
+}
+.iconfont {
+  color: #999;
+}
+</style>

二进制
src/static/font/FANDOLFANG-REGULAR.OTF


二进制
src/static/font/IMPACT.TTF


+ 84 - 0
src/static/iconfont/iconfont.css

@@ -0,0 +1,84 @@
+/* @font-face {
+  font-family: 'iconfont'; 
+  src: url('https://at.alicdn.com/t/font_2394829_cpwu6e12c4.eot');
+  src: url('https://at.alicdn.com/t/font_2394829_cpwu6e12c4.eot?#iefix') format('embedded-opentype'),
+  url('https://at.alicdn.com/t/font_2394829_cpwu6e12c4.woff2') format('woff2'),
+  url('https://at.alicdn.com/t/font_2394829_cpwu6e12c4.woff') format('woff'),
+  url('https://at.alicdn.com/t/font_2394829_cpwu6e12c4.ttf') format('truetype'),
+  url('https://at.alicdn.com/t/font_2394829_cpwu6e12c4.svg#iconfont') format('svg');
+} */
+
+
+@font-face {
+  font-family: 'iconfont';
+  /* Project id 2394829 */
+  src: url('https://at.alicdn.com/t/font_2394829_ken0vmyss6a.woff2?t=1623131965202') format('woff2'),
+    url('https://at.alicdn.com/t/font_2394829_ken0vmyss6a.woff?t=1623131965202') format('woff'),
+    url('https://at.alicdn.com/t/font_2394829_ken0vmyss6a.ttf?t=1623131965202') format('truetype'),
+}
+
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+
+.icon-xingzhuang8:before {
+  content: "\e66b";
+}
+
+.icon-daochu:before {
+  content: "\e613";
+}
+
+.icon-xiajiantou_huaban:before {
+  content: "\e63d";
+}
+
+.icon-saoyisao:before {
+  content: "\e607";
+}
+
+.icon-dianhua1:before {
+  content: "\e61d";
+}
+
+.icon-daohang:before {
+  content: "\e612";
+}
+
+.icon-youjiantou:before {
+  content: "\e629";
+}
+
+.icon-zhuye:before {
+  content: "\e64e";
+}
+
+.icon-shezhi:before {
+  content: "\e611";
+}
+
+.icon-xiaoxi:before {
+  content: "\e606";
+}
+
+.icon-circulation-full:before {
+  content: "\e858";
+}
+
+.icon-yanzheng:before {
+  content: "\e86a";
+}
+
+.icon-phone:before {
+  content: "\e64f";
+}
+
+.icon-guanbi:before {
+  content: "\e610";
+}

二进制
src/static/iconfont/iconfont.ttf


+ 39 - 0
src/static/iconfont/uciconfont/iconfont.css

@@ -0,0 +1,39 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 3620854 */
+  src: url('iconfont.woff2?t=1662690989920') format('woff2'),
+       url('iconfont.woff?t=1662690989920') format('woff'),
+       url('iconfont.ttf?t=1662690989920') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.ucicon-filter:before {
+  content: "\e7c7";
+}
+
+.ucicon-appstore:before {
+  content: "\e792";
+}
+
+.ucicon-map:before {
+  content: "\e719";
+}
+
+.ucicon-info-circle-fill:before {
+  content: "\e844";
+}
+
+.ucicon-eye:before {
+  content: "\e78f";
+}
+
+.ucicon-eye-close:before {
+  content: "\e8ff";
+}
+

二进制
src/static/iconfont/uciconfont/iconfont.ttf


二进制
src/static/iconfont/uciconfont/iconfont.woff


二进制
src/static/iconfont/uciconfont/iconfont.woff2


二进制
src/static/index/ge1.png


二进制
src/static/index/ge2.png


二进制
src/static/index/ge3.png


二进制
src/static/index/ge4.png


二进制
src/static/login-bg.png


二进制
src/static/login-bg2.png


二进制
src/static/logo.png


二进制
src/static/start.png


二进制
src/static/startUp.png


二进制
src/static/startup.jpeg


二进制
src/static/tabBar/analyse-selected.png


二进制
src/static/tabBar/analyse.png


二进制
src/static/tabBar/feiqi/analyse-selected.png


二进制
src/static/tabBar/feiqi/analyse.png


二进制
src/static/tabBar/feiqi/home-selected.png


二进制
src/static/tabBar/feiqi/home.png


二进制
src/static/tabBar/feiqi/info-selected.png


二进制
src/static/tabBar/feiqi/info.png


二进制
src/static/tabBar/feiqi/setting-selected.png


二进制
src/static/tabBar/feiqi/setting.png


二进制
src/static/tabBar/home-selected.png


二进制
src/static/tabBar/home.png


二进制
src/static/tabBar/info-selected.png


二进制
src/static/tabBar/info.png


二进制
src/static/tabBar/setting-selected.png


二进制
src/static/tabBar/setting.png


+ 13 - 0
src/store/index.js

@@ -0,0 +1,13 @@
+import { createPinia } from "pinia";
+import { createPersistedState } from 'pinia-plugin-persistedstate'
+
+const store = createPinia()
+
+store.use(createPersistedState({
+    serializer: { // 指定参数序列化器
+        serialize: JSON.stringify,
+        deserialize: JSON.parse,
+    }
+}))
+
+export default store

+ 145 - 0
src/store/modules/public.js

@@ -0,0 +1,145 @@
+import { defineStore } from "pinia";
+
+const publicStore = defineStore("public", {
+  state: () => ({
+    leftBtn: true, //左侧收起按钮
+    rightBtn: true, //右侧收起按钮
+
+    mapBool: 1, //1.高德 2.测绘院
+    streetTownList: [
+      { value: "", label: "全区" },
+      { value: "华漕镇", label: "华漕镇" },
+      { value: "虹桥镇", label: "虹桥镇" },
+      { value: "梅陇镇", label: "梅陇镇" },
+      { value: "七宝镇", label: "七宝镇" },
+      { value: "颛桥镇", label: "颛桥镇" },
+      { value: "马桥镇", label: "马桥镇" },
+      { value: "吴泾镇", label: "吴泾镇" },
+      { value: "浦江镇", label: "浦江镇" },
+      { value: "新虹街道", label: "新虹街道" },
+      { value: "古美路街道", label: "古美路街道" },
+      { value: "江川路街道", label: "江川路街道" },
+      { value: "浦锦街道", label: "浦锦街道" },
+      { value: "莘庄镇", label: "莘庄镇" },
+    ],
+    timeList: [
+      new Date().getFullYear() +
+        "-" +
+        (new Date().getMonth() + 1 < 10 ? "0" + (new Date().getMonth() + 1) : "" + (new Date().getMonth() + 1)) +
+        "-" +
+        (new Date().getDate() < 10 ? "0" + new Date().getDate() : new Date().getDate()) +
+        " 00:00:00",
+      new Date().getFullYear() +
+        "-" +
+        (new Date().getMonth() + 1 < 10 ? "0" + (new Date().getMonth() + 1) : "" + (new Date().getMonth() + 1)) +
+        "-" +
+        (new Date().getDate() < 10 ? "0" + new Date().getDate() : new Date().getDate()) +
+        " 23:59:59",
+    ],
+
+    mhjz: [
+      { streetTown: "全区", id: 12, x: 121.4175597, y: 31.119248 },
+      {
+        streetTown: "江川路街道",
+        id: 1201,
+        x: 121.399126538181,
+        y: 31.0099719391863,
+      },
+      {
+        streetTown: "新虹街道",
+        id: 1217,
+        x: 121.319329296294,
+        y: 31.1983901916889,
+      },
+      {
+        streetTown: "古美路街道",
+        id: 1206,
+        x: 121.388451866936,
+        y: 31.1478233480159,
+      },
+      {
+        streetTown: "浦锦街道",
+        id: 1218,
+        x: 121.483929120352,
+        y: 31.089967318558,
+      },
+      {
+        streetTown: "浦江镇",
+        id: 1215,
+        x: 121.524058543447,
+        y: 31.0540039472667,
+      },
+      {
+        streetTown: "吴泾镇",
+        id: 1213,
+        x: 121.454076463728,
+        y: 31.04860402113,
+      },
+      {
+        streetTown: "马桥镇",
+        id: 1214,
+        x: 121.352680027718,
+        y: 31.0213512298508,
+      },
+      {
+        streetTown: "颛桥镇",
+        id: 1209,
+        x: 121.40607138504,
+        y: 31.0612972443508,
+      },
+      {
+        streetTown: "莘庄镇",
+        id: 1207,
+        x: 121.37064864047,
+        y: 31.1154549548722,
+      },
+      {
+        streetTown: "梅陇镇",
+        id: 1212,
+        x: 121.421346814491,
+        y: 31.1069718313722,
+      },
+      {
+        streetTown: "七宝镇",
+        id: 1208,
+        x: 121.350366186317,
+        y: 31.1553292680362,
+      },
+      {
+        streetTown: "虹桥镇",
+        id: 1211,
+        x: 121.37956256207,
+        y: 31.1806219953212,
+      },
+      {
+        streetTown: "华漕镇",
+        id: 1210,
+        x: 121.277541517147,
+        y: 31.2289121171624,
+      },
+      {
+        streetTown: "莘庄工业区",
+        id: 1216,
+        x: 121.376508452784,
+        y: 31.0678185611843,
+      },
+    ],
+
+    arrayList: [], //撒点弹框数据存储
+  }),
+  persist: {
+    // 自定义数据持久化方式
+    // key: 'store-key', //指定key进行存储,此时非key的值不会持久化,刷新就会丢失
+    storage: window ? window.localStorage : uni.setStorageSync(), // 指定换成地址
+    // paths: ['nested.data'],// 指定需要持久化的state的路径名称
+    beforeRestore: (context) => {
+      console.log("Before" + context);
+    },
+    afterRestore: (context) => {
+      console.log("After" + context);
+    },
+  },
+  actions: {},
+});
+
+export default publicStore;

+ 22 - 0
src/store/modules/user.js

@@ -0,0 +1,22 @@
+import { defineStore } from "pinia";
+
+const useStores = defineStore("useStores", {
+  state: () => ({
+    userName: "",
+  }),
+  persist: {
+    // 自定义数据持久化方式
+    // key: 'store-key', 指定key进行存储,此时非key的值不会持久化,刷新就会丢失
+    storage: window ? window.localStorage : uni.setStorageSync(), // 指定换成地址
+    // paths: ['nested.data'],// 指定需要持久化的state的路径名称
+    beforeRestore: (context) => {
+      console.log("Before" + context);
+    },
+    afterRestore: (context) => {
+      console.log("After" + context);
+    },
+  },
+  actions: {},
+});
+
+export default useStores;

+ 127 - 0
src/store/modules/xunJian.js

@@ -0,0 +1,127 @@
+import { defineStore } from "pinia";
+
+const useXunJianStore = defineStore("xunJian", {
+  state: () => ({
+    planTabs: 0, //巡检计划页 tabs切换值
+    siteId: null, //巡检计划页 站点id
+    planSonId: null, //巡检计划页 子计划id
+    planSonId1: null, //巡检计划页 子计划id
+    siteNubmber: null, //巡检计划页 站点号码
+    siteStatus: null, //巡检详情页 定位状态
+    contentArray: {},
+
+    collectDataList: [], //巡检采集
+  }),
+  persist: {
+    // 自定义数据持久化方式
+    // key: 'store-key', 指定key进行存储,此时非key的值不会持久化,刷新就会丢失
+    storage: window ? window.localStorage : uni.setStorageSync(), // 指定换成地址
+    // paths: ['nested.data'],// 指定需要持久化的state的路径名称
+    beforeRestore: (context) => {
+      console.log("Before" + context);
+    },
+    afterRestore: (context) => {
+      console.log("After" + context);
+    },
+  },
+  actions: {
+    getDate() {
+      var date = new Date();
+      var year = date.getFullYear(); //  返回的是年份
+      var month = date.getMonth() + 1; //  返回的月份上个月的月份,记得+1才是当月
+      if (month < 10) {
+        month = "0" + month;
+      }
+      var dates = date.getDate(); //  返回的是几号
+      if (dates < 10) {
+        dates = "0" + dates;
+      }
+      var day = date.getDay(); //  周一返回的是1,周六是6,但是周日是0
+      var arr = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
+      return {
+        year,
+        month,
+        dates,
+        day,
+        arr,
+      };
+    },
+    /**
+     * @处理公共日期格式
+     */
+    formatterDate(date, fmt) {
+      let nowDate = {
+        yyyy: date.getFullYear(), // 年
+        MM: date.getMonth() + 1, // 月份
+        dd: date.getDate(), //日
+        hh: date.getHours(),
+        mm: date.getMinutes(),
+        ss: date.getSeconds(),
+      };
+      if (/(y+)/.test(fmt)) {
+        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
+      }
+      for (var k in nowDate) {
+        if (new RegExp("(" + k + ")").test(fmt)) {
+          fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? nowDate[k] : ("00" + nowDate[k]).substr(("" + nowDate[k]).length));
+        }
+      }
+      return fmt;
+    },
+
+    /**
+     * @统计两个日期之间的月份
+     */
+    getMonths(date1, date2) {
+      //用-分成数组
+      date1 = date1.split("-");
+      date2 = date2.split("-");
+      //获取年,月数
+      var year1 = parseInt(date1[0]),
+        month1 = parseInt(date1[1]),
+        year2 = parseInt(date2[0]),
+        month2 = parseInt(date2[1]),
+        //通过年,月差计算月份差
+        months = (year2 - year1) * 12 + (month2 - month1) + 1;
+      return months;
+    },
+
+    /**
+     * @计算当前坐标和G点坐标的偏差值
+     * @returns
+     */
+    caculateLL(lat1, lng1, lat2, lng2) {
+      var radLat1 = (lat1 * Math.PI) / 180.0;
+      var radLat2 = (lat2 * Math.PI) / 180.0;
+      var a = radLat1 - radLat2;
+      var b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0;
+      var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
+      s = s * 6378.137;
+      s = Math.round(s * 10000) / 10;
+      console.log(s);
+      return s;
+    },
+
+    /**
+     * @数组对象排序
+     * @return
+     * @param {数据} data
+     * @param {0 从小到大 1 从大到小} sort
+     */
+    sortEvent(data, sort) {
+      let arr = [];
+      // 将需要排序的 key, 进行排列
+      let sortKeys = Object.keys(JSON.parse(JSON.stringify(data))).sort((a, b) => {
+        return sort == 0 ? JSON.parse(JSON.stringify(data))[a].sort - JSON.parse(JSON.stringify(data))[b].sort : JSON.parse(JSON.stringify(data))[b].sort - JSON.parse(JSON.stringify(data))[a].sort;
+      });
+      // 循环排列好的 key, 重新组成一个新的数组
+      for (var sortIndex in sortKeys) {
+        arr.push(JSON.parse(JSON.stringify(data))[sortKeys[sortIndex]]);
+      }
+
+      return arr;
+    },
+  },
+});
+
+export default useXunJianStore;

+ 75 - 0
src/uni.scss

@@ -0,0 +1,75 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+/* 颜色变量 */
+@import "@/uni_modules/uview-plus/theme.scss";
+/* 行为相关颜色 */
+$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;

+ 145 - 0
src/utils/api.js

@@ -0,0 +1,145 @@
+// const BASE_URL = "http://172.16.120.165:13200/prod-api"; //本地请求地址
+const BASE_URL = 'http://mobile.usky.cn:8099/prod-api'//线上请求地址
+const websiteUrl = "https://qhome.usky.cn";
+
+// 同时发送异步代码的次数,防止一次点击中有多次请求,用于处理
+let ajaxTimes = 0;
+
+function myRequest(options) {
+  let showLoading = options.showLoading || false;
+
+  // 显示加载中 效果
+  if (showLoading) {
+    ajaxTimes++;
+    uni.showLoading({
+      title: "加载中",
+      mask: true,
+    });
+  }
+
+  return new Promise((resolve, reject) => {
+    uni.request({
+      url: BASE_URL + options.url,
+      method: options.method,
+      data: options.data || {},
+      header: {
+        // 'Content-Type': 'multipart/form-data',//图片上传
+        // 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',//form表单
+        'Content-Type':  'application/json;charset=utf-8',//json串
+        // "Content-Type": options.header["Content-Type"],
+        Authorization: uni.getStorageSync("Authorization"),
+      },
+      success: (res) => {
+        if (res.data.code == 200) {
+          uni.showToast({
+            title: res.data.msg ? res.data.msg : "获取数据失败",
+            icon: "none",
+          });
+        } else if (res.data.code == 401) {
+          uni.removeStorageSync("Authorization");
+          uni.navigateTo({
+            url: "/pages/login/login",
+          });
+        } else if (res.data.status == "ERROR" || res.data.code == 500) {
+          uni.showToast({
+            title: res.data.msg ? res.data.msg : "获取数据失败",
+            icon: "none",
+          });
+        }
+        resolve(res);
+      },
+      fail: (err) => {
+        uni.showModal({
+          showCancel: false,
+          content: "请求接口失败",
+        });
+        // uni.showToast({
+        // 	title: '请求接口失败',
+        // 	icon:"none"
+        // })
+        reject(err);
+      },
+      // 完成之后关闭加载效果
+      complete: () => {
+        if (showLoading) {
+          ajaxTimes--;
+          if (ajaxTimes === 0) {
+            //  关闭正在等待的图标
+            uni.hideLoading();
+          }
+        }
+      },
+    });
+  });
+}
+
+function sendUploadFile(options) {
+  let showLoading = options.showLoading || false;
+
+  // 显示加载中 效果
+  if (showLoading) {
+    ajaxTimes++;
+    uni.showLoading({
+      title: "正在上传图片",
+      mask: true,
+    });
+  }
+
+  return new Promise(function (resolve, reject) {
+    uni.uploadFile({
+      url: BASE_URL + options.url,
+      method: options.method,
+      filePath: options.filePath,
+      name: "file",
+      header: {
+        Authorization: uni.getStorageSync("Authorization"),
+      },
+      success: (res) => {
+        const data = JSON.parse(res.data);
+        if (data.code != 200) {
+          uni.showToast({
+            title: "获取图片成功",
+            icon: "none",
+          });
+        } else if (data.code == 401) {
+          uni.removeStorageSync("Authorization");
+          uni.navigateTo({
+            url: "/pages/login/login",
+          });
+        }
+        resolve(data);
+      },
+      fail: (err) => {
+        uni.showModal({
+          showCancel: false,
+          content: "请求接口失败",
+        });
+        reject(err);
+      },
+      // 完成之后关闭加载效果
+      complete: () => {
+        if (showLoading) {
+          ajaxTimes--;
+          if (ajaxTimes === 0) {
+            //  关闭正在等待的图标
+            uni.hideLoading();
+          }
+        }
+      },
+    });
+  });
+}
+
+/**
+ * @路由拦截器
+ */
+function addInterceptor() {
+  uni.addInterceptor(STRING, OBJECT);
+}
+
+export default {
+  BASE_URL,
+  myRequest,
+  sendUploadFile,
+  websiteUrl,
+};

+ 0 - 0
src/utils/auth.js


+ 52 - 0
src/utils/jssdk.js

@@ -0,0 +1,52 @@
+import BASE_URL from './api.js';
+
+// jwx.js
+//#ifdef H5
+const jweixin = import('weixin-js-sdk')
+//#endif
+export function configWeiXin(callback) {
+	const url = window.location.href.split('#')[0];
+	// const url= "https://s.yxin.tech/hello.html"
+	// start
+	uni.request({
+		// url: "/web/sign.php",
+		// url:"https://s.yxin.tech/sign.php",	
+		url: "https://qhome.usky.cn/USKYZHAF/sign.php",
+		header: {
+			'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
+		},
+		data: {
+			"url": url
+		},
+		method: 'GET',
+		success: (res) => {
+			// console.log('请求的签名的参数')
+			// console.log(res)
+
+			let apiList = [ // 可能需要用到的能力 需要啥就写啥。多写也没有坏处
+				'openLocation',
+				'getLocation',
+				'scanQRCode'
+			];
+			let info = {
+				debug: false, // 调试,发布的时候改为false
+				appId: res.data.appid,
+				nonceStr: res.data.nonceStr,
+				timestamp: parseInt(res.data.timestamp),
+				signature: res.data.sha_str,
+				jsApiList: apiList
+			};
+
+			jweixin.config(info);
+			jweixin.error(err => {
+				alert('config fail:', err);
+				return
+			});
+
+			jweixin.ready(res => {
+				if (callback) callback(jweixin);
+			});
+		}
+	});
+	// end
+}

+ 8 - 0
src/utils/router/config.js

@@ -0,0 +1,8 @@
+export default {
+    //不需要登录的页面,白名单
+    whiteList: [
+        "/pages/login/login",
+    ],
+    //登录页
+    loginPage: "/pages/login/login"
+}

+ 52 - 0
src/utils/router/init.js

@@ -0,0 +1,52 @@
+import config from "./config.js"
+export default function initApp() {
+
+    /**
+     * 页面跳转拦截器
+     */
+    let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"];
+    list.forEach(item => { //用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器
+        uni.addInterceptor(item, {
+            invoke(e) { // 调用前拦截
+
+                //获取用户的token
+                const token = uni.getStorageSync('Authorization')
+
+                let url = e.url.split('?')[0];
+
+                let notNeed = config.whiteList.includes(url)
+                // 如果在whiteList里面就不需要登录
+                if (notNeed) {
+                    return e
+                } else {
+                    //需要登录  
+                    if (!token) {
+                        uni.showToast({
+                            title: '请先登录',
+                            icon: 'none'
+                        })
+                        uni.navigateTo({
+                            url: config.loginPage
+                        })
+                        return false
+
+                    } else {
+                        return e
+                    }
+                }
+
+            },
+            fail(err) { // 失败回调拦截 
+                console.log(err);
+                if (Debug) {
+                    console.log(err);
+                    uni.showModal({
+                        content: JSON.stringify(err),
+                        showCancel: false
+                    });
+                }
+            }
+        })
+    })
+    //添加uniCloud云函数拦截器
+}

+ 26 - 0
vite.config.js

@@ -0,0 +1,26 @@
+import { defineConfig } from "vite";
+import path from "path";
+import uni from "@dcloudio/vite-plugin-uni";
+// https://vitejs.dev/config/
+export default defineConfig(({ mode, command }) => {
+  return {
+    base: "./", // 打包路径
+    server: {
+      open: true, // 启动项目自动弹出浏览器
+      port: 8080, // 启动端口
+    },
+    plugins: [uni()],
+    resolve: {
+      alias: {
+        "@/": path.resolve(__dirname, "src"),
+        "@/static": path.resolve(__dirname, "src/static"),
+        "@/utils": path.resolve(__dirname, "src/utils"),
+      },
+    },
+    configureWebpack: {
+      externals: {
+        AMap: "AMap",
+      },
+    },
+  };
+});

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