jiangniuniu 4 anni fa
parent
commit
f12d78d85c
46 ha cambiato i file con 1868 aggiunte e 184 eliminazioni
  1. 14 8
      App.vue
  2. 1 0
      README.md
  3. 8 6
      components/date-time-pick-group/date-time-pick-group.vue
  4. 1 1
      components/date-time-picker/date-time-picker.vue
  5. 63 0
      components/tm-simple-btn-group/tm-simple-btn-group.vue
  6. 2 2
      components/tm-steps/tm-steps.vue
  7. 3 11
      components/tm-trees/row.vue
  8. 91 89
      manifest.json
  9. 13 0
      package-lock.json
  10. 1 0
      package.json
  11. 286 0
      pages/creatingSituations/components/checkMap.vue
  12. 137 0
      pages/creatingSituations/components/checkMapAdd.vue
  13. 151 0
      pages/creatingSituations/components/checkMapDetail.vue
  14. 284 0
      pages/creatingSituations/components/checkPlan.vue
  15. 170 0
      pages/creatingSituations/components/checkRent.vue
  16. 124 25
      pages/creatingSituations/components/condition.vue
  17. 189 0
      pages/creatingSituations/components/situationPreview.vue
  18. 50 29
      pages/creatingSituations/components/theme.vue
  19. 129 12
      pages/creatingSituations/creatingSituations.vue
  20. 35 0
      pages/creatingSituations/model.js
  21. 26 0
      pages/creatingSituations/server.js
  22. 3 0
      pages/model.js
  23. 0 0
      static/bottom-img.png
  24. 0 0
      static/disable-img.png
  25. 0 0
      static/icon-add-dis.png
  26. 0 0
      static/icon-add.png
  27. 0 0
      static/icon-blueMore.png
  28. 0 0
      static/icon-del.png
  29. 0 0
      static/icon-jinyong.png
  30. 0 0
      static/icon-map-dis.png
  31. 0 0
      static/icon-map.png
  32. 0 0
      static/icon-qiyong.png
  33. 0 0
      static/icon-shang-dis.png
  34. 0 0
      static/icon-shang.png
  35. 0 0
      static/icon-xia-dis.png
  36. 0 0
      static/icon-xia.png
  37. 0 0
      static/incon-more.png
  38. BIN
      static/list-close.png
  39. BIN
      static/list-open.png
  40. 0 0
      static/theme.png
  41. 0 0
      static/theme0.png
  42. 0 0
      static/theme1.png
  43. 0 0
      static/top-img.png
  44. 14 0
      utils/arrFilter.js
  45. 72 0
      utils/dateHandle.js
  46. 1 1
      utils/request.js

+ 14 - 8
App.vue

@@ -36,20 +36,15 @@
 
 <style lang="less">
 	/*每个页面公共css */
-
+	
 	body,
 	uni-app,
 	uni-page,
 	uni-page-wrapper,
 	uni-page-body {
 		height: 100%;
-		font-size: 12.5rpx;
-		line-height: 18.75rpx;
-	}
-
-	body,
-	uni-app,
-	uni-page {
+		font-size: 20rpx;
+		line-height: 30rpx;
 		background-color: #F5F6FA;
 	}
 
@@ -85,4 +80,15 @@
 			color: #3377FF;
 		}
 	}
+	// 新建情境样式start
+	.creatingSituations {
+		.title {
+			padding-bottom: 35rpx;
+			padding-left: 25rpx;
+			font-size: 30rpx;
+			line-height: 45rpx;
+			color: #292C33;
+		}
+	}
+	// 新建情境样式end
 </style>

+ 1 - 0
README.md

@@ -8,6 +8,7 @@
 2. 树形控件:tm-trees。
 3. 底部tabBar:tm-tabbar。
 4. 单选列表组合/下拉式单选列表组合:tm-radio-group。使用步骤看tm-radio-group/README.md
+5. 底部简单双按钮:tm-simple-btn-group。
 
 ### 公共组件的注册方式
 ---

+ 8 - 6
components/date-time-pick-group/date-time-pick-group.vue

@@ -10,7 +10,7 @@
         :pickType="'start'"
         placeholder="开始日期时间"
 			  @change="bindChange" />
-				 <text class="inner">~</text>
+			<text class="inner">~</text>
 			<date-time-picker
 				:fields="fields"
 				:start="dateObj.startTime"
