Bladeren bron

Merge branch 'master' of ssh://1582597470426922.onaliyun.com@s1.nsloop.com:29418/web_TracerMethodology

yuwenfen 4 jaren geleden
bovenliggende
commit
b51c8e8791

+ 14 - 0
README.md

@@ -0,0 +1,14 @@
+### 项目结构:
+---
+1. 公共样式写在App.vue;
+
+### 公共组件说明:
+---
+1. 步骤条:tm-steps,详细传参说明在组件内部。
+2. 树形控件:tm-trees。
+
+### 公共组件的注册方式 
+---
+ 1. 在main.js中全局注册;
+ 2. 在components目录下创建文件夹=文件名的组件,会自动全局注册,但是需要注意:在模板中使用的名字也必须与定义的名字一致,比如定义了n-navigation/n-navigation.vue组件,必须是<n-navigation></n-navigation>;因为标签推荐kebab-case方式,所以定义的公共组件也推荐这种命名方式
+ 

+ 22 - 10
components/lxh-steps/lxh-steps.vue → components/tm-steps/tm-steps.vue

@@ -1,6 +1,6 @@
 <template>
-	<view class="lxh-steps">
-		<view class="lxh-steps-top">
+	<view class="tm-steps">
+		<view class="tm-steps-top">
 			<view class="item" v-for="(item, index) in options" 
 				:style="{flex: index === 0 ? 'none' : 1}" 
 				:class="{active: active === index, over: active > index}"
@@ -9,30 +9,42 @@
 				<view class="content">
 					<view class="content-top">
 						<image v-if="active > index" 
-							src="../../static/creatingSituations/steps-over.png"></image>
+							src="../../static/steps-over.png"></image>
 						<view v-else>{{ index + 1 }}</view>
 					</view>
 					<text>{{ item.title }}</text>
 				</view>
 			</view>
 		</view>
-		<component class="lxh-steps-content" 
-			v-bind:is="options[active].component"></component>
+		<scroll-view scroll-y="true" class="component-wrap">
+			<component v-bind:is="options[active].component"></component>
+		</scroll-view>
 	</view>
 </template>
 
 <script>
+	/**
+	 * 步骤条
+	 * 参数说明:
+	 * options:{
+		 * title: '显示的文字',
+		 * component: '内容组件(传组件对象或者全局注册过的组件名)'
+		}
+	 * active:当前进度,从0开始
+	 */
 	export default {
 		props: ['options', 'active']
 	}
 </script>
 
 <style lang="less">
