maotao 7 mēneši atpakaļ
vecāks
revīzija
41a653db9b

+ 13 - 7
.hbuilderx/launch.json

@@ -4,13 +4,19 @@
4 4
     "version" : "0.0",
5 5
     "configurations" : [
6 6
         {
7
-            "default" : {
8
-                "launchtype" : "local"
9
-            },
10
-            "mp-weixin" : {
11
-                "launchtype" : "local"
12
-            },
13
-            "type" : "uniCloud"
7
+        	"app-plus" : 
8
+        	{
9
+        		"launchtype" : "local"
10
+        	},
11
+        	"default" : 
12
+        	{
13
+        		"launchtype" : "local"
14
+        	},
15
+        	"mp-weixin" : 
16
+        	{
17
+        		"launchtype" : "local"
18
+        	},
19
+        	"type" : "uniCloud"
14 20
         },
15 21
         {
16 22
             "playground" : "standard",

+ 42 - 35
components/repairsFilter.vue

@@ -4,17 +4,17 @@
4 4
       <view class="category">
5 5
         <text class="name">状态</text>
6 6
         <text class="value">
7
-					<uni-data-picker @change="categoryChange" v-model="searchData.category" :localdata="pageData.categoryList" popup-title="请选择状态" :map="{text:'category',value:'id'}">
7
+					<uni-data-picker @change="categoryChange" v-model="searchData.category" :clear-icon="false" :localdata="pageData.categoryList" popup-title="请选择状态">
8 8
 						
9 9
 					</uni-data-picker>
10 10
 				</text>
11 11
       </view>
12
-			<view class="category">
12
+		<!-- 	<view class="category">
13 13
 				<label class="uni-list-cell uni-list-cell-pd">
14 14
 					<text class="name">待评价</text>
15 15
 					<checkbox value="1" color="#49b856" :checked="searchData.evaluate" />
16 16
 				</label>
17
-			</view>
17
+			</view> -->
18 18
     </view>
19 19
     <view class="container_foot">
20 20
       <view class="clear" @click="clear">清除选项</view>
@@ -45,7 +45,15 @@
45 45
   const pageData = reactive({
46 46
     pageRouter: 'default',
47 47
     areaList: [],
48
-    categoryList: [],
48
+    categoryList: [
49
+			{text: '全部', value: 0},
50
+			{text: '待受理', value: 'accept,storage'},
51
+			{text: '处理中', value: 'pending,handler,reassign'},
52
+			{text: '待评价', value: 'close0', hasWxdegree: 0},
53
+			{text: '已关闭', value: 'close1', hasWxdegree: 1},
54
+			{text: '不受理', value: 'reject'},
55
+			{text: '撤销', value: 'cancel'},
56
+		],
49 57
   });
50 58
 	
51 59
   const searchData = reactive({
@@ -53,7 +61,7 @@
53 61
     hospital: {},
54 62
     selected: 'todoingAll',
55 63
     area: {id: 0, area: '全部'},
56
-    category: {},
64
+    category: 0,
57 65
     acceptDate: [],
58 66
 		categoryChangeData:[]
59 67
   })
@@ -82,39 +90,38 @@
82 90
 		searchData.categoryChangeData = val.detail.value
83 91
 	}
84 92
 	
85
-  // 获取故障现象列表
86 93
   function getCategoryList(){
87
-    uni.showLoading({
88
-      title: "加载中",
89
-      mask: true,
90
-    });
94
+   //  uni.showLoading({
95
+   //    title: "加载中",
96
+   //    mask: true,
97
+   //  });
91 98
     
92
-    let postData = {
93
-      idx: 0,
94
-      sum: 9999,
95
-      incidentcategory: {
99
+   //  let postData = {
100
+   //    idx: 0,
101
+   //    sum: 9999,
102
+   //    incidentcategory: {
96 103
 
97
-			},
98
-    }
99
-    if(loginUserStore.loginUser.user.duty){
100
-      postData.incidentcategory.duty = loginUserStore.loginUser.user.duty.id;
101
-    }else if(loginUserStore.loginUser.user.branch){
102
-      postData.incidentcategory.branch = loginUserStore.loginUser.user.branch.id;
103
-    }
104
+			// },
105
+   //  }
106
+   //  if(loginUserStore.loginUser.user.duty){
107
+   //    postData.incidentcategory.duty = loginUserStore.loginUser.user.duty.id;
108
+   //  }else if(loginUserStore.loginUser.user.branch){
109
+   //    postData.incidentcategory.branch = loginUserStore.loginUser.user.branch.id;
110
+   //  }
104 111
     
105
-    api_incidentcategory(postData).then(res => {
106
-      uni.hideLoading();
107
-      if(res.status == 200){
108
-        let list = res.list || [];
109
-				list = list.map(i=> ({...i, parentid: i.parent?.id}))
110
-				pageData.categoryList = transform(list, 'id', 'parentid')
111
-      }else{
112
-        uni.showToast({
113
-          icon: 'none',
114
-          title: res.msg || '请求数据失败!'
115
-        });
116
-      }
117
-    })
112
+   //  api_incidentcategory(postData).then(res => {
113
+   //    uni.hideLoading();
114
+   //    if(res.status == 200){
115
+   //      let list = res.list || [];
116
+			// 	list = list.map(i=> ({...i, parentid: i.parent?.id}))
117
+			// 	pageData.categoryList = transform(list, 'id', 'parentid')
118
+   //    }else{
119
+   //      uni.showToast({
120
+   //        icon: 'none',
121
+   //        title: res.msg || '请求数据失败!'
122
+   //      });
123
+   //    }
124
+   //  })
118 125
   }
119 126
 	
120 127
   // 页面路由跳转
@@ -128,7 +135,7 @@
128 135
   }
129 136
 	
130 137
   onLoad((option) => {
131
-		getCategoryList()
138
+		// getCategoryList()
132 139
 		let data = repositorySearchStore.repositorySearch.data
133 140
     searchData.category = data && data.category;
134 141
 		searchData.title = data && data.title;

+ 213 - 0
components/u-circle-progress/u-circle-progress.vue

@@ -0,0 +1,213 @@
1
+<template>
2
+	<view
3
+		class="u-circle-progress"
4
+		:style="{
5
+			width: widthPx + 'px',
6
+			height: widthPx + 'px',
7
+			backgroundColor: bgColor
8
+		}"
9
+	>
10
+		<!-- 支付宝小程序不支持canvas-id属性,必须用id属性 -->
11
+		<canvas
12
+			class="u-canvas-bg"
13
+			:canvas-id="elBgId"
14
+			:id="elBgId"
15
+			:style="{
16
+				width: widthPx + 'px',
17
+				height: widthPx + 'px'
18
+			}"
19
+		></canvas>
20
+		<canvas
21
+			class="u-canvas"
22
+			:canvas-id="elId"
23
+			:id="elId"
24
+			:style="{
25
+				width: widthPx + 'px',
26
+				height: widthPx + 'px'
27
+			}"
28
+		></canvas>
29
+		<slot></slot>
30
+	</view>
31
+</template>
32
+
33
+<script>
34
+/**
35
+ * circleProgress 环形进度条
36
+ * @description 展示操作或任务的当前进度,比如上传文件,是一个圆形的进度条。注意:此组件的percent值只能动态增加,不能动态减少。
37
+ * @tutorial https://www.uviewui.com/components/circleProgress.html
38
+ * @property {String Number} percent 圆环进度百分比值,为数值类型,0-100
39
+ * @property {String} inactive-color 圆环的底色,默认为灰色(该值无法动态变更)(默认#ececec)
40
+ * @property {String} active-color 圆环激活部分的颜色(该值无法动态变更)(默认#19be6b)
41
+ * @property {String Number} width 整个圆环组件的宽度,高度默认等于宽度值,单位rpx(默认200)
42
+ * @property {String Number} border-width 圆环的边框宽度,单位rpx(默认14)
43
+ * @property {String Number} duration 整个圆环执行一圈的时间,单位ms(默认呢1500)
44
+ * @property {String} type 如设置,active-color值将会失效
45
+ * @property {String} bg-color 整个组件背景颜色,默认为白色
46
+ * @example <u-circle-progress active-color="#2979ff" :percent="80"></u-circle-progress>
47
+ */
48
+export default {
49
+	name: 'u-circle-progress',
50
+	props: {
51
+		// 圆环进度百分比值
52
+		percent: {
53
+			type: Number,
54
+			default: 0,
55
+			// 限制值在0到100之间
56
+			validator: val => {
57
+				return val >= 0 && val <= 100;
58
+			}
59
+		},
60
+		// 底部圆环的颜色(灰色的圆环)
61
+		inactiveColor: {
62
+			type: String,
63
+			default: '#ececec'
64
+		},
65
+		// 圆环激活部分的颜色
66
+		activeColor: {
67
+			type: String,
68
+			default: '#19be6b'
69
+		},
70
+		// 圆环线条的宽度,单位rpx
71
+		borderWidth: {
72
+			type: [Number, String],
73
+			default: 14
74
+		},
75
+		// 整个圆形的宽度,单位rpx
76
+		width: {
77
+			type: [Number, String],
78
+			default: 200
79
+		},
80
+		// 整个圆环执行一圈的时间,单位ms
81
+		duration: {
82
+			type: [Number, String],
83
+			default: 0
84
+		},
85
+		// 主题类型
86
+		type: {
87
+			type: String,
88
+			default: ''
89
+		},
90
+		// 整个圆环进度区域的背景色
91
+		bgColor: {
92
+			type: String,
93
+			default: '#ffffff'
94
+		}
95
+	},
96
+	data() {
97
+		return {
98
+			elBgId: 'uCircleProgressBgId',
99
+			elId: 'uCircleProgressElId',
100
+			widthPx: uni.upx2px(this.width), // 转成px后的整个组件的背景宽度
101
+			borderWidthPx: uni.upx2px(this.borderWidth), // 转成px后的圆环的宽度
102
+			startAngle: -Math.PI / 2, // canvas画圆的起始角度,默认为3点钟方向,定位到12点钟方向
103
+			progressContext: null, // 活动圆的canvas上下文
104
+			newPercent: 0, // 当动态修改进度值的时候,保存进度值的变化前后值,用于比较用
105
+			oldPercent: 0 // 当动态修改进度值的时候,保存进度值的变化前后值,用于比较用
106
+		};
107
+	},
108
+	watch: {
109
+		percent(nVal, oVal = 0) {
110
+			if (nVal > 100) nVal = 100;
111
+			if (nVal < 0) oVal = 0;
112
+			// 此值其实等于this.percent,命名一个新
113
+			this.newPercent = nVal;
114
+			this.oldPercent = oVal;
115
+			setTimeout(() => {
116
+				// 无论是百分比值增加还是减少,需要操作还是原来的旧的百分比值
117
+				// 将此值减少或者新增到新的百分比值
118
+				this.drawCircleByProgress(oVal);
119
+			}, 0);
120
+		}
121
+	},
122
+	created() {
123
+		// 赋值,用于加载后第一个画圆使用
124
+		this.newPercent = this.percent;
125
+		this.oldPercent = 0;
126
+	},
127
+	computed: {
128
+		// 有type主题时,优先起作用
129
+		circleColor() {
130
+			return this.activeColor
131
+		}
132
+	},
133
+	mounted() {
134
+		// 在h5端,必须要做一点延时才起作用,this.$nextTick()无效(HX2.4.7)
135
+		setTimeout(() => {
136
+			this.drawProgressBg();
137
+			this.drawCircleByProgress(this.oldPercent);
138
+		}, 50);
139
+	},
140
+	methods: {
141
+		drawProgressBg() {
142
+			let ctx = uni.createCanvasContext(this.elBgId, this);
143
+			ctx.setLineWidth(this.borderWidthPx); // 设置圆环宽度
144
+			ctx.setStrokeStyle(this.inactiveColor); // 线条颜色
145
+			ctx.beginPath(); // 开始描绘路径
146
+			// 设置一个原点(110,110),半径为100的圆的路径到当前路径
147
+			let radius = this.widthPx / 2;
148
+			ctx.arc(radius, radius, radius - this.borderWidthPx, 0, 2 * Math.PI, false);
149
+			ctx.stroke(); // 对路径进行描绘
150
+			ctx.draw();
151
+		},
152
+		drawCircleByProgress(progress) {
153
+			// 第一次操作进度环时将上下文保存到了this.data中,直接使用即可
154
+			let ctx = this.progressContext;
155
+			if (!ctx) {
156
+				ctx = uni.createCanvasContext(this.elId, this);
157
+				this.progressContext = ctx;
158
+			}
159
+			// 表示进度的两端为圆形
160
+			ctx.setLineCap('round');
161
+			// 设置线条的宽度和颜色
162
+			ctx.setLineWidth(this.borderWidthPx);
163
+			ctx.setStrokeStyle(this.circleColor);
164
+			// 将总过渡时间除以100,得出每修改百分之一进度所需的时间
165
+			let time = Math.floor(this.duration / 100);
166
+			// 结束角的计算依据为:将2π分为100份,乘以当前的进度值,得出终止点的弧度值,加起始角,为整个圆从默认的
167
+			// 3点钟方向开始画图,转为更好理解的12点钟方向开始作图,这需要起始角和终止角同时加上this.startAngle值
168
+			let endAngle = ((2 * Math.PI) / 100) * progress + this.startAngle;
169
+			ctx.beginPath();
170
+			// 半径为整个canvas宽度的一半
171
+			let radius = this.widthPx / 2;
172
+			ctx.arc(radius, radius, radius - this.borderWidthPx, this.startAngle, endAngle, false);
173
+			ctx.stroke();
174
+			ctx.draw();
175
+			// 如果变更后新值大于旧值,意味着增大了百分比
176
+			if (this.newPercent > this.oldPercent) {
177
+				// 每次递增百分之一
178
+				progress++;
179
+				// 如果新增后的值,大于需要设置的值百分比值,停止继续增加
180
+				if (progress > this.newPercent) return;
181
+			} else {
182
+				// 同理于上面
183
+				progress--;
184
+				if (progress < this.newPercent) return;
185
+			}
186
+			setTimeout(() => {
187
+				// 定时器,每次操作间隔为time值,为了让进度条有动画效果
188
+				this.drawCircleByProgress(progress);
189
+			}, time);
190
+		}
191
+	}
192
+};
193
+</script>
194
+
195
+<style lang="scss" scoped>
196
+// @import "../../libs/css/style.components.scss";
197
+.u-circle-progress {
198
+	position: relative;
199
+	/* #ifndef APP-NVUE */
200
+	display: inline-flex;		
201
+	/* #endif */
202
+	align-items: center;
203
+	justify-content: center;
204
+}
205
+
206
+.u-canvas-bg {
207
+	position: absolute;
208
+}
209
+
210
+.u-canvas {
211
+	position: absolute;
212
+}
213
+</style>

+ 22 - 1
http/api.js

@@ -275,4 +275,25 @@ export function api_getNotice(data){
275 275
  */
276 276
 export function api_getCount(data){
277 277
   return post("/repair/incident/count", data);
278
-}
278
+}
279
+
280
+/**
281
+ * 报修端-保存个人信息
282
+ */
283
+export function api_userSave(data){
284
+  return post("/user/data/addData/user", data);
285
+}
286
+
287
+/**
288
+ * 报修端-保存个人信息
289
+ */
290
+export function api_taskresolve(data){
291
+  return post("/flow/incident/task/resolve", data);
292
+}
293
+
294
+/**
295
+ * 报修端-提交报修
296
+ */
297
+export function api_request(data){
298
+  return post("/flow/incident/task/request", data);
299
+}

+ 2 - 2
manifest.json

@@ -62,8 +62,8 @@
62 62
         "devServer" : {
63 63
             "proxy" : {
64 64
                 "/service" : {
65
-                    // "target" : "http://192.168.3.111", //请求的目标域名
66
-										"target" : "http://192.168.4.163", //宋程玉本地
65
+                    "target" : "http://192.168.3.111", //请求的目标域名
66
+										// "target" : "http://192.168.4.163", //宋程玉本地
67 67
                     "changeOrigin" : true, //是否跨域
68 68
                     "secure" : false
69 69
                 },

+ 45 - 18
pages.json

@@ -182,7 +182,6 @@
182 182
 	     }
183 183
 	   }
184 184
 	 },
185
-<<<<<<< HEAD
186 185
 	 {
187 186
 		 "path": "pages/repair/home",
188 187
 		 "style": {
@@ -214,8 +213,31 @@
214 213
 				 "titleNView": false
215 214
 			 }
216 215
 		 }
217
-	 }
218
-=======
216
+	 },
217
+	 {
218
+		 "path": "pages/repair/config",
219
+		 "style": {
220
+			 "h5": {
221
+				 "titleNView": false
222
+			 }
223
+		 }
224
+	 },
225
+	 {
226
+		 "path": "pages/repair/deptSelect",
227
+		 "style": {
228
+			 "h5": {
229
+				 "titleNView": false
230
+			 }
231
+		 }
232
+	 },
233
+	 {
234
+		 "path": "pages/repair/repairsDetail",
235
+		 "style": {
236
+			 "h5": {
237
+				 "titleNView": false
238
+			 }
239
+		 }
240
+	 },
219 241
    {
220 242
      "path": "pages/inspection/inspectionExecute/inspectionExecute",
221 243
      "style": {
@@ -233,7 +255,6 @@
233 255
        }
234 256
      }
235 257
    }
236
->>>>>>> f04f9a92e4933a3c5cda21806e1a8f4c5698e134
237 258
   ],
238 259
   "globalStyle": {
239 260
     "navigationBarTextStyle": "black",
@@ -246,35 +267,41 @@
246 267
     "borderStyle": "black",
247 268
     "backgroundColor": "#ffffff",
248 269
     "list": [
249
-			// {
250
-			//   "pagePath": "pages/repair/home",
251
-			//   "iconPath": "static/img/icon_index.png",
252
-			//   "selectedIconPath": "static/img/icon_index_active.png",
253
-			//   "text": "首页"
254
-			// },
255 270
 			{
256 271
       "pagePath": "pages/incidentList/incidentList",
257 272
       "iconPath": "static/img/icon_incidentList.png",
258 273
       "selectedIconPath": "static/img/icon_incidentList_active.png",
259
-      "text": "故障"
274
+      "text": "故障",
275
+			"visible": false
260 276
 			}, 
261 277
 			{
262
-			"pagePath": "pages/repair/home",
263
-			"iconPath": "static/img/icon_repairList.png",
264
-			"selectedIconPath": "static/img/icon_repairList_active.png",
265
-			"text": "我的报修"
266
-			}, {
267 278
       "pagePath": "pages/inspection/inspectionExecute/inspectionExecute",
268 279
       "iconPath": "static/img/icon_inspectionExecute.png",
269 280
       "visible": false,
270 281
       "selectedIconPath": "static/img/icon_inspectionExecute_active.png",
271 282
       "text": "巡检"
272
-    }, {
283
+			}, 
284
+			{
285
+			"pagePath": "pages/repair/home",
286
+			"iconPath": "static/img/icon_inspectionExecute.png",
287
+			"selectedIconPath": "static/img/icon_inspectionExecute_active.png",
288
+			"text": "我的报修",
289
+			"visible": false
290
+			}, 
291
+			{
273 292
       "pagePath": "pages/my/my",
274 293
       "iconPath": "static/img/icon_my.png",
275 294
       "selectedIconPath": "static/img/icon_my_active.png",
276
-      "text": "我的"
295
+      "text": "我的",
296
+			"visible": false
277 297
 			},
298
+			{
299
+			"pagePath": "pages/repair/config",
300
+			"iconPath": "static/img/icon_my.png",
301
+			"selectedIconPath": "static/img/icon_my_active.png",
302
+			"text": "设置",
303
+			"visible": false
304
+			}
278 305
 		]
279 306
   }
280 307
 }

+ 14 - 2
pages/homePage/homePage.vue

@@ -10,7 +10,7 @@
10 10
   import { encryptByEnAESLogin } from '@/utils/index.js'
11 11
   import { onLoad } from '@dcloudio/uni-app'
12 12
   import { defaultColor } from '@/static/js/theme.js'
13
-  import { api_wechatLoginEncrypt, api_loginEncrypt } from "@/http/api.js"
13
+  import { api_wechatLoginEncrypt, api_loginEncrypt, api_systemConfiguration } from "@/http/api.js"
14 14
   import { useWechatAuth } from '@/share/useWechatAuth.js'
15 15
   import { useLoginSuccess } from '@/share/useLoginSuccess.js'
16 16
   import { useSetTitle } from '@/share/useSetTitle.js'
@@ -39,6 +39,7 @@
39 39
         uni.hideLoading();
