Explorar el Código

单选列表组合/下拉式单选列表组合封装

yuwenfen hace 4 años
padre
commit
e08628a9c6

+ 13 - 5
App.vue

@@ -36,7 +36,7 @@
 
 <style lang="less">
 	/*每个页面公共css */
-	
+
 	body,
 	uni-app,
 	uni-page,
@@ -46,19 +46,19 @@
 		font-size: 12.5rpx;
 		line-height: 18.75rpx;
 	}
-	
+
 	body,
 	uni-app,
 	uni-page {
 		background-color: #F5F6FA;
 	}
-	
+
 	view,
 	label,
 	scroll-view {
 		box-sizing: border-box;
 	}
-	
+
 	// 底部固定的按钮
 	.fixed-buttom-btn {
 		position: fixed;
@@ -71,10 +71,18 @@
 		width: 100%;
 		height: 75rpx;
 		background-color: #3377FF;
-		
+
 		.btn-text {
+			flex: 1;
 			font-size: 22.5rpx;
 			color: #fff;
+			text-align: center;
+		}
+
+		.btn-text.cancle {
+			line-height: 76.25rpx;
+			background-color: #FFFFFF;
+			color: #3377FF;
 		}
 	}
 </style>

+ 2 - 3
README.md

@@ -7,10 +7,9 @@
 1. 步骤条:tm-steps,详细传参说明在组件内部。
 2. 树形控件:tm-trees。
 3. 底部tabBar:tm-tabbar。
-4. 单选列表组合:tm-radio-group。
+4. 单选列表组合/下拉式单选列表组合:tm-radio-group。使用步骤看tm-radio-group/README.md
 
-### 公共组件的注册方式 
+### 公共组件的注册方式
 ---
  1. 在main.js中全局注册;
  2. 在components目录下创建文件夹=文件名的组件,会自动全局注册,但是需要注意:在模板中使用的名字也必须与定义的名字一致,比如定义了n-navigation/n-navigation.vue组件,必须是<n-navigation></n-navigation>;因为标签推荐kebab-case方式,所以定义的公共组件也推荐这种命名方式
- 

+ 108 - 0
components/tm-radio-group/README.md

@@ -0,0 +1,108 @@
+#### 使用方式
+
+#####  一: 单选列表组合 type="default"(如指派改善任务)
+<!-- 在 template 中使用组件 -->
+```html
+	<tm-radio-group
+    :list="list"
+    label="改善工具"
+    :defaultValue='defaultValue'
+    @change="changeSelect"
+    :setting="{
+      value: 'value',
+      name: 'label'
+    }"
+  />
+```
+<!--  在script中写入 -->
+```js
+	export default {
+		data() {
+			return {
+        // 默认选中
+        defaultValue: 1,
+        // 渲染的原数据
+				list: [
+					{value: 1, label: 'PDCA1'},
+					{value: 2, label: 'PDCA2'},
+					{value: 3, label: 'PDCA3'},
+					{value: 4, label: 'PDCA4'}
+				]
+			}
+		},
+		methods: {
+      /***
+       * 选中状态改变触发
+       * @param {Number | String} selectData 当前选中的值
+			 * @param {Object} selectData 当前选中的整条数据
+			 * @param {Number} index 当前选中下标
+      */
+			changeSelect(selectVal, selectData, index) {
+				this.defaultValue = selectVal;
+			}
+		}
+	}
+```
+
+#####  二: 下拉式单选列表组合 type="select"(如人员架构)
+<!-- 在 template 中使用组件 -->
+```html
+<tm-radio-group
+  type="select"
+  :list="list"
+  :defaultValue='defaultValue'
+  @change="changeSelect"
+  :openkeys="[0]"
+  :setting="{
+    pName: 'pName',
+    child: 'childList',
+    value: 'value',
+    name: 'label'
+  }"
+/>
+```
+<!-- 在script中写入 -->
+```js
+	export default {
+		data() {
+			return {
+       // 默认选中
+       defaultValue: 1,
+       // 渲染的原数据
+       list: [
+          {
+            pValue: 1,
+            pName: '门诊',
+            childList: [
+              {value: 1, label: 'PDCA1'},
+					    {value: 2, label: 'PDCA2'},
+				    	{value: 3, label: 'PDCA3'},
+					    {value: 4, label: 'PDCA4'}
+            ]
+          },
+          {
+            pValue: 2,
+            pName: '分诊',
+            childList: [
+              {value: 11, label: '许玮琛1'},
+					    {value: 22, label: '许玮琛2'},
+				    	{value: 33, label: '许玮琛3'},
+					    {value: 44, label: '许玮琛4'}
+            ]
+          }
+				]
+			}
+		},
+		methods: {
+      /***
+       * 选中状态改变触发
+       * @param {Number | String} selectData 当前选中的值
+			 * @param {Object} selectData 当前选中的整条数据
+			 * @param {Number} index 当前选中下标
+      */
+			changeSelect(selectVal, selectData, index) {
+				this.defaultValue = selectVal;
+			}
+		}
+	}
+```