-	.lxh-steps {
+	.tm-steps {
 		display: flex;
 		flex-direction: column;
-		flex: 1;
-		.lxh-steps-top {
+		width: 100%;
+		height: 100%;
+		
+		.tm-steps-top {
 			display: flex;
 			flex-direction: row;
 			justify-content: space-between;
@@ -100,9 +112,9 @@
 				}
 			}
 		}
-		.lxh-steps-content {
+		.component-wrap {
 			width: 100%;
-			height: 100%;
+			height: calc(100% - 101.87rpx);
 		}
 	}
 </style>

+ 141 - 0
components/tm-trees/row.vue

@@ -0,0 +1,141 @@
+<template>
+	<view class="row">
+		<view class="content-wrap" @click="rowClick">
+			<view class="left">
+				<view>
+					<image class="left-icon" 
+						:style="{width: hasChildren ? '25rpx' : '20rpx'}"
+						:src="`../../static/${leftIcon}.png`"></image>
+				</view>
+				<text>{{ option.label }}</text>
+			</view>
+			<view v-if="!hasChildren" class="right" @click="checkedHandle">
+				<image :src="`../../static/${rightIcon}.png`"></image>
+			</view>
+		</view>
+		<view class="children-wrap" v-if="open">
+			<tm-trees-row v-for="(item,index) in option.children" 
+				:option="item" 
+				:openKeys="openKeys"
+				:checkedKeys="checkedKeys"
+				v-on:open-keys="openKeysHandle"
+				v-on:checked-keys="checkedKeysHandle"
+				:key="index"/>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {_stopPropagation} from "../../utils/compatible.js";
+	
+	export default {
+		data() {
+			return {}
+		},
+		props: ['option', 'openKeys', 'checkedKeys'],
+		computed: {
+			hasChildren: function() {
+				return this.option.children && this.option.children.length > 0;
+			},
+			open: function() {
+				return this.hasChildren && this.openKeys.includes(this.option.key);
+			},
+			checked: function() {
+				return this.checkedKeys.includes(this.option.key);
+			},
+			leftIcon: function() {
+				let iconName = 'parent-open';
+				if(this.hasChildren) {
+					if(this.open) {
+						iconName = 'parent-close';
+					}
+				} else {
+					iconName = 'child'
+				}
+				return iconName;
+			},
+			rightIcon: function() { 
+				return this.checked ? 'check-checkbox' : 'check-no';
+			}
+		},
+		methods: {
+			rowClick: function() {
+				if(!this.hasChildren) return;
+				this.openKeysHandle(this.keysHandle(this.open, 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;
+			},
+			openKeysHandle: function(arr) {
+				this.$emit('open-keys', arr);
+			},
+			checkedKeysHandle: function(arr) {
+				this.$emit('checked-keys', arr);
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.row {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		padding-left: 25rpx;
+		width: 100%;
+		background-color: #fff;
+		
+		.content-wrap {
+			display: flex;
+			flex-direction: row;
+			justify-content: space-between;
+			align-items: center;
+			border-bottom: 0.62rpx solid #DADEE6;
+			width: 100%;
+			height: 87.5rpx;
+			font-size: 22.5rpx;
+			line-height: 33.75rpx;
+			color: #292C33;
+			
+			.left {
+				display: flex;
+				flex-direction: row;
+				align-items: center;
+				view {
+					margin-right: 20rpx;
+					height: 28rpx;
+					image {
+						width: 25rpx;
+						height: 22.5rpx;
+					}
+				}
+			}
+			.right {
+				display: flex;
+				flex-direction: row;
+				justify-content: center;
+				align-items: center;
+				width: 87.5rpx;
+				height: 87.5rpx;
+				image {
+					width: 25rpx;
+					height: 25rpx;
+				}
+			}
+		}
+		.children-wrap {
+			width: 100%;
+			padding-left: 77.5rpx;
+		}
+	}
+</style>

+ 64 - 0
components/tm-trees/tm-trees.vue

@@ -0,0 +1,64 @@
+<template>
+	<view class="tm-trees">
+		<tm-trees-row v-for="(item,index) in options" 
+			:option="item" 
+			:openKeys="openKeys"
+			:checkedKeys="checkedKeys"
+			v-on:open-keys="openKeysHandle"
+			v-on:checked-keys="checkedKeysHandle"
+			:key="index"/>
+	</view>
+</template>
+
+<script>
+	/**
+	 * 树形控件,支持多选
+	 * 千里及
+	 * 2021.2.1
+	 * props: {
+		 * options:树节点数据,
+		 * defaultOpen:默认展开的项(节点key),
+		 * defaultChecked:默认选中的项(节点key),
+		 * open-keys:展开事件监听,会返回展开项的key,
+		 * checked-keys:选中事件监听,返回选中项的key
+		 * }
+	 */
+	export default {
+		data() {
+			return {
+				openKeys: [],
+				checkedKeys: []
+			};
+		},
+		props: ['options', 'defaultOpen', 'defaultChecked'],
+		created:function(){
+			this.openKeys = this.defaultOpen || [];
+			this.checkedKeys = this.defaultChecked || [];
+		},
+		watch: {
+			defaultOpen: function(open) {
+				this.openKeys = open;
+			},
+			defaultChecked: function(checked) {
+				this.checkedKeys = checked;
+			}
+		},
+		methods: {
+			openKeysHandle: function(keys) {
+				this.openKeys = keys;
+				this.$emit('open-keys', keys);
+			},
+			checkedKeysHandle: function(keys) {
+				this.checkedKeys = keys;
+				this.$emit('checked-keys', keys);
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.tm-trees {
+		width: 100%;
+		height: 100%;
+	}
+</style>

+ 11 - 2
main.js

@@ -1,11 +1,20 @@
 import Vue from 'vue'
 import App from './App'
+import { store } from './store/index.js';
+import dateTimePickGroup from './components/date-time-pick-group/date-time-pick-group.vue';
+import dateTimePick from './components/date-time-pick/date-time-pick.vue';
+import row from "./components/tm-trees/row.vue";
 
-Vue.config.productionTip = false
+Vue.config.productionTip = false;
+Vue.prototype.$store = store;
+Vue.component('com-date-pick-group', dateTimePickGroup);
+Vue.component('com-date-time-pick', dateTimePick);
+Vue.component('tm-trees-row', row);
 
 App.mpType = 'app'
 
 const app = new Vue({
-    ...App
+  ...App,
+  store
 })
 app.$mount()

+ 21 - 0
package.json

@@ -0,0 +1,21 @@
+{
+  "name": "web_tracermethodology",
+  "version": "1.0.0",
+  "description": "",
+  "main": "main.js",
+  "dependencies": {
+    "moment": "^2.29.1",
+    "qs": "^6.9.6",
+    "vuex": "^3.6.0"
+  },
+  "devDependencies": {},
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "ssh://yuwenfen@1582597470426922.onaliyun.com@s1.nsloop.com:29418/web_NurseSide.git"
+  },
+  "author": "",
+  "license": "ISC"
+}

+ 43 - 0
pages/creatingSituations/components/condition.vue

@@ -0,0 +1,43 @@
+<template>
+	<view class="condition">
+		
+		<tm-trees :options="options"
+		 :defaultOpen="defaultOpen" 
+		 :defaultChecked="defaultChecked"
+		 v-on:checked-keys="checkedHandle"></tm-trees>
+	</view>
+</template>
+
+<script>
+	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']
+			}
+		},
+		methods: {
+			checkedHandle: function(keys) {
+				console.log(keys);
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+</style>

+ 2 - 2
pages/creatingSituations/components/theme.vue

@@ -4,7 +4,7 @@
 		<view class="content">
 			<view class="item">
 				<view class="left">
-					<image src="../../../static/creatingSituations/gean.png"></image>
+					<image src="../../../static/gean.png"></image>
 				</view>
 				<view class="right">
 					<text>个案追踪</text>
@@ -13,7 +13,7 @@
 			</view>
 			<view class="item">
 				<view class="left">
-					<image src="../../../static/creatingSituations/xitong.png"></image>
+					<image src="../../../static/xitong.png"></image>
 				</view>
 				<view class="right">
 					<text>系统追踪</text>

+ 11 - 6
pages/creatingSituations/creatingSituations.vue

@@ -1,24 +1,25 @@
 <template>
-	<view>
-		<lxh-steps :options="options" :active="active"></lxh-steps>
+	<view class="creatingSituations">
+		<tm-steps :options="options" :active="active"></tm-steps>
 	</view>
 </template>
 
 <script>
 	import theme from "./components/theme.vue";
+	import condition from "./components/condition.vue";
 	
 	export default {
 		data() {
 			return {
 				options: [
 					{title: '主题', component: theme},
-					{title: '条件'},
+					{title: '条件', component: condition},
 					{title: '查核组'},
 					{title: '地图'},
 					{title: '计划'},
 					{title: '配置'},
 				],
-				active: 0
+				active: 1
 			}
 		},
 		methods: {
@@ -27,6 +28,10 @@
 	}
 </script>
 
-<style>
-
+<style lang="less">
+		.creatingSituations {
+			width: 100%;
+			height: 100%;
+			background-color: #F5F6FA;
+		}
 </style>

+ 0 - 0
static/creatingSituations/多选-已选状态.png → static/check-checkbox.png


+ 0 - 0
static/creatingSituations/勾选-未选状态.png → static/check-no.png


BIN
static/check-radio.png


BIN
static/child.png


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


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


BIN
static/icon上移(禁用).png


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


BIN
static/icon下移(禁用).png


BIN
static/icon删除.png


BIN
static/icon启用.png


BIN
static/icon地点.png


BIN
static/icon地点(禁用).png


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


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


BIN
static/icon禁用.png


+ 0 - 0
static/creatingSituations/收起.png → static/parent-close.png


BIN
static/parent-open.png


+ 0 - 0
static/creatingSituations/steps-over.png → static/steps-over.png


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


BIN
static/主题勾选.png


+ 0 - 0
static/creatingSituations/导航栏返回.png → static/导航栏返回.png


BIN
static/展开(查核组).png


BIN
static/收起(查核组).png


BIN
static/查看更多_.png


BIN
static/禁用标志.png


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


BIN
static/蓝色勾选.png


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


+ 10 - 0
utils/compatible.js

@@ -0,0 +1,10 @@
+/**
+ * 做兼容相关的函数集文件
+ */
+
+/**
+ * 阻止事件冒泡
+ */
+export const _stopPropagation = (e) => {
+	window.event ? window.event.cancelBubble = true : e.stopPropagation();
+}