40 40
         if (res.state == 200) {
41 41
           loginSuccess(res.user);
42
+					getConfig();
42 43
         } else if (res.state == 501) {
43 44
           uni.showModal({
44 45
             title: '提示',
@@ -74,6 +75,7 @@
74 75
     };
75 76
     api_loginEncrypt(postData).then(res => {
76 77
       uni.hideLoading();
78
+			getConfig();
77 79
       if (res.state == 200) {
78 80
         loginSuccess(res.data);
79 81
       } else {
@@ -84,7 +86,17 @@
84 86
       }
85 87
     });
86 88
   }
87
-
89
+	
90
+	// 获取配置项
91
+	function getConfig(){
92
+		api_systemConfiguration({
93
+			idx: 0,
94
+			sum: 9999,
95
+		}).then(res=>{
96
+			uni.setStorageSync('sysData',JSON.stringify(res.list))
97
+		})
98
+	}
99
+	
88 100
   onLoad((option) => {
89 101
     uni.clearStorageSync();
90 102
     // 获取当前页面的实例

+ 3 - 2
pages/incidentList/incidentList.vue

@@ -377,8 +377,9 @@
377 377
   }
378 378
 
379 379
   onLoad((option) => {
380
-    // 巡检tabbar
381
-    setTabbar(1);
380
+    for(let i = 0; i<5; i++){
381
+    	setTabbar(i)
382
+    }
382 383
     onLoadFn();
383 384
   })
384 385
 

+ 3 - 2
pages/inspection/inspectionExecute/inspectionExecute.vue

@@ -272,8 +272,9 @@
272 272
   }
273 273
 
274 274
   onLoad((option) => {
275
-    // 巡检tabbar
276
-    setTabbar(1);
275
+    for(let i = 0; i<5; i++){
276
+    	setTabbar(i)
277
+    }
277 278
     onLoadFn();
278 279
   })
279 280
 

+ 3 - 2
pages/my/my.vue

@@ -158,8 +158,9 @@
158 158
   }
159 159
   
160 160
   onLoad((option) => {
161
-    // 巡检tabbar
162
-    setTabbar(1);
161
+    for(let i = 0; i<5; i++){
162
+    	setTabbar(i)
163
+    }
163 164
     onLoadFn();
164 165
   })
165 166
   

+ 131 - 0
pages/repair/appraise.vue

@@ -0,0 +1,131 @@
1
+<template>
2
+	<view class="bgColor">
3
+	    <view class="rapirMessage">
4
+	        <view class="label">
5
+	            报修信息
6
+	        </view>
7
+	        <view class="state">
8
+	            <view>工单单号:&nbsp;{{data.incidentsign}}</view>
9
+	            <view :class="stateClassFn(data.state.name)">{{data.state.name}}</view>
10
+	        </view>
11
+	        <view class="description">
12
+	            <view>
13
+	                报修内容:
14
+	            </view>
15
+	            <view>
16
+	                {{data.description||"暂无"}}
17
+	            </view>
18
+	        </view>
19
+	        <view class="ipt">
20
+	            <view>
21
+	                报修图片:
22
+	            </view>
23
+	            <view class="imgs-container">
24
+	                <img :src="img" v-for="(img, index) in imgs_wechatRequesterIncident" :key="index" @click="handleImgsClick(index, 'wechatRequesterIncident')" v-if="imgs_wechatRequesterIncident.length">
25
+	                <span v-if="!imgs_wechatRequesterIncident.length">暂无</span>
26
+	            </view>
27
+	        </view>
28
+	        <view class="ipt">
29
+	            <view>
30
+	                处理图片:
31
+	            </view>
32
+	            <view class="imgs-container">
33
+	              <img :src="img" v-for="(img, index) in imgs_incident" :key="index" @click="handleImgsClick(index, 'incident')" v-if="imgs_incident.length">
34
+	              <span v-if="!imgs_incident.length">暂无</span>
35
+	            </view>
36
+	        </view>
37
+	        <view class="faultLocation">
38
+	            <view>
39
+	                报修地址:
40
+	            </view>
41
+	            <view>
42
+	                {{data.houseNumber}}
43
+	            </view>
44
+	        </view>
45
+	    </view>
46
+	    <view class="label">
47
+	        报修评价
48
+	    </view>
49
+	    <view class="rate">
50
+	        <span class="pj">评价:</span><cube-rate v-model="rate"></cube-rate>
51
+	    </view>
52
+	    <view class="rateText">
53
+	        <cube-textarea v-model="rateText" placeholder="您可以从响应速度、解决情况、服务态度等方面,给我们作出相应的评价"></cube-textarea>
54
+	    </view>
55
+	    <view class="chehuiBox">
56
+	
57
+	    </view>
58
+	    <view class="chehui">
59
+	        <view class="btn" @click="evaluate()">提&nbsp;交&nbsp;评&nbsp;价</view>
60
+	    </view>
61
+	    <promp-ting :conents="promptingConent" :status="promptingStatus"></promp-ting>
62
+	    <load-ing v-show="loadShow"></load-ing>
63
+	</view>
64
+</template>
65
+
66
+<script setup>
67
+	import { startOfDay, endOfDay, format, add } from 'date-fns'
68
+	import { ref, reactive, computed } from 'vue'
69
+	import { onLoad, onShow, onPullDownRefresh, onReachBottom, onTabItemTap } from '@dcloudio/uni-app'
70
+	import { api_getDictionary, api_taskresolve,} from "@/http/api.js"
71
+	import { filterFormatDate } from '@/filters/filterFormatDate.js'
72
+	import { computedPriorityStyle } from '@/filters/computedPriorityStyle.js'
73
+	import { computedStateStyle } from '@/filters/computedStateStyle.js'
74
+	import { computedCurrentLogOverTime } from '@/filters/computedCurrentLogOverTime.js'
75
+	import { defaultColor } from '@/static/js/theme.js'
76
+	import { useSetTitle } from '@/share/useSetTitle.js'
77
+	import { useMakePhoneCall } from '@/share/useMakePhoneCall.js'
78
+	import { useLoginUserStore } from '@/stores/loginUser'
79
+	import { useIncidentNumStore } from '@/stores/incidentNum'
80
+	import { useIncidentListSearchStore } from '@/stores/incidentListSearch'
81
+	
82
+	
83
+	useSetTitle();
84
+	const loginUserStore = useLoginUserStore();
85
+	const incidentNumStore = useIncidentNumStore();
86
+	const incidentListSearchStore = useIncidentListSearchStore();
87
+	const { formatDate }  = filterFormatDate();
88
+	const { priorityStyle }  = computedPriorityStyle();
89
+	const { stateStyle }  = computedStateStyle();
90
+	const { currentLogOverTime }  = computedCurrentLogOverTime();
91
+	const { makePhoneCall }  = useMakePhoneCall();
92
+	
93
+	// 主题颜色
94
+	const primaryColor = ref(defaultColor)
95
+	
96
+	const assignFlag = ref(false);//指派权限
97
+	const qiangdan = ref(false);//接单权限
98
+	const deptRepair = ref({});//科内报修
99
+	const publicRepair = ref({});//公共报修
100
+	// 数据
101
+	const dataInfo = reactive({
102
+	  tabs: [{id: 0, name: '我的报修', value: 'all', num: ''},],
103
+	  tabActiveId: 0,//当前选择的tab
104
+	  list: [],//工单列表
105
+	  idx: 0,//页码
106
+	  hasMore: true,//是否有更多数据
107
+	  isFilter: false,//筛选框开关
108
+	  isAttachment: false,//图片和录音开关
109
+	  incidentId: undefined,
110
+		stateValue:0,
111
+	  evtFilter: {
112
+	    hospital: {},
113
+	    selected: 'todoingAll',
114
+	    area: {id: 0, area: '全部'},
115
+	    category: {id: 0, category: '全部'},
116
+	    acceptDate: [],
117
+	  }
118
+	})
119
+	
120
+	function (){
121
+		api_taskresolve().then(res=>{
122
+			
123
+		})
124
+	}
125
+	onLoad((option) => {
126
+		console.log(option)
127
+	})
128
+</script>
129
+
130
+<style>
131
+</style>

+ 360 - 0
pages/repair/config.vue

@@ -0,0 +1,360 @@
1
+<template>
2
+  <view class="mine">
3
+    <scroll-view scroll-y class="body">
4
+      <view class="bottom">
5
+        <view class="bottom_name">个人信息</view>
6
+        <view class="bottom_list">
7
+          <view class="bottom_list_item">
8
+            <view class="name"><text class="required newicon newicon-bitian"></text>工号</view>
9
+            <view class="value no-mar">{{loginUserStore.loginUser.user.account}}</view>
10
+          </view>
11
+					<view class="bottom_list_item">
12
+					  <view class="name"><text class="required newicon newicon-bitian"></text>姓名</view>
13
+					  <view class="value no-mar">{{loginUserStore.loginUser.user.name}}</view>
14
+					</view>
15
+					<view class="bottom_list_item">
16
+					  <view class="name"><text class="required newicon newicon-bitian"></text>院区名称</view>
17
+						<uni-data-picker class="value" placeholder="请选择院区名称"
18
+							v-model="dataForm.branch" :localdata="branchData"
19
+							:clear-icon="false" :class="{formRed: isSubmit && !dataForm.branch}">
20
+						</uni-data-picker>
21
+						<text class="newicon newicon-youjiantou icon"></text>
22
+					</view>
23
+					<view class="bottom_list_item" v-if="deptRepair.valueconfig==1">
24
+					  <view class="name"><text class="required newicon newicon-bitian"></text>科室名称</view>
25
+						<uni-data-picker class="value" placeholder="请选择报修科室"
26
+							v-model="dataForm.dept" :localdata="deptData"
27
+							:clear-icon="false" :class="{formRed: isSubmit && !dataForm.dept}">
28
+						</uni-data-picker>
29
+						<text class="newicon newicon-youjiantou icon"></text>
30
+					</view>
31
+					<view class="bottom_list_item" v-if="deptRepair.valueconfig==1" @click="deptSelect">
32
+					  <view class="name">常用科室</view>
33
+					  <view class="value">{{commonDeptName}}</view>
34
+						<text class="newicon newicon-youjiantou icon"></text>
35
+					</view>
36
+          <view class="bottom_list_item">
37
+            <view class="name"><text class="required newicon newicon-bitian"></text>联系电话</view>
38
+            <view class="value no-mar" @click="makePhoneCall(loginUserStore.loginUser.user.phone)">{{loginUserStore.loginUser.user.phone}}</view>
39
+          </view>
40
+        </view>
41
+      </view>
42
+    </scroll-view>
43
+    <view class="foot_common_btns">
44
+			<button @click="addInfo" type="default" class="primaryButton btn">保存</button>
45
+    </view>
46
+  </view>
47
+</template>
48
+
49
+<script setup>
50
+  import { ref, reactive } from 'vue'
51
+  import { onLoad, onTabItemTap } from '@dcloudio/uni-app'
52
+  import { api_userSave, api_department, api_branch, api_systemConfiguration} from "@/http/api.js"
53
+  import { defaultColor } from '@/static/js/theme.js'
54
+  import { useSetTitle } from '@/share/useSetTitle.js'
55
+  import { useMakePhoneCall } from '@/share/useMakePhoneCall.js'
56
+  import { useLoginUserStore } from '@/stores/loginUser'
57
+  import { useIncidentNumStore } from '@/stores/incidentNum'
58
+  import { repositoryListSearchStore } from '@/stores/repositorySearch'
59
+  import { useSetTabbar } from '@/share/useSetTabbar.js'
60
+	
61
+  useSetTitle();
62
+  const loginUserStore = useLoginUserStore();
63
+  const incidentNumStore = useIncidentNumStore();
64
+  const { makePhoneCall }  = useMakePhoneCall();
65
+  const repositorySearchStore = repositoryListSearchStore();
66
+  const { setTabbar }  = useSetTabbar();
67
+	
68
+  // 主题颜色
69
+  const primaryColor = ref(defaultColor)
70
+  
71
+	const deptRepair = ref(null)
72
+	
73
+	const deptData = ref([])
74
+	
75
+	const branchData = ref([])
76
+	
77
+	const commonDeptName = ref(null)
78
+	
79
+	const commonDeptData = ref(null)
80
+	
81
+	const dataForm = reactive({
82
+	  dept: '',
83
+		branch:''
84
+	})
85
+	
86
+	const userData = reactive(loginUserStore.loginUser.user)
87
+	
88
+	const commonDeptDTO = ref([])
89
+	
90
+	// 是否提交
91
+	const isSubmit = ref(false)
92
+	
93
+  // 数据
94
+  const dataInfo = reactive({
95
+    todo: 0,
96
+    doing: 0,
97
+    owns: 0,
98
+    resolve: 0,
99
+  })
100
+  
101
+  // 保存
102
+  function addInfo(){
103
+    isSubmit.value = true
104
+		uni.showLoading({
105
+		  title: "加载中",
106
+		  mask: true,
107
+		});
108
+		userData.branch.id = dataForm.branch
109
+		userData.commonDeptName = commonDeptName.value
110
+		userData.dept={
111
+			id:dataForm.dept
112
+		}
113
+		let arr = []
114
+		for(let i of commonDeptDTO.value){
115
+			arr.push({
116
+				dept:i
117
+			})
118
+		}
119
+		let postData = {
120
+			...loginUserStore.loginUser.user,
121
+			commonDept:commonDeptData.value,
122
+			commonDeptDTO:arr
123
+		}
124
+		api_userSave({
125
+		  user: postData,
126
+		}).then(res => {
127
+		  uni.hideLoading();
128
+			if(res.status == 200){
129
+				loginUserStore.setLoginUser(postData);
130
+				uni.showToast({
131
+				  icon: 'none',
132
+				  title: '保存成功'
133
+				});
134
+			}else{
135
+				uni.showToast({
136
+				  icon: 'none',
137
+				  title: res.msg || '请求数据失败!'
138
+				});
139
+			}
140
+		})
141
+  }
142
+  
143
+	// 获取科室列表
144
+	function getRepairTypes(){
145
+	  uni.showLoading({
146
+	    title: "加载中",
147
+	    mask: true,
148
+	  });
149
+	  let postData = {
150
+			department: {
151
+			  branch: '',
152
+			},
153
+			idx:0,
154
+			sum:9999
155
+		}
156
+		if(loginUserStore.loginUser.user.duty){
157
+		  postData.department.branch = loginUserStore.loginUser.user.duty.id;
158
+		}else if(loginUserStore.loginUser.user.branch){
159
+		  postData.department.branch = loginUserStore.loginUser.user.branch.id;
160
+		}
161
+	  api_department(postData).then(res => {
162
+	    uni.hideLoading();
163
+			getBranch()
164
+	    res = res.list || [];
165
+	    deptData.value = res.map(v => ({
166
+	      text: v.dept,
167
+	      value: v.id,
168
+	    }));
169
+	  })
170
+	}
171
+	
172
+	// 获取院区列表
173
+	function getBranch(){
174
+		let postData = {
175
+			branch:'',
176
+			idx:0,
177
+			sum:9999
178
+		}
179
+		if(loginUserStore.loginUser.user.duty){
180
+		  postData.branch = loginUserStore.loginUser.user.duty.id;
181
+		}else if(loginUserStore.loginUser.user.branch){
182
+		  postData.branch = loginUserStore.loginUser.user.branch.id;
183
+		}
184
+		api_branch(postData).then(res => {
185
+		  uni.hideLoading();
186
+		  res = res.list || [];
187
+		  branchData.value = res.map(v => ({
188
+		    text: v.hosName,
189
+		    value: v.id,
190
+		  }));
191
+		})
192
+	}
193
+	
194
+	// 选择常用科室
195
+	function deptSelect(){
196
+		uni.setStorageSync('configData',JSON.stringify(dataForm))
197
+		let data = commonDeptData.value ? 
198
+		commonDeptData.value : loginUserStore.loginUser.user.commonDept
199
+		if(!data){
200
+			data = null
201
+		}
202
+		uni.navigateTo({
203
+		  url: '/pages/repair/deptSelect?data='+JSON.stringify(data)
204
+		})
205
+	}
206
+	
207
+  // 初始化
208
+  function onLoadFn(){
209
+		let data = JSON.parse(uni.getStorageSync('sysData'))
210
+		deptRepair.value = data.find(i=>i.keyconfig=='deptRepair')
211
+		getRepairTypes()
212
+  }
213
+  
214
+  onLoad((option) => {
215
+		if(option.data){
216
+			let data = JSON.parse(option.data)
217
+			commonDeptData.value = data.data.join(',')
218
+			commonDeptName.value = data.name.join('/')
219
+			commonDeptDTO.value = data.name
220
+		}else{
221
+			let user = loginUserStore.loginUser.user
222
+			if(user){
223
+				dataForm.branch = user.branch.id
224
+				dataForm.dept = user.dept.id
225
+				if(user.commonDeptDTO){
226
+					let dept = user.commonDeptDTO.map(i=>{
227
+						return i.dept
228
+					})
229
+					commonDeptName.value = dept.join('/')
230
+				}else{
231
+					commonDeptName.value = user.commonDeptName
232
+				}
233
+			}
234
+		}
235
+		let data = uni.getStorageSync('configData')
236
+		if(data){
237
+			data = JSON.parse(data)
238
+			dataForm.dept = data.dept
239
+			dataForm.branch = data.branch
240
+		}
241
+		for(let i = 0; i<5; i++){
242
+			setTabbar(i)
243
+		}
244
+    onLoadFn();
245
+  })
246
+  
247
+  onTabItemTap(e => {
248
+    onLoadFn();
249
+  })
250
+</script>
251
+
252
+<style scoped>
253
+	>>> .uni-data-tree-input{
254
+		width: 100% !important;
255
+	}
256
+	>>> .input-value-border{
257
+		border: none !important;
258
+	}
259
+	>>> .input-value{
260
+		padding:0 !important;
261
+		flex-direction: row-reverse !important;
262
+	}
263
+	>>> .selected-list{
264
+		flex-direction: row-reverse !important;
265
+	}
266
+	>>> .arrow-area{
267
+		display: none !important;
268
+	}
269
+	>>>.uni-data-tree-dialog{
270
+		z-index: 9999;
271
+	}
272
+</style>
273
+<style lang="scss" scoped>
274
+page{
275
+  height: calc(100vh - var(--window-bottom));
276
+  background-color: #EBEBEB;
277
+}
278
+.mine{
279
+  height: 100%;
280
+  display: flex;
281
+  flex-direction: column;
282
+  justify-content: space-between;
283
+  .phone-filled{
284
+    margin-right: 5rpx;
285
+  }
286
+  .newicon-xinjian2,
287
+	.newicon-zhishiku{
288
+    margin-right: 10rpx;
289
+  }
290
+  .body{
291
+    width: 714rpx;
292
+    height: 100%;
293
+    margin: 16rpx auto var(--window-bottom) auto;
294
+    box-sizing: border-box;
295
+    border-radius: 8rpx;
296
+    .top{
297
+      padding: 30rpx;
298
+      background-color: #fff;
299
+      .top_name{
300
+        font-size: 28rpx;
301
+        font-weight: bold;
302
+      }
303
+      .top_count{
304
+        margin-top: 45rpx;
305
+        display: flex;
306
+        align-items: center;
307
+        justify-content: space-between;
308
+        .top_count_item{
309
+          text-align: center;
310
+          .name{
311
+            color: #949494;
312
+            font-size: 22rpx;
313
+          }
314
+          .value{
315
+            font-size: 50rpx;
316
+            font-weight: bold;
317
+            margin-top: 15rpx;
318
+          }
319
+        }
320
+      }
321
+    }
322
+    
323
+    .bottom{
324
+      background-color: #fff;
325
+      margin-top: 15rpx;
326
+      .bottom_name{
327
+        font-size: 26rpx;
328
+        color: $uni-primary;
329
+        padding: 21rpx 24rpx;
330
+      }
331
+      .bottom_list{
332
+        .bottom_list_item{
333
+          border-top: 1rpx solid #DEDEDE;
334
+          padding: 30rpx 30rpx 30rpx 30rpx;
335
+          display: flex;
336
+          justify-content: space-between;
337
+          align-items: center;
338
+          font-size: 24rpx;
339
+					position: relative;
340
+          .value{
341
+            max-width: 380rpx;
342
+            color: #333;
343
+            display: flex;
344
+            align-items: center;
345
+            text-align: justify;
346
+						margin-right: 30rpx;
347
+          }
348
+					.no-mar{
349
+						margin-right:0 !important;
350
+					}
351
+					.icon{
352
+						position: absolute;
353
+						right: 20rpx;
354
+					}
355
+        }
356
+      }
357
+    }
358
+  }
359
+}
360
+</style>

+ 265 - 0
pages/repair/deptSelect.vue