+ 88 - 0
components/tm-radio-group/radio-group.vue

@@ -0,0 +1,88 @@
+<template>
+	<view class="radio-group-view">
+		<view v-if="label" class="label-view">
+			<text>{{ label }}</text>
+		</view>
+		<view class="radio-group">
+			<template v-for="(item, i) in list">
+				<view class="radio-item" :key="i" @click="toggleSelect(item, i)">
+					<text class="text">{{ item[setting.name] }}</text>
+					<image class="icon"
+					  :src="`/static/${item[setting.value] === defaultValue ? 'check-radio' : 'check-no'}.png`"></image>
+				</view>
+			</template>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * 单选列表组合
+	 * 芦荟
+	 * 2021.2.2
+	 * props:属性说明看tm-radio-gruop.vue
+	 */
+	export default {
+	  props: ['list', 'defaultValue', 'label', 'setting'],
+		methods: {
+			/**
+			 * 选中变化调用
+			 * @param {Object} selectData 当前选中的对象
+			 * @param {Object} index 当前选中下标
+			 *
+			 * 返回的参数
+			 * selectData[this.setting.value]: 当前选中的值
+			 * selectData: 当前选中的整条数据
+			 * index:      当前选中的下标
+			 */
+			toggleSelect(selectData, index){
+				this.$emit(
+				  'change',
+				  selectData ? selectData[this.setting.value] : '',
+					selectData,
+					index
+				);
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.radio-group-view {
+
+		.label-view {
+			height: 47.5rpx;
+			line-height: 45rpx;
+			padding-left: 25rpx;
+
+			>text {
+				font-size: 22.5rpx;
+				color: #666F80;
+			}
+		}
+
+		.radio-group {
+			padding-left: 25rpx;
+			background-color: #fff;
+
+			.radio-item {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				height: 87.5rpx;
+				border-bottom: 0.62rpx solid #DADEE6;
+				padding-right: 25rpx;
+
+				.text {
+					font-size: 22.5rpx;
+					color: #292C33;
+				}
+
+				.icon {
+					width: 25rpx;
+					height: 25rpx;
+				}
+			}
+		}
+	}
+</style>

+ 92 - 0
components/tm-radio-group/radio-select-group.vue

@@ -0,0 +1,92 @@
+<template>
+	<view class="radio-slect-group">
+    <template v-for="(item, i) in list">
+      <view class="radio-slect-item" :key="i">
+        <view class="p-view" @click="changeOpenKey(i)">
+          <image class="icon"
+            :src="`/static/${isOpen(i) ? 'up-icon' : 'down-icon'}.png`"></image>
+					<text>{{ item[setting.pName] }}</text>
+        </view>
+        <template v-if="isOpen(i)">
+					<view class="child-radio-group">
+						<child-radio-group
+						  :list="item[setting.child] || []"
+						  :defaultValue="defaultValue"
+						  :label="label"
+						  :setting="setting"
+						  @change="toggleSelect"
+						/>
+					</view>
+        </template>
+      </view>
+    </template>
+	</view>
+</template>
+
+<script>
+	/**
+	 * 下拉式单选列表组合
+	 * 芦荟
+	 * 2021.2.3
+	 * props:属性说明看tm-radio-gruop.vue
+	 */
+
+  import childRadioGroup from './radio-group.vue'
+	export default {
+    props: ['list', 'defaultValue', 'label', 'setting', 'openkeys'],
+		created() {
+		},
+		methods: {
+			/**
+			 * 选中变化调用
+			 * @param {Object} selectData 当前选中的对象
+			 * @param {Object} index 当前选中下标
+			 */
+			toggleSelect(selectVal, selectData, index){
+		  	this.$emit('change', selectVal, selectData, index);
+      },
+      changeOpenKey(key) {
+        let openKey = this.openkeys.find(openKey => openKey === key);
+        this.$emit('changeOpenPKey', (openKey || openKey === 0 ? 'close' : 'open'), key)
+      },
+      isOpen(key) {
+        let openKey = this.openkeys.find(openKey => openKey === key);
+        return openKey || openKey === 0
+      }
+    },
+    components: {
+      childRadioGroup
+    }
+	}
+</script>
+
+<style lang="less">
+	.radio-slect-group {
+    background: #ffffff;
+
+		.radio-slect-item {
+
+      .p-view {
+				display: flex;
+				align-items: center;
+        height: 75rpx;
+				padding-left: 25rpx;
+
+				.icon {
+					margin-right: 15rpx;
+					width: 21.25rpx;
+					height: 12.5rpx;
+        }
+
+        >text {
+          font-size: 22.5rpx;
+					color: #292C33;
+        }
+      }
+    }
+		
+		.child-radio-group {
+			padding-left: 62.5rpx;
+		}
+	}
+</style>

+ 81 - 40
components/tm-radio-group/tm-radio-group.vue

@@ -1,39 +1,43 @@
 <template>
 	<view class="tm-radio-group">
-		<view v-if="label" class="label-view">
-			<text>{{ label }}</text>
-		</view>
-		<view class="radio-group">
-			<template v-for="(item, i) in list">
-				<view class="radio-item" :key="i" @click="toggleSelect(item, i)">
-					<text class="text">{{ item[setting.name] }}</text>
-					<image class="icon" 
-					  :src="`/static/${item[setting.value] === defaultValue ? 'check-radio' : 'check-no'}.png`"></image>
-				</view>
-			</template>
-		</view>
+    <component
+      :is="currentComponet"
+      :list="list"
+      :defaultValue="defaultValue"
+      :label="label"
+      :setting="setting"
+      :openkeys="openPkeys"
+      @change="toggleSelect"
+      @changeOpenPKey="changeOpenPKey"
+     />
 	</view>
 </template>
 
 <script>
 	/**
-	 * 单选列表组合
+	 * 单选列表组合/下拉式单选列表组合
 	 * 芦荟
 	 * 2021.2.2
 	 * props:看下面,有注释说明
 	 */
+
+import radioGroup from './radio-group.vue'
+import radioSelectGroup from './radio-select-group.vue'
+
 	export default {
 		props: {
 			// 渲染的数据
 			list: {
 				type: Array,
-				default: []
-			},	
-			// 选中的数据 
+				default: () => {
+          return []
+        }
+			},
+			// 选中的数据
 			defaultValue: {
 				type: Number | String,
 				default: ''
-			},
+      },
 			// 单选列表组合名字
 			label: {
 				type: String,
@@ -41,54 +45,91 @@
 			},
 			// 单选组配置
 			setting: {
-				type: Object, 
-				default: {
-					value: 'value', // 设置当前选中的值(默认取value)
-					name: 'name' // 当前显示的文字(默认取name)
-				}
-			}
-		},
+				type: Object,
+				default: () => {
+          return  {
+            pName: 'pName',   // 父级显示的文字
+            child: 'child',  // 子数据list
+				  	value: 'value', // 设置当前选中的值(默认取value)
+				  	name: 'name' // 当前显示的文字(默认取name)
+				  }
+        }
+      },
+      /**
+       *  单选列表组合 或 下拉式单选列表组合
+       *  default:单选列表组合(如指派改善任务)  默认值
+       *  select:  下拉式单选列表组合(如人员架构)
+       */
+      type: {
+        type: String,
+				default: 'default'
+      },
+      // 默认展开的父级下标(注意: 数组存父级元素下标)
+      openkeys: {
+        type: Array,
+				default: () => {
+          return []
+        }
+      },
+    },
+    computed: {
+      // 当前显示的组件
+      currentComponet() {
+        return this.type === 'default' ? 'radio-group' : 'radio-select-group'
+      }
+    },
+    data() {
+      return {
+        // 展开的父级下标
+        openPkeys: this.openkeys
+      }
+    },
 		methods: {
 			/**
 			 * 选中变化调用
 			 * @param {Object} selectData 当前选中的对象
 			 * @param {Object} index 当前选中下标
-			 * 
+			 *
 			 * 返回的参数
 			 * selectData[this.setting.value]: 当前选中的值
 			 * selectData: 当前选中的整条数据
 			 * index:      当前选中的下标
 			 */
-			toggleSelect(selectData, index){
-				this.$emit(
-				  'change', 
-				  selectData ? selectData[this.setting.value] : '', 
-					selectData, 
-					index
-				);
-			}
-		}
+			toggleSelect(selectVal, selectData, index){
+				this.$emit('change', selectVal, selectData, index);
+      },
+      // 更改父级展开的下标
+      changeOpenPKey(type, key) {
+        this.openPkeys = type === 'open'
+          ? [...this.openPkeys, key]
+          : this.openPkeys.filter(openKey => openKey != key);
+      }
+    },
+    components: {
+      radioGroup,
+      radioSelectGroup
+    }
 	}
 </script>
 
 <style lang="less">
 	.tm-radio-group {
-		
+
 		.label-view {
 			height: 47.5rpx;
 			line-height: 45rpx;
 			padding-left: 25rpx;
-			
+
 			>text {
 				font-size: 22.5rpx;
 				color: #666F80;
 			}
 		}
-		
+
 		.radio-group {
 			padding-left: 25rpx;
 			background-color: #fff;
-			
+
 			.radio-item {
 				display: flex;
 				align-items: center;
@@ -96,12 +137,12 @@
 				height: 87.5rpx;
 				border-bottom: 0.62rpx solid #DADEE6;
 				padding-right: 25rpx;
-				
+
 				.text {
 					font-size: 22.5rpx;
 					color: #292C33;
 				}
-				
+
 				.icon {
 					width: 25rpx;
 					height: 25rpx;

+ 166 - 0
components/tm-upload-img/tm-upload-img.vue

@@ -0,0 +1,166 @@
+<template>
+	<view class="tm-upload-img">
+		<view class="row" @click="uploadPicture">
+			<view class="label-view">
+				<text>上传图片</text>
+			</view>
+			<text class="placeholder" v-show="filePaths.length === 0">点击上传图片</text>
+			<image class="img-icon" src="/static/img-icon.png"></image>
+		</view>
+		<!-- 预览图片 -->
+		<view class="img-preview">
+			<view class="img-item" v-for="(src, i) in filePaths" :key="i">
+				<image :src="src"></image>
+				<image
+				  class="del-close"
+				  src="/static/del-close.png"
+					@click="delImg(i)" />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * 图片上传(支持单张图片上传 和 多张图片上传)
+	 * 芦荟
+	 * 2021.2.3
+	 * props:属性说明看tm-radio-gruop.vue
+	 */
+
+  import { URL } from "../../utils/requestUrl.js";
+	export default {
+	  props: {
+			// 上传的图片路径列表
+			filePaths: {
+				type: Array,
+				default: () => {
+          return []
+        }
+			},
+			// 是否多选	(默认单选)
+      isMultiple: {
+				type: Boolean,
+				default: false
+			}
+		},
+		methods: {
+			// 上传图片
+			uploadPicture() {
+				uni.chooseImage({
+					count: this.isMultiple ? 0 : 1, // 是否多选
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					success: res1 => {
+						let filePathStr = res1.tempFilePaths.join(',');
+						console.log(filePathStr)
+						uni.uploadFile({
+							url: `${URL}/eduscreen/upload/picture`,
+							fileType: 'image',
+							filePath: filePathStr,
+							name: 'file',
+							success: res2 => {
+								if (res2.statusCode == 200) {
+									let data = JSON.parse(res2.data || '{}');
+									if (parseInt(data.meta.code, 10) === 200) {
+										const { viewUrl, picture } = data.body;
+										this.$emit('changeFilePaths', [...this.filePaths, viewUrl])
+										this.picture = picture;
+									} else {
+										uni.showToast({
+											position: 'top',
+											icon: 'none',
+											title: '上传图片失败',
+											duration: 1000
+										});
+									}
+								}
+							},
+							error(e) {
+								uni.showToast({
+									position: 'top',
+									icon: 'none',
+									title: '上传图片失败',
+									duration: 1000
+								});
+							}
+						});
+					},
+					error: e => {
+						console.log('选择图片失败', e);
+					}
+				});
+			},
+			// 删除图片
+			delImg(i) {
+				this.$emit('changeFilePaths',  this.filePaths.filter((item, index) => index != i))
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.tm-upload-img {
+		background-color: #fff;
+		padding-left: 25rpx;
+
+		.row {
+			position: relative;
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			flex: 1;
+			padding-right: 25rpx;
+
+			.label-view {
+				width: 175rpx;
+				line-height: 37.5rpx;
+				padding: 25rpx 0;
+
+				text {
+					font-size: 22.5rpx;
+					color: #666F80;
+				}
+			}
+
+			.placeholder {
+				position: absolute;
+				left: 175rpx;
+				font-size: 22.5rpx;
+				color: #B8BECC;
+			}
+
+			.img-icon {
+				width: 30rpx;
+				height: 25rpx;
+			}
+		}
+
+		.img-preview {
+			display: flex;
+			flex-wrap: wrap;
+
+			.img-item {
+				position: relative;
+				margin-right: 25rpx;
+				margin-bottom: 25rpx;
+				width: 300rpx;
+				height: 225rpx;
+
+				>image {
+					width: 300rpx;
+					height: 225rpx;
+				}
+
+				.del-close {
+					position: absolute;
+					top: -12.5rpx;
+					right: -12.5rpx;
+					width: 37.5rpx;
+					height: 37.5rpx;
+				}
+			}
+		}
+	}
+
+</style>

+ 26 - 20
components/uni-segmented-control/uni-segmented-control.vue

@@ -1,20 +1,24 @@
 <template>
-	<view :class="[styleType === 'text'?'segmented-control--text' : 'segmented-control--button' ]" :style="{ borderColor: styleType === 'text' ? '' : activeColor }"
-	 class="segmented-control">
-		<view v-for="(item, index) in values" :class="[ styleType === 'text'?'segmented-control__item--text': 'segmented-control__item--button' , index === currentIndex&&styleType === 'button'?'segmented-control__item--button--active': '' , index === 0&&styleType === 'button'?'segmented-control__item--button--first': '',index === values.length - 1&&styleType === 'button'?'segmented-control__item--button--last': '' ]"
-		 :key="index" :style="{
-        backgroundColor: index === currentIndex && styleType === 'button' ? activeColor : '',borderColor: index === currentIndex&&styleType === 'text'||styleType === 'button'?activeColor:'transparent'
-      }"
-		 class="segmented-control__item" @click="_onClick(index)">
-			<text :style="{color:
-          index === currentIndex
-            ? styleType === 'text'
-              ? activeColor
-              : '#fff'
-            : styleType === 'text'
-              ? '#000'
-              : activeColor}"
-			 class="segmented-control__text">{{ item }}</text>
+	<view 
+	  :class="[styleType === 'text'?'segmented-control--text' : 'segmented-control--button' ]" 
+	  :style="{ borderColor: styleType === 'text' ? '' : activeColor }"
+	   class="segmented-control">
+		<view :class="[ 
+				    styleType === 'text'?'segmented-control__item--text': 'segmented-control__item--button',
+				    index === currentIndex&&styleType === 'button'?'segmented-control__item--button--active': '' ,
+				    index === 0&&styleType === 'button'?'segmented-control__item--button--first': '',
+				    index === values.length - 1&&styleType === 'button'?'segmented-control__item--button--last': ''
+			    ]"
+			    v-for="(item, index) in values" 
+		      :key="index" 
+					:style="{
+             backgroundColor: index === currentIndex && styleType === 'button' ? activeColor : '',
+						 borderColor: index === currentIndex&&styleType === 'text'||styleType === 'button'?activeColor:'transparent'
+          }"
+		      class="segmented-control__item" @click="_onClick(index)">
+			<text :style="{color: index === currentIndex  ? styleType === 'text'
+						? activeColor : '#fff' : styleType === 'text' ? '#000' : activeColor}"
+			   class="segmented-control__text">{{ item }}</text>
 		</view>
 	</view>
 </template>
@@ -77,8 +81,9 @@
 		box-sizing: border-box;
 		/* #endif */
 		flex-direction: row;
-		height: 36px;
+		height: 52.5rpx;
 		overflow: hidden;
+		background-color: #fff;
 	}
 
 	.segmented-control__item {
@@ -113,12 +118,13 @@
 
 	.segmented-control__item--text {
 		border-bottom-style: solid;
-		border-bottom-width: 3px;
+		border-bottom-width: 3.75rpx;
 	}
 
 	.segmented-control__text {
-		font-size: 16px;
-		line-height: 20px;
+		font-size: 22.5rpx;
+		font-weight: 500;
+		line-height: 52.5rpx;
 		text-align: center;
 	}
 </style>

+ 18 - 18
pages/mission-action/components/assign-mission/assign-mission.vue → pages/mission-action/components/assign-mission.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="assign-mission">
 		<scroll-view class="scroll-y" scroll-y="true">
-			<tm-radio-group 
+			<tm-radio-group
 			  :list="list"
 				label="改善工具"
 				:defaultValue='defaultValue'
@@ -10,20 +10,20 @@
 				  value: 'value',
 				  name: 'label'
 			  }"
-		/>
-		<view class="switch-box">
-			<text class="label">需要审核改善方案</text>
-			<switch checked="true" style="transform:scale(1.5)" />
-		</view>
-		<tm-radio-group
+		  />
+		  <view class="switch-box">
+			  <text class="label">需要审核改善方案</text>
+			  <switch checked="true" style="transform:scale(1.5)" />
+		  </view>
+		  <tm-radio-group
 			  :list="list"
-				:defaultValue='defaultValue'
-				@change="changeSelect"
-				:setting="{
+			  :defaultValue='defaultValue'
+			  @change="changeSelect"
+			  :setting="{
 				  value: 'value',
 				  name: 'label'
 			  }"