@@ -105,7 +105,7 @@ export default {
 .date-pick {
 	display: flex;
 	align-items: center;
-	height: 25rpx;
+	// height: 25rpx;
 
 	.label {
 		margin-right: 3.12rpx;
@@ -118,11 +118,13 @@ export default {
 		display: flex;
 		justify-content: space-between;
 		align-items: center;
-		width: 238.28rpx;
-		height: 25rpx;
-		background: #ffffff;
-		border-radius: 3.12rpx;
+		border-radius: 5rpx;
 		border: 0.78rpx solid #e1e4ed;
+		padding: 9.37rpx 25rpx;
+		// width: 238.28rpx;
+		// height: 25rpx;
+		white-space: nowrap;
+		background: #ffffff;
 		color: #2e2f33;
 		box-sizing: border-box;
 

+ 1 - 1
components/date-time-picker/date-time-picker.vue

@@ -89,7 +89,7 @@ export default {
       // 设置默认值
       this.setDefaultValue();
     },
-    start(){
+    start(newVal, oldVal){
        if(newVal != oldVal){
         this.setDisabled()
       }

+ 63 - 0
components/tm-simple-btn-group/tm-simple-btn-group.vue

@@ -0,0 +1,63 @@
+<template>
+	<view class="tm-simple-btn-group">
+		<button v-for="(item, index) in options" 
+			@click="changeStep(item.id)"
+			:key="index">{{item.label}}</button>
+	</view>
+</template>
+
+<script>
+	/**
+	 * 底部组件,只有两个按钮的简单组件(只有文字没图标),按钮内容需要自行传入数据
+	 * props:{
+		 * options: [{id:按钮的唯一id,会在点击后返回,label:显示的文本内容}]
+		 * callback: 点击事件返回函数,返回参数是按钮id
+		 * }
+	 */
+	export default {
+		props: {
+			options: {
+				type: Array,
+				default: [
+					{id: 'pre', label: '上一步'},
+					{id: 'next', label: '下一步'}
+				]
+			}
+		},
+		methods: {
+			changeStep: function(type) {
+				this.$emit('callback', type);
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.tm-simple-btn-group {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		display: flex;
+		flex-direction: row;
+		border-top: 0.62rpx solid #DADEE6;
+		width: 100%;
+		height: 75rpx;
+		
+		button {
+			border-radius: 0;
+			width: 50%;
+			height: 100%;
+			font-size: 22.5rpx;
+			line-height: 75rpx;
+			color: #3377FF;
+			background-color: #fff;
+			&:last-child {
+				color: #fff;
+				background-color: #3377FF;
+			}
+			&:after {
+				border: 0;
+			}
+		}
+	}
+</style>

+ 2 - 2
components/tm-steps/tm-steps.vue

@@ -49,7 +49,7 @@
 			flex-direction: row;
 			justify-content: space-between;
 			align-items: center;
-			margin: 37.5rpx 25rpx 50rpx 25rpx;
+			padding: 37.5rpx 25rpx 50rpx 25rpx;
 			
 			.item {
 				display: flex;
@@ -114,7 +114,7 @@
 		}
 		.component-wrap {
 			width: 100%;
-			height: calc(100% - 101.87rpx);
+			height: calc(100% - 160rpx);
 		}
 	}
 </style>

+ 3 - 11
components/tm-trees/row.vue

@@ -27,6 +27,7 @@
 
 <script>
 	import {_stopPropagation} from "../../utils/compatible.js";
+	import {arrFilter} from "../../utils/arrFilter.js";
 	
 	export default {
 		data() {
@@ -61,20 +62,11 @@
 		methods: {
 			rowClick: function() {
 				if(!this.hasChildren) return;
-				this.openKeysHandle(this.keysHandle(this.open, this.openKeys));
+				this.openKeysHandle(arrFilter(this.option.key, this.openKeys));
 			},
 			checkedHandle: function(e) {
 				_stopPropagation(e);
-				this.checkedKeysHandle(this.keysHandle(this.checked, this.checkedKeys));
-			},
-			keysHandle: function(condition, oldKeys) {
-				let keys = [];
-				if(condition) {
-					keys = oldKeys.filter((key)=> key !== this.option.key);
-				} else {
-					keys = [...oldKeys, this.option.key];
-				}
-				return keys;
+				this.checkedKeysHandle(arrFilter(this.option.key, this.checkedKeys));
 			},
 			openKeysHandle: function(arr) {
 				this.$emit('open-keys', arr);

+ 91 - 89
manifest.json

@@ -1,91 +1,93 @@
 {
-	"name" : "TracerMethodology",
-	"appid" : "__UNI__E410614",
-	"description": "",
-	"versionName": "1.0.0",
-	"versionCode": "100",
-	"transformPx": false,
-	"app-plus": { /* 5+App特有相关 */
-		"usingComponents": true,
-		"nvueCompiler": "uni-app",
-		"splashscreen": {
-			"alwaysShowBeforeRender": true,
-			"waiting": true,
-			"autoclose": true,
-			"delay": 0
-		},
-		"modules": { /* 模块配置 */
-
-		},
-		"distribute": { /* 应用发布信息 */
-			"android": { /* android打包配置 */
-				"permissions": [
-					"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
-					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
-					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
-					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
-					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-					"<uses-feature android:name=\"android.hardware.camera\"/>",
-					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
-				]
-			},
-			"ios": { /* ios打包配置 */
-
-			},
-			"sdkConfigs": { /* SDK配置 */
-
-			}
-		}
-	},
-	"quickapp": { /* 快应用特有相关 */
-
-	},
-	"mp-weixin": { /* 小程序特有相关 */
-		"appid": "",
-		"setting": {
-			"urlCheck": false
-		},
-		"usingComponents": true
-	},
-	"h5" : {
-	    "title" : "追踪方法学",
-	    "router" : {
-	        "mode" : "hash",
-	        "base" : "/TracerMethodology/"
-	    },
-	    "devServer" : {
-	        "port" : 8901,
-	        "headers" : {
-	            "Access-Control-Allow-Origin" : "*"
-	        },
-	        "proxy" : {
-	            "/TracerMethodology/api/*" : {
-	                "pathRewrite" : {
-	                    "^/TracerMethodology/api" : "/topro"
-	                },
-	                // "target" : "http://192.168.1.55:8901", // 内网
-	                "target" : "http://192.168.1.45:8088", // 内网
-	                "changeOrigin" : true,
-	                "secure" : false,
-	                "logLevel" : "debug"
-	            }
-	        }
-	    },
-	    "optimization" : {
-	        "treeShaking" : {
-	            "enable" : true
-	        }
-	    },
-	    "networkTimeout" : {
-	        "request" : 5000
-	    }
-	}
+    "name" : "TracerMethodology",
+    "appid" : "__UNI__E410614",
+    "description" : "",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    "app-plus" : {
+        /* 5+App特有相关 */
+        "usingComponents" : true,
+        "nvueCompiler" : "uni-app",
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        "modules" : {},
+        /* 模块配置 */
+        "distribute" : {
+            /* 应用发布信息 */
+            "android" : {
+                /* android打包配置 */
+                "permissions" : [
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            "ios" : {},
+            /* ios打包配置 */
+            "sdkConfigs" : {
+                "ad" : {}
+            }
+        }
+    },
+    /* SDK配置 */
+    "quickapp" : {},
+    /* 快应用特有相关 */
+    "mp-weixin" : {
+        /* 小程序特有相关 */
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false
+        },
+        "usingComponents" : true
+    },
+    "h5" : {
+        "title" : "追踪方法学",
+        "router" : {
+            "mode" : "hash",
+            "base" : "/TracerMethodology/"
+        },
+        "devServer" : {
+            "port" : 8901,
+            "headers" : {
+                "Access-Control-Allow-Origin" : "*"
+            },
+            "proxy" : {
+                "/TracerMethodology/api/*" : {
+                    "pathRewrite" : {
+                        "^/TracerMethodology/api" : ""
+                    },
+                    // "target" : "http://192.168.1.55:8901", // 内网
+                    "target" : "http://192.168.1.45:8088", // 内网
+                    "changeOrigin" : true,
+                    "secure" : false,
+                    "logLevel" : "debug"
+                }
+            }
+        },
+        "optimization" : {
+            "treeShaking" : {
+                "enable" : true
+            }
+        },
+        "networkTimeout" : {
+            "request" : 5000
+        }
+    }
 }

+ 13 - 0
package-lock.json

@@ -14,11 +14,24 @@
       "resolved": "https://registry.npm.taobao.org/moment/download/moment-2.29.1.tgz",
       "integrity": "sha1-sr52n6MZQL6e7qZGnAdeNQBvo9M="
     },
+    "ometa": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npm.taobao.org/ometa/download/ometa-0.2.2.tgz",
+      "integrity": "sha1-9TxHNbptVq9aRrBN+3xDNMWW1E4="
+    },
     "qs": {
       "version": "6.9.6",
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
       "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ=="
     },
+    "scss": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npm.taobao.org/scss/download/scss-0.2.4.tgz",
+      "integrity": "sha1-BA2QPtN8XU+krTOuH9OJrBKk4GU=",
+      "requires": {
+        "ometa": "0.2.2"
+      }
+    },
     "vuex": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",

+ 1 - 0
package.json

@@ -7,6 +7,7 @@
     "crypto-js": "^4.0.0",
     "moment": "^2.29.1",
     "qs": "^6.9.6",
+    "scss": "^0.2.4",
     "vuex": "^3.6.0"
   },
   "devDependencies": {},

+ 286 - 0
pages/creatingSituations/components/checkMap.vue

@@ -0,0 +1,286 @@
+<template>
+	<view class="check-map">
+		<view class="title">请对查核地图进行配置</view>
+		<view class="list">
+			<view class="item" 
+				v-for="(item, index) in list" 
+				:class="{disable: item.status === 'disable'}"
+				@click="detail(item)"
+				:key="index">
+				<view class="title-wrap">
+					<text>{{item.name}}</text>
+					<view>
+						<image src="../../../static/icon-map.png"></image>
+						<text>{{item.deptClassName}}</text>
+					</view>
+				</view>
+				<view class="content">
+					<text>包含{{item.pointCount}}个查核要点,{{item.itemCount}}个查核项目</text>
+					<text>
+						<text v-for="(point, c) in item.pointList" :key="c">
+							{{point.name}};
+						</text>
+					</text>
+				</view>
+				<view class="btn-group">
+					<view class="btn" 
+						v-for="(btn, index) in btnGroupArr" 
+						@click="btnClick($event, btn.id)"
+						:key="index">
+						<image :src="`../../static/icon-${btn.id}${item.status === 'disable' 
+							? 'dis' : ''}.png`"></image>
+						<text>{{btn.label}}</text>
+					</view>
+					<view class="btn">
+						<image :src="`../../static/icon-${creatIcon(item.status)['icon']}.png`">
+						</image>
+						<text>{{ creatIcon(item.status)['label'] }}</text>
+					</view>
+				</view>
+				<view class="add-img-wrap" v-if="item.status === 'add'">
+					<image src="../../../static/top-img.png"></image>
+					<text>新增项</text>
+				</view>
+				<view class="dis-img-wrap" v-if="item.status === 'disable'">
+					<image src="../../../static/disable-img.png"></image>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import { mapState } from "vuex";
+	import {_stopPropagation} from "../../../utils/compatible.js";
+	const btnGroupArr = [
+		{id: 'add', label: '新增'},
+		{id: 'shang', label: '上移'},
+		{id: 'xia', label: '下移'},
+	];
+	export default {
+		data() {
+			return {
+				btnGroupArr,
+				list: [
+					{status: 'normal'},
+					{status: 'add'},
+					{status: 'disable'},
+				]
+			}
+		},
+		computed: {
+			...mapState({
+				checkMap: state => state.creatingSituations.checkMap,
+				checkRent: state => state.creatingSituations.checkRent,
+				condition: state => state.creatingSituations.condition,
+			})
+		},
+		created:function(){
+			if(this.checkMap.list.length === 0) {
+				const {points} = this.checkRent.checkedItem;
+				if(!points) return;
+				let checkPointIds = points.map(({id})=> id);
+				console.log(checkPointIds)
+				this.$store.dispatch({
+					type: 'creatingSituations/commActions',
+					key: 'checkDeptList',
+					data: { 
+						depType: this.condition.depType,
+						checkPointIds,
+					}
+				}).then((data)=> {
+					if(data) this.myCommit('list', data);
+				});
+			}
+		},
+		methods: {
+			creatIcon: function(status) {
+				let obj = {icon: 'jinyong', label: '禁用'};
+				switch(status) {
+					case 'add': 
+						obj = {icon: 'del', label: '删除'};
+						break;
+					case 'disable': 
+						obj = {icon: 'qiyong', label: '启用'};
+						break;
+				}
+				return obj;
+			},
+			detail: function(item) {
+				this.$store.commit({
+					type: 'creatingSituations/comChangeState',
+					key: 'showCheckMapDetail',
+					data: true
+				});
+			},
+			btnClick: function(e, id) {
+				_stopPropagation(e);
+				switch(id) {
+					case 'add': 
+						this.$store.commit({
+							type: 'creatingSituations/comChangeState',
+							key: 'showCheckMapAdd',
+							data: true
+						});
+						break;
+				}
+			},
+			/**
+			 * 更新condition数据
+			 * @param {Object} key 要更新的属性
+			 * @param {Object} value 值
+			 */
+			myCommit: function(key, value) {
+				let data = {...this.checkMap};
+				data[key] = value;
+				this.$store.commit({
+					type: 'creatingSituations/comChangeState', 
+					key: 'checkMap', 
+					data
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.check-map {
+		.list {
+			overflow: hidden;
+			padding: 0 25rpx;
+			.item {
+				position: relative;
+				overflow: hidden;
+				margin-bottom: 25rpx;
+				border-radius: 5rpx;
+				padding-top: 16.25rpx;
+				padding-bottom: 0;
+				width: 100%;
+				background-color: #fff;
+				box-shadow: 0 3.75rpx 12.5rpx 0 rgba(0, 13, 51, 0.1);
+				
+				.title-wrap {
+					display: flex;
+					flex-direction: row;
+					align-items: center;
+					padding: 0 25rpx;
+					>text {
+						font-size: 35rpx;
+						line-height: 52.5rpx;
+						color: #292C33;
+					}
+					>view {
+						display: flex;
+						flex-direction: row;
+						align-items: center;
+						margin-left: 20rpx;
+						border-radius: 17.5rpx;
+						height: 35rpx;
+						font-size: 17.5rpx;
+						line-height: 35rpx;
+						color: #8F9BB3;
+						background-color: #EDF2FA;
+						image {
+							width: 35rpx;
+							height: 35rpx;
+						}
+						text {
+							padding-left: 10rpx;
+							padding-right: 20rpx;
+						}
+					}
+				}
+				.content {
+					display: flex;
+					flex-direction: column;
+					padding: 11.25rpx 25rpx 20rpx;
+					text {
+						overflow: hidden;
+						white-space: nowrap;
+						text-overflow: ellipsis;
+						font-size: 20rpx;
+						line-height: 30rpx;
+						color: #666F80;
+						&:first-child {
+							margin-bottom: 5rpx;
+							font-weight: bold;
+							color: #292C33;
+						}
+					}
+				}
+				.btn-group {
+					display: flex;
+					flex-direction: row;
+					padding: 15rpx 0;
+					width: 100%;
+					height: 77.5rpx;
+					background-color: #FAFBFC;
+					.btn {
+						display: flex;
+						flex-direction: column;
+						align-items: center;
+						justify-content: center;
+						border-right: 1px solid #DADEE6;
+						flex: 1;
+						font-size: 17.5rpx;
+						line-height: 26.25rpx;
+						color: #7A8599;
+						&:last-child {
+							border-right: 0;
+						}
+						image {
+							width: 25rpx;
+							height: 25rpx;
+						}
+					}
+				}
+				.dis-img-wrap,
+				.add-img-wrap {
+					position: absolute;
+					top: 18.75rpx;
+					right: 18.75rpx;
+					width: 93.75rpx;
+					height: 93.75rpx;
+					image {
+						width: 100%;
+						height: 100%;
+					}
+				}
+				.add-img-wrap {
+					top: 0;
+					right: 0;
+					width: 100rpx;
+					height: 35rpx;
+					text {
+						position: absolute;
+						top: 4.37rpx;
+						left: 28.75rpx;
+						font-size: 17.5rpx;
+						line-height: 26.25rpx;
+						color: #fff;
+					}
+				}
+				&.disable {
+					.title-wrap {
+						>text, >view {
+							color: #B8BECC;
+						}
+					}
+					.content {
+						text {
+							color: #B8BECC;
+						}
+					}
+					.btn-group {
+						.btn {
+							color: #B8BECC;
+							&:last-child {
+								color: #7A8599;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 137 - 0
pages/creatingSituations/components/checkMapAdd.vue

@@ -0,0 +1,137 @@
+<template>
+	<view class="modal">
+		<scroll-view scroll-y="true" class="modal-body">
+			<view class="body-content">
+				<text class="top-title">选择要新增的单位</text>
+				<view class="list">
+					<view class="item">
+						<view class="item-title">门诊</view>
+						<view class="chidren">
+							<view class="child" 
+								:class="{active: checkedIds.includes(0)}"
+								@click="changeChecked(0)">
+								<text>挂号处</text>
+								<image v-if="checkedIds.includes(0)" 
+									src="../../../static/bottom-img.png"></image>
+							</view>
+							<view class="child">
+								<text>分诊处</text>
+							</view>
+							<view class="child">
+								<text>挂号处</text>
+							</view>
+							<view class="child">
+								<text>分诊处</text>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<tm-simple-btn-group :options="botmBtnGroup"
+				v-on:callback="btnClick" ></tm-simple-btn-group>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	import {arrFilter} from "../../../utils/arrFilter.js";
+	export default {
+		data() {
+			return {
+				checkedIds: []
+			}
+		},
+		computed: {
+			botmBtnGroup: function() {
+				return [
+					{id: 'cancle', label: '取消'},
+					{id: 'ok', label: `已选${this.checkedIds.length}项,确定新增`}
+				];
+			}
+		},
+		methods: {
+			changeChecked: function(id) {
+				this.checkedIds = arrFilter(id, this.checkedIds);
+			},
+			btnClick: function(id) {
+				if(id === 'ok') {
+					
+				} else {
+					this.$store.commit({
+						type: 'creatingSituations/comChangeState',
+						key: 'showCheckMapAdd',
+						data: false
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.modal {
+		position: absolute;
+		bottom: 0;
+		width: 100%;
+		height: 100%;
+		z-index: 1000;
+		background-color: rgba(18, 20, 26, 0.5);
+		
+		.modal-body {
+			margin-top: 10%;
+			border-radius: 25rpx 25rpx 0 0;
+			padding: 35rpx 40rpx 75rpx;
+			width: 100%;
+			height: 90%;
+			font-size: 22.5rpx;
+			line-height: 33.75rpx;
+			color: #292C33;
+			background-color: #fff;
+			.top-title {
+				font-size: 30rpx;
+				line-height: 45rpx;
+			}
+			.list {
+				margin-top: 25rpx;
+				.item {
+					.item-title {
+						margin-bottom: 3.75rpx;
+						font-size: 25rpx;
+						line-height: 37.5rpx;
+						font-weight: bold;
+					}
+					.chidren {
+						display: flex;
+						flex-direction: row;
+						flex-wrap: wrap;
+						justify-content: space-between;
+						.child {
+							position: relative;
+							display: flex;
+							flex-direction: row;
+							justify-content: center;
+							align-items: center;
+							margin: 10rpx 0;
+							border-radius: 5rpx;
+							width: 200rpx;
+							height: 50rpx;
+							font-weight: 500;
+							background-color: #EBEDF2;
+							image {
+								position: absolute;
+								right: 0;
+								bottom: 0;
+								width: 25rpx;
+								height: 25rpx;
+							}
+							&.active {
+								color: #3377FF;
+								background-color: #E6EEFF;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 151 - 0
pages/creatingSituations/components/checkMapDetail.vue

@@ -0,0 +1,151 @@
+<template>
+	<view class="check-map-detail">
+		<view class="item">
+			<view class="icon-wrap" @click="openChildren(0)">
+				<image :src="`../../static/list-${openItems.includes(0)
+					?'close':'open'}.png`"></image>
+			</view>
+			<view class="content">
+				<view class="content-title" @click="openChildren(0)">疼痛之评估及再评估</view>
+				<view class="children" v-if="openItems.includes(0)">
+					<view class="child">
+						<text>PRN order时间间隔与时机</text>
+						<view class="check-icon-wrap" @click="changeChecked(1)">
+							<image :src="`../../static/check-${checkedIds.includes(1)
+								?'checkbox':'no'}.png`"></image>
+						</view>
+					</view>
+					<view class="child">
+						<text>过敏反应表现</text>
+						<view class="check-icon-wrap">
+							<image src="../../../static/check-no.png"></image>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="item">
+			<view class="icon-wrap" @click="openChildren(1)">
+				<image :src="`../../static/list-${openItems.includes(1)
+					?'close':'open'}.png`"></image>
+			</view>
+			<view class="content">
+				<view class="content-title" @click="openChildren(1)">疼痛之评估及再评估</view>
+				<view class="children" v-if="openItems.includes(1)">
+					<view class="child">
+						<text>PRN order时间间隔与时机</text>
+						<view class="check-icon-wrap">
+							<image src="../../../static/check-no.png"></image>
+						</view>
+					</view>
+					<view class="child">
+						<text>过敏反应表现</text>
+						<view class="check-icon-wrap">
+							<image src="../../../static/check-no.png"></image>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<tm-simple-btn-group :options="botmBtnGroup"
+			v-on:callback="btnClick" ></tm-simple-btn-group>
+	</view>
+</template>
+
+<script>
+	import {arrFilter} from "../../../utils/arrFilter.js";
+	
+	export default {
+		data() {
+			return {
+				openItems: [],
+				checkedIds: [],
+			}
+		},
+		computed: {
+			botmBtnGroup: function() {
+				return [
+					{id: 'cancle', label: '取消'},
+					{id: 'ok', label: `已选${this.checkedIds.length}项,确定`}
+				];
+			}
+		},
+		methods: {
+			openChildren: function(key) {
+				this.openItems = arrFilter(key, this.openItems);
+			},
+			changeChecked: function(id) {
+				this.checkedIds = arrFilter(id, this.checkedIds);
+			},
+			btnClick: function(id) {
+				if(id === 'ok') {
+					
+				} else {
+					this.$store.commit({
+						type: 'creatingSituations/comChangeState',
+						key: 'showCheckMapDetail',
+						data: false
+					});
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="less">
+	.check-map-detail {
+		padding-bottom: 75rpx;
+		width: 100%;
+		height: 100%;
+		.item {
+			display: flex;
+			flex-direction: row;
+			border-top: 1px solid #DADEE6;
+			padding-left: 25rpx;
+			width: 100%;
+			background-color: #fff;
+			.icon-wrap {
+				padding-top: 28.12rpx;
+				padding-right: 23.75rpx;
+				width: 45rpx;
+				height: inherit;
+				image {
+					width: 100%;
+					height: 12.5rpx;
+				}
+			}
+			.content {
+				width: 100%;
+				color: #292C33;
+				line-height: 87.5rpx;
+				.content-title {
+					height: 87.5rpx;
+					font-size: 22.5rpx;
+					font-weight: 500;
+				}
+				.children {
+					width: 100%;
+					.child {
+						display: flex;
+						flex-direction: row;
+						justify-content: space-between;
+						border-top: 1px solid #DADEE6;
+						height: 87.5rpx;
+						.check-icon-wrap {
+							display: flex;
+							flex-direction: row;
+							justify-content: center;
+							align-items: center;
+							width: 75rpx;
+							height: 100%;
+							image {
+								width: 25rpx;
+								height: 25rpx;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 284 - 0
pages/creatingSituations/components/checkPlan.vue

@@ -0,0 +1,284 @@
+<template>
+	<view class="check-plan">
+		<view class="title">请制定查核计划({{showCheckPlan1 ? 1 : 2}}/2)</view>
+		<view class="content1" v-if="showCheckPlan1">
+			<view class="list">
+				<view class="item" v-for="(item, index) in list" :key="index">
+					<view class="text-wrap">
+						<input v-if="item.id === 'custom'" 
+							v-model="item.model" 
+							type="number" 
+							@input="createList"
+							placeholder="自定义" />
+						<text>{{item.label}}</text>
+					</view>
+					<view class="img-wrap" @click="checkModel(item)">
+						<image :src="`../../static/check-${checkedItem.id === item.id 
+							? 'radio': 'no'}.png`"></image>
+					</view>
+				</view>
+			</view>
+			<view class="date-box">
+				<text>起止时间</text>
+				<view>
+					<date-time-pick-group fields="day" 
+						:startTime="startTime()"
+						:startSelectValue="dateObj.start"
+						:endSelectValue="dateObj.end"
+						v-on:changeDate="changeDate"></date-time-pick-group>
+					<image src="../../../static/incon-more.png"></image>
+				</view>
+			</view>
+			<view class="result-box">
+				<text>查核频次</text>
+				<text>{{checkNumber}}</text>
+			</view>
+		</view>
+		<view class="content2" v-else>
+			<view class="top-box">
+				<view class="result-box">
+					<text>开始日期</text>
+					<text>{{dateObj.start}}</text>
+				</view>
+				<view class="date-box">
+					<text>结束日期</text>
+					<view>
+						<date-time-picker fields="day"
+							placeholder="请选择结束日期"
+							pickType="end"
+							:start="startTime()"
+							:defaultValue="dateObj.end"
+							v-on:change="changeDate"></date-time-picker>
+						<image src="../../../static/incon-more.png"></image>
+					</view>
+				</view>
+			</view>
+			<view class="content2-list">
+				<view class="item" v-for="(item, index) in checkList" :key="index">
+					<text>第{{index + 1}}次查核</text>
+					<view class="date-box">
+						<text>开始日期</text>
+						<view>
+							<date-time-picker fields="day"
+								:start="startDate(index)"
+								:end="formateStartEnd(endDate())"
+								placeholder="请选择开始日期"
+								:defaultValue="item"
+								v-on:change="changeChildDate($event, index)"></date-time-picker>
+							<image src="../../../static/incon-more.png"></image>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {dateHandle} from "../../../utils/dateHandle.js";
+	import { mapState } from "vuex";
+	const {dateDiff, getNewData, todayDate, compare} = dateHandle;
+	const list = [
+		{id: 'week', label: '每周', model: 7},
+		{id: 'month', label: '每月', model: 30},
+		{id: 'twoMonth', label: '每两月', model: 60},
+		{id: 'quarter', label: '每季度', model: 90},
+		{id: 'halfAYear', label: '每半年', model: 180},
+		{id: 'custom', label: '天', model: null},
+	];
+	export default {
+		data() {
+			return {
+				list, 
+				checkedItem: list[1], // 选中的取模方式对象
+				dateObj: { // 保存开始日期结束日期的对象
+					start: todayDate(),
+					end: '',
+					dayNum: 0 // 两个日期间隔的天数
+				}, 
+				checkList: [], // 核查计划数组
+			}
+		},
+		computed: {
+			...mapState({
+				showCheckPlan1: state => state.creatingSituations.showCheckPlan1,
+			}),
+			checkNumber: function() { // 查核频次
+				return this.checkList.length;
+			}
+		},
+		methods: {
+			checkModel: function(item) {
+				this.checkedItem = item;
+				this.createList();
+			},
+			/**
+			 * 开始、结束日期变化函数
+			 * @param {Object} date 日期对象
+			 * @param {Object} type 返回类型(start/end)
+			 */
+			changeDate: function(date, type) {
+				this.dateObj[type] = date.f1;
+				const {start, end} = this.dateObj;
+				if(start && end) {
+					this.dateObj.dayNum = dateDiff(start, end);
+					this.createList();
+				}
+			},
+			/**
+			 * 构造计划列表
+			 */
+			createList: function() {
+				const { model } = this.checkedItem;
+				const {start, dayNum} = this.dateObj;
+				if(model && dayNum > 0) { // 确保前两步都做好了
+					let num = Math.floor(dayNum / model);
+					this.checkList = [start];
+					for(let i = 0; i < num - 1; i++) {
+						this.checkList[i+1] = getNewData(this.checkList[i], model);
+					}
+				} else {
+					this.checkList = [];
+				}
+			},
+			/**
+			 * 已经生成的计划日期变化
+			 * @param {Object} date
+			 */
+			changeChildDate: function(date, index) {
+				let newList = this.checkList.slice(0, index); // 不包括index
+				newList[index] = date.f1;
+				const { model } = this.checkedItem;
+				let i = index;
+				// 判断下一个计划开始时间日期不能大于结束的前X(模)天
+				while(compare(this.endDate(), getNewData(newList[i], model))) { 
+					newList[i+1] = getNewData(newList[i], model);
+					i++;
+				}
+				this.checkList = newList;
+			},
+			startTime: function() { // 限制只能从今天开始
+				return this.formateStartEnd(todayDate());
+			},
+			endDate: function() { // 获取能选择的最大日期,取结束日期的前模天
+				let day = -Number(this.checkedItem.model); // 使用负数能取前X天
+				return getNewData(this.dateObj.end, day);
+			},
+			startDate: function(index) { // 子级能选择的最早开始时间
+				if(index > 0) {
+					let day = Number(this.checkedItem.model);
+					return this.formateStartEnd(getNewData(this.checkList[index - 1], day));
+				} else {
+					return this.startTime();
+				}
+			},
+			formateStartEnd: function(str) {
+				return str + ' 00:00';
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.check-plan {
+		font-size: 22.5rpx;
+		line-height: 33.75rpx;
+		color: #292C33;
+		.content1 {
+			.list {
+				padding-left: 25rpx;
+				background-color: #fff;
+				.item {
+					display: flex;
+					flex-direction: row;
+					justify-content: space-between;
+					align-items: center;
+					border-bottom: 1px solid #DADEE6;
+					width: 100%;
+					height: 87.5rpx;
+					.text-wrap {
+						display: flex;
+						flex-direction: row;
+						align-items: center;
+						input {
+							margin-right: 25rpx;
+							width: 75rpx;
+							font-size: 22.5rpx;
+							line-height: 33.75rpx;
+							color: #292C33;
+						}
+					}
+					.img-wrap {
+						display: flex;
+						flex-direction: row;
+						justify-content: center;
+						align-items: center;
+						width: 75rpx;
+						height: 100%;
+						image {
+							width: 25rpx;
+							height: 25rpx;
+						}
+					}
+				}
+			}
+		}
+		.content2 {
+			.top-box {
+				padding-left: 25rpx;
+				background-color: #fff;
+				.date-box,
+				.result-box {
+					padding-left: 0;
+				}
+				.result-box {
+					border-bottom: 1px solid #DADEE6;
+				}
+			}
+			.content2-list {
+				padding-bottom: 25rpx;
+				.item {
+					display: flex;
+					flex-direction: column;
+					margin-top: 19.37rpx;
+					>text {
+						padding-bottom: 9.37rpx;
+						padding-left: 25rpx;
+						color: #666F80;
+					}
+				}
+			}
+			.date-box,
+			.result-box {
+				margin-top: 0;
+			}
+		}
+		.date-box,
+		.result-box {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			margin-top: 15rpx;
+			padding: 0 25rpx;
+			width: 100%;
+			height: 87.5rpx;
+			background-color: #fff;
+			>text:first-child {
+				margin-right: 85rpx;
+				white-space: nowrap;
+				color: #525866;
+			}
+			>view {
+				display: flex;
+				flex-direction: row;
+				justify-content: space-between;
+				align-items: center;
+				width: 100%;
+				image {
+					width: 12.5rpx;
+					height: 21.25rpx;
+				}
+			}
+		}
+	}
+</style>

+ 170 - 0
pages/creatingSituations/components/checkRent.vue

@@ -0,0 +1,170 @@
+<template>
+	<view class="check-rent">
+		<view class="title">请指定负责查核的查核组</view>
+		<view class="list">
+			<view class="item" 
+				v-for="(item, index) in checkRent.list" 
+				:key="index"
+				@click="openItemHandle(item.id)">
+				<view class="img-wrap">
+					<image :src="`../../static/list-${openItems.includes(item.id)
+						?'close':'open'}.png`"></image>
+				</view>
+				<view class="content">
+					<view class="info">
+						<view class="text">
+							<view>{{item.name}}</view>
+							<view>组长:{{item.groupManagerName}}</view>
+						</view>
+						<view class="icon" @click="checkedHandle($event, item)">
+							<image :src="`../../static/check-${checkRent.checkedItem.id === item.id ? 'radio' : 'no'}.png`"></image>
+						</view>
+					</view>
+					<view class="chidren" v-if="openItems.includes(item.id)">
+						<view class="chid-item"> 
+							<view>小组成员</view>
+							<view>{{item.members.join('、')}}</view>
+						</view>
+						<view class="chid-item"> 
+							<view>负责要点</view>
+							<view>
+								<text v-for="(point, c) in item.points" :key="c">
+									{{point.name}};
+								</text>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import { mapState } from "vuex";
+	import {_stopPropagation} from "../../../utils/compatible.js";
+	import {arrFilter} from "../../../utils/arrFilter.js";
+	
+	export default {
+		data() {
+			return {
+				openItems: []
+			}
+		},
+		computed: {
+			...mapState({
+				checkRent: state => state.creatingSituations.checkRent,
+				condition: state => state.creatingSituations.condition,
+			})
+		},
+		created:function(){
+			if(this.checkRent.list.length === 0) {
+				this.$store.dispatch({
+					type: 'creatingSituations/commActions',
+					key: 'checkGroupList',
+					data: { conditionIds: this.condition.conditionIds}
+				}).then((data)=> {
+					if(data) this.myCommit('list', data);
+				});
+			}
+		},
+		methods: {
+			openItemHandle: function(key) {
+				this.openItems = arrFilter(key, this.openItems);
+			},
+			checkedHandle: function(e, item) {
+				_stopPropagation(e);
+				this.myCommit('checkedItem', item);
+			},
+			/**
+			 * 更新condition数据
+			 * @param {Object} key 要更新的属性
+			 * @param {Object} value 值
+			 */
+			myCommit: function(key, value) {
+				let data = {...this.checkRent};
+				data[key] = value;
+				this.$store.commit({
+					type: 'creatingSituations/comChangeState', 
+					key: 'checkRent', 
+					data
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.check-rent {
+		.list {
+			.item {
+				display: flex;
+				flex-direction: row;
+				justify-content: space-between;
+				margin-bottom: 15rpx;
+				padding: 25rpx;
+				padding-right: 0;
+				width: 100%;
+				background-color: #fff;
+				
+				.img-wrap {
+					width: 36.25rpx;
+					image {
+						width: 21.25rpx;
+						height: 12.5rpx;
+					}
+				}
+				.content {
+					width: calc(100% - 36.25rpx);
+					font-size: 20rpx;
+					line-height: 30rpx;
+					color: #666E80;
+					.info {
+						display: flex;
+						flex-direction: row;
+						justify-content: space-between;
+						margin-top: -25rpx;
+						.text {
+							padding-top: 25rpx;
+							view:first-child {
+								margin-bottom: 25rpx;
+								font-size: 25rpx;
+								line-height: 37.5rpx;
+								color: #292C33;
+							}
+						}
+						.icon { // 图标样式,用view包裹img防止挤压变形
+							padding-top: 25rpx;
+							padding-left: 25rpx;
+							width: 75rpx;
+							height: inherit;
+							image {
+								width: 25rpx;
+								height: 25rpx;
+							}
+						}
+					}
+					.chidren {
+						margin-top: 25rpx;
+						border-top: 1px solid #DADEE6;
+						width: 100%;
+						.chid-item {
+							padding-top: 25rpx;
+							padding-right: 25rpx;
+							view {
+								overflow: hidden;
+								white-space: nowrap;
+								text-overflow: ellipsis;
+								&:first-child {
+									padding-bottom: 15rpx;
+									font-weight: bold;
+									color: #292C33;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 124 - 25
pages/creatingSituations/components/condition.vue

@@ -1,43 +1,142 @@
 <template>
 	<view class="condition">
-		
-		<tm-trees :options="options"
-		 :defaultOpen="defaultOpen" 
-		 :defaultChecked="defaultChecked"
+		<view class="title">请选择追踪条件(可多选)</view>
+		<view class="select-btn">
+			<text>选择门诊或急诊</text>
+			<view>
+				<button :class="{active: condition.depType === 1}" 
+					@click="selectBtnHandle(1)">门诊</button>
+				<button :class="{active: condition.depType === 2}" 
+					@click="selectBtnHandle(2)">急诊</button>
+			</view>
+		</view>
+		<tm-trees :options="condition.options"
+		 :defaultOpen="condition.defaultOpen" 
+		 :defaultChecked="condition.conditionIds"
 		 v-on:checked-keys="checkedHandle"></tm-trees>
 	</view>
 </template>
 
 <script>
+	import { mapState } from "vuex";
 	export default {
-		data() {
-			return {
-				options: [
-					{key: 'zhuyuan',label: '住院', children: [
-						{key: 'ICU',label: 'ICU', children: []},
-						{key: 'RCC',label: 'RCC', children: []},
-						{key: 'shengchan',label: '生产', children: [{
-							key: 'ziranchan',label: '自然产'
-						}]},
-					]},{key: 'zhuyuan',label: '住院', children: [
-						{key: 'ICU',label: 'ICU', children: []},
-						{key: 'RCC',label: 'RCC', children: []},
-						{key: 'shengchan',label: '生产', children: [{
-							key: 'ziranchan',label: '自然产'
-						}]},
-					]}
-				],
-				defaultOpen: ['zhuyuan'],
-				defaultChecked: ['ICU']
-			}
+		computed: {
+			...mapState({
+				condition: state => state.creatingSituations.condition,
+				theme: state => state.creatingSituations.theme
+			})
+		},
+		created: function(){
+			if(this.condition.options.length === 0)
+				this.getOptions(this.condition.depType);
 		},
 		methods: {
 			checkedHandle: function(keys) {
-				console.log(keys);
+				this.myCommit('conditionIds', keys);
+			},
+			selectBtnHandle: function(depType) {
+				this.myCommit('depType', depType);
+				this.getOptions(depType);
+			},
+			/**
+			 * 获取树形节点数据
+			 */
+			getOptions: function(depType) {
+				this.checkedHandle([]); // 切换后清空选中
+				const {id} = this.theme;
+				if(id || id === 0) {
+					this.$store.dispatch({
+						type: 'creatingSituations/commActions',
+						key: 'conditions',
+						data: { depType, type: id }
+					}).then((data)=> {
+						if(data) {
+							if(data.length > 0) {
+								this.myCommit('defaultOpen', [data[0].id]);
+							}
+							this.myCommit('options', this.optionsHandle(data));
+						} 
+					});
+				} else {
+					uni.showModal({
+					  title: '温馨提示',
+					  content: '请先选择主题!',
+					  showCancel: false
+					});
+				}
+			},
+			/**
+			 * 增加树形数据字段,以适配公共组件
+			 * @param {Object} data
+			 */
+			optionsHandle: function(data) {
+				let options = data.map((item, i)=>{
+					return {
+						...item,
+						key: item.id,
+						label: item.name,
+						children: this.optionsHandle(item.child)
+					}
+				});
+				return options;
+			},
+			/**
+			 * 更新condition数据
+			 * @param {Object} key 要更新的属性
+			 * @param {Object} value 值
+			 */
+			myCommit: function(key, value) {
+				let data = {...this.condition};
+				data[key] = value;
+				this.$store.commit({
+					type: 'creatingSituations/comChangeState', 
+					key: 'condition', 
+					data
+				});
 			}
 		}
 	}
 </script>
 
 <style lang="less">
+	.select-btn {
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 15rpx;
+		padding: 0 25rpx;
+		width: 100%;
+		height: 87.5rpx;
+		font-size: 22.5rpx;
+		line-height: 33.75rpx;
+		color: #525866;
+		background-color: #fff;
+		
+		view {
+			display: flex;
+			flex-direction: row;
+			
+			button {
+				border: 0;
+				border-radius: 25rpx;
+				padding: 0 46.25rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				color: #292C33;
+				background-color: #EBEFF7;
+				
+				&:first-child {
+					margin-right: 20rpx;
+				}
+				&::after {
+					border: 0;
+				}
+				&.active {
+					color: #fff;
+					background-color: #3377FF;
+				}
+			}
+		}
+	}
 </style>

+ 189 - 0
pages/creatingSituations/components/situationPreview.vue

@@ -0,0 +1,189 @@
+<template>
+	<view class="situation-preview">
+		<view class="title">情境预览</view>
+		<view class="box1">
+			<view class="row1">
+				<view class="top">
+					<text>主题:个案追踪</text>
+					<view>
+						<text>查看查核地图</text>
+						<image src="../../../static/icon-blueMore.png"></image>
+					</view>
+				</view>
+				<view class="list">
+					<text>门诊</text>
+					<text>住院</text>
+					<text>ICU</text>
+				</view>
+			</view>
+			<view class="row2">
+				<view class="item">
+					<text>查核组</text>
+					<text>内科查核二组</text>
+				</view>
+				<view class="item">
+					<text>组长</text>
+					<text>王晓雪</text>
+				</view>
+			</view>
+		</view>
+		<view class="box2">
+			<view>情景名称</view>
+			<view class="input-wrap">
+				<input placeholder="限2~16个中文、英文或数字" />
+			</view>
+		</view>
+		<view class="box2">
+			<view>
+				<text>计划开始前</text>
+				<input placeholder="请输入" type="number" />
+				<text>天的</text>
+				<input placeholder="请输入" type="number" />
+				<text>时提醒</text>
+			</view>
+			<view>
+				<text>启动</text>
+				<input placeholder="请输入" type="number" />
+				<text>天前提醒</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.situation-preview {
+		overflow: hidden;
+		font-size: 22.5rpx;
+		line-height: 33.75rpx;
+		color: #292C33;
+		.box1,
+		.box2 {
+			margin-bottom: 15rpx;
+			padding: 25rpx;
+			width: 100%;
+			background-color: #fff;
+		}
+		.box1 {
+			display: flex;
+			flex-direction: column;
+			.row1 {
+				display: flex;
+				flex-direction: column;
+				margin-bottom: 35rpx;
+				.top {
+					display: flex;
+					flex-direction: row;
+					justify-content: space-between;
+					margin-bottom: 6.25rpx;
+					>text {
+						font-size: 30rpx;
+						line-height: 45rpx;
+					}
+					>view {
+						display: flex;
+						flex-direction: row;
+						align-items: center;
+						font-size: 20rpx;
+						line-height: 30rpx;
+						color: #3377FF;
+						image {
+							margin-left: 10rpx;
+							width: 11.87rpx;
+							height: 20rpx;
+						}
+					}
+				}
+				.list {
+					overflow: hidden;
+					display: flex;
+					flex-direction: row;
+					flex-wrap: wrap;
+					align-items: center;
+					>text {
+						margin-top: 6.25rpx;
+						margin-right: 15rpx;
+						border-radius: 5rpx;
+						padding: 2.5rpx 20.62rpx;
+						font-size: 17.5rpx;
+						line-height: 26.25rpx;
+						color: #7A8499;
+						background-color: #EBEFF7;
+					}
+				}
+			}
+			.row2 {
+				display: flex;
+				flex-direction: row;
+				justify-content: center;
+				align-items: center;
+				.item {
+					display: flex;
+					flex-direction: column;
+					width: 47.5%;
+					text {
+						overflow: hidden;
+						white-space: nowrap;
+						text-overflow: ellipsis;
+						font-size: 25rpx;
+						line-height: 37.5rpx;
+					}
+					text:first-child {
+						margin-bottom: 4.37rpx;
+						font-size: 17.5rpx;
+						line-height: 26.25rpx;
+						color: #666F80;
+					}
+					&:first-child {
+						margin-right: 5%;
+						border-right: 1px solid #DADEE6;
+					}
+				}
+			}
+		}
+		.box2 {
+			padding: 0;
+			padding-left: 25rpx;
+			>view {
+				display: flex;
+				flex-direction: row;
+				align-items: center;
+				border-bottom: 1px solid #DADEE6;
+				height: 87.5rpx;
+				color: #525866;
+				>text {
+					white-space: nowrap;
+					color: #292C33;
+				}
+				>input {
+					padding: 0 9.37rpx;
+					width: 80rpx;
+					height: 33.75rpx;
+					font-size: 22.5rpx;
+					line-height: 33.75rpx;
+					text-align: center;
+				}
+				&:last-child {
+					border-bottom: 0;
+				}
+				&.input-wrap {
+					>input {
+						padding: 0;
+						padding-right: 25rpx;
+						width: 100%;
+						text-align: left;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 50 - 29
pages/creatingSituations/components/theme.vue

@@ -1,34 +1,53 @@
 <template>
 	<view class="theme">
-		<text class="title">请先选定一个主题进行追踪</text>
+		<view class="title">请先选定一个主题进行追踪</view>
 		<view class="content">
-			<view class="item">
+			<view class="item" 
+				v-for="(item, index) in themeList" 
+				@click="checkedHandle(item)"
+				:key="index">
 				<view class="left">
-					<image src="../../../static/gean.png"></image>
+					<image :src="`../../static/theme${item.id}.png`"></image>
 				</view>
 				<view class="right">
-					<text>个案追踪</text>
-					<text>评价诊疗服务的内涵质量以及对各种诊疗规范、临床路径等的执行力</text>
-				</view>
-			</view>
-			<view class="item">
-				<view class="left">
-					<image src="../../../static/xitong.png"></image>
-				</view>
-				<view class="right">
-					<text>系统追踪</text>
-					<text>评价对各种质量与安全管理制度与流程的执行力、医院服务的连贯性及多学科综合的服务能力</text>
+					<text>{{item.title}}</text>
+					<text>{{item.des}}</text>
 				</view>
+				<image v-if="theme.id === item.id" src="../../../static/theme.png"></image>
 			</view>
 		</view>
 	</view>
 </template>
 
 <script>
+	import { mapState } from "vuex";
+	const themeList = [{
+			id: 0, 
+			title: '个案追踪', 
+			des: '评价诊疗服务的内涵质量以及对各种诊疗规范、临床路径等的执行力',
+		},{
+			id: 1, 
+			title: '系统追踪', 
+			des: '评价对各种质量与安全管理制度与流程的执行力、医院服务的连贯性及多学科综合的服务能力',
+	}]
 	export default {
 		data() {
 			return {
-				
+				themeList
+			}
+		},
+		computed: {
+			...mapState({
+				theme: state => state.creatingSituations.theme
+			})
+		},
+		methods: {
+			checkedHandle: function(item) {
+				this.myCommit('theme', item);
+				this.myCommit('stepActive', 1);
+			},
+			myCommit: function(key, data) {
+				this.$store.commit({type: 'creatingSituations/comChangeState',key,data});
 			}
 		}
 	}
@@ -36,29 +55,30 @@
 
 <style lang="less">
 	.theme {
+		overflow: hidden;
 		width: 100%;
-		.title {
-			padding-left: 25rpx;
-			font-size: 30rpx;
-			line-height: 45rpx;
-			color: #292C33;
-		}
 		.content {
 			display: flex;
 			flex-direction: column;
 			align-items: center;
-			margin-top: 25rpx;
 			.item {
+				position: relative;
 				display: flex;
 				flex-direction: row;
-				margin-top: 125rpx;
+				margin: 62.5rpx 0;
 				border-radius: 15rpx;
 				padding: 37.5rpx 50rpx;
 				width: 625rpx;
 				height: 187.5rpx;
-				background: linear-gradient(270deg, #00CCBB 0%, #00CCAA 100%);
-				box-shadow: 0 12.5rpx 12.5rpx 0 rgba(0, 204, 170, 0.2);
-				
+				background: linear-gradient(270deg, #6697FE 0%, #4980F2 100%);
+				box-shadow: 0 12.5rpx 12.5rpx 0 rgba(73, 128, 242, 0.2);
+				>image {
+					position: absolute;
+					top: 10rpx;
+					right: 10rpx;
+					width: 46.87rpx;
+					height: 46.87rpx;
+				}
 				.left {
 					margin-right: 25rpx;
 					image {
@@ -81,9 +101,10 @@
 						}
 					}
 				}
-				&:last-child {
-					background: linear-gradient(270deg, #6697FE 0%, #4980F2 100%);
-					box-shadow: 0 12.5rpx 12.5rpx 0 rgba(73, 128, 242, 0.2);
+				&:first-child {
+					margin-top: 125rpx;
+					background: linear-gradient(270deg, #00CCBB 0%, #00CCAA 100%);
+					box-shadow: 0 12.5rpx 12.5rpx 0 rgba(0, 204, 170, 0.2);
 				}
 			}
 		}

+ 129 - 12
pages/creatingSituations/creatingSituations.vue

@@ -1,37 +1,154 @@
 <template>
 	<view class="creatingSituations">
-		<tm-steps :options="options" :active="active"></tm-steps>
+		<check-map-detail v-if="showCheckMapDetail"></check-map-detail>
+		<view v-else class="page-wrap" 
+			:style="{paddingBottom: stepActive !== 0 ? '75rpx' : 0}">
+			<tm-steps :options="options" :active="stepActive"></tm-steps>
+			<tm-simple-btn-group v-if="stepActive !== 0" 
+				:options="botmBtnGroup"
+				v-on:callback="changeStep"></tm-simple-btn-group>
+		</view>
+		<check-map-add v-if="showCheckMapAdd"></check-map-add>
 	</view>
 </template>
 
 <script>
+	import { mapState } from "vuex";
 	import theme from "./components/theme.vue";
 	import condition from "./components/condition.vue";
+	import checkRent from "./components/checkRent.vue";
+	import checkMap from "./components/checkMap.vue";
+	import checkMapDetail from "./components/checkMapDetail.vue";
+	import checkMapAdd from "./components/checkMapAdd.vue";
+	import checkPlan from "./components/checkPlan.vue";
+	import situationPreview from "./components/situationPreview.vue";
+	
+	const normalBtnGroup = [
+		{id: 'pre', label: '上一步'},
+		{id: 'next', label: '下一步'}
+	];
+	const btnGroupPlan1 = [
+		{id: 'pre', label: '上一步'},
+		{id: 'checkPlanCreate', label: '生成查核计划'}
+	];
+	const btnGroupPlan2 = [
+		{id: 'checkPlanCallback', label: '返回'},
+		{id: 'next', label: '下一步'}
+	];
+	const btnGroupSituationPreview = [
+		{id: 'pre', label: '上一步'},
+		{id: 'situationPreviewOK', label: '完成'}
+	];
 	
 	export default {
 		data() {
 			return {
 				options: [
-					{title: '主题', component: theme},
-					{title: '条件', component: condition},
-					{title: '查核组'},
-					{title: '地图'},
-					{title: '计划'},
-					{title: '配置'},
-				],
-				active: 1
+					{id: 'theme', title: '主题', component: theme},
+					{id: 'condition', title: '条件', component: condition, hint: '追踪条件'},
+					{id: 'checkRent', title: '查核组', component: checkRent, hint: '查核组'},
+					{id: 'checkMap', title: '地图', component: checkMap, hint: '地图'},
+					{id: 'checkPlan', title: '计划', component: checkPlan, hint: '计划'},
+					{id: 'situationPreview', title: '预览', component: situationPreview},
+				]
+			}
+		},
+		computed: {
+			...mapState({
+				showCheckMapDetail: state => state.creatingSituations.showCheckMapDetail,
+				showCheckMapAdd: state => state.creatingSituations.showCheckMapAdd,
+				showCheckPlan1: state => state.creatingSituations.showCheckPlan1,
+				stepActive: state => state.creatingSituations.stepActive,
+				condition: state => state.creatingSituations.condition,
+				checkRent: state => state.creatingSituations.checkRent,
+			}),
+			botmBtnGroup: function() {
+				if(this.stepActive === 4) {
+					if(this.showCheckPlan1) {
+						return btnGroupPlan1;
+					} else {
+						return btnGroupPlan2;
+					}
+				} else if(this.stepActive === 5) {
+					return btnGroupSituationPreview;
+				} else {
+					return normalBtnGroup;
+				}
 			}
 		},
 		methods: {
-			
+			changeStep: function(id) {
+				switch(id) {
+					case 'pre': // 上一步
+						if(this.stepActive > 0) 
+							this.myCommit('stepActive', this.stepActive - 1);
+						break;
+					case 'next': // 下一步
+						if(this.stepActive < this.options.length) 
+							this.nextHandle(this.stepActive);
+						break;
+					case 'checkPlanCreate': // 生成查核计划
+						this.myCommit('showCheckPlan1', false);
+						break;
+					case 'checkPlanCallback': // 生成查核计划-返回
+						this.myCommit('showCheckPlan1', true);
+						break;
+				}
+			},
+			/**
+			 * 处理【下一步】逻辑
+			 */
+			nextHandle: function(stepActive) {
+				let flage = false;
+				switch(stepActive) {
+					case 1: 
+						flage = this.errorHandle(this.condition.conditionIds.length > 0, 1);
+						break;
+					case 2: 
+						const {points} = this.checkRent.checkedItem;
+						let condition = this.checkRent.checkedItem.id !== null && points;
+						flage = this.errorHandle(condition, 2);
+						break;
+				}
+				if(flage) this.myCommit('stepActive', stepActive + 1);
+			},
+			/**
+			 * 错误处理,满足条件返回true
+			 * @param {Object} condition 条件
+			 * @param {Object} index 当前下标
+			 */
+			errorHandle: function(condition, index) {
+				if(condition) {
+					return true;
+				} else {
+					uni.showModal({
+						title: '温馨提示',
+						content: `请先选择${this.options[index].hint}!`,
+						showCancel: false
+					});
+					return false;
+				}
+			},
+			myCommit: function(key, data) {
+				this.$store.commit({type: 'creatingSituations/comChangeState',key,data});
+			}
+		},
+		components: {
+			checkMapDetail,
+			checkMapAdd
 		}
 	}
 </script>
 
 <style lang="less">
-		.creatingSituations {
+	.creatingSituations {
+		width: 100%;
+		height: 100%;
+		background-color: #F5F6FA;
+		.page-wrap {
+			padding-bottom: 75rpx;
 			width: 100%;
 			height: 100%;
-			background-color: #F5F6FA;
 		}
+	}
 </style>

+ 35 - 0
pages/creatingSituations/model.js

@@ -0,0 +1,35 @@
+import { commServer } from './server.js';
+
+export default {
+  namespaced: true,
+  state: {
+		showCheckMapDetail: false,
+		showCheckMapAdd: false,
+		showCheckPlan1: true,
+		stepActive: 0, // 步骤进度
+		theme: {id: null, title: null, des: null}, // 主题选中数据(id: 0个案 1系统)
+		condition: { // 条件页面数据
+			options: [], // 树形节点数据
+			conditionIds: [], // 选中的key
+			depType: 1, // 门急诊类型 1-门诊 2-急诊
+			defaultOpen: [], // 默认展开的项
+		},
+		checkRent: { // 查核组页面数据
+			list: [],
+			checkedItem: {id: null}
+		},
+		checkMap: { // 查核地图数据
+			list: [], // 列表数据
+		}
+  },
+  mutations: {
+		comChangeState(state, {key, data}) {
+			state[key] = data;
+		},
+  },
+  actions: {
+		commActions({ commit, state }, { key, data }) {
+      return commServer(key, data);
+		},
+  }
+}

+ 26 - 0
pages/creatingSituations/server.js

@@ -0,0 +1,26 @@
+import { creatRequest } from '../../utils/request.js';
+
+const requestList = {
+  // 获取条件树
+  conditions: {
+    method: 'GET',
+    url: 'common/conditions',
+		// successMessage: '',
+		// needLoading: false // 还有这两个参数,但不是必传的,默认loading
+  }, 
+	// 查核组列表
+  checkGroupList: {
+    method: 'POST',
+    url: 'situation/checkGroupList',
+  },
+	// 查核地图列表
+  checkDeptList: {
+    method: 'POST',
+    url: 'situation/checkDeptList',
+  },
+};
+
+export const commServer = (key, data) => {
+  let obj = requestList[key];
+  return creatRequest(obj, data);
+}

+ 3 - 0
pages/model.js

@@ -4,6 +4,8 @@ import roleSwitching from './role-switching/model.js';
 import configure from './configure/model.js';
 import messages from './messages/model.js';
 import mission from './mission/model.js';
+import creatingSituations from "./creatingSituations/model.js";
+
 export default module = {
   login,
   configure,
@@ -11,4 +13,5 @@ export default module = {
   roleSwitching,
   messages,
   mission,
+	creatingSituations
 }

+ 0 - 0
static/蓝色勾选.png → static/bottom-img.png


+ 0 - 0
static/禁用标志.png → static/disable-img.png


+ 0 - 0
static/icon新增(禁用).png → static/icon-add-dis.png


+ 0 - 0
static/icon新增.png → static/icon-add.png


+ 0 - 0
static/蓝色查看更多_.png → static/icon-blueMore.png


+ 0 - 0
static/icon删除.png → static/icon-del.png


+ 0 - 0
static/icon禁用.png → static/icon-jinyong.png


+ 0 - 0
static/icon地点(禁用).png → static/icon-map-dis.png


+ 0 - 0
static/icon地点.png → static/icon-map.png


+ 0 - 0
static/icon启用.png → static/icon-qiyong.png


+ 0 - 0
static/icon上移(禁用).png → static/icon-shang-dis.png


+ 0 - 0
static/icon上移.png → static/icon-shang.png


+ 0 - 0
static/icon下移(禁用).png → static/icon-xia-dis.png


+ 0 - 0
static/icon下移.png → static/icon-xia.png


+ 0 - 0
static/查看更多_.png → static/incon-more.png


BIN
static/list-close.png


BIN
static/list-open.png


+ 0 - 0
static/主题勾选.png → static/theme.png


+ 0 - 0
static/gean.png → static/theme0.png


+ 0 - 0
static/xitong.png → static/theme1.png


+ 0 - 0
static/绿色角标.png → static/top-img.png


+ 14 - 0
utils/arrFilter.js

@@ -0,0 +1,14 @@
+/**
+ * 判断原来的数组里是否有某个值,有就删除,没有就添加,然后返回新数组。
+ * 千里及
+ * 2021.2.2
+ */
+export const arrFilter = (key, oldKeys) => {
+	let keys = [];
+	if(oldKeys.includes(key)) {
+		keys = oldKeys.filter((item)=> item !== key);
+	} else {
+		keys = [...oldKeys, key];
+	}
+	return keys;
+}

+ 72 - 0
utils/dateHandle.js

@@ -0,0 +1,72 @@
+/**
+ * 千里及
+ * 2021.2.3
+ * 处理日期的对象
+ */
+export const dateHandle = {
+	/**
+	 * 获取今天的日期时间串
+	 */
+	todayDate: function() {
+		var date = new Date();
+		var year = date.getFullYear();
+		var month = date.getMonth() + 1;
+		var day = date.getDate();
+		return year + "-" + dateHandle.add0(month) + "-" + dateHandle.add0(day);
+	},
+	/**
+	 * 计算两个日期之间相差的天数
+	 * @param {Object} sDate1
+	 * @param {Object} sDate2
+	 */
+	dateDiff: function(sDate1, sDate2) {
+		if(sDate1 == sDate2){
+			return 0;
+		}
+		if(!sDate1){
+			var date = new Date();
+			var year = date.getFullYear();
+			var month = date.getMonth()+1;
+			var day = date.getDate();
+			sDate1 = year + "-" + month + "-" + day;
+		}
+		var oDate1, oDate2, iDays ; 
+		oDate1 = dateHandle.createDate(sDate1);
+		oDate2 = dateHandle.createDate(sDate2);
+		//把相差的毫秒数转换为天数  
+		iDays  =  parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24);
+		return  iDays;  
+	},
+	/**
+	 * 计算指定日期之后X天数的日期
+	 * @param {Object} dateTemp
+	 * @param {Object} days
+	 */
+	getNewData: function(dateTemp, days) {  
+		var nDate = dateHandle.createDate(dateTemp);
+		var millSeconds = Math.abs(nDate) + (days * 24 * 60 * 60 * 1000);  
+		var rDate = new Date(millSeconds);
+		var year = rDate.getFullYear();  
+		var month = rDate.getMonth() + 1;  
+		var date = rDate.getDate();  
+		return year + "-" + dateHandle.add0(month) + "-" + dateHandle.add0(date); 
+	},
+	/**
+	 * 比较第一个日期是否大于第二个
+	 * @param {Object} date1
+	 * @param {Object} date2
+	 */
+	compare: function(date1, date2) {
+		var oDate1 = dateHandle.createDate(date1);
+	 	var oDate2 = dateHandle.createDate(date2);
+		return oDate1.getTime() > oDate2.getTime();
+	},
+	createDate: function(str) {
+		var dateTemp = str.split("-");
+		return new Date(dateTemp[0], Number(dateTemp[1]) - 1, dateTemp[2]);
+	},
+	add0: function(num) {
+		if (Number(num) < 10) num = "0" + num; 
+		return num;
+	}
+}

+ 1 - 1
utils/request.js

@@ -116,7 +116,7 @@ function notifyException(resArr, additional) {
       uni.showModal({
         title: '提示',
         content: '登录过期,请重新登录!',
-        success: function(_res) {
+        success: function (_res) {
           if (_res.confirm) {
             LoginExpired();
           } else if (_res.cancel) {