@@ -0,0 +1,265 @@
1
+<template>
2
+  <view class="mine">
3
+    <scroll-view scroll-y class="body">
4
+      <view class="bottom">
5
+        <checkbox-group @change="checkboxChange" :value="optionData">
6
+					<label class="litem-list" v-for="item in deptData" :key="item.value">
7
+						<view>{{item.text}}</view>
8
+						<checkbox :value="item.value" color="#49b856" :checked="item.checked" />
9
+					</label>
10
+				</checkbox-group>
11
+      </view>
12
+    </scroll-view>
13
+    <view class="foot_common_btns">
14
+    	<button @click="goBackOrToList" type="default" class="cancelButton btn">返回</button>
15
+    	<button @click="submit" type="default" class="primaryButton btn">确认</button>
16
+    </view>
17
+  </view>
18
+</template>
19
+
20
+<script setup>
21
+  import { ref, reactive } from 'vue'
22
+  import { onLoad, onTabItemTap } from '@dcloudio/uni-app'
23
+  import { api_incident_count, api_department, api_branch} from "@/http/api.js"
24
+  import { defaultColor } from '@/static/js/theme.js'
25
+  import { useSetTitle } from '@/share/useSetTitle.js'
26
+  import { useMakePhoneCall } from '@/share/useMakePhoneCall.js'
27
+  import { useLoginUserStore } from '@/stores/loginUser'
28
+  import { useIncidentNumStore } from '@/stores/incidentNum'
29
+  import { repositoryListSearchStore } from '@/stores/repositorySearch'
30
+  import { useSetTabbar } from '@/share/useSetTabbar.js'
31
+	import { useGoBack } from '@/share/useGoBack.js'
32
+	
33
+  useSetTitle();
34
+  const loginUserStore = useLoginUserStore();
35
+  const incidentNumStore = useIncidentNumStore();
36
+  const { makePhoneCall }  = useMakePhoneCall();
37
+  const repositorySearchStore = repositoryListSearchStore();
38
+  const { setTabbar }  = useSetTabbar();
39
+	const { goBack }  = useGoBack();
40
+	
41
+	const deptData = ref([])
42
+	
43
+	const dataForm = reactive({
44
+	  dept: '',
45
+		branch:''
46
+	})
47
+	
48
+	const deptSelectData = ref(null)
49
+	const deptSelectName = ref(null)
50
+	const checkBox = ref([])
51
+	const optionData = ref(null)
52
+	
53
+	// 是否提交
54
+	const isSubmit = ref(false)
55
+  
56
+	// 上一步或者返回列表
57
+	function goBackOrToList(){
58
+	  goBack();
59
+	}
60
+	
61
+	function checkboxChange (e) {
62
+		var items = deptData.value;
63
+		let values = e.detail.value;
64
+		deptSelectName.value = []
65
+		for (var i = 0, lenI = items.length; i < lenI; ++i) {
66
+			const item = items[i]
67
+			if(values.includes(item.value)){
68
+				deptSelectName.value.push(item)
69
+			}
70
+		}
71
+	}
72
+				
73
+	// 获取科室列表
74
+	function getRepairTypes(){
75
+	  uni.showLoading({
76
+	    title: "加载中",
77
+	    mask: true,
78
+	  });
79
+	  let postData = {
80
+			department: {
81
+			  branch: '',
82
+			},
83
+			idx:0,
84
+			sum:9999
85
+		}
86
+		if(loginUserStore.loginUser.user.duty){
87
+		  postData.department.branch = loginUserStore.loginUser.user.duty.id;
88
+		}else if(loginUserStore.loginUser.user.branch){
89
+		  postData.department.branch = loginUserStore.loginUser.user.branch.id;
90
+		}
91
+	  api_department(postData).then(res => {
92
+	    uni.hideLoading();
93
+	    res = res.list || [];
94
+	    deptData.value = res.map(v => ({
95
+	      text: v.dept,
96
+	      value: v.id+'',
97
+				checked: false
98
+	    }));
99
+			for(let i of deptData.value){
100
+				for(let t of optionData.value){
101
+					if(i.value == Number(t)){
102
+						i.checked = true
103
+					}
104
+				}
105
+			}
106
+			if(optionData.value){
107
+				checkBox.value = optionData.value
108
+			}
109
+	  })
110
+	}
111
+	
112
+	function submit(){
113
+		if(!deptSelectName.value){
114
+			uni.showToast({
115
+				icon: 'none',
116
+			  title: '请先选择科室'
117
+			});
118
+			return
119
+		}
120
+		let id = []
121
+		let name = []
122
+		for(let i of deptSelectName.value){
123
+			id.push(i.value)
124
+			name.push(i.text)
125
+		}
126
+		let data = {
127
+			data:id,
128
+			name:name
129
+		}
130
+		uni.reLaunch({
131
+		  url: '/pages/repair/config?data='+JSON.stringify(data)
132
+		})
133
+	}
134
+	
135
+  // 初始化
136
+  function onLoadFn(){
137
+		getRepairTypes()
138
+  }
139
+  
140
+  onLoad((option) => {
141
+		if(option.data!=null){
142
+			let data = JSON.parse(option.data).split(',')
143
+			optionData.value = data
144
+		}
145
+    onLoadFn();
146
+  })
147
+  
148
+  onTabItemTap(e => {
149
+    onLoadFn();
150
+  })
151
+</script>
152
+
153
+<style scoped>
154
+	>>> .uni-data-tree-input{
155
+		width: 100% !important;
156
+	}
157
+	>>> .input-value-border{
158
+		border: none !important;
159
+	}
160
+	>>> .input-value{
161
+		padding:0 !important;
162
+		flex-direction: row-reverse !important;
163
+	}
164
+	>>> .selected-list{
165
+		flex-direction: row-reverse !important;
166
+	}
167
+	>>> .arrow-area{
168
+		display: none !important;
169
+	}
170
+</style>
171
+<style lang="scss" scoped>
172
+.uni-checkbox-input:hover{
173
+	border-color:#49b856;
174
+}
175
+.mine{
176
+  display: flex;
177
+  flex-direction: column;
178
+  justify-content: space-between;
179
+	background: #fff;
180
+  .phone-filled{
181
+    margin-right: 5rpx;
182
+  }
183
+  .newicon-xinjian2,
184
+	.newicon-zhishiku{
185
+    margin-right: 10rpx;
186
+  }
187
+  .body{
188
+    height: 88vh;
189
+    // padding: 0 30rpx;
190
+    box-sizing: border-box;
191
+    border-radius: 8rpx;
192
+    .top{
193
+      padding: 30rpx;
194
+      background-color: #fff;
195
+      .top_name{
196
+        font-size: 28rpx;
197
+        font-weight: bold;
198
+      }
199
+      .top_count{
200
+        margin-top: 45rpx;
201
+        display: flex;
202
+        align-items: center;
203
+        justify-content: space-between;
204
+        .top_count_item{
205
+          text-align: center;
206
+          .name{
207
+            color: #949494;
208
+            font-size: 22rpx;
209
+          }
210
+          .value{
211
+            font-size: 50rpx;
212
+            font-weight: bold;
213
+            margin-top: 15rpx;
214
+          }
215
+        }
216
+      }
217
+    }
218
+    
219
+    .bottom{
220
+      background-color: #fff;
221
+      margin-top: 15rpx;
222
+			.litem-list{
223
+				display: flex;
224
+				justify-content: space-between;
225
+				height: 70rpx;
226
+				align-items: center;
227
+				border-bottom: 1px solid #f5f5f5;
228
+				padding: 0 20rpx;
229
+				font-size: 28rpx;
230
+			}
231
+      .bottom_name{
232
+        font-size: 26rpx;
233
+        color: $uni-primary;
234
+        padding: 21rpx 24rpx;
235
+      }
236
+      .bottom_list{
237
+        .bottom_list_item{
238
+          border-top: 1rpx solid #DEDEDE;
239
+          padding: 30rpx 30rpx 30rpx 30rpx;
240
+          display: flex;
241
+          justify-content: space-between;
242
+          align-items: center;
243
+          font-size: 24rpx;
244
+					position: relative;
245
+          .value{
246
+            max-width: 380rpx;
247
+            color: #333;
248
+            display: flex;
249
+            align-items: center;
250
+            text-align: justify;
251
+						margin-right: 30rpx;
252
+          }
253
+					.no-mar{
254
+						margin-right:0 !important;
255
+					}
256
+					.icon{
257
+						position: absolute;
258
+						right: 20rpx;
259
+					}
260
+        }
261
+      }
262
+    }
263
+  }
264
+}
265
+</style>

+ 27 - 31
pages/repair/home.vue

@@ -13,7 +13,7 @@
13 13
 				</view>
14 14
 				<view>
15 15
 					<view class="con-title">本月维修费用(元)</view>
16
-					<view class="con-value-gr">{{repairData.deptCurrentMonthPrice}}</view>
16
+					<view class="con-value-gr">{{repairData.deptCurrentMonthPrice || 0}}</view>
17 17
 				</view>
18 18
 		  </view>
19 19
 		</view>
@@ -63,10 +63,10 @@
63 63
 	import { api_systemConfiguration, api_getNotice, api_getCount } from "@/http/api.js"
64 64
 	import { useSetTitle } from '@/share/useSetTitle.js'
65 65
 	import { repositoryListSearchStore } from '@/stores/repositorySearch'
66
+	import { useSetTabbar } from '@/share/useSetTabbar.js'
66 67
 	useSetTitle();
67
-	
68
+	const { setTabbar }  = useSetTabbar();
68 69
 	// 数据
69
-	const sysData = ref({})
70 70
 	const isDept = ref({})
71 71
 	const isRepair = ref({})
72 72
 	const noticeData = ref('')
@@ -105,6 +105,10 @@
105 105
 	
106 106
 	// 获取报修数量