-		/>
+		  />
 		</scroll-view>
 		<view class="fixed-buttom-btn">
 			<text class="btn-text">确定</text>
@@ -39,9 +39,9 @@
 				defaultValue: 1,
 				list: [
 					{value: 1, label: 'PDCA1'},
-					{value: 2, label: 'PDCA2'},
-					{value: 3, label: 'PDCA3'},
-					{value: 4, label: 'PDCA4'}
+					// {value: 2, label: 'PDCA2'},
+					// {value: 3, label: 'PDCA3'},
+					// {value: 4, label: 'PDCA4'}
 				]
 			}
 		},
@@ -61,19 +61,19 @@
 <style lang="less">
 	.assign-mission {
 		height: 100%;
-		
+
 		.scroll-y {
 			height: calc(100% - 87.5rpx);
-			
+
 			.switch-box {
 				display: flex;
 				justify-content: space-between;
 				align-items: center;
-				margin-bottom: 15rpx;
+				margin: 15rpx 0;
 				height: 87.5rpx;
 				background-color: #fff;
 				padding: 0 25rpx;
-				
+
 				.label {
 					font-size: 22.5rpx;
 					color: #292C33;

+ 70 - 0
pages/mission-action/components/disagree.vue

@@ -0,0 +1,70 @@
+<template>
+	<view class="disagree-page">
+    <scroll-view class="scroll-y" scroll-y="true">
+      <view class="textarea-box">
+			  <view class="label-view">
+				  <text>原因</text>
+			  </view>
+			  <textarea class="textarea"
+			    placeholder="请输入"
+			  	placeholder-style="color: #B8BECC"
+			  	:maxlength="-1"
+          auto-height
+			  />
+		</view>
+    </scroll-view>
+		<view class="fixed-buttom-btn">
+			<text class="btn-text">确定</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	// 不认可原因
+	export default {
+		created() {
+			uni.setNavigationBarTitle({
+				title: '原因'
+			});
+		}
+	}
+</script>
+
+<style lang="less">
+	.disagree-page {
+		height: 100%;
+
+    .scroll-y {
+			height: calc(100% - 87.5rpx);
+      padding-top: 15rpx;
+
+      .textarea-box {
+		   	display: flex;
+		   	width: 100%;
+		   	background-color: #fff;
+				padding: 25rpx 0;
+		   	padding-left: 25rpx;
+
+	       .label-view {
+		       width: 175rpx;
+		   		 line-height: 37.5rpx;
+
+		   		>text {
+		   			font-size: 22.5rpx;
+		   			color: #666F80;
+		   		}
+	       }
+
+		   	.textarea {
+          flex: 1;
+          min-height: 768.75rpx;
+		   		padding: 0 25rpx;
+		   		line-height: 37.5rpx;
+		   		font-size: 22.5rpx;
+		   		color: #525866;
+		   		box-sizing: border-box;
+		   	}
+		   }
+		}
+	}
+</style>

+ 141 - 0
pages/mission-action/components/pdca-components/do-and-check.vue

@@ -0,0 +1,141 @@
+<template>
+	<view class="com-plan-content">
+		<view class="title">
+			<text>{{ title }}</text>
+		</view>
+		<view class="item-view">
+			<view class="top-action">
+				<text>改善确认(1)</text>
+				<text class="close-text">删除</text>
+			</view>
+			<view class="main">
+				<view class="row">
+					<view class="label-view">
+						<text>{{ label }}</text>
+					</view>
+					<view class="content">
+						<textarea class="textarea"
+					    :key="title"
+						  placeholder="请输入"
+							placeholder-style="color: #B8BECC"
+							:maxlength="-1"
+							auto-height
+					    
+						/>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	// 执行过程记录(Do)和 改善确认(Check)
+	export default {
+		props: {
+      // 多行文本框标题
+			title: {
+        type: String,
+        default: '执行过程记录(Do)'
+			},
+      // 多行文本框子标题
+			label: {
+        type: String,
+        default: '执行过程记录'
+      }
+    },
+    data() {
+      return {
+        // list长度 控制个数
+        list: [
+					{gcjl: '', date: '', imgPath: '' },
+					{gcjl: '', date: '', imgPath: '' }
+				]
+      }
+    },
+		methods: {
+      changeVal(e) {
+        if(this.label === '改善计划'){
+          this.planvalue = e.target.value;
+        }else {
+          this.actionvalue = e.target.value;
+        }
+      }
+		},
+	}
+</script>
+
+<style lang="less">
+	.com-plan-content {
+		height: 100%;
+		padding-top: 35rpx;
+
+		.title {
+			line-height: 35rpx;
+			padding: 0 25rpx;
+
+			text {
+				font-size: 35rpx;
+				color: #292C33;
+			}
+		}
+		
+		.item-view {
+			
+			.top-action {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				margin-top: 25rpx;
+				margin-bottom: 15rpx;
+				height: 22.5rpx;
+				padding: 0 25rpx;
+				
+				text {
+					font-size: 22.5rpx;
+					color: #666F80;
+				}
+				
+				.close-text {
+					font-size: 20rpx;
+					color: #3377FF;
+				}
+			}
+			
+			.main {
+				padding-left: 25rpx;
+				background-color: #fff;
+				
+				.row {
+					display: flex;
+					
+					.label-view {
+						width: 175rpx;
+						line-height: 37.5rpx;
+						padding: 25rpx 0;
+					
+						>text {
+							font-size: 22.5rpx;
+							color: #666F80;
+						}
+					}
+					
+					.content {
+						flex: 1;
+						padding: 25rpx 0;
+					
+						.textarea {
+							width: 100%;
+							min-height: 200rpx;
+							padding: 0 25rpx;
+							line-height: 38.5rpx;
+							font-size: 22.5rpx;
+							color: #525866;
+							box-sizing: border-box;
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 117 - 0
pages/mission-action/components/pdca-components/one-textarea.vue

@@ -0,0 +1,117 @@
+<template>
+	<view class="com-plan-content">
+		<view class="title">
+			<text>{{ title }}</text>
+		</view>
+		<view class="item-container">
+			<view class="label-view">
+				<text>{{ label }}</text>
+			</view>
+			<view class="content">
+				<textarea class="textarea"
+          :key="title"
+				  placeholder="请输入"
+					placeholder-style="color: #B8BECC"
+					:maxlength="-1"
+					auto-height
+          :value="label === '改善计划' ? planvalue : actionvalue"
+          @input="changeVal"
+				/>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	// 单个多行输入框 (改善计划(Plan)/oneTextarea)
+
+	export default {
+		props: {
+      // 多行文本框标题
+			title: {
+        type: String,
+        default: '改善计划(Plan)'
+			},
+      // 多行文本框子标题
+			label: {
+        type: String,
+        default: '改善计划'
+      },
+      // 改善计划默认值
+      defaultPlanValue: {
+        type: String,
+        default: ''
+      },
+      // 对策处置默认值
+      defaultactionValue: {
+        type: String,
+        default: ''
+      }
+    },
+    data() {
+      return {
+        planvalue: this.defaultPlanValue, // 改善计划
+        actionvalue: this.defaultactionValue // 对策处置
+      }
+    },
+		methods: {
+      changeVal(e) {
+        if(this.label === '改善计划'){
+          this.planvalue = e.target.value;
+        }else {
+          this.actionvalue = e.target.value;
+        }
+      }
+		},
+	}
+</script>
+
+<style lang="less">
+	.com-plan-content {
+		height: 100%;
+		padding-top: 35rpx;
+
+		.title {
+			line-height: 35rpx;
+			padding: 0 25rpx;
+
+			text {
+				font-size: 35rpx;
+				color: #292C33;
+			}
+		}
+
+		.item-container {
+			display: flex;
+			margin-top: 25rpx;
+			padding-left: 25rpx;
+			background-color: #FFFFFF;
+
+			.label-view {
+				width: 175rpx;
+				line-height: 37.5rpx;
+				padding: 25rpx 0;
+
+				>text {
+					font-size: 22.5rpx;
+					color: #666F80;
+				}
+			}
+
+			.content {
+				flex: 1;
+				padding: 25rpx 0;
+
+				.textarea {
+					width: 100%;
+					min-height: 810rpx;
+					padding: 0 25rpx;
+					line-height: 37.5rpx;
+					font-size: 22.5rpx;
+					color: #525866;
+					box-sizing: border-box;
+				}
+			}
+		}
+	}
+</style>

+ 85 - 0
pages/mission-action/components/pdca.vue

@@ -0,0 +1,85 @@
+<template>
+	<view class="pdca-page">
+		<uni-segmented-control
+		  :current="current"
+			:values="items"
+			@clickItem="onClickItem"
+			style-type="text"
+			active-color="#3377FF" />
+		<view class="content">
+			<scroll-view class="scroll-y" scroll-y="true">
+        <one-textarea
+          v-if="current === 0"
+          :defaultPlanValue="'99999'"
+         />
+				 <do-and-check
+					 v-if="current === 1"
+					/>
+				<view v-if="current === 2">
+						选项卡3的内容
+				</view>
+				<one-textarea
+          v-if="current === 3"
+          title="对策处置(Action)"
+          label="对策处置"
+          :defaultactionValue="'123'"
+         />
+			</scroll-view>
+			<view class="fixed-buttom-btn">
+				<view class="btn-text cancle">
+					<text>取消</text>
+				</view>
+				<view class="btn-text">
+					<text>确定</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	// 改善任务PDCA
+	import uniSegmentedControl from "@/components/uni-segmented-control/uni-segmented-control.vue"
+	import oneTextarea from './pdca-components/one-textarea.vue'
+	import doAndCheck from './pdca-components/do-and-check.vue'
+
+	export default {
+		data() {
+			return {
+				items: ['改善计划(P)', '执行过程(D)', '改善确认(C)', '对策处置(A)'],
+        current: 1,
+			}
+		},
+		created() {
+			uni.setNavigationBarTitle({
+				title: '改善计划'
+			});
+		},
+		methods: {
+			onClickItem(e) {
+				if (this.current !== e.currentIndex) {
+					this.current = e.currentIndex;
+				}
+			}
+		},
+		components: {
+			uniSegmentedControl,
+			oneTextarea,
+			doAndCheck
+		}
+	}
+</script>
+
+<style lang="less">
+	.pdca-page {
+		height: 100%;
+
+		.content {
+			height: calc(100% - 141.5rpx);
+
+			.scroll-y {
+				height: 100%;
+			}
+		}
+	}
+</style>

+ 77 - 0
pages/mission-action/components/personnel.vue

@@ -0,0 +1,77 @@
+<template>
+	<view class="personnel-page">
+		<scroll-view class="scroll-y" scroll-y="true">
+			<tm-radio-group
+        type="select"
+			  :list="list"
+				:defaultValue='defaultValue'
+				@change="changeSelect"
+        :openkeys="[0]"
+				:setting="{
+          pName: 'pName',
+          child: 'childList',
+				  value: 'value',
+				  name: 'label'
+			  }"
+			/>
+		</scroll-view>
+		<view class="fixed-buttom-btn">
+			<text class="btn-text">确定</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	// 人员架构
+	export default {
+		data(){
+			return {
+				defaultValue: 1,
+				list: [
+          {
+            pValue: 1,
+            pName: '门诊',
+            childList: [
+              {value: 1, label: 'PDCA1'},
+					    {value: 2, label: 'PDCA2'},
+				    	{value: 3, label: 'PDCA3'},
+					    {value: 4, label: 'PDCA4'}
+            ]
+          },
+          {
+            pValue: 2,
+            pName: '分诊',
+            childList: [
+              {value: 11, label: '许玮琛1'},
+					    {value: 22, label: '许玮琛2'},
+				    	{value: 33, label: '许玮琛3'},
+					    {value: 44, label: '许玮琛4'}
+            ]
+          },
+
+				]
+			}
+		},
+		created() {
+			uni.setNavigationBarTitle({
+				title: '人员架构'
+			});
+    },
+    methods: {
+      changeSelect(selectVal) {
+        this.defaultValue = selectVal
+      }
+    },
+	}
+</script>
+
+<style lang="less">
+	.personnel-page {
+		height: 100%;
+
+		.scroll-y {
+			height: calc(100% - 87.5rpx);
+			padding-top: 15rpx;
+		}
+	}
+</style>

+ 88 - 0
pages/mission-action/components/write-back.vue

@@ -0,0 +1,88 @@
+<template>
+	<view class="write-back-page">
+		<scroll-view class="scroll-y" scroll-y="true" >
+			<view class="item-box">
+				<view class="label-view">
+					<text>回复内容</text>
+				</view>
+				<textarea class="textarea"
+				  placeholder="请输入"
+					placeholder-style="color: #B8BECC"
+					:maxlength="-1"
+          auto-height
+				/>
+			</view>
+			<tm-upload-img
+			  :filePaths="filePaths"
+				:isMultiple="true"
+				@changeFilePaths="changeFilePaths"
+			/>
+		</scroll-view>
+		<view class="fixed-buttom-btn">
+			<text class="btn-text">确定</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	// 改善回复
+
+	export default {
+		data() {
+			return {
+				filePaths: ['/static/img-icon.png', '/static/img-icon.png']
+			}
+		},
+		created() {
+			uni.setNavigationBarTitle({
+				title: '原因'
+			});
+		},
+		methods: {
+			changeFilePaths(filePaths) {
+				this.filePaths = filePaths;
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.write-back-page {
+		height: 100%;
+		padding-top: 15rpx;
+
+		.scroll-y {
+			height: calc(100% - 102rpx);
+
+			.item-box {
+				display: flex;
+				background-color: #FFFFFF;
+				border-bottom: 0.62rpx solid #DADEE6;
+				padding: 25rpx 0;
+				padding-left: 25rpx;
+
+				.label-view {
+					width: 175rpx;
+					line-height: 37.5rpx;
+					
+
+					>text {
+						font-size: 22.5rpx;
+						color: #666F80;
+					}
+				}
+
+				.textarea {
+					width: 100%;
+					min-height: 587.5rpx;
+					background-color: #fff;
+					padding: 0 25rpx;
+					line-height: 37.5rpx;
+					font-size: 22.5rpx;
+					color: #525866;
+					box-sizing: border-box;
+				}
+			}
+		}
+	}
+</style>

+ 29 - 5
pages/mission-action/mission-action.vue

@@ -1,22 +1,46 @@
 <template>
 	<view class="mission-action-page">
-		<assign-mission />
+		<!-- 指派改善任务 -->
+		<component
+		  :is="currentComponet"
+		/>
 	</view>
 </template>
 
 <script>
-	import assignMission from './components/assign-mission/assign-mission.vue'
+	import assignMission from './components/assign-mission.vue';
+	import disagree from './components/disagree.vue'
+	import personnel from './components/personnel.vue'
+	import writeBack from './components/write-back.vue'
+	import pdca from './components/pdca.vue'
+
 	export default {
 		data() {
 			return {
-				
+				// 当前显示的组件
+				currentComponet: 'pdca',
+				compoentList: [
+					{type: 1, name: '指派改善任务', component: 'assign-mission'},
+					{type: 2, name: '原因', component: 'disagree'},
+					{type: 3, name: '人员架构', component: 'personnel'},
+					{type: 4, name: '改善回复', component: 'write-back'},
+					{type: 5, name: 'PDCA', component: 'pdca'},
+				]
 			}
 		},
+		created() {
+			// console.log(this.compoentList[0].component)
+			// this.currentComponet = this.compoentList[0].component
+		},
 		methods: {
-			
+
 		},
 		components: {
-			assignMission
+			assignMission,
+			disagree,
+			personnel,
+			writeBack,
+			pdca
 		}
 	}
 </script>

+ 1 - 1
pages/mission-details/mission-details.vue

@@ -31,7 +31,7 @@
 						  </view>
 						</view>
 						<view class="btn-group" v-if="i === list.length-1">
-							<tm-button type="pramary" btnText="重新发送" />
+							<tm-button type="pramary" btnText="不认可" @btnClick="clickRightBtn" />
 							<tm-button btnText="指派改善任务" @btnClick="clickRightBtn" />
 						</view>
 					</template>

BIN
static/del-close.png


+ 0 - 0
static/down-ion.png → static/down-icon.png