107 107
 	function getCount(){
108
+		uni.showLoading({
109
+		  title: "加载中",
110
+		  mask: true,
111
+		});
108 112
 		api_getCount({}).then(res=>{
109 113
 			repairData.value = res.data
110 114
 			getNotice()
@@ -113,6 +117,13 @@
113 117
 	
114 118
 	// 快速报修
115 119
 	function addRepairs(){
120
+		if(isDept.value.valueconfig==0 && isRepair.value.valueconfig==0){
121
+			uni.showToast({
122
+				icon: 'none',
123
+			  title: '请先开启科室报修或公共报修'
124
+			});
125
+			return
126
+		}
116 127
 		uni.navigateTo({
117 128
 		  url: '/pages/repair/rapidRep'
118 129
 		})
@@ -120,25 +131,16 @@
120 131
 	
121 132
 	// 扫资产报修
122 133
 	function scanCodes(){
134
+		uni.showToast({
135
+			icon: 'none',
136
+		  title: '暂未开通'
137
+		});
138
+		return;
123 139
 		SM().then((res) => {
124 140
 		  let postData = {
125 141
 		    code: ress1,
126 142
 		    account: loginUserStore.loginUser.user.account,
127 143
 		  };
128
-		  // api_scanCode(postData).then((res) => {
129
-		  //   uni.hideLoading();
130
-		  //   if (res.status == 200) {
131
-		  //     inspectionValueStore.setInspectionValueData(res.data);
132
-		  //     uni.navigateTo({
133
-		  //       url: `/pages/inspection/inspectionValue/inspectionValue?inspectionExecuteId=${data.id}`
134
-		  //     })
135
-		  //   } else {
136
-		  //     uni.showToast({
137
-		  //       icon: 'none',
138
-		  //       title: res.msg || '请求数据失败!'
139
-		  //     });
140
-		  //   }
141
-		  // });
142 144
 		})
143 145
 	}
144 146
 	
@@ -150,23 +152,17 @@
150 152
 	}
151 153
 	
152 154
 	onLoad((option) => {
153
-		
155
+		// 巡检tabbar
156
+		for(let i = 0; i<5; i++){
157
+			setTabbar(i)
158
+		}
154 159
 	})
155 160
 	
156 161
 	onShow((option) => {
157
-		uni.showLoading({
158
-		  title: "加载中",
159
-		});
160
-	  api_systemConfiguration({
161
-			idx: 0,
162
-			sum: 9999,
163
-		}).then(res=>{
164
-			sysData.value = res.list
165
-			isDept.value = res.list.find(i=>i.keyconfig=='deptRepair')
166
-			isRepair.value = res.list.find(i=>i.keyconfig=='cmdbRepair')
167
-			uni.setStorageSync('sysData',JSON.stringify(res.list))
168
-			getCount()
169
-		})
162
+		getCount()
163
+		let data = JSON.parse(uni.getStorageSync('sysData'))
164
+		isDept.value = data.find(i=>i.keyconfig=='deptRepair')
165
+		isRepair.value = data.find(i=>i.keyconfig=='cmdbRepair')
170 166
 	})
171 167
 	
172 168
 

+ 267 - 138
pages/repair/rapidRep.vue

@@ -3,21 +3,21 @@
3 3
 		<view class="body view-body">
4 4
 			<view class="form_item column">
5 5
 				<view class="title"><text class="required newicon newicon-bitian"></text>故障描述:</view>
6
-				<uni-easyinput class="value" type="textarea" v-model="dataInfo.deferralRemark" placeholder="请输入故障描述" :class="{formRed: isSubmit && !dataInfo.deferralRemark.trim()}" />
6
+				<uni-easyinput class="value" type="textarea" v-model="dataInfo.description" placeholder="请输入故障描述" :class="{formRed: isSubmit && !dataInfo.description.trim()}" />
7 7
 			</view>
8
-			<view class="candidate">
8
+		<!-- 	<view class="candidate">
9 9
 				<view class="candidate-item" v-for="item in candidateData" :key="item" @click="itemCandidate(item)">{{item.name}}</view>
10
-			</view>
10
+			</view> -->
11 11
 			<view class="form_item" v-if="cmdbRepair.valueconfig==1">
12 12
 				<view class="title select">关联资产:</view>
13
-				<input class="item-input" focus placeholder="请扫描资产卡二维码" v-model="dataInfo.property"/>
13
+				<input class="item-input" placeholder="请扫描资产卡二维码" v-model="dataInfo.property"/>
14 14
 				<text class="newicon newicon-saoma icon" @click="scanCodes"></text>
15 15
 			</view>
16 16
 			<view class="form_item">
17 17
 				<view class="title">照片录像:</view>
18 18
 				<view class="value">
19 19
 					<uni-file-picker ref="handlerImgRef" v-model="dataInfo.handlerImgList"
20
-					 limit="4" @success="handlerImgSuccess" 
20
+					 limit="4" @success="handlerImgSuccess" file-mediatype="all" mode="grid"
21 21
 					@fail="handlerImgFail" @select="handlerImgSelect" @delete="handlerImgDelete">
22 22
 					</uni-file-picker>
23 23
 					<view class="imgTips">(支持JPG/PNG格式图片,单张大小3M以内,录像支持30秒)</view>
@@ -25,10 +25,13 @@
25 25
 			</view>
26 26
 			<view class="form_item">
27 27
 				<view class="title">录音:</view>
28
-				<view class="chunk" v-if="!dataInfo.recBlob" @click="examineRecord" @mouseup="recStop">按住录音</view>
29
-				<view v-if="dataInfo.recBlob">
30
-					<!-- <audio src="dataInfo.recBlob" controls></audio> -->
31
-					<icon type="clear" size="26" @click="clearRec"/>
28
+				<view class="chunk" v-if="!dataInfo.localId" @longpress="examineRecord($event)" @touchend="recStop($event)">长按录音</view>
29
+				<view class="chunk-2" v-if="dataInfo.localId">
30
+					<view class="chunk-2-2" @click="playAudio">
31
+						<view>播放录音</view>
32
+						<image v-if="isPlayOut==1" class="chunk-img" src="../../static/img/audio_play.gif" mode=""></image>
33
+					</view>
34
+					<icon class="chunk-icon" type="clear" size="22" @click="clearRec"/>
32 35
 				</view>
33 36
 			</view>
34 37
 		</view>
@@ -36,6 +39,14 @@
36 39
 			<button @click="goBackOrToList" type="default" class="cancelButton btn">返回</button>
37 40
 			<button @click="submit" type="default" class="primaryButton btn">下一步</button>
38 41
 		</view>
42
+		<view class="mask-class" v-if="isrecordType">
43
+			<view class="mask-box">
44
+				<image class="mask-img" src="../../static/img/audio_play.gif" mode=""></image>
45
+			</view>
46
+			<view class="mask-bottom">
47
+				<view class="mask-bottom-txt">松开完成</view>
48
+			</view>
49
+		</view>
39 50
 	</view>
40 51
 </template>
41 52
 
@@ -53,12 +64,13 @@
53 64
   import { useGoBack } from '@/share/useGoBack.js'
54 65
   import { useLoginUserStore } from '@/stores/loginUser'
55 66
   import { useHandlerStore } from '@/stores/handler'
56
-  
57
-	import Recorder from 'recorder-core';
58
-	import 'recorder-core/src/engine/mp3';
59
-  import 'recorder-core/src/engine/mp3-engine';
60
-  import 'recorder-core/src/engine/wav';
61
-  import 'recorder-core/src/extensions/waveview';
67
+	import { post } from "@/http/http.js"
68
+	import wx from 'weixin-jsapi'
69
+	// import Recorder from 'recorder-core';
70
+	// import 'recorder-core/src/engine/mp3';
71
+ //  import 'recorder-core/src/engine/mp3-engine';
72
+ //  import 'recorder-core/src/engine/wav';
73
+ //  import 'recorder-core/src/extensions/waveview';
62 74
 			
63 75
   useSetTitle();
64 76
   const loginUserStore = useLoginUserStore();
@@ -66,7 +78,8 @@
66 78
   const { makePhoneCall }  = useMakePhoneCall();
67 79
   const { uploadFile }  = useUploadFile();
68 80
   const { goBack }  = useGoBack();
69
-  
81
+  let rec = null
82
+  let wave = null
70 83
   // 主题颜色
71 84
   const primaryColor = ref(defaultColor)
72 85
 	
@@ -79,10 +92,12 @@
79 92
     tabActiveValue: 0,//当前选择的tab
80 93
     incidentId: undefined,//事件ID
81 94
     incidentData: {},//事件对象
82
-    deferralRemark: '',//故障描述
95
+    description: '',//故障描述
83 96
 		property:'', //资产
97
+		assetId:'',//资产id
84 98
     handlerImgList: [],//处理图片列表
85
-		recBlob:'' //录音
99
+		localId:'' ,//录音本地id
100
+		serverId:'',//录音服务器id
86 101
   })
87 102
   
88 103
 	// 故障处理用是否提供备用机
@@ -96,7 +111,23 @@
96 111
   
97 112
   // 处理图片
98 113
   const handlerImgRef = ref(null)
99
-  
114
+	
115
+  const ifShow = ref(false)
116
+	
117
+	const listStyles = ref({
118
+		// 是否显示边框
119
+		border: true,
120
+		// 是否显示分隔线
121
+		dividline: true,
122
+		// 线条样式
123
+		borderStyle: {
124
+			width:1,
125
+			color:'blue',
126
+			radius:2
127
+		}
128
+	})
129
+
130
+				
100 131
   const candidateData = ref([
101 132
 		{name:'马桶肃杀'},
102 133
 		{name:'马桶肃杀'},
@@ -111,10 +142,14 @@
111 142
   
112 143
 	const cmdbRepair = ref(null)
113 144
 	
114
-	let rec = null;
115
-	let wave = null;
116 145
 	const recwave = ref(null);
117 146
 	
147
+	// 是否播放完毕
148
+	const isPlayOut = ref(null);
149
+	
150
+	// 录音状态
151
+	const isrecordType = ref(false);
152
+	
118 153
   // 上一步或者返回列表
119 154
   function goBackOrToList(){
120 155
 		uni.setStorageSync('repairData','')
@@ -122,121 +157,120 @@
122 157
   }
123 158
 	
124 159
 	function itemCandidate(item){
125
-		dataInfo.deferralRemark = item.name
160
+		dataInfo.description = item.name
126 161
 	}
127 162
 	
128
-	// 获取录音权限
163
+	// 开始录音
129 164
 	function recOpen() {
130
-		rec = Recorder({
131
-		    type: 'wav', //录音格式,可以换成wav等其他格式
132
-		    sampleRate: 16000, //录音的采样率,越大细节越丰富越细腻
133
-		    bitRate: 16, //录音的比特率,越大音质越好
134
-		    onProcess: (buffers, powerLevel, bufferDuration, bufferSampleRate) => {
135
-					if (wave) {
136
-						wave.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate);
137
-					}
138
-				},
139
-		  });
140
-		  if (!rec) {
141
-		    alert('当前浏览器不支持录音功能!');
142
-		    return;
165
+		let param = {
166
+		  requestUrl: location.href.split('#')[0]
167
+		};
168
+		post("/wechat/getJsConfig", param).then(res => {
169
+		  if (res) {
170
+		    wx.config({
171
+		      debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
172
+		      appId: res.appId, // 必填,企业号的唯一标识,此处填写企业号corpid
173
+		      timestamp: res.timestamp, // 必填,生成签名的时间戳
174
+		      nonceStr: res.nonceStr, // 必填,生成签名的随机串
175
+		      signature: res.signature, // 必填,签名,见附录1
176
+		      jsApiList: res.jsApiList // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
177
+		    });
178
+		    wx.ready(function() {
179
+					// 开始录音
180
+					wx.startRecord({
181
+						success: function() {		
182
+							isrecordType.value = true
183
+						},					
184
+						cancel: function() {
185
+							alert('用户拒绝授权录音');
186
+						}
187
+					});
188
+					
189
+					// 录音录音自动停止接口
190
+					wx.onVoiceRecordEnd({
191
+						complete: function (res) {
192
+							dataInfo.localId = res.localId;
193
+						}
194
+					})
195
+					
196
+					// 监听语音播放完毕接口
197
+					wx.onVoicePlayEnd({
198
+						success: function (res) {
199
+							dataInfo.localId = res.localId; // 返回音频的本地ID
200
+							isPlayOut.value = 2
201
+						},
202
+						fail:function(res){
203
+							
204
+						},
205
+						complete: function(res) {
206
+							dataInfo.localId = res.localId; // 返回音频的本地ID
207
+							isPlayOut.value = 2
208
+						}
209
+					});
210
+		    });
143 211
 		  }
144
-		  //打开录音,获得权限
145
-		  rec.open(
146
-		    () => {
147
-		      console.log('录音已打开');
148
-					startRecord()
149
-		      if (recwave.value) {
150
-		        //创建音频可视化图形绘制对象
151
-		        wave = Recorder.WaveView({ elem: recwave.value });
152
-		      }
153
-		    },
154
-		    (msg, isUserNotAllow) => {
155
-		      //用户拒绝了录音权限,或者浏览器不支持录音
156
-		      console.log((isUserNotAllow ? 'UserNotAllow,' : '') + '无法录音:' + msg);
157
-		    },
158
-		  );
159
-
160
-		// uni.getSetting({
161
-		//   success(res) {
162
-		//     // 判断是否开启了录音权限
163
-		//     if (res.authSetting['scope.record']) {
164
-		// 			startRecord()
165
-		//     } else {
166
-		// 			uni.showToast({
167
-		// 				icon: 'none',
168
-		// 			  title: '录音权限未开启,无法录音',
169
-		// 			  mask: true,
170
-		// 			});
171
-		//     }
172
-		//   }
173
-		// })
212
+		})
174 213
 	}
175 214
 	
176
-	// 检查录音
177
-	function examineRecord() {
215
+	// 开始录音
216
+	function examineRecord(e) {
217
+		// uni.vibrateLong({
218
+		// 	success: function () {
219
+		// 		console.log('success');
220
+		// 	}
221
+		// });
178 222
 		recOpen()
179 223
 	}
180 224
 	
181
-  function startRecord(){
182
-		if (!rec) {
183
-			console.error('未打开录音');
184
-			return;
225
+	// 结束录音
226
+	function recStop(e) {
227
+		if(isrecordType.value){
228
+			wx.stopRecord({
229
+				success: function (res) {
230
+					dataInfo.localId = res.localId;
231
+					isrecordType.value = false
232
+				}
233
+			});
185 234
 		}
186
-		rec.start();
187 235
 	}
188 236
 	
189
-	// 结束录音
190
-	function recStop() {
191
-	  if (!rec) {
192
-	    console.error('未打开录音');
193
-	    return;
194
-	  }
195
-	  rec.stop(
196
-	    (blob, duration) => {
197
-	      //blob就是我们要的录音文件对象,可以上传,或者本地播放
198
-	      dataInfo.recBlob = blob;
199
-	      //简单利用URL生成本地文件地址,此地址只能本地使用,比如赋值给audio.src进行播放,赋值给a.href然后a.click()进行下载(a需提供download="xxx.mp3"属性)
200
-	      const localUrl = (window.URL || window.webkitURL).createObjectURL(blob);
201
-	      console.log('录音成功', blob, localUrl, '时长:' + duration + 'ms');
202
-	      // upload(blob); //把blob文件上传到服务器
203
-	      rec.close(); //关闭录音,释放录音资源,当然可以不释放,后面可以连续调用start
204
-	      rec = null;
205
-	    },
206
-	    (err) => {
207
-	      console.error('结束录音出错:' + err);
208
-	      rec.close(); //关闭录音,释放录音资源,当然可以不释放,后面可以连续调用start
209
-	      rec = null;
210
-	    },
211
-	  );
237
+	// 播放录音
238
+	function playAudio(){
239
+		wx.playVoice({
240
+		    localId: dataInfo.localId, // 需要播放的音频的本地ID,由stopRecord接口获得
241
+				success: function (res) {
242
+					isPlayOut.value = 1
243
+				}
244
+		})
212 245
 	}
213 246
 	
214 247
 	// 删除录音
215 248
 	function clearRec(){
216
-		dataInfo.recBlob = null
249
+		dataInfo.localId = null
250
+		isPlayOut.value = 2
251
+	}
252
+	
253
+	// 上传录音
254
+	function uploadAudio(){
255
+		wx.uploadVoice({
256
+			localId: dataInfo.localId, // 需要上传的音频的本地ID,由stopRecord接口获得
257
+			isShowProgressTips: 1, // 默认为1,显示进度提示
258
+			success: function (res) {
259
+				dataInfo.serverId = res.serverId; // 返回音频的服务器端ID
260
+				setTimeout(_=>{
261
+					uni.setStorageSync('repairData',JSON.stringify(dataInfo))
262
+					uni.navigateTo({
263
+					  url: `/pages/repair/rapidRepNext`,
264
+					});
265
+				},100)
266
+			}
267
+		});
217 268
 	}
218 269
 	
219 270
 	// 扫码资产码
220 271
 	function scanCodes(){
221 272
 		SM().then((res) => {
222
-		  let postData = {
223
-		    code: ress1,
224
-		    account: loginUserStore.loginUser.user.account,
225
-		  };
226
-		  // api_scanCode(postData).then((res) => {
227
-		  //   uni.hideLoading();
228
-		  //   if (res.status == 200) {
229
-		  //     inspectionValueStore.setInspectionValueData(res.data);
230
-		  //     uni.navigateTo({
231
-		  //       url: `/pages/inspection/inspectionValue/inspectionValue?inspectionExecuteId=${data.id}`
232
-		  //     })
233
-		  //   } else {
234
-		  //     uni.showToast({
235
-		  //       icon: 'none',
236
-		  //       title: res.msg || '请求数据失败!'
237
-		  //     });
238
-		  //   }
239
-		  // });
273
+			dataInfo.assetId = res;
240 274
 		})
241 275
 	}
242 276
 	
@@ -245,7 +279,7 @@
245 279
     dataInfo.handlerImgList.forEach(v => {
246 280
       v.url = v.path;
247 281
     })
248
-    console.log(dataInfo.handlerImgList);
282
+    console.log('上传成功',dataInfo.handlerImgList);
249 283
     let handlerOrder$ = handlerOrder();
250 284
     let requestList = [handlerOrder$];
251 285
     dataInfo.handlerImgList.forEach(v => {
@@ -262,11 +296,6 @@
262 296
           title: '处理成功',
263 297
           mask: true,
264 298
         });
265
-        setTimeout(() => {
266
-          uni.reLaunch({
267
-            url: '/pages/incidentList/incidentList',
268
-          })
269
-        }, 1500)
270 299
       }else{
271 300
         uni.showToast({
272 301
           icon: 'none',
@@ -284,10 +313,44 @@
284 313
     console.log(dataInfo.handlerImgList);
285 314
   }
286 315
   
316
+	
287 317
   // 选择上传图片
288 318
   function handlerImgSelect(e){
289
-    dataInfo.handlerImgList = dataInfo.handlerImgList.concat(e.tempFiles);
290
-    console.log(dataInfo.handlerImgList);
319
+		console.log(6666,e.tempFiles)
320
+		if(e.tempFiles[0].extname=='mp4' ||
321
+			e.tempFiles[0].extname=='avi' || 
322
+			e.tempFiles[0].extname=='mpeg' || 
323
+			e.tempFiles[0].extname=='wmv'){
324
+				let item = dataInfo.handlerImgList.findIndex(i=>i.extname==e.tempFiles[0].extname)
325
+				if(item!=-1){
326
+					uni.showToast({
327
+						icon: 'none',
328
+						title: '只能上传一个视频文件'
329
+					});
330
+					dataInfo.handlerImgList = dataInfo.handlerImgList.splice(item,1);
331
+				}else{
332
+					dataInfo.handlerImgList = dataInfo.handlerImgList.concat(e.tempFiles);
333
+				}
334
+			}else{
335
+				dataInfo.handlerImgList = dataInfo.handlerImgList.concat(e.tempFiles);
336
+				
337
+				if(e.tempFiles[0].extname=='png' || 
338
+					e.tempFiles[0].extname=='jpg' || 
339
+					e.tempFiles[0].extname=='gif' ||
340
+					e.tempFiles[0].extname=='mp4' ||
341
+					e.tempFiles[0].extname=='avi' || 
342
+					e.tempFiles[0].extname=='mpeg' || 
343
+					e.tempFiles[0].extname=='wmv'
344
+					){
345
+					}else{
346
+						uni.showToast({
347
+							icon: 'none',
348
+						  title: '不支持此类型文件'
349
+						});
350
+						let item = dataInfo.handlerImgList.findIndex(i=>i.uuid==e.tempFiles[0].uuid)
351
+						dataInfo.handlerImgList.splice(item,1);
352
+					}
353
+			}
291 354
   }
292 355
   
293 356
   // 删除上传图片
@@ -301,8 +364,9 @@
301 364
 		if(uni.getStorageSync('repairData')){
302 365
 			let data = JSON.parse(uni.getStorageSync('repairData'))
303 366
 			if(data){
304
-				dataInfo.deferralRemark = data.deferralRemark
367
+				dataInfo.description = data.description
305 368
 				dataInfo.property = data.property
369
+				dataInfo.assetId = data.assetId
306 370
 				dataInfo.handlerImgList = data.handlerImgList
307 371
 				dataInfo.recBlob = data.recBlob
308 372
 			}
@@ -312,38 +376,37 @@
312 376
   // 下一步
313 377
   function submit(){
314 378
 		isSubmit.value = true;
315
-		if(dataInfo.deferralRemark==''){
379
+		if(dataInfo.description==''){
316 380
 		  uni.showToast({
317 381
 		  	icon: 'none',
318 382
 		    title: '请选择输入故障描述'
319 383
 		  });
320 384
 		  return;
321 385
 		}
322
-		uni.setStorageSync('repairData',JSON.stringify(dataInfo))
323
-		uni.navigateTo({
324
-		  url: `/pages/repair/rapidRepNext`,
325
-		});
386
+		if(dataInfo.localId){
387
+			uploadAudio()
388
+		}else{
389
+			uni.setStorageSync('repairData',JSON.stringify(dataInfo))
390
+			uni.navigateTo({
391
+			  url: `/pages/repair/rapidRepNext`,
392
+			});
393
+		}
326 394
   }
327 395
   
328 396
   // 处理提交事件
329 397
   function handlerOrder(){
330 398
 		dataInfo.incidentData.returnBackupMachine = dataInfo.returnBackupMachine
331 399
     let postData = {
332
-      incident: dataInfo.incidentData,
333
-			solutionId:solutionId.value
400
+      incident: dataInfo.incidentData
334 401
     }
335
-    postData.incident.handleDescription = dataInfo.handleDescription;
336
-    postData.incident.handleCategory = {id: dataInfo.handleCategory};
337
-    postData.incident.closecode = {id: dataInfo.closecode};
338
-    postData.incident.category = dataInfo.category;
339
-    postData.incident.synergetic = dataInfo.synergetic;
340
-    
402
+    postData.incident.description = dataInfo.description;
403
+    postData.incident.assetId = dataInfo.assetId;
341 404
     return api_incidentTask(dataInfo.tabActiveValue, postData);
342 405
   }
343 406
   
344 407
   // 处理图片
345 408
   function handlerOrderImg(imgObj){
346
-    return uploadFile(imgObj, 'incident', dataInfo.incidentId)
409
+    return uploadFile(imgObj, 'wechatRequesterIncident', dataInfo.incidentId)
347 410
   }
348 411
 	
349 412
   onLoad((option) => {
@@ -363,6 +426,47 @@
363 426
 </script>
364 427
 
365 428
 <style lang="scss" scoped>
429
+.mask-class{
430
+	position: fixed;
431
+	width: 100%;
432
+	height: 100%;
433
+	top: 0;
434
+	left: 0;
435
+	background: rgba(0,0,0,0.3);
436
+	display: flex;
437
+	justify-content: center;
438
+	align-items: center;
439
+	.mask-box{
440
+		height: 160rpx;
441
+		padding: 0 25%;
442
+		background: #95EC6A;
443
+		border-radius: 25rpx;
444
+		display: flex;
445
+		align-items: center;
446
+		.mask-img{
447
+			width: 100rpx;
448
+			height: 100rpx;
449
+			position: relative;
450
+			background-color: transparent;
451
+			mix-blend-mode: multiply;
452
+		}
453
+	}
454
+	.mask-bottom{
455
+		position: absolute;
456
+		bottom: 0;
457
+		width: 100%;
458
+		height: 300rpx;
459
+		color: #A5A5A5;
460
+		background: #eee;
461
+		text-align: center;
462
+		border-top-left-radius: 30rpx;
463
+		border-top-right-radius: 30rpx;
464
+		.mask-bottom-txt{
465
+			margin-top: 50rpx;
466
+			font-weight: 500;
467
+		}
468
+	}
469
+}
366 470
 .handler{
367 471
   height: 100%;
368 472
   display: flex;
@@ -507,6 +611,31 @@
507 611
 				box-shadow: 0px 3px 6px 1px rgba(0,0,0,0.16);
508 612
 				border-radius: 10rpx;
509 613
 			}
614
+			.chunk-2{
615
+				width: 100%;
616
+				height: 70rpx;
617
+				display: flex;
618
+				align-items: center;
619
+				.chunk-2-2{
620
+					flex: 1;
621
+					height: 70rpx;
622
+					display: flex;
623
+					align-items: center;
624
+					justify-content: center;
625
+					background: #F3FAF7;
626
+					.chunk-img{
627
+						width: 80rpx;
628
+						height: 80rpx;
629
+						position: relative;
630
+						background-color: transparent;
631
+						mix-blend-mode: multiply; /* 根据需要选择合适的混合模式 */
632
+					}
633
+
634
+				}
635
+				.chunk-icon{
636
+					margin-left: 20rpx;
637
+				}
638
+			}
510 639
       &.column{
511 640
         height: auto;
512 641
         flex-direction: column;

+ 307 - 190
pages/repair/rapidRepNext.vue

@@ -8,59 +8,74 @@
8 8
 		<view class="body view-body" :class="{ page_padding: !(dataInfo.tabActiveValue === 'doing' && isInSummaryOrder), bg: (dataInfo.tabActiveValue === 'doing' && isInSummaryOrder) }">
9 9
       <!-- 科内报修 -->
10 10
       <template v-if="dataInfo.tabActiveValue === 'doing'">
11
+				<view class="form_item" v-if="isRepair.valueconfig==1">
12
+				  <view class="title select"><text class="required newicon newicon-bitian"></text>院区:</view>
13
+					<uni-data-picker class="value" placeholder="请选择院区"
14
+						v-model="dataInfo.branch" :localdata="branchData"
15
+						:clear-icon="false" :class="{formRed: isSubmit && !dataInfo.branch}">
16
+					</uni-data-picker>
17
+				</view>
11 18
         <view class="form_item">
12 19
           <view class="title select"><text class="required newicon newicon-bitian"></text>报修科室:</view>
13 20
         	<uni-data-picker class="value" placeholder="请选择报修科室"
14
-        		v-model="dataInfo.dept" :localdata="dataInfo.repairTypeList"
15
-        		:clear-icon="false" :class="{formRed: isSubmit && !dataInfo.dept}">
21
+        		v-model="dataInfo.department" :localdata="dataInfo.repairTypeList"
22
+        		:clear-icon="false" :class="{formRed: isSubmit && !dataInfo.department}">
16 23
         	</uni-data-picker>
17 24
         </view>
18
-				<view class="candidate">
19
-					<view class="candidate-item" v-for="item in candidateData" :key="item" @click="itemCandidate(item)">{{item.name}}</view>
25
+				<view class="candidate" v-if="candidateData.commonDeptDTO.length">
26
+					<view class="candidate-item" v-for="item in candidateData.commonDeptDTO" :key="item" @click="itemCandidate(item)">{{item.dept}}</view>
20 27
 				</view>
21 28
 				
22
-				<view class="form_item column">
29
+				<view class="form_item column" v-if="isRepair.valueconfig==1">
23 30
 					<view class="title"><text class="required newicon newicon-bitian"></text>详细地址:</view>
24
-					<uni-easyinput class="value" type="textarea" v-model="dataInfo.addres" placeholder="请输入详细地址"  :class="{formRed: isSubmit && !dataInfo.addres }" />
31
+					<uni-easyinput class="value" type="textarea" v-model="dataInfo.address" placeholder="请输入详细地址"  :class="{formRed: isSubmit && !dataInfo.address }" />
25 32
 				</view>
26 33
 				<view class="candidate">
27 34
 					<view class="candidate-item" v-for="item in addresData" :key="item" @click="itemAddres(item)">{{item.name}}</view>
28 35
 				</view>
29 36
 				
30
-				<view class="form_item" :class="{formRed: isSubmit && !dataInfo.name}">
37
+				<view class="form_item" :class="{formRed: isSubmit && !dataInfo.contacts}">
31 38
 					<view class="title select"><text class="required newicon newicon-bitian"></text>联系人:</view>
32
-					<input class="item-input" placeholder="请输入联系人" v-model="dataInfo.name" />
39
+					<input class="item-input" placeholder="请输入联系人" v-model="dataInfo.contacts" />
33 40
 				</view>
34 41
 				
35
-				<view class="form_item" :class="{formRed: isSubmit && !dataInfo.phone}">
42
+				<view class="form_item" :class="{formRed: isSubmit && !dataInfo.contactsInformation}">
36 43
 					<view class="title select"><text class="required newicon newicon-bitian"></text>联系电话:</view>
37
-					<input class="item-input" placeholder="请输入联系电话" v-model="dataInfo.phone"/>
44
+					<input class="item-input" placeholder="请输入联系电话" v-model="dataInfo.contactsInformation"/>
38 45
 				</view>
39 46
       </template>
40
-      
41
-      <!-- 公报修 -->
47
+
48
+      <!-- 公报修 -->
42 49
       <template v-if="dataInfo.tabActiveValue === 'overtime'">
43
-       <view class="form_item">
44
-         <view class="title select"><text class="required newicon newicon-bitian"></text>楼层楼栋:</view>
45
-       	<uni-data-picker class="value" placeholder="请选择楼层楼栋"
46
-       		v-model="dataInfo.building" :localdata="dataInfo.buildingTypeList"
47
-       		:clear-icon="false" :class="{formRed: isSubmit && !dataInfo.building}">
50
+       <view class="form_item" v-if="isRepair.valueconfig==1">
51
+         <view class="title select"><text class="required newicon newicon-bitian"></text>楼栋:</view>
52
+       	<uni-data-picker class="value" placeholder="请选择楼栋" @change="areaChange"
53
+       		v-model="dataInfo.areaId" :localdata="dataInfo.buildingTypeList"
54
+       		:clear-icon="false" :class="{formRed: isSubmit && !dataInfo.areaId}">
48 55
        	</uni-data-picker>
49 56
        </view>
50 57
        
51
-       <view class="form_item column">
58
+			 <view class="form_item" v-if="isRepair.valueconfig==1">
59
+			   <view class="title select"><text class="required newicon newicon-bitian"></text>楼层:</view>
60
+			 	<uni-data-picker class="value" placeholder="请选择楼层"
61
+			 		v-model="dataInfo.placeId" :localdata="dataInfo.placeTypeList"
62
+			 		:clear-icon="false" :class="{formRed: isSubmit && !dataInfo.placeId}">
63
+			 	</uni-data-picker>
64
+			 </view>
65
+			 
66
+       <view class="form_item column" v-if="isRepair.valueconfig==1">
52 67
        	<view class="title"><text class="required newicon newicon-bitian"></text>详细地址:</view>
53
-       	<uni-easyinput class="value" type="textarea" v-model="dataInfo.addres" placeholder="请输入详细地址" :class="{formRed: isSubmit && !dataInfo.addres}" />
68
+       	<uni-easyinput class="value" type="textarea" v-model="dataInfo.address" placeholder="请输入详细地址" :class="{formRed: isSubmit && !dataInfo.address}" />
54 69
        </view>
55 70
        
56
-       <view class="form_item" :class="{formRed: isSubmit && !dataInfo.name}">
71
+       <view class="form_item" :class="{formRed: isSubmit && !dataInfo.contacts}">
57 72
        	<view class="title select"><text class="required newicon newicon-bitian"></text>联系人:</view>
58
-       	<input class="item-input value" focus placeholder="请输入联系人" v-model="dataInfo.name"/>
73
+       	<input class="item-input value" focus placeholder="请输入联系人" v-model="dataInfo.contacts"/>
59 74
        </view>
60 75
        
61
-       <view class="form_item" :class="{formRed: isSubmit && !dataInfo.phone}">
76
+       <view class="form_item" :class="{formRed: isSubmit && !dataInfo.contactsInformation}">
62 77
        	<view class="title select"><text class="required newicon newicon-bitian"></text>联系电话:</view>
63
-       	<input class="item-input value" focus placeholder="请输入联系电话" v-model="dataInfo.phone"/>
78
+       	<input class="item-input value" focus placeholder="请输入联系电话" v-model="dataInfo.contactsInformation"/>
64 79
        </view>
65 80
       </template>
66 81
 		</view>
@@ -69,7 +84,8 @@
69 84
       <button @click="submit" type="default" class="primaryButton btn">提交</button>
70 85
     </view>
71 86
     <NumberModal v-if="dataInfo.isNumber" @cancelEmit="cancelNumber" @confirmEmit="conformNumber" @removeEmit="removeNumber" :selectData="dataInfo.selectData" :selectType="dataInfo.selectType" :evtNumber="dataInfo.evtNumber" showRemove></NumberModal>
72
-  </view>
87
+		
88
+	</view>
73 89
 </template>
74 90
 
75 91
 <script setup>
@@ -77,7 +93,7 @@
77 93
   import NumberModal from '@/components/NumberModal.vue';
78 94
   import { onLoad } from '@dcloudio/uni-app'
79 95
   import { generateNumberArray } from '@/utils/index.js'
80
-  import { api_group, api_incidentDetail, api_getSolution, api_area, api_user, api_incidentTask, api_branch, api_dutyDepartment, api_department, api_querySummaryDoc, api_addSummaryDoc } from "@/http/api.js"
96
+  import { api_getDictionary, api_sj,api_request, api_place, api_getSolution, api_area, api_user, api_incidentTask, api_branch, api_dutyDepartment, api_department, api_querySummaryDoc, api_addSummaryDoc } from "@/http/api.js"
81 97
   import { defaultColor } from '@/static/js/theme.js'
82 98
   import { useSetTitle } from '@/share/useSetTitle.js'
83 99
   import { useMakePhoneCall } from '@/share/useMakePhoneCall.js'
@@ -108,17 +124,12 @@
108 124
 		},
109 125
 	])
110 126
 	
111
-	const candidateData = ref([
112
-		{name:'马桶肃杀'},
113
-		{name:'马桶肃杀'},
114
-		{name:'马桶肃杀'},
115
-		{name:'马桶肃杀'},
116
-		{name:'马桶肃杀'},
117
-		{name:'马桶肃杀'},
118
-		{name:'马桶肃杀'},
119
-		{name:'马桶肃杀'},
120
-		{name:'马桶肃杀'},
121
-	])
127
+	const isDept = ref({})
128
+	const isRepair = ref({})
129
+	const branchData = ref([])
130
+	const candidateData = ref(loginUserStore.loginUser.user)
131
+	
132
+	const repairIncident = ref(null)
122 133
 	
123 134
 	const addresData = ref([
124 135
 		{name:'护士站'},
@@ -135,14 +146,24 @@
135 146
     ],
136 147
     tabActiveValue: 'doing',//当前选择的tab
137 148
     incidentId: undefined,//事件ID
138
-    incidentData: {},//事件对象
149
+    incidentData: {
150
+			repairIncidentType:{
151
+				id:''
152
+			},
153
+			department:{
154
+				id:''
155
+			}
156
+		},//事件对象
139 157
 		repairTypeList:[],//科室数据
140 158
 		buildingTypeList:[],//楼栋数据
141
-    dept:'',//报修科室
142
-		addres:'',//详细地址
143
-		name:'',//联系人
144
-		phone:'',//手机
145
-		building:''//楼栋
159
+		placeTypeList:[],//楼层数据
160
+    department:'',//报修科室
161
+		address:'',//详细地址
162
+		contacts:'',//联系人
163
+		contactsInformation:'',//手机
164
+		areaId:'',//楼栋
165
+		placeId:'',//楼层
166
+		branch:'', //院区
146 167
   })
147 168
   
148 169
 	// 故障处理用是否提供备用机
@@ -170,11 +191,13 @@
170 191
   
171 192
   // 重置
172 193
   function reset(){
173
-		dataInfo.dept = '',//报修科室
174
-		dataInfo.addres = '',//详细地址
175
-		dataInfo.name = '',//联系人
176
-		dataInfo.phone = ''//手机
177
-		dataInfo.building = ''//楼栋
194
+		// dataInfo.department = '',//报修科室
195
+		dataInfo.address = '',//详细地址
196
+		// dataInfo.contacts = '',//联系人
197
+		// dataInfo.contactsInformation = ''//手机
198
+		dataInfo.areaId = ''//楼栋
199
+		dataInfo.placeId = '' //院区
200
+		dataInfo.placeTypeList = []
178 201
   }
179 202
   
180 203
   // 初始化表单
@@ -187,11 +210,11 @@
187 210
   }
188 211
   
189 212
 	function itemCandidate(item){
190
-		dataInfo.dept = item.id
213
+		dataInfo.department = item.id
191 214
 	}
192 215
 	
193 216
 	function itemAddres(item){
194
-		dataInfo.addres = item.name
217
+		dataInfo.address = item.name
195 218
 	}
196 219
 	
197 220
   // 点击tab
@@ -213,15 +236,69 @@
213 236
     if(uni.getStorageSync('rapidRepNext')){
214 237
     	let data = JSON.parse(uni.getStorageSync('rapidRepNext'))
215 238
     	if(data){
216
-    		dataInfo.dept = data.dept//报修科室
217
-    		dataInfo.addres = data.addres//详细地址
218
-    		dataInfo.name = data.name//联系人
219
-    		dataInfo.phone = data.phone//手机
220
-    		dataInfo.building = data.building//楼栋
239
+    		dataInfo.department = data.department//报修科室
240
+    		dataInfo.address = data.address//详细地址
241
+    		dataInfo.contacts = data.contacts//联系人
242
+    		dataInfo.contactsInformation = data.contactsInformation//手机
243
+				dataInfo.branch = data.branch//院区
244
+    		dataInfo.areaId = data.areaId//楼栋
221 245
     	}
222 246
     }
247
+		if(uni.getStorageSync('repairData')){
248
+			let data = JSON.parse(uni.getStorageSync('repairData'))
249
+			if(data){
250
+				dataInfo.description = data.description
251
+				dataInfo.handlerImgList = data.handlerImgList
252
+				dataInfo.serverId = data.serverId
253
+				dataInfo.assetId = data.assetId
254
+			}
255
+		}
256
+		
257
+		let data = JSON.parse(uni.getStorageSync('sysData'))
258
+		isDept.value = data.find(i=>i.keyconfig=='deptRepair')
259
+		isRepair.value = data.find(i=>i.keyconfig=='publicRepair')
260
+		
261
+		let user = loginUserStore.loginUser.user
262
+		if(user){
263
+			dataInfo.branch = user.branch.id
264
+			dataInfo.contacts = user.name
265
+			dataInfo.contactsInformation = user.phone
266
+			dataInfo.department = user.dept.id
267
+		}
268
+		
269
+		let postData = {
270
+		  "key": 'repair_incident_type',
271
+		  "type": "list",
272
+		};
273
+		api_getDictionary(postData).then(res => {
274
+		  res = res || [];
275
+		  repairIncident.value = res
276
+		})
277
+		getBranch()
223 278
   }
224 279
   
280
+	// 获取院区列表
281
+	function getBranch(){
282
+		let postData = {
283
+			branch:'',
284
+			idx:0,
285
+			sum:9999
286
+		}
287
+		if(loginUserStore.loginUser.user.duty){
288
+		  postData.branch = loginUserStore.loginUser.user.duty.id;
289
+		}else if(loginUserStore.loginUser.user.branch){
290
+		  postData.branch = loginUserStore.loginUser.user.branch.id;
291
+		}
292
+		api_branch(postData).then(res => {
293
+		  uni.hideLoading();
294
+		  res = res.list || [];
295
+		  branchData.value = res.map(v => ({
296
+		    text: v.hosName,
297
+		    value: v.id,
298
+		  }));
299
+		})
300
+	}
301
+	
225 302
   // 获取报修科室列表
226 303
   function getRepairTypes(){
227 304
     uni.showLoading({
@@ -230,7 +307,7 @@
230 307
     });
231 308
     let postData = {
232 309
 			department: {
233
-			  branch: dataInfo.incidentData.branch,
310
+			  branch: '',
234 311
 			},
235 312
 			idx:0,
236 313
 			sum:9999
@@ -269,7 +346,8 @@
269 346
 		  postData.area.branch = loginUserStore.loginUser.user.branch.id;
270 347
 		}
271 348
     api_area(postData).then(res => {
272
-      uni.hideLoading();
349
+			// getPlaceList()
350
+			 uni.hideLoading();
273 351
       res = res.list || [];
274 352
       dataInfo.buildingTypeList = res.map(v => ({
275 353
         text: v.area,
@@ -278,6 +356,33 @@
278 356
     })
279 357
   }
280 358
   
359
+	function areaChange(e){
360
+		getPlaceList(dataInfo.areaId)
361
+	}
362
+	
363
+	// 获取楼层
364
+	function getPlaceList(e){
365
+	  let postData = {
366
+	    idx: 0,
367
+	    sum: 9999,
368
+			place: {
369
+			  area: {id: e },
370
+			}
371
+	  };
372
+		// if(loginUserStore.loginUser.user.duty){
373
+		//   postData.area.branch = loginUserStore.loginUser.user.duty.id;
374
+		// }else if(loginUserStore.loginUser.user.branch){
375
+		//   postData.area.branch = loginUserStore.loginUser.user.branch.id;
376
+		// }
377
+	  api_place(postData).then(res => {
378
+	    res = res.list || [];
379
+	    dataInfo.placeTypeList = res.map(v => ({
380
+	      text: v.place,
381
+	      value: v.id
382
+	    }));
383
+	  })
384
+	}
385
+	
281 386
   // 提交
282 387
   function submit(){
283 388
 		isSubmit.value = true;
@@ -286,23 +391,107 @@
286 391
   
287 392
   // 处理提交事件
288 393
   function handlerOrder(){
289
-		dataInfo.incidentData.returnBackupMachine = dataInfo.returnBackupMachine
394
+		if(dataInfo.tabActiveValue === 'doing'){
395
+			let data = repairIncident.value.find(i=>i.value=='dept')
396
+			dataInfo.incidentData.repairIncidentType.id = data.id
397
+		}else if(dataInfo.tabActiveValue === 'overtime'){
398
+			let data = repairIncident.value.find(i=>i.value=='public')
399
+			dataInfo.incidentData.repairIncidentType.id = data.id
400
+		}
401
+		dataInfo.incidentData.department.id = dataInfo.department
290 402
     let postData = {
291 403
       incident: dataInfo.incidentData,
292
-			solutionId:solutionId.value
404
+			serverId: ''
293 405
     }
294
-    postData.incident.handleDescription = dataInfo.handleDescription;
295
-    postData.incident.handleCategory = {id: dataInfo.handleCategory};
296
-    postData.incident.closecode = {id: dataInfo.closecode};
297
-    postData.incident.category = dataInfo.category;
298
-    postData.incident.synergetic = dataInfo.synergetic;
299
-    
300
-    return api_incidentTask(dataInfo.tabActiveValue, postData);
406
+    postData.incident.description = dataInfo.description;
407
+		if(dataInfo.serverId){
408
+			postData.serverId = dataInfo.serverId;
409
+		}else{
410
+			delete postData.serverId 
411
+		}
412
+    postData.incident.assetId = dataInfo.assetId;
413
+		postData.incident.address = dataInfo.address;
414
+		postData.incident.contacts = dataInfo.contacts;
415
+		postData.incident.contactsInformation = dataInfo.contactsInformation;
416
+		postData.incident.branch = dataInfo.branch;
417
+		postData.incident.areaId = dataInfo.areaId; //areaId:楼栋   
418
+    postData.incident.placeId = dataInfo.placeId;//placeId:楼层
419
+		api_getDictionary({
420
+			key: "incident_source",
421
+			type: "list"
422
+		}).then(res1=>{
423
+				let incidentSourceList = res1 || [];
424
+			  let im = incidentSourceList.find(v => v.value === 'im');
425
+				api_sj().then(res2=>{
426
+					postData.incident.incidentsign = res2.data;
427
+					postData.incident.source = im;
428
+					postData.incident.fromWx = true;
429
+					postData.incident.requester = loginUserStore.loginUser.user;
430
+					postData.incident.acceptUser = loginUserStore.loginUser.user;
431
+					postData.incident.deleteFlag = 0
432
+					api_request(postData).then(res=>{
433
+						if(res.state == 200){
434
+							dataInfo.incidentId = res.data.id
435
+							let handlerOrder$ = res.data;
436
+							let requestList = [handlerOrder$];
437
+							if(dataInfo.handlerImgList.length){ // 有图片
438
+								dataInfo.handlerImgList.forEach(v => {
439
+								  let handlerOrderImg$ = handlerOrderImg(v);
440
+								  requestList.push(handlerOrderImg$);
441
+								})
442
+								 console.log(9999,requestList);
443
+								Promise.all(requestList).then(resList => {
444
+								  uni.hideLoading();
445
+								  console.log(9999,resList);
446
+								  // if(resList[0].state == 200){
447
+								    uni.showToast({
448
+								    	icon: 'none',
449
+								      title: '报修成功',
450
+								      mask: true,
451
+								    });
452
+										setTimeout(() => {
453
+											uni.setStorageSync('rapidRepNext','')
454
+											uni.setStorageSync('repairData','')
455
+										  uni.reLaunch({
456
+										    url: '/pages/repair/home',
457
+										  })
458
+										}, 1500)
459
+								  // }else{
460
+								  //   uni.showToast({
461
+								  //     icon: 'none',
462
+								  //     title: resList[0].msg || '请求数据失败!'
463
+								  //   });
464
+								  // }
465
+								})
466
+							}else{
467
+								uni.showToast({
468
+									icon: 'none',
469
+								  title: '报修成功',
470
+								  mask: true,
471
+								});
472
+								setTimeout(() => {
473
+									uni.setStorageSync('rapidRepNext','')
474
+									uni.setStorageSync('repairData','')
475
+								  uni.reLaunch({
476
+								    url: '/pages/repair/home',
477
+								  })
478
+								}, 1500)
479
+							}
480
+						}else{
481
+						  uni.showToast({
482
+						    icon: 'none',
483
+						    title: res.msg || '请求数据失败!'
484
+						  });
485
+						}
486
+					})
487
+				})
488
+		})
489
+
301 490
   }
302 491
   
303 492
   // 处理图片
304 493
   function handlerOrderImg(imgObj){
305
-    return uploadFile(imgObj, 'incident', dataInfo.incidentId)
494
+    return uploadFile(imgObj, 'wechatRequesterIncident', dataInfo.incidentId)
306 495
   }
307 496
   
308 497
   // 处理提交
@@ -317,16 +506,32 @@
317 506
 			  return;
318 507
 			}
319 508
 		}else{
320
-			if(dataInfo.building==''){
509
+			if(dataInfo.branch==''){
510
+			  uni.showToast({
511
+			  	icon: 'none',
512
+			    title: '请选择院区'
513
+			  });
514
+			  return;
515
+			}
516
+			
517
+			if(dataInfo.areaId==''){
518
+			  uni.showToast({
519
+			  	icon: 'none',
520
+			    title: '请选择楼栋'
521
+			  });
522
+			  return;
523
+			}
524
+			
525
+			if(dataInfo.placeId==''){
321 526
 			  uni.showToast({
322 527
 			  	icon: 'none',
323
-			    title: '请选择楼层楼栋'
528
+			    title: '请选择楼层'
324 529
 			  });
325 530
 			  return;
326 531
 			}
327 532
 		}
328 533
 
329
-    if(dataInfo.addres==''){
534
+    if(dataInfo.address==''){
330 535
       uni.showToast({
331 536
       	icon: 'none',
332 537
         title: '请输入详细地址'
@@ -334,7 +539,7 @@
334 539
       return;
335 540
     }
336 541
     
337
-    if(dataInfo.name==''){
542
+    if(dataInfo.contacts==''){
338 543
       uni.showToast({
339 544
       	icon: 'none',
340 545
         title: '请输入联系人'
@@ -342,7 +547,7 @@
342 547
       return;
343 548
     }
344 549
     
345
-    if(dataInfo.phone==''){
550
+    if(dataInfo.contactsInformation==''){
346 551
       uni.showToast({
347 552
       	icon: 'none',
348 553
         title: '请输入联系电话'
@@ -354,126 +559,38 @@
354 559
       title: "加载中",
355 560
       mask: true,
356 561
     });
357
-    
358
-		// 没有图片
359
-		let handlerOrder$ = handlerOrder();
360
-		let requestList = [handlerOrder$];
361
-		Promise.all(requestList).then(resList => {
362
-			uni.hideLoading();
363
-			console.log(resList);
364
-			if(resList[0].state == 200){
365
-				uni.showToast({
366
-					icon: 'none',
367
-					title: '处理成功',
368
-					mask: true,
369
-				});
370
-				setTimeout(() => {
371
-					uni.reLaunch({
372
-						url: '/pages/incidentList/incidentList',
373
-					})
374
-				}, 1500)
375
-			}else{
376
-				uni.showToast({
377
-					icon: 'none',
378
-					title: resList[0].msg || '请求数据失败!'
379
-				});
380
-			}
381
-		})
382
-    uni.setStorageSync('rapidRepNext','')
383
-  }
384
-  
385
-  // 延期处理提交
386
-  function submitOvertime(){
387
-    if(!dataInfo.repairTypeId){
388
-      uni.showToast({
389
-      	icon: 'none',
390
-        title: '请选择延期原因'
391
-      });
392
-      return;
393
-    }
394
-    
395
-    if(!dataInfo.deferralRemark.trim()){
396
-      uni.showToast({
397
-      	icon: 'none',
398
-        title: '请填写延期说明'
399
-      });
400
-      return;
401
-    }
402
-    
403
-    if(!dataInfo.deferralDayId){
404
-      uni.showToast({
405
-      	icon: 'none',
406
-        title: '请选择延期天数'
407
-      });
408
-      return;
409
-    }
410
-    
411
-    uni.showLoading({
412
-      title: "加载中",
413
-      mask: true,
414
-    });
415
-    dataInfo.incidentData.provideBackupMachine = dataInfo.provideBackupMachine
416
-    let postData = {
417
-      incident: dataInfo.incidentData,
418
-    }
419
-    
420
-    postData.incident.currentLog = {
421
-      remark: dataInfo.deferralRemark,
422
-      extra1: dataInfo.repairTypeId,
423
-      extra2: dataInfo.deferralDayId,
424
-    }
425
-    
426
-    api_incidentTask(dataInfo.tabActiveValue, postData).then(res => {
427
-      uni.hideLoading();
428
-      if(res.state == 200){
429
-        uni.showToast({
430
-        	icon: 'none',
431
-          title: '延期处理成功',
432
-          mask: true,
433
-        });
434
-        setTimeout(() => {
435
-          uni.reLaunch({
436
-            url: '/pages/incidentList/incidentList',
437
-          })
438
-        }, 1500)
439
-      }else{
440
-        uni.showToast({
441
-          icon: 'none',
442
-          title: res.msg || '请求数据失败!'
443
-        });
444
-      }
445
-    })
562
+		handlerOrder()
563
+		return
564
+		if(dataInfo.handlerImgList.length){
565
+		  // 有图片
566
+		  // handlerImgRef.value.upload();
567
+		}else{
568
+		  // 没有图片
569
+		  let handlerOrder$ = handlerOrder();
570
+		  let requestList = [handlerOrder$];
571
+		  Promise.all(requestList).then(resList => {
572
+		    uni.hideLoading();
573
+		    if(resList[0].state == 200){
574
+		      uni.showToast({
575
+		      	icon: 'none',
576
+		        title: '报修成功',
577
+		        mask: true,
578
+		      });
579
+		      setTimeout(() => {
580
+						uni.setStorageSync('rapidRepNext','')
581
+		        uni.reLaunch({
582
+		          url: '/pages/repair/home',
583
+		        })
584
+		      }, 1500)
585
+		    }else{
586
+		      uni.showToast({
587
+		        icon: 'none',
588
+		        title: resList[0].msg || '请求数据失败!'
589
+		      });
590
+		    }
591
+		  })
592
+		}
446 593
   }
447
-  
448
-	// 获取知识库数量
449
-	function getIntroduceCount(categoryId){
450
-	  uni.showLoading({
451
-	    title: "加载中",
452
-	    mask: true,
453
-	  });
454
-	  let postData = {
455
-	    idx: 0,
456
-	    sum: 9999,
457
-	    solution: {
458
-				category:{
459
-					id:categoryId,
460
-				},
461
-				status:{id:72},
462
-	    }
463
-	  }
464
-	  
465
-	  api_getSolution(postData).then(res => {
466
-	    uni.hideLoading();
467
-	    if(res.status == 200){
468
-				dataInfo.introduceCount = res.totalNum
469
-	    }else{
470
-	      uni.showToast({
471
-	        icon: 'none',
472
-	        title: res.msg || '请求数据失败!'
473
-	      });
474
-	    }
475
-	  })
476
-	}
477 594
 	
478 595
 	// 获取文本内容
479 596
 	function getHtml(html) {

+ 696 - 0
pages/repair/repairsDetail.vue

@@ -0,0 +1,696 @@
1
+<template>
2
+  <view class="incidentDetail">
3
+    <view class="head">
4
+      <view class="tab" :class="{active: tab.value === dataInfo.tabActiveValue}" v-for="tab in dataInfo.tabs" :key="tab.id" @click="clickTab(tab.value)">
5
+        {{tab.name}}<text v-if="tab.num !== ''">({{tab.num}})</text>
6
+      </view>
7
+    </view>
8
+    <scroll-view scroll-y class="body">
9
+      <!-- 工单信息 -->
10
+      <template v-if="dataInfo.tabActiveValue === '1'">
11
+        <view class="detail_head">
12
+          <text class="title">报修信息</text>
13
+          <view class="other">
14
+            <text class="priority" :style="priorityStyle(dataInfo.incidentData.priority)">{{dataInfo.incidentData.priority ? dataInfo.incidentData.priority.name + ' ' : ''}}</text>
15
+            <view class="status" :style="stateStyle(dataInfo.incidentData.state)">{{dataInfo.incidentData.state ? dataInfo.incidentData.state.name : ''}}</view>
16
+          </view>
17
+        </view>
18
+        <view class="detail_item_wrap">
19
+          <view class="deital_item">
20
+            <text class="name">故障描述:</text>
21
+            <text class="value">{{dataInfo.incidentData.description || '无'}}</text>
22
+          </view>
23
+					<view class="deital_item">
24
+					  <text class="name">关联资产:</text>
25
+					  <text class="value">{{dataInfo.incidentData.description || '无'}}</text>
26
+					</view>
27
+          <view class="deital_item">
28
+            <text class="name">图片视频:</text>
29
+            <view class="value img">
30
+              <image class="imgItem" :src="img.thumbFilePath" mode="aspectFill" v-for="(img, i) in dataInfo.repairImgs" :key="i" @click="previewImg(i, 'repairImgs')"></image>
31
+							<!-- <video class="videoItem" :poster="img.imgF" v-for="(img, i) in dataInfo.repairVideo" :key="i" @click="videoView(i)"></video> -->
32
+							<image class="imgItem" src="/static/img/300.jpg" v-for="(img, i) in dataInfo.repairVideo" :key="i" @click="videoView(img)"></image>
33
+						</view>
34
+          </view>
35
+					<view class="deital_item">
36
+					  <text class="name">录音:</text>
37
+					  <view class="value img" v-if="dataInfo.repairAudio.length>0">
38
+							<sy-audio class="imgItem" ref="audio" isCountDown :src="img.thumbFilePath" v-for="(img, i) in dataInfo.repairAudio" :key="i" ></sy-audio>
39
+					  </view>
40
+					</view>
41
+          <view class="deital_item">
42
+            <text class="name">联系人:</text>
43
+            <text class="value">{{dataInfo.incidentData.contacts || '无'}}</text>
44
+            <text v-if="dataInfo.incidentData.contactsInformation" @click="makePhoneCall(dataInfo.incidentData.contactsInformation)">{{dataInfo.incidentData.contactsInformation}}<uni-icons type="phone-filled" class="phone-filled" :size="18" :color="primaryColor"></uni-icons></text>
45
+          </view>
46
+       <!--   <view class="deital_item">
47
+            <text class="name">联系电话:</text>
48
+            <view class="value" @click="makePhoneCall(dataInfo.incidentData.incomingPhone)" v-if="dataInfo.incidentData.incomingPhone">{{dataInfo.incidentData.incomingPhone}}<uni-icons type="phone-filled" class="phone-filled" :size="18" :color="primaryColor"></uni-icons></view>
49
+            <text class="value" v-else>无</text>
50
+            <uni-icons v-if="dataInfo.incidentData.callID" @click="attachmentClick" type="mic-filled" class="mic-filled" :size="22" :color="primaryColor"></uni-icons>
51
+          </view> -->
52
+          <view class="deital_item" v-if="isDept.valueconfig==1">
53
+            <text class="name">报修科室:</text>
54
+            <text class="value">{{dataInfo.incidentData.department ? dataInfo.incidentData.department.dept : '无'}}</text>
55
+          </view>
56
+          <view class="deital_item">
57
+            <text class="name">详细地址:</text>
58
+            <text class="value" v-if="dataInfo.incidentData.place || dataInfo.incidentData.houseNumber">{{dataInfo.incidentData.place ? (dataInfo.incidentData.place.area.area + dataInfo.incidentData.place.place) : ''}}{{dataInfo.incidentData.houseNumber || ''}}</text>
59
+            <text class="value" v-else>无</text>
60
+          </view>
61
+          <view class="deital_item">
62
+            <text class="name">报修人:</text>
63
+            <text class="value">{{dataInfo.incidentData.requester ? dataInfo.incidentData.requester.name : '无'}}</text>
64
+          </view>
65
+					<view class="deital_item">
66
+					  <text class="name">报修类型:</text>
67
+					  <text class="value" v-if="dataInfo.incidentData.repairIncidentType">{{dataInfo.incidentData.repairIncidentType.name}}</text>
68
+					</view>
69
+        </view>
70
+
71
+        <view class="detail_head">
72
+          <text class="title">处理信息</text>
73
+        </view>
74
+        <view class="detail_item_wrap">
75
+          <view class="deital_item">
76
+            <text class="name">处理人:</text>
77
+            <text class="value" v-if="dataInfo.incidentData.state.value == 'pending' && dataInfo.incidentData.currentLog">{{dataInfo.incidentData.currentLog.workerName}}<text @click="makePhoneCall(dataInfo.incidentData.currentLog.workerPhone)" v-if="dataInfo.incidentData.currentLog.workerPhone">({{dataInfo.incidentData.currentLog.workerPhone}})<uni-icons type="phone-filled" class="phone-filled" :size="18" :color="primaryColor"></uni-icons></text></text>
78
+
79
+            <text class="value" v-else-if="dataInfo.incidentData.state.value != 'pending' && dataInfo.incidentData.handlingPersonnelUser">{{dataInfo.incidentData.handlingPersonnelUser.name}}<text @click="makePhoneCall(dataInfo.incidentData.handlingPersonnelUser.phone)" v-if="dataInfo.incidentData.handlingPersonnelUser.phone">({{dataInfo.incidentData.handlingPersonnelUser.phone}})<uni-icons type="phone-filled" class="phone-filled" :size="18" :color="primaryColor"></uni-icons></text></text>
80
+            <text class="value" v-else>无</text>
81
+          </view>
82
+<!-- 					<view class="deital_item">
83
+					  <text class="name">处理人电话:</text>
84
+					  <view class="value" @click="makePhoneCall(dataInfo.incidentData.incomingPhone)" v-if="dataInfo.incidentData.incomingPhone">{{dataInfo.incidentData.incomingPhone}}<uni-icons type="phone-filled" class="phone-filled" :size="18" :color="primaryColor"></uni-icons></view>
85
+					  <text class="value" v-else>无</text>
86
+					  <uni-icons v-if="dataInfo.incidentData.callID" @click="attachmentClick" type="mic-filled" class="mic-filled" :size="22" :color="primaryColor"></uni-icons>
87
+					</view> -->
88
+          <view class="deital_item">
89
+            <text class="name">处理图片:</text>
90
+            <view class="value img">
91
+              <image class="imgItem" :src="img.thumbFilePath" mode="aspectFill" v-for="(img, i) in dataInfo.handlerImgs" :key="i" @click="previewImg(i, 'handlerImgs')"></image>
92
+            </view>
93
+          </view>
94
+          <view class="deital_item">
95
+            <text class="name">维修总价:</text>
96
+            <text class="value">{{dataInfo.incidentData.rsPrice === undefined ? '无' : dataInfo.incidentData.rsPrice + '元'}}</text>
97
+          </view>
98
+        </view>
99
+      </template>
100
+
101
+      <!-- 维修汇总单 -->
102
+      <template v-if="dataInfo.tabActiveValue === '2'">
103
+        <view class="detail_head">
104
+          <text class="title">耗材清单</text>
105
+        </view>
106
+        <view class="summaryItem_bodyItem" v-for="item in dataInfo.summaryObj.consumableList" :key="item.id">
107
+          <view class="summaryItem_bodyItem_top">
108
+            <text class="name ellipsis">{{ item.consumableName }}<template v-if="item.consumableBrandModel">({{ item.consumableBrandModel }})</template></text>
109
+            <text class="value">{{ item.consumableEndPrice }}元</text>
110
+          </view>
111
+          <view class="summaryItem_bodyItem_bottom">
112
+            <text class="name">x{{ item.consumablesNum }}{{ item.consumablesUnit }}</text>
113
+            <text class="value">总价{{item.consumablesNum * item.consumableEndPrice}}元</text>
114
+          </view>
115
+        </view>
116
+        <view class="summaryItem_bodyItem_total">耗材总价:{{dataInfo.summaryObj.consumablePrice}}元</view>
117
+        <view class="detail_head">
118
+          <text class="title">工时清单</text>
119
+        </view>
120
+        <view class="summaryItem_bodyItem" v-for="item in dataInfo.summaryObj.workHourManagementList" :key="item.id">
121
+          <view class="summaryItem_bodyItem_top">
122
+            <text class="name ellipsis">{{ item.workName }}</text>
123
+            <text class="value">{{ item.wage }}元</text>
124
+          </view>
125
+          <view class="summaryItem_bodyItem_bottom">
126
+            <text class="name">x{{ item.workHourNum2 }}{{ item.workUnit }}</text>
127
+            <text class="value">总价{{item.workHourNum2 * item.wage}}元</text>
128
+          </view>
129
+        </view>
130
+        <view class="summaryItem_bodyItem_total">工时总价:{{dataInfo.summaryObj.workHourPrice}}元</view>
131
+        <view class="summaryItem_total">汇总单总价:{{dataInfo.summaryObj.totalMaintenancePrice}}元</view>
132
+      </template>
133
+
134
+      <!-- 处理流程 -->
135
+      <template v-if="dataInfo.tabActiveValue === '3'">
136
+        <view class="process_item_wrap">
137
+          <view class="process_item" v-for="item in dataInfo.incidentLogList" :key="item.id">
138
+            <view class="process_item_top">
139
+              <view class="name">{{item.logType ? item.logType.name : ''}}</view>
140
+              <view class="value" v-if="item.remark">({{item.remark}})</view>
141
+            </view>
142
+            <view class="process_item_bottom">
143
+              <text class="name">{{formatDate(item.startTime, 'yyyy-MM-dd HH:mm:ss')}}</text>
144
+              <text class="value" v-if="item.appointorName">{{item.appointorName}}</text>
145
+            </view>
146
+          </view>
147
+        </view>
148
+      </template>
149
+
150
+      <!-- 评价信息 -->
151
+      <template v-if="dataInfo.tabActiveValue === '4'">
152
+        <view class="detail_head">
153
+          <text class="title">评价信息</text>
154
+        </view>
155
+        <view class="appraise_detail" v-for="item in dataInfo.resolveLogs" :key="item.id">
156
+          <view class="appraise_detail_top">
157
+            <text>{{formatDate(item.startTime, 'yyyy-MM-dd HH:mm:ss')}}</text>
158
+            <view v-if="dataInfo.incidentData.wxdegree">
159
+              <uni-rate readonly :value="dataInfo.incidentData.wxdegree.value" />
160
+            </view>
161
+          </view>
162
+          <view class="appraise_detail_bottom">
163
+            <text>{{item.remark}}</text>
164
+          </view>
165
+        </view>
166
+
167
+        <view class="detail_head">
168
+          <text class="title">回访信息</text>
169
+        </view>
170
+        <view class="appraise_detail" v-for="item in dataInfo.callbackLogs" :key="item.id">
171
+          <view class="appraise_detail_top">
172
+            <text>{{formatDate(item.startTime, 'yyyy-MM-dd HH:mm:ss')}}</text>
173
+            <text v-if="dataInfo.incidentData.degree">{{dataInfo.incidentData.degree.name}}</text>
174
+          </view>
175
+          <view class="appraise_detail_bottom">
176
+            <text>{{item.remark}}</text>
177
+          </view>
178
+        </view>
179
+      </template>
180
+    </scroll-view>
181
+    <view class="foot_common_btns">
182
+      <button @click="goBack" type="default" class="primaryButton btn">返回</button>
183
+    </view>
184
+    <IncidentAttachment v-if="dataInfo.isAttachment" @knowEmit="knowAttachment" :incidentData="dataInfo.incidentData"></IncidentAttachment>
185
+		<uni-popup ref="popup" background-color="#fff" type="center" :before-close="true">
186
+			<view class="popup-content">
187
+				<video :src="videoUrl" controls></video>
188
+			</view>
189
+			<view class="foot_common_btns">
190
+			  <button @click="closePop" type="default" class="primaryButton btn">关闭</button>
191
+			</view>
192
+		</uni-popup>
193
+	</view>
194
+</template>
195
+
196
+<script setup>
197
+  import { ref, reactive } from 'vue'
198
+  import IncidentAttachment from '@/components/IncidentAttachment.vue';
199
+  import { onLoad } from '@dcloudio/uni-app'
200
+  import { api_listAttachment, api_incidentDetail, api_querySummaryDoc, api_incidentLog } from "@/http/api.js"
201
+  import { defaultColor } from '@/static/js/theme.js'
202
+  import { useSetTitle } from '@/share/useSetTitle.js'
203
+  import { useMakePhoneCall } from '@/share/useMakePhoneCall.js'
204
+  import { useGoBack } from '@/share/useGoBack.js'
205
+  import { useLoginUserStore } from '@/stores/loginUser'
206
+  import { computedPriorityStyle } from '@/filters/computedPriorityStyle.js'
207
+  import { computedStateStyle } from '@/filters/computedStateStyle.js'
208
+  import { filterFormatDate } from '@/filters/filterFormatDate.js'
209
+
210
+  useSetTitle();
211
+  const loginUserStore = useLoginUserStore();
212
+  const { makePhoneCall }  = useMakePhoneCall();
213
+  const { goBack }  = useGoBack();
214
+  const { priorityStyle }  = computedPriorityStyle();
215
+  const { stateStyle }  = computedStateStyle();
216
+  const { formatDate }  = filterFormatDate();
217
+
218
+  // 主题颜色
219
+  const primaryColor = ref(defaultColor)
220
+	
221
+	const isDept = ref(null)
222
+	const videoUrl = ref(null)
223
+	const popup = ref(null)
224
+
225
+  // 数据
226
+  const dataInfo = reactive({
227
+    tabs: [
228
+      {id: 1, name: '工单信息', value: '1', num: ''},
229
+      // {id: 2, name: '维修汇总单', value: '2', num: ''},
230
+      {id: 3, name: '处理流程', value: '3', num: ''},
231
+      {id: 4, name: '评价信息', value: '4', num: ''},
232
+    ],
233
+    tabActiveValue: 0,//当前选择的tab
234
+    incidentId: undefined,//事件ID
235
+    incidentData: {},//事件对象
236
+    repairImgs: [],//报修图片
237
+		repairVideo:[], //视频
238
+		repairAudio:[], //录音
239
+    handlerImgs: [],//处理图片
240
+    summaryObj: {
241
+      consumableList: [],//耗材列表
242
+      workHourManagementList: [],//工时列表
243
+    },//汇总单信息
244
+    incidentLogList: [],//流程列表
245
+    resolveLogs: [],//评价
246
+    callbackLogs: [],//回访
247
+    isAttachment: false,//录音开关
248
+  })
249
+
250
+  // 点击录音
251
+  function attachmentClick(){
252
+    dataInfo.isAttachment = true;
253
+  }
254
+
255
+  // 知道了录音
256
+  function knowAttachment(){
257
+    dataInfo.isAttachment = false;
258
+  }
259
+
260
+  // 获取汇总单信息
261
+  function getSummaryList(){
262
+    uni.showLoading({
263
+      title: "加载中",
264
+      mask: true,
265
+    });
266
+    let postData = {
267
+      "incidentId": dataInfo.incidentId,
268
+    };
269
+    api_querySummaryDoc(postData).then(res => {
270
+      uni.hideLoading();
271
+      if(res.status == 200){
272
+        dataInfo.summaryObj = {...{consumableList:[], workHourManagementList: []}, ...res };
273
+      }else{
274
+        uni.showToast({
275
+          icon: 'none',
276
+          title: res.msg || '请求数据失败!'
277
+        });
278
+      }
279
+    })
280
+  }
281
+
282
+  // 获取流程列表
283
+  function getIncidentLogList(){
284
+    uni.showLoading({
285
+      title: "加载中",
286
+      mask: true,
287
+    });
288
+    let postData = {
289
+        "idx": 0,
290
+        "sum": 9999,
291
+        "incidentLog": {
292
+            "incidentId": dataInfo.incidentId,
293
+        }
294
+    };
295
+    api_incidentLog(postData).then(res => {
296
+      uni.hideLoading();
297
+      if(res.status == 200){
298
+        let incidentLogList = res.list || [];
299
+        dataInfo.incidentLogList = incidentLogList;
300
+      }else{
301
+        uni.showToast({
302
+          icon: 'none',
303
+          title: res.msg || '请求数据失败!'
304
+        });
305
+      }
306
+    })
307
+  }
308
+	
309
+	function videoView(item){
310
+		videoUrl.value = item.thumbFilePath
311
+		popup.value.open()
312
+	}
313
+	
314
+	function closePop(){
315
+		popup.value.close()
316
+	}
317
+	
318
+  // 预览图片
319
+  function previewImg(index, type){
320
+    uni.previewImage({
321
+      current: index,
322
+      urls: dataInfo[type].map(v => v.previewUrl),
323
+      longPressActions: {
324
+        itemList: ['发送给朋友', '保存图片', '收藏'],
325
+        success: function(data) {
326
+          console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
327
+        },
328
+        fail: function(err) {
329
+          console.log(err.errMsg);
330
+        }
331
+      }
332
+    });
333
+  }
334
+
335
+  // 初始化表单
336
+  function initForm(){
337
+    if(dataInfo.tabActiveValue === '1'){
338
+      getRepairImgs();
339
+      getHandlerImgs();
340
+    }else if(dataInfo.tabActiveValue === '2'){
341
+      getSummaryList();
342
+    }else if(dataInfo.tabActiveValue === '3'){
343
+      getIncidentLogList();
344
+    }else if(dataInfo.tabActiveValue === '4'){
345
+
346
+    }
347
+  }
348
+
349
+  // 点击tab
350
+  function clickTab(tabValue){
351
+    if(dataInfo.tabActiveValue == tabValue){
352
+      return;
353
+    }
354
+    dataInfo.tabActiveValue = tabValue;
355
+    initForm()
356
+  }
357
+
358
+  // 获取事件详情
359
+  function getIncidentDetail(){
360
+    uni.showLoading({
361
+      title: "加载中",
362
+      mask: true,
363
+    });
364
+
365
+    api_incidentDetail(dataInfo.incidentId).then(res => {
366
+      uni.hideLoading();
367
+      if(res.status == 200){
368
+        dataInfo.incidentData = res.data || {};
369
+        let logs = dataInfo.incidentData.logs || [];
370
+        dataInfo.resolveLogs = logs.filter(v => v.logType.value == 'resolve').slice(0, 1);
371
+        dataInfo.callbackLogs = logs.filter(v => v.logType.value == 'callback').slice(0, 1);
372
+
373
+        // 维修汇总单
374
+        if(dataInfo.incidentData.state.value == 'close' && dataInfo.incidentData.duty.addSummary == 1 && dataInfo.incidentData.summaryId){
375
+          let flag = dataInfo.tabs.some(v => v.value === '2');
376
+          !flag && dataInfo.tabs.splice(1, 0, {id: 2, name: '维修汇总单', value: '2', num: ''});
377
+        }
378
+
379
+        dataInfo.tabActiveValue = dataInfo.tabs[0].value;
380
+        initForm()
381
+      }else{
382
+        uni.showToast({
383
+          icon: 'none',
384
+          title: res.msg || '请求数据失败!'
385
+        });
386
+      }
387
+    })
388
+  }
389
+
390
+  // 获取报修图片
391
+  function getRepairImgs(){
392
+    uni.showLoading({
393
+      title: "加载中",
394
+      mask: true,
395
+    });
396
+    api_listAttachment('wechatRequesterIncident', dataInfo.incidentId).then(res => {
397
+      uni.hideLoading();
398
+      res.data = res.data || [];
399
+      res.data.forEach(v => {
400
+        // v.previewUrl = location.origin + "/file" + v.relativeFilePath;
401
+        v.thumbFilePath = location.origin + "/file" + v.relativeFilePath;
402
+      })
403
+			dataInfo.repairImgs = []
404
+			dataInfo.repairVideo = []
405
+			dataInfo.repairAudio = []
406
+			for(let i of res.data){
407
+				if(i.suffix=='jpg' || i.suffix=='png' || i.suffix=='gif'){
408
+					dataInfo.repairImgs.push(i)
409
+				}else if(i.suffix=='mp4' || i.suffix=='avi' || 
410
+					i.suffix=='mpeg' || i.suffix=='wmv'){
411
+					dataInfo.repairVideo.push(i)
412
+				}else if(i.extra1=='wechatIncidentRecord'){
413
+					dataInfo.repairAudio.push(i)
414
+				}
415
+			}
416
+    })
417
+  }
418
+
419
+  // 获取处理图片
420
+  function getHandlerImgs(){
421
+    uni.showLoading({
422
+      title: "加载中",
423
+      mask: true,
424
+    });
425
+    api_listAttachment('incident', dataInfo.incidentId).then(res => {
426
+      uni.hideLoading();
427
+      res.data = res.data || [];
428
+      res.data.forEach(v => {
429
+        v.previewUrl = location.origin + "/file" + v.relativeFilePath;
430
+        v.thumbFilePath = location.origin + "/file" + v.thumbFilePath;
431
+      })
432
+      dataInfo.handlerImgs = res.data;
433
+    })
434
+  }
435
+
436
+  onLoad((option) => {
437
+    dataInfo.incidentId = option.incidentId;
438
+		let data = JSON.parse(uni.getStorageSync('sysData'))
439
+		isDept.value = data.find(i=>i.keyconfig=='deptRepair')
440
+    getIncidentDetail();
441
+  })
442
+</script>
443
+
444
+<style lang="scss" scoped>
445
+.popup-content{
446
+	padding: 40rpx;
447
+}
448
+.incidentDetail{
449
+  height: 100%;
450
+  display: flex;
451
+  flex-direction: column;
452
+  justify-content: space-between;
453
+  .head{
454
+    height: 88rpx;
455
+    display: flex;
456
+    position: fixed;
457
+    z-index: 99;
458
+    width: 100%;
459
+    background-color: #fff;
460
+    font-size: 30rpx;
461
+    .tab{
462
+      flex: 1;
463
+      display: flex;
464
+      justify-content: center;
465
+      align-items: center;
466
+      border-bottom: 4rpx solid transparent;
467
+      position: relative;
468
+      &:last-of-type{
469
+        &:after{
470
+          display: none;
471
+        }
472
+      }
473
+      &:after{
474
+        content: '';
475
+        position: absolute;
476
+        right: 0;
477
+        top: 50%;
478
+        transform: translateY(-50%);
479
+        width: 1rpx;
480
+        height: 44rpx;
481
+        background-color: #515151;
482
+      }
483
+      &.active{
484
+        color: $uni-primary;
485
+        border-color: $uni-primary;
486
+      }
487
+    }
488
+  }
489
+  .body{
490
+    margin-top: 88rpx;
491
+    box-sizing: border-box;
492
+    flex: 1;
493
+    min-height: 0;
494
+    border-top: 7rpx solid #EBEBEB;
495
+    .phone-filled{
496
+      margin-left: 5rpx;
497
+    }
498
+    .mic-filled{
499
+      margin-right: 100rpx;
500
+    }
501
+    .detail_item_wrap{
502
+      padding-bottom: 24rpx;
503
+    }
504
+    .detail_head{
505
+      padding: 24rpx;
506
+      border-top: 1rpx solid #D2D2D2;
507
+      border-bottom: 1rpx solid #D2D2D2;
508
+      display: flex;
509
+      justify-content: space-between;
510
+      align-items: center;
511
+      &:first-of-type{
512
+        border-top: none;
513
+      }
514
+      .title{
515
+        font-size: 26rpx;
516
+        color: $uni-primary;
517
+        padding-left: 18rpx;
518
+        position: relative;
519
+        &:before{
520
+          content: '';
521
+          width: 8rpx;
522
+          height: 25rpx;
523
+          background-color: $uni-primary;
524
+          position: absolute;
525
+          left: 0;
526
+          top: 50%;
527
+          transform: translateY(-50%);
528
+        }
529
+      }
530
+      .other{
531
+        display: flex;
532
+        align-items: center;
533
+        .priority{
534
+          font-size: 26rpx;
535
+          margin-right: 15rpx;
536
+        }
537
+        .status{
538
+          padding: 4rpx 10rpx;
539
+          border-radius: 20rpx;
540
+          background-color: #DBE8FE;
541
+          font-size: 22rpx;
542
+          color: #006CF9;
543
+        }
544
+      }
545
+    }
546
+
547
+    .deital_item{
548
+      font-size: 26rpx;
549
+      color: #555;
550
+      padding: 24rpx 24rpx 0;
551
+      display: flex;
552
+			flex-wrap: wrap;
553
+      align-items: center;
554
+      .name{
555
+        width: 8em;
556
+        margin-right: 24rpx;
557
+      }
558
+      .value{
559
+        flex: 1;
560
+        word-break: break-all;
561
+        &.img{
562
+          display: flex;
563
+          .imgItem{
564
+            width: 150rpx;
565
+            height: 150rpx;
566
+            margin-right: 24rpx;
567
+            &:last-of-type{
568
+              margin-right: 0;
569
+            }
570
+          }
571
+					.videoItem{
572
+						width: 150rpx;
573
+						height: 150rpx;
574
+						margin-right: 24rpx;
575
+						&:last-of-type{
576
+						  margin-right: 0;
577
+						}
578
+					}
579
+        }
580
+      }
581
+    }
582
+
583
+    .summaryItem_bodyItem{
584
+      padding: 24rpx 24rpx 0;
585
+      font-size: 26rpx;
586
+      .summaryItem_bodyItem_top{
587
+        display: flex;
588
+        justify-content: space-between;
589
+        align-items: center;
590
+        .value{
591
+          padding-left: 48rpx;
592
+          flex-shrink: 0;
593
+        }
594
+      }
595
+      .summaryItem_bodyItem_bottom{
596
+        margin-top: 24rpx;
597
+        display: flex;
598
+        justify-content: space-between;
599
+        align-items: center;
600
+        .name{
601
+          text-align: right;
602
+          flex: 1;
603
+        }
604
+        .value{
605
+          width: 220rpx;
606
+          text-align: right;
607
+          flex-shrink: 0;
608
+        }
609
+      }
610
+    }
611
+
612
+    .summaryItem_bodyItem_total{
613
+      text-align: right;
614
+      padding: 24rpx;
615
+      font-size: 26rpx;
616
+    }
617
+
618
+    .summaryItem_total{
619
+      text-align: center;
620
+      padding-top: 24rpx;
621
+      font-size: 32rpx;
622
+      font-weight: bold;
623
+      color: $uni-primary;
624
+      border-top: 1rpx solid #D2D2D2;
625
+    }
626
+
627
+    .process_item_wrap{
628
+      padding: 38rpx;
629
+      .process_item{
630
+        &:last-of-type{
631
+          .process_item_bottom{
632
+            border-left: none;
633
+          }
634
+        }
635
+        .process_item_top{
636
+          padding-left: 30rpx;
637
+          display: flex;
638
+          align-items: center;
639
+          position: relative;
640
+          &:before{
641
+            content: '';
642
+            position: absolute;
643
+            left: -13rpx;
644
+            top: 50%;
645
+            width: 26rpx;
646
+            height: 26rpx;
647
+            border-radius: 50%;
648
+            background-color: $uni-primary;
649
+            transform: translateY(-50%);
650
+          }
651
+          .name{
652
+            font-size: 30rpx;
653
+          }
654
+          .value{
655
+            margin-left: 20rpx;
656
+            font-size: 22rpx;
657
+            color: #A1A1A1;
658
+						flex: 1;
659
+          }
660
+        }
661
+        .process_item_bottom{
662
+          min-height: 82rpx;
663
+          border-left: 1rpx solid #B7BDC6;
664
+          margin-top: 5rpx;
665
+          padding-left: 30rpx;
666
+          display: flex;
667
+          font-size: 24rpx;
668
+          color: #A1A1A1;
669
+          .value{
670
+            margin-left: 20rpx;
671
+          }
672
+        }
673
+      }
674
+    }
675
+
676
+    .appraise_detail{
677
+      padding: 24rpx 24rpx 24rpx 40rpx;
678
+      .appraise_detail_top{
679
+        display: flex;
680
+        align-items: center;
681
+        justify-content: space-between;
682
+        font-size: 26rpx;
683
+        .name{
684
+          color: #A1A1A1;
685
+        }
686
+        .value{}
687
+      }
688
+      .appraise_detail_bottom{
689
+        font-size: 30rpx;
690
+        margin-top: 24rpx;
691
+        word-break: break-all;
692
+      }
693
+    }
694
+  }
695
+}
696
+</style>

+ 278 - 133
pages/repair/repairsList.vue

@@ -9,7 +9,7 @@
9 9
       </view>
10 10
     </view>
11 11
     <view class="body" v-if="dataInfo.list.length">
12
-      <view class="body_item" v-for="data in dataInfo.list" :key="data.id" @click="toIncidentDetail(data)">
12
+      <view class="body_item" v-for="data in dataInfo.list" :key="data.id" @click.stop="toIncidentDetail(data)">
13 13
         <view class="body_item_head ellipsis-multiline">
14 14
           {{data.description}}
15 15
         </view>
@@ -18,15 +18,15 @@
18 18
 					<view class="body_item_content_p" v-if="data.place || data.houseNumber">
19 19
 					  <text class="name ellipsis">详细地址:{{data.place ? data.place.area.area : ''}}{{data.place ? data.place.place : ''}}{{data.houseNumber}}</text>
20 20
 					</view>
21
-          <view class="body_item_content_p" v-if="data.department">
22
-            <text class="name ellipsis">维修总价:{{data.department.dept}}</text>
21
+          <view class="body_item_content_p" v-if="data.rsprice">
22
+            <text class="name ellipsis">维修总价:{{data.rsprice}}</text>
23 23
             <view class="status" :style="stateStyle(data.state)">{{data.state ? data.state.name : ''}}</view>
24 24
           </view>
25 25
           <view class="body_item_content_p">
26 26
 						 <view class="name ellipsis" @click.stop="makePhoneCall(data.contactsInformation)">维修人员电话:{{data.contactsInformation || '暂无'}}<uni-icons v-if="data.contactsInformation" type="phone-filled" class="phone-filled" :size="18" :color="primaryColor"></uni-icons></view>
27 27
           </view>
28
-					<view class="body_item_content_p" v-if="data.department">
29
-					  <text class="name ellipsis">维修说明:{{data.department.dept}}</text>
28
+					<view class="body_item_content_p" v-if="data.currentLog && data.currentLog.remark">
29
+					  <text class="name ellipsis">维修说明:{{data.currentLog.remark}}</text>
30 30
 					</view>
31 31
         </view>
32 32
 
@@ -36,12 +36,19 @@
36 36
             <text class="date">{{formatDate(data.acceptDate, 'yyyy-MM-dd HH:mm')}}</text>
37 37
           </view>
38 38
           <view class="btns">
39
-            <button @click.stop="handler('changeUser', data.id)" type="default" class="primaryButton btn">评价</button>
40
-            <!-- <button @click.stop="handler('handler', data.id)" type="default" class="primaryButton btn" v-if="data.state.value === 'handler' && data.handlingPersonnelUser && data.handlingPersonnelUser.id == loginUserStore.loginUser.user.id">处理</button> -->
41
-            <!-- <button @click.stop="receive(data)" type="default" class="primaryButton btn" v-if="computedReceive(data)">接单</button> -->
39
+            <button v-if="!data.wxdegree && (data.state.name=='待评价'|| data.state.name=='已关闭')" @click.stop="handler('changeUser', data)" type="default" class="primaryButton btn">评价</button>
42 40
           </view>
43 41
         </view>
44
-				<div class="sign-style" v-if="deptRepair && publicRepair">科</div>
42
+				<div class="sign-style" v-if="deptRepair && publicRepair">
43
+					<view class="img-box" v-if="data.repairIncidentType && data.repairIncidentType.name=='科室报修'">
44
+						<view class="img-url1"></view>
45
+						<view class="img-name">科</view>
46
+					</view>
47
+					<view class="img-box" v-if="data.repairIncidentType && data.repairIncidentType.name=='公共报修'">
48
+						<view class="img-url2"></view>
49
+						<view class="img-name">公</view>
50
+					</view>
51
+				</div>
45 52
       </view>
46 53
     </view>
47 54
     <view class="zanwu" v-else>
@@ -49,7 +56,23 @@
49 56
     </view>
50 57
     <repairsFilter v-if="dataInfo.isFilter" @cancelEmit="cancelFilter" @confirmEmit="conformFilter" :evt="dataInfo.evtFilter"></repairsFilter>
51 58
     <IncidentAttachment v-if="dataInfo.isAttachment" @knowEmit="knowAttachment" :incidentData="dataInfo.incidentData"></IncidentAttachment>
52
-  </view>
59
+		<uni-popup ref="popup" background-color="#fff" type="center" :before-close="true">
60
+			<view class="popup-content">
61
+				<view class="form_item column">
62
+					<view class="title"><text class="required newicon newicon-bitian"></text>星级:</view>
63
+					<uni-rate class="value" v-model="rate" />
64
+				</view>
65
+				<view class="form_item column">
66
+					<view class="title"><text class="required newicon newicon-bitian"></text>内容:</view>
67
+					<uni-easyinput class="value" type="textarea" v-model="wxdegreeremark" placeholder="请输入评价内容"/>
68
+				</view>
69
+			</view>
70
+			<view class="foot_common_btns">
71
+			  <button @click="closePop" type="default" class="cancelButton btn">取消</button>
72
+			  <button @click="submit" type="default" class="primaryButton btn">提交</button>
73
+			</view>
74
+		</uni-popup>
75
+	</view>
53 76
 </template>
54 77
 
55 78
 <script setup>
@@ -58,7 +81,7 @@
58 81
   import { startOfDay, endOfDay, format, add } from 'date-fns'
59 82
   import { ref, reactive, computed } from 'vue'
60 83
   import { onLoad, onShow, onPullDownRefresh, onReachBottom, onTabItemTap } from '@dcloudio/uni-app'
61
-  import { api_getDictionary, api_incident, api_incident_count, api_incidentTask } from "@/http/api.js"
84
+  import { api_getDictionary, api_incident, api_incident_count, api_incidentTask, api_taskresolve } from "@/http/api.js"
62 85
   import { filterFormatDate } from '@/filters/filterFormatDate.js'
63 86
   import { computedPriorityStyle } from '@/filters/computedPriorityStyle.js'
64 87
   import { computedStateStyle } from '@/filters/computedStateStyle.js'
@@ -82,12 +105,18 @@
82 105
 
83 106
   // 主题颜色
84 107
   const primaryColor = ref(defaultColor)
85
-
108
+	const popup = ref(null);//弹框
86 109
   const assignFlag = ref(false);//指派权限
87 110
   const qiangdan = ref(false);//接单权限
88 111
 	const deptRepair = ref({});//科内报修
89 112
 	const publicRepair = ref({});//公共报修
90 113
 	
114
+	const degreeDictionary = ref(null); //星级字典
115
+	const rowData = ref(null); //选择的数据
116
+	const isSubmit = ref(false);
117
+	const rate = ref(3);//星级
118
+	const wxdegreeremark = ref(null);//评价内容
119
+	
91 120
   // 判断是否显示接单按钮
92 121
   const computedReceive = computed(() => (data) => {
93 122
     let inUser = data.currentLog && data.currentLog.workerId == loginUserStore.loginUser.user.id;
@@ -106,7 +135,9 @@
106 135
   const computedSynergetic = computed(() => (synergetic) => {
107 136
     return (synergetic && synergetic.length) ? synergetic.map(v => v.name).join(',') : ''
108 137
   })
109
-
138
+	
139
+	const repairIncident = ref(null);
140
+	
110 141
   // 数据
111 142
   const dataInfo = reactive({
112 143
     tabs: [{id: 0, name: '我的报修', value: 'all', num: ''},],
@@ -117,6 +148,7 @@
117 148
     isFilter: false,//筛选框开关
118 149
     isAttachment: false,//图片和录音开关
119 150
     incidentId: undefined,
151
+		stateValue:0,
120 152
     evtFilter: {
121 153
       hospital: {},
122 154
       selected: 'todoingAll',
@@ -129,7 +161,7 @@
129 161
   // 工单详情
130 162
   function toIncidentDetail(data){
131 163
     uni.navigateTo({
132
-      url: `/pages/incidentDetail/incidentDetail?incidentId=${data.id}`
164
+      url: `/pages/repair/repairsDetail?incidentId=${data.id}`
133 165
     })
134 166
   }
135 167
 
@@ -142,22 +174,30 @@
142 174
 		let data = JSON.parse(uni.getStorageSync('sysData'))
143 175
 		deptRepair.value = data.find(i=>i.keyconfig=='deptRepair')
144 176
 		publicRepair.value = data.find(i=>i.keyconfig=='publicRepair')
145
-		if(deptRepair.value){
177
+		let postData = {
178
+		  "key": 'repair_incident_type',
179
+		  "type": "list",
180
+		};
181
+		if(deptRepair.value.valueconfig==1){
182
+			api_getDictionary(postData).then(res => {
183
+			  res = res || [];
184
+			  repairIncident.value = res.find(i=>i.value=='dept')
185
+				getList(0);
186
+			})
146 187
 			 dataInfo.tabs = [
147 188
 				 {id: 0, name: '我的报修', value: 'all', num: ''},
148 189
 				 {id: 1, name: '科内报修', value: '2', num: ''}
149 190
 			 ]
150 191
 		}else{
192
+			getList(0);
151 193
 			dataInfo.tabs = [
152 194
 				{id: 0, name: '我的报修', value: 'all', num: ''},
153 195
 			]
154 196
 		}
155
-		getList(0);
156 197
   }
157 198
 
158 199
   // 点击tab
159 200
   function clickTab(tabId){
160
-		console.log(tabId)
161 201
     dataInfo.tabActiveId = tabId;
162 202
     getList(0);
163 203
   }
@@ -169,7 +209,8 @@
169 209
 
170 210
   // 确认筛选
171 211
   function conformFilter(evtFilter){
172
-    dataInfo.evtFilter = evtFilter;
212
+		console.log(777,evtFilter)
213
+    dataInfo.stateValue = evtFilter.category;
173 214
     dataInfo.isFilter = false;
174 215
     getList(0);
175 216
   }
@@ -190,54 +231,78 @@
190 231
     dataInfo.isAttachment = false;
191 232
   }
192 233
 
193
-  // 处理按钮
194
-  function handler(type, incidentId){
195
-    uni.navigateTo({
196
-      url: `/pages/${type}/${type}?incidentId=${incidentId}`
197
-    })
198
-  }
199
-
200
-  // 接单调用方案
201
-  function receiveFn(incidentData){
202
-    uni.showLoading({
203
-      title: "加载中",
204
-      mask: true,
205
-    });
206
-
207
-    let postData = {
208
-      incident: incidentData,
209
-    }
210
-
211
-    api_incidentTask('receive', postData).then(res => {
212
-      uni.hideLoading();
213
-      if(res.state == 200){
214
-        getList(0);
215
-        uni.showToast({
216
-        	icon: 'none',
217
-          title: '接单成功',
218
-        });
219
-      }else{
220
-        uni.showToast({
221
-          icon: 'none',
222
-          title: res.msg || '请求数据失败!'
223
-        });
224
-      }
225
-    })
226
-  }
227
-  // 接单按钮
228
-  function receive(incidentData){
229
-    uni.showModal({
230
-      title: '提示',
231
-      content: `您确认要接单吗?`,
232
-      confirmColor: defaultColor,
233
-      confirmText: '确认',
234
-      success: function(res) {
235
-        if (res.confirm) {
236
-          receiveFn(incidentData);
237
-        }
238
-      }
239
-    });
234
+  // 评价
235
+  function handler(type, data){
236
+		rowData.value = data
237
+		popup.value.open()
238
+		let postData = {
239
+		  key: "incident_degree",
240
+		  type: "list"
241
+		};
242
+		api_getDictionary(postData).then(res => {
243
+		  res = res || [];
244
+			degreeDictionary.value = res
245
+		})
240 246
   }
247
+	
248
+	function closePop(){
249
+		rate.value = 3
250
+		wxdegreeremark.value = null
251
+		popup.value.close()
252
+	}
253
+	
254
+	function submit(){
255
+		if(!rate.value){
256
+			uni.showToast({
257
+				icon: 'none',
258
+			  title: '请选择星级'
259
+			});
260
+			return;
261
+		}
262
+		if(!wxdegreeremark.value){
263
+			uni.showToast({
264
+				icon: 'none',
265
+			  title: '请输入评价内容'
266
+			});
267
+			return;
268
+		}
269
+		let rateData = null
270
+		if(rate.value==0){
271
+		   rateData=degreeDictionary.value[0].id
272
+		}else if(rate.value==1){
273
+		   rateData=degreeDictionary.value[4].id
274
+		}else if(rate.value==2){
275
+		   rateData=degreeDictionary.value[3].id
276
+		}else if(rate.value==3){
277
+		   rateData=degreeDictionary.value[2].id
278
+		}else if(rate.value==4){
279
+		   rateData=degreeDictionary.value[1].id
280
+		}else if(rate.value==5){
281
+		   rateData=degreeDictionary.value[0].id
282
+		}
283
+		let postData = {
284
+			...rowData.value,
285
+			wxdegree: rateData==0?degreeDictionary.value[0]:{id: rateData},
286
+			wxdegreeremark: wxdegreeremark.value
287
+		}
288
+		api_taskresolve({incident:postData}).then(res => {
289
+		  uni.hideLoading();
290
+		  if(res.state == 200){
291
+		    getList(0);
292
+		    uni.showToast({
293
+		    	icon: 'none',
294
+		      title: '评价成功',
295
+		    });
296
+		  }else{
297
+		    uni.showToast({
298
+		      icon: 'none',
299
+		      title: res.msg || '请求数据失败!'
300
+		    });
301
+		  }
302
+		})
303
+		closePop()
304
+	}
305
+	
241 306
 
242 307
   // 获取列表信息
243 308
   function getList(idx){
@@ -250,53 +315,24 @@
250 315
       dataInfo.list = [];
251 316
     }
252 317
     let postData = {
253
-        "idx": dataInfo.idx,
254
-        "sum": 10,
255
-        "incident": {
256
-            "queryTask": dataInfo.evtFilter.selected || undefined,
257
-            "assignee": loginUserStore.loginUser.user.id,
258
-            "statusId": dataInfo.tabActiveId || undefined,
259
-        }
260
-    }
261
-
262
-    // 请求参数调整
263
-    if(!postData.incident){
264
-        postData.incident = {};
265
-    }
266
-
267
-    if(postData.incident.queryTask === 'all' || postData.incident.queryTask === 'callback'){
268
-      if(loginUserStore.loginUser.user.duty){
269
-        // 当前的所属责任科室
270
-        postData.incident.duty = loginUserStore.loginUser.user.duty;
271
-      }else if(loginUserStore.loginUser.user.branch){
272
-        // 当前的所属院区
273
-        postData.incident.branch = loginUserStore.loginUser.user.branch.id;
274
-      }
275
-    }else{
276
-      delete postData.incident.duty;
277
-      delete postData.incident.branch;
278
-    }
279
-
280
-    if(postData.incident.queryTask === 'todo' || postData.incident.queryTask === 'owns' || postData.incident.queryTask === 'todoingAll'){
281
-        postData.incident.candidateGroups = loginUserStore.loginUser.user.group.map(v => v.id).toString();
282
-    }else{
283
-        delete postData.incident.candidateGroups;
284
-    }
285
-
286
-    if(dataInfo.evtFilter && dataInfo.evtFilter.category && dataInfo.evtFilter.category.id){
287
-      postData.incident.levelCategory = { id: dataInfo.evtFilter.category.id };
288
-    }
289
-
290
-    if(dataInfo.evtFilter && Array.isArray(dataInfo.evtFilter.acceptDate) && dataInfo.evtFilter.acceptDate.length){
291
-      postData.incident.acceptDate = format(startOfDay(new Date(dataInfo.evtFilter.acceptDate[0])), 'yyyy-MM-dd HH:mm:ss');
292
-      postData.incident.acceptDateEnd = format(endOfDay(dataInfo.evtFilter.acceptDate[1]), 'yyyy-MM-dd HH:mm:ss');
293
-    }
294
-
295
-    if(dataInfo.evtFilter && dataInfo.evtFilter.area && dataInfo.evtFilter.area.id){
296
-      postData.incident.area = dataInfo.evtFilter.area
318
+			"idx": dataInfo.idx,
319
+			"sum": 20,
320
+			incident: {
321
+				requester: dataInfo.tabActiveId == 0 ? { id: loginUserStore.loginUser.user.id } : undefined,
322
+				department: dataInfo.tabActiveId == 1 ? { id: loginUserStore.loginUser.user.dept.id } : undefined,
323
+				statesValues: (dataInfo.stateValue === 'close0' || dataInfo.stateValue === 'close1') ? 'close' : (dataInfo.stateValue || undefined),
324
+				hasWxdegree: dataInfo.stateValue === 'close0' ? 0 : (dataInfo.stateValue === 'close1' ? 1 : undefined),
325
+				repairIncidentType:{
326
+					id:''
327
+				}
328
+			}
297 329
     }
298
-
299
-    // incidentListSearchStore.setIncidentListSearchData(dataInfo);
330
+		if(dataInfo.tabActiveId == 1){
331
+			postData.incident.repairIncidentType.id = repairIncident.value.id
332
+		}
333
+		if(JSON.stringify(postData.incident.statesValues) === '{}'){
334
+			delete postData.incident.statesValues
335
+		}
300 336
     api_incident(postData).then(res => {
301 337
       uni.hideLoading();
302 338
       uni.stopPullDownRefresh();
@@ -315,10 +351,9 @@
315 351
         });
316 352
       }
317 353
     })
318
-
319
-    getCount(postData.incident);
354
+    // getCount(postData.incident);
320 355
   }
321
-
356
+	
322 357
   // 获取列表数量
323 358
   function getCount(incident = {}){
324 359
     let postData = {
@@ -346,24 +381,6 @@
346 381
 
347 382
   // 初始化
348 383
   function onLoadFn(){
349
-    // 我的-数量跳转
350
-    // if(incidentNumStore.incidentNum.data){
351
-    //   dataInfo.evtFilter.selected = incidentNumStore.incidentNum.data.queryTask;
352
-    //   dataInfo.tabActiveId = incidentNumStore.incidentNum.data.statusId;
353
-    //   incidentNumStore.clearIncidentNumData();
354
-    // }else if(incidentListSearchStore.incidentListSearch.data){
355
-    //   // 缓存的搜索条件
356
-    //   Object.assign(dataInfo, incidentListSearchStore.incidentListSearch.data);
357
-    // }
358
-
359
-    // for (let i = 0; i < loginUserStore.loginUser.menu.length; i++) {
360
-    //   if (loginUserStore.loginUser.menu[i].link == "shijianliebiao_assign") {
361
-    //     assignFlag.value = true;
362
-    //   }
363
-    //   if (loginUserStore.loginUser.menu[i].link == "shijianliebiao_qiangdan") {
364
-    //     qiangdan.value = true
365
-    //   }
366
-    // }
367 384
     getTabs();
368 385
   }
369 386
 
@@ -393,6 +410,12 @@
393 410
   })
394 411
 </script>
395 412
 
413
+<style scoped>
414
+	>>> .uni-popup__wrapper{
415
+		width: 80%;
416
+		padding: 40rpx;
417
+	}
418
+</style>
396 419
 <style lang="scss" scoped>
397 420
 page{
398 421
   height: calc(100vh - var(--window-bottom));
@@ -441,7 +464,27 @@ page{
441 464
 			.sign-style{
442 465
 				position: absolute;
443 466
 				right: 0;
444
-				top: 0;
467
+				top: -25rpx;
468
+				.img-box{
469
+					position: relative;
470
+					.img-url1{
471
+						width: 70rpx;
472
+						height: 70rpx;
473
+						background-image: url('../../static/img/jiaobiao1.png');
474
+					}
475
+					.img-url2{
476
+						width: 70rpx;
477
+						height: 70rpx;
478
+						background-image: url('../../static/img/jiaobiao2.png');
479
+					}
480
+					.img-name{
481
+						position: absolute;
482
+						right: 8rpx;
483
+						top: 0;
484
+						color: #fff;
485
+						font-size: 24rpx;
486
+					}
487
+				}
445 488
 			}
446 489
       .body_item_head{
447 490
         word-break: break-all;
@@ -512,5 +555,107 @@ page{
512 555
       margin-top: 140rpx;
513 556
     }
514 557
   }
558
+	.popup-content{
559
+		.form_item{
560
+		  display: flex;
561
+		  align-items: center;
562
+		  padding-top: 24rpx;
563
+		  min-height: 86rpx;
564
+			position: relative;
565
+			.chunk{
566
+				width: 100%;
567
+				height: 70rpx;
568
+				line-height: 70rpx;
569
+				text-align: center;
570
+				background: #F7F8FA;
571
+				box-shadow: 0px 3px 6px 1px rgba(0,0,0,0.16);
572
+				border-radius: 10rpx;
573
+			}
574
+		  &.column{
575
+		    height: auto;
576
+		    flex-direction: column;
577
+		    align-items: flex-start;
578
+				.import-rep{
579
+					padding: 5rpx 10rpx;
580
+					border-radius: 50rpx;
581
+					background: #d1fcd5;
582
+					color: #49b856;
583
+					font-size: 24rpx;
584
+				}
585
+		    .title{
586
+		      margin-right: 0;
587
+		    }
588
+				.title-width{
589
+					width: 100%;
590
+				}
591
+				.title-fl-sb{
592
+					display: flex;
593
+					justify-content: space-between;
594
+					width: 100%;
595
+				}
596
+		    .value{
597
+		      margin-top: 10rpx;
598
+		      // padding-left: 20rpx;
599
+		      box-sizing: border-box;
600
+		    }
601
+		    .tips{
602
+		      padding: 24rpx;
603
+		      text-align: center;
604
+		      font-size: 22rpx;
605
+		      color: #909399;
606
+		      width: 100%;
607
+		      box-sizing: border-box;
608
+		    }
609
+		  }
610
+		  .title{
611
+		    font-size: 26rpx;
612
+		    display: flex;
613
+		    align-items: center;
614
+		    margin-right: 12rpx;
615
+		    flex-shrink: 0;
616
+		    &.select{
617
+		      width: calc(5em + 20rpx);
618
+		    }
619
+		  }
620
+		  .value{
621
+		    width: 100%;
622
+		    &.category{
623
+		      width: 100%;
624
+		      display: flex;
625
+		      justify-content: space-between;
626
+		      align-items: center;
627
+		      .categoryName{
628
+		        font-size: 26rpx;
629
+		        color: #555;
630
+		        flex: 1;
631
+		      }
632
+		      .newicon-weibiaoti2010104{
633
+		        color: $uni-primary;
634
+		        margin-left: 24rpx;
635
+		      }
636
+		    }
637
+		    .imgTips{
638
+		      color: #909399;
639
+		      font-size: 22rpx;
640
+					margin-top: 10rpx;
641
+		    }
642
+		  }
643
+			.item-input{
644
+				border: 1px solid #DBDBDB;
645
+				height: 70rpx;
646
+				line-height: 70rpx;
647
+				padding: 0 10rpx;
648
+				border-radius: 4rpx;
649
+				width: 100%;
650
+				font-size: 14px;
651
+			}
652
+			.icon{
653
+				position: absolute;
654
+				right: 20rpx;
655
+				color: #49b856;
656
+			}
657
+		}
658
+	}
659
+	
515 660
 }
516 661
 </style>

+ 37 - 7
share/useSetTabbar.js

@@ -8,20 +8,50 @@ export function useSetTabbar() {
8 8
     let flag = false;
9 9
     
10 10
     switch(index){
11
+			case 0:
12
+			  // 故障
13
+			  if(loginUserStore.loginUser.user.engineer == 1){
14
+			    flag = true;
15
+			  }
16
+			  break;
11 17
       case 1:
12 18
         // 巡检
13
-        if(loginUserStore.loginUser.menu.some(v => v.link === 'app.inspection.inspectList')){
19
+				if(loginUserStore.loginUser.user.engineer == 0){
20
+					flag = false;
21
+				}else if(loginUserStore.loginUser.menu.some(v => v.link === 'app.inspection.inspectList')){
14 22
           flag = true;
15 23
         }
16 24
         break;
25
+			case 2:
26
+			  // 我的报修
27
+			  if(loginUserStore.loginUser.user.engineer == 0){
28
+			    flag = true;
29
+			  }else{
30
+					flag = true;
31
+				}
32
+			  break;
33
+			case 3:
34
+			  // 我的
35
+			  if(loginUserStore.loginUser.user.engineer == 1){
36
+			    flag = true;
37
+			  }else{
38
+					flag = false;
39
+				}
40
+			  break;
41
+			case 4:
42
+				// 设置
43
+				if(loginUserStore.loginUser.user.engineer == 0){
44
+				  flag = true;
45
+				}else{
46
+					flag = false;
47
+				}
48
+				break;
17 49
     }
18 50
     
19
-    if(flag){
20
-      uni.setTabBarItem({
21
-        index,
22
-        visible: true,
23
-      });
24
-    }
51
+		uni.setTabBarItem({
52
+			index,
53
+			visible: flag,
54
+		});
25 55
   }
26 56
 
27 57
   return {

+ 36 - 23
share/useUploadFile.js

@@ -24,30 +24,43 @@ export function useUploadFile() {
24 24
    * 上传图片
25 25
    */
26 26
   const uploadFile = async (imgObj, type, incidentId) => {
27
-    const res = await uni.getImageInfo({src: imgObj.url});
28
-    console.log('压缩前', res)
29
-    let canvasWidth = res.width //图片原始长宽
30
-    let canvasHeight = res.height
31
-    let img = new Image()
32
-    img.src = res.path
33
-    let canvas = document.createElement('canvas');
34
-    let ctx = canvas.getContext('2d')
35
-    canvas.width = canvasWidth
36
-    canvas.height = canvasHeight
37
-    await newImage(img)
38
-    ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight)
27
+		console.log('44444', type)
28
+		if(imgObj.extname=='mp4' || imgObj.extname=='avi' || imgObj.extname=='mpeg' || imgObj.extname=='wmv'){
29
+			return uni.uploadFile({
30
+			  url: api_uploadAttachment(type, incidentId),
31
+			  filePath: imgObj.path,
32
+			  name: 'file',
33
+			  formData: {
34
+			    'filename': imgObj.name
35
+			  }
36
+			})
37
+		}else{
38
+			const res = await uni.getImageInfo({src: imgObj.url});
39
+			console.log('压缩前', res)
40
+			let canvasWidth = res.width //图片原始长宽
41
+			let canvasHeight = res.height
42
+			let img = new Image()
43
+			img.src = res.path
44
+			let canvas = document.createElement('canvas');
45
+			let ctx = canvas.getContext('2d')
46
+			canvas.width = canvasWidth
47
+			canvas.height = canvasHeight
48
+			await newImage(img)
49
+			ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight)
50
+			
51
+			const fileSrc = await toBlob(canvas, imgObj)
52
+			let tp = window.URL.createObjectURL(fileSrc)
53
+			console.log('压缩后', tp);
54
+			return uni.uploadFile({
55
+			  url: api_uploadAttachment(type, incidentId),
56
+			  filePath: tp,
57
+			  name: 'file',
58
+			  formData: {
59
+			    'filename': imgObj.name
60
+			  }
61
+			});
62
+		}
39 63
     
40
-    const fileSrc = await toBlob(canvas, imgObj)
41
-    let tp = window.URL.createObjectURL(fileSrc)
42
-    console.log('压缩后', tp);
43
-    return uni.uploadFile({
44
-      url: api_uploadAttachment(type, incidentId),
45
-      filePath: tp,
46
-      name: 'file',
47
-      formData: {
48
-        'filename': imgObj.name
49
-      }
50
-    });
51 64
   }
52 65
 
53 66
   return {

+ 26 - 3
static/font/demo_index.html

@@ -55,6 +55,12 @@
55 55
           <ul class="icon_lists dib-box">
56 56
           
57 57
             <li class="dib">
58
+              <span class="icon newicon">&#xe633;</span>
59
+                <div class="name">右箭头</div>
60
+                <div class="code-name">&amp;#xe633;</div>
61
+              </li>
62
+          
63
+            <li class="dib">
58 64
               <span class="icon newicon">&#xe661;</span>
59 65
                 <div class="name">扫一扫</div>
60 66
                 <div class="code-name">&amp;#xe661;</div>
@@ -240,9 +246,9 @@
240 246
 <pre><code class="language-css"
241 247
 >@font-face {
242 248
   font-family: 'newicon';
243
-  src: url('iconfont.woff2?t=1721722303907') format('woff2'),
244
-       url('iconfont.woff?t=1721722303907') format('woff'),
245
-       url('iconfont.ttf?t=1721722303907') format('truetype');
249
+  src: url('iconfont.woff2?t=1721874329610') format('woff2'),
250
+       url('iconfont.woff?t=1721874329610') format('woff'),
251
+       url('iconfont.ttf?t=1721874329610') format('truetype');
246 252
 }
247 253
 </code></pre>
248 254
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -269,6 +275,15 @@
269 275
         <ul class="icon_lists dib-box">
270 276
           
271 277
           <li class="dib">
278
+            <span class="icon newicon newicon-youjiantou"></span>
279
+            <div class="name">
280
+              右箭头
281
+            </div>
282
+            <div class="code-name">.newicon-youjiantou
283
+            </div>
284
+          </li>
285
+          
286
+          <li class="dib">
272 287
             <span class="icon newicon newicon-saoma"></span>
273 288
             <div class="name">
274 289
               扫一扫
@@ -549,6 +564,14 @@
549 564
           
550 565
             <li class="dib">
551 566
                 <svg class="icon svg-icon" aria-hidden="true">
567
+                  <use xlink:href="#newicon-youjiantou"></use>
568
+                </svg>
569
+                <div class="name">右箭头</div>
570
+                <div class="code-name">#newicon-youjiantou</div>
571
+            </li>
572
+          
573
+            <li class="dib">
574
+                <svg class="icon svg-icon" aria-hidden="true">
552 575
                   <use xlink:href="#newicon-saoma"></use>
553 576
                 </svg>
554 577
                 <div class="name">扫一扫</div>

+ 7 - 3
static/font/iconfont.css

@@ -1,8 +1,8 @@
1 1
 @font-face {
2 2
   font-family: "newicon"; /* Project id 4304860 */
3
-  src: url('iconfont.woff2?t=1721722303907') format('woff2'),
4
-       url('iconfont.woff?t=1721722303907') format('woff'),
5
-       url('iconfont.ttf?t=1721722303907') format('truetype');
3
+  src: url('iconfont.woff2?t=1721874329610') format('woff2'),
4
+       url('iconfont.woff?t=1721874329610') format('woff'),
5
+       url('iconfont.ttf?t=1721874329610') format('truetype');
6 6
 }
7 7
 
8 8
 .newicon {
@@ -13,6 +13,10 @@
13 13
   -moz-osx-font-smoothing: grayscale;
14 14
 }
15 15
 
16
+.newicon-youjiantou:before {
17
+  content: "\e633";
18
+}
19
+
16 20
 .newicon-saoma:before {
17 21
   content: "\e661";
18 22
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
static/font/iconfont.js


+ 7 - 0
static/font/iconfont.json

@@ -6,6 +6,13 @@
6 6
   "description": "",
7 7
   "glyphs": [
8 8
     {
9
+      "icon_id": "9021524",
10
+      "name": "右箭头",
11
+      "font_class": "youjiantou",
12
+      "unicode": "e633",
13
+      "unicode_decimal": 58931
14
+    },
15
+    {
9 16
       "icon_id": "6757421",
10 17
       "name": "扫一扫",
11 18
       "font_class": "saoma",

BIN
static/font/iconfont.ttf


BIN
static/font/iconfont.woff


BIN
static/font/iconfont.woff2


BIN
static/img/300.jpg


BIN
static/img/audio_play.gif


BIN
static/img/jiaobiao1.png


BIN
static/img/jiaobiao2.png


BIN
static/logo.png


BIN
static/sound-recording/pause.png


BIN
static/sound-recording/play.png


BIN
static/sound-recording/voice.png


+ 1 - 2
uni_modules/sy-audio/components/sy-audio/sy-audio.vue

@@ -97,7 +97,6 @@
97 97
 		async mounted() {
98 98
 			this.innerAudioContext.src = typeof(this.src) == 'string' ? this.src : this.src[0];
99 99
       this.countDown();
100
-
101 100
 			if (this.autoplay) {
102 101
 				if (!this.src) return console.error('src cannot be empty,The target value is string or array')
103 102
 
@@ -189,7 +188,7 @@
189 188
 				}, 100)
190 189
 			},
191 190
 			clickAudio() {
192
-
191
+				console.log(888,this.innerAudioContext)
193 192
 				if (this.audio_status && !this.innerAudioContext.paused) {
194 193
 					this.innerAudioContext.pause();
195 194
 					clearInterval(timer);