随手拍改造完成
This commit is contained in:
		
							
								
								
									
										27
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/App.vue
									
									
									
									
									
								
							| @@ -148,31 +148,4 @@ button.primary { | ||||
|   align-items: center; | ||||
|   margin-right: 8px; | ||||
| } | ||||
|  | ||||
| .flex { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|  | ||||
|   &.spb { | ||||
|     justify-content: space-between; | ||||
|   } | ||||
|  | ||||
|   &.wrap { | ||||
|     flex-wrap: wrap; | ||||
|   } | ||||
|  | ||||
|   &.column { | ||||
|     flex-direction: column; | ||||
|   } | ||||
|  | ||||
|   &.start { | ||||
|     align-items: flex-start; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .fill { | ||||
|   flex: 1; | ||||
|   min-width: 0; | ||||
|   min-height: 0; | ||||
| } | ||||
| </style> | ||||
|   | ||||
							
								
								
									
										81
									
								
								src/components/AiEvaluation/AiEvaluation.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/components/AiEvaluation/AiEvaluation.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| <template> | ||||
|   <section class="AiEvaluation"> | ||||
|     <AiPagePicker v-if="type=='submit'&&!hasEvaluated" type="custom" :ops="ops" nodeKey=""> | ||||
|       <slot v-if="$slots.default"/> | ||||
|       <div v-else v-text="placeholder"/> | ||||
|     </AiPagePicker> | ||||
|     <div v-if="type=='show'"> | ||||
|       <slot v-if="$slots.default"/> | ||||
|       <AiGroup description no-border labelColor="#999" v-else> | ||||
|         <AiItem label="评级分数"> | ||||
|           <u-rate v-model="detail.score" disabled inactive-icon="star-fill" active-color="#F8B425"/> | ||||
|           {{ detail.rateText || "" }} | ||||
|         </AiItem> | ||||
|         <AiItem label="评价详情" top-label> | ||||
|           <div v-html="detail.content"/> | ||||
|         </AiItem> | ||||
|         <AiItem label="附件" top-label> | ||||
|           <AiUploader :def="detail.files" disabled/> | ||||
|         </AiItem> | ||||
|       </AiGroup> | ||||
|     </div> | ||||
|     <slot name="finish" v-if="$slots.finish"/> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import AiPagePicker from "../AiPagePicker/AiPagePicker"; | ||||
| import AiGroup from "../AiGroup/AiGroup"; | ||||
| import AiItem from "../AiItem/AiItem"; | ||||
| import AiUploader from "../AiUploader/AiUploader"; | ||||
|  | ||||
| export default { | ||||
|   name: "AiEvaluation", | ||||
|   model: { | ||||
|     prop: "info", | ||||
|     event: "input" | ||||
|   }, | ||||
|   props: { | ||||
|     info: {default: () => ({})}, | ||||
|     placeholder: {default: "去评价"}, | ||||
|     bid: {default: ""}, | ||||
|     type: {default: "submit"} //可选值: submit:提交评价,show:展示评价 | ||||
|   }, | ||||
|   components: {AiUploader, AiItem, AiGroup, AiPagePicker}, | ||||
|   computed: { | ||||
|     isShow: v => v.type == 'show', | ||||
|     hasEvaluated: v => !!v.detail?.id | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       detail: {}, | ||||
|       ops: { | ||||
|         rateTexts: ['非常不满意', '不满意', '一般', '满意', '非常满意'], | ||||
|         url: "/components/pages/submitEvaluation?bid=" + this.bid | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     bid: { | ||||
|       immediate: true, | ||||
|       handler() { | ||||
|         this.getDetail() | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getDetail() { | ||||
|       const bizId = this.bid | ||||
|       bizId && this.$instance.post("/app/appbusinesscompletionevaluation/queryMyEvaluationByBizId", null, { | ||||
|         params: {bizId} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           const info = res.data?.[0] | ||||
|           this.detail = {...info, rateText: this.rateTexts?.[info.score - 1]} | ||||
|           this.$emit("input", this.detail) | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
| @@ -1,12 +1,33 @@ | ||||
| <template> | ||||
|   <section class="AiGroup"> | ||||
|   <section class="AiGroup" :class="{noBorder,description}" :style="{paddingLeft:left+'rpx'}"> | ||||
|     <div class="groupHeader" v-if="title" v-text="title"/> | ||||
|     <slot/> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "AiGroup" | ||||
|   name: "AiGroup", | ||||
|   provide() { | ||||
|     return { | ||||
|       labelColor: this.labelColor, | ||||
|       description: this.description, | ||||
|       activeStep: this.activeStep | ||||
|     } | ||||
|   }, | ||||
|   props: { | ||||
|     title: String, | ||||
|     noBorder: Boolean, | ||||
|     left: {default: 32}, | ||||
|     labelColor: {default: "#333"}, | ||||
|     description: {default: false}, //用于展示则不会又红星,会把标签的内间距去掉 | ||||
|     activeStep: {default: 0}//用于步骤组件的当前步数 | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       items: [] | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| @@ -14,10 +35,27 @@ export default { | ||||
| .AiGroup { | ||||
|   background: #FFFFFF; | ||||
|   box-shadow: inset 0px -1px 0px 0px #DDDDDD; | ||||
|   padding-left: 32px; | ||||
|  | ||||
|   &.noBorder { | ||||
|     box-shadow: none; | ||||
|   } | ||||
|  | ||||
|   & + .AiGroup { | ||||
|     margin-top: 16px; | ||||
|   } | ||||
|  | ||||
|   .groupHeader { | ||||
|     font-weight: bold; | ||||
|     font-size: 36px; | ||||
|     padding-left: 20px; | ||||
|     margin-bottom: 16px; | ||||
|   } | ||||
|  | ||||
|   &.description { | ||||
|     .groupHeader { | ||||
|       padding-left: 0; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
| </style> | ||||
|   | ||||
| @@ -1,18 +1,18 @@ | ||||
| <template> | ||||
|   <section class="AiItem" :class="{border}"> | ||||
|   <section class="AiItem" :class="{border,readonly}"> | ||||
|     <div v-if="topLabel" class="topLabel"> | ||||
|       <div class="labelPane flex"> | ||||
|         <div class="label" :class="{required,labelBold}" v-text="label"/> | ||||
|         <div class="label" :class="{required,labelBold}" :style="{color}" v-text="label"/> | ||||
|         <slot name="sub" v-if="$slots.sub"/> | ||||
|       </div> | ||||
|       <div class="content"> | ||||
|       <div class="itemContent"> | ||||
|         <slot v-if="$slots.default"/> | ||||
|         <div v-else v-text="value"/> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div v-else class="normal flex"> | ||||
|       <div class="fill flex"> | ||||
|         <div class="label" :class="{required,labelBold}" v-text="label"/> | ||||
|         <div class="label" :class="{required,labelBold}" :style="{color}" v-text="label"/> | ||||
|         <slot name="sub" v-if="$slots.sub"/> | ||||
|       </div> | ||||
|       <div class="flexContent"> | ||||
| @@ -26,16 +26,21 @@ | ||||
| <script> | ||||
| export default { | ||||
|   name: "AiItem", | ||||
|   inject: { | ||||
|     labelColor: {default: "#333"}, | ||||
|     description: {default: false} | ||||
|   }, | ||||
|   props: { | ||||
|     value: {default: ""}, | ||||
|     label: {default: ""}, | ||||
|     required: Boolean, | ||||
|     topLabel: Boolean, | ||||
|     border: {default: true}, | ||||
|     labelBold: Boolean | ||||
|     labelBold: Boolean, | ||||
|   }, | ||||
|   data() { | ||||
|     return {} | ||||
|   computed: { | ||||
|     color: v => v.labelColor, | ||||
|     readonly: v => !!v.description | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| @@ -44,7 +49,7 @@ export default { | ||||
| .AiItem { | ||||
|   font-family: PingFangSC-Regular, PingFang SC; | ||||
|  | ||||
|   .border { | ||||
|   &.border { | ||||
|     .normal { | ||||
|       border-bottom: 2px solid #ddd; | ||||
|     } | ||||
| @@ -68,7 +73,6 @@ export default { | ||||
|   .label { | ||||
|     padding-left: 20px; | ||||
|     font-weight: 400; | ||||
|     color: #333333; | ||||
|     margin-right: 20px; | ||||
|     position: relative; | ||||
|  | ||||
| @@ -95,7 +99,7 @@ export default { | ||||
|       margin-bottom: 32px; | ||||
|     } | ||||
|  | ||||
|     .content { | ||||
|     .itemContent { | ||||
|       padding-left: 20px; | ||||
|  | ||||
|       .AiMore > .u-icon { | ||||
| @@ -103,5 +107,18 @@ export default { | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   //展示模式下的特有样式 | ||||
|   &.readonly { | ||||
|     .label, .itemContent { | ||||
|       padding-left: 0; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .AiStep:last-of-type { | ||||
|     .stepLine { | ||||
|       display: none | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
|   | ||||
							
								
								
									
										79
									
								
								src/components/AiStep/AiStep.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/components/AiStep/AiStep.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| <template> | ||||
|   <section class="AiStep flex start" :class="{active:!!index&&active==index}"> | ||||
|     <div class="leftPane mar-r32"> | ||||
|       <div class="num" v-text="stepIndex"/> | ||||
|       <div v-if="!isLast" class="stepLine fill"/> | ||||
|     </div> | ||||
|     <div class="fill"> | ||||
|       <slot/> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "AiStep", | ||||
|   inject: ['activeStep'], | ||||
|   props: { | ||||
|     index: {default: null}, | ||||
|   }, | ||||
|   computed: { | ||||
|     active: v => v.activeStep, | ||||
|     stepIndex: v => { | ||||
|       const index = v.$parent.items.findIndex(e => e == v._uid) | ||||
|       return index > -1 ? index + 1 : "" | ||||
|     }, | ||||
|     isLast: v => v.$parent.items.length == v.stepIndex | ||||
|   }, | ||||
|   created() { | ||||
|     this.$parent.items.splice(this.index, 0, this._uid) | ||||
|   }, | ||||
|   destroyed() { | ||||
|     const index = this.$parent.items.findIndex(e => e == this._uid) | ||||
|     this.$parent.items.splice(index, 1) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AiStep { | ||||
|   width: 100%; | ||||
|   font-size: 28px; | ||||
|   position: relative; | ||||
|  | ||||
|   .leftPane { | ||||
|     width: 32px; | ||||
|  | ||||
|     .num { | ||||
|       color: #333; | ||||
|       height: 32px; | ||||
|       width: 32px; | ||||
|       font-size: 28px; | ||||
|       line-height: 32px; | ||||
|       text-align: center; | ||||
|       border: 4px solid #CCCCCC; | ||||
|       border-radius: 50%; | ||||
|     } | ||||
|  | ||||
|     .stepLine { | ||||
|       position: absolute; | ||||
|       top: 40px; | ||||
|       bottom: 0; | ||||
|       width: 4px; | ||||
|       left: 20px; | ||||
|       transform: translateX(-50%); | ||||
|       background: #eee; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   &.active { | ||||
|     .leftPane { | ||||
|       .num { | ||||
|         background: #26f; | ||||
|         border-color: #26f; | ||||
|         color: #fff; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -3,7 +3,7 @@ | ||||
|     <div class="imgList" v-if="type == 'image'"> | ||||
|       <div class="item" v-for="(item, i) in fileList" :key="i"> | ||||
|         <ai-image :src="item.url" :preview="preview"/> | ||||
|         <u-icon class="delBtn" color="#f46" name="close-circle-fill" size="40" @click="remove(i)"/> | ||||
|         <u-icon v-if="!disabled" class="delBtn" color="#f46" name="close-circle-fill" size="40" @click="remove(i)"/> | ||||
|       </div> | ||||
|       <div v-if="!disabled&&(fileList.length == 0 || (fileList.length < limit))" class="default" @click="upload"> | ||||
|         <u-icon name="photo" size="64" :label="placeholder" label-pos="bottom" label-color="#89b"/> | ||||
| @@ -70,6 +70,8 @@ export default { | ||||
|             this.fileList = v | ||||
|           } else if (v?.url) { | ||||
|             this.fileList = [v] | ||||
|           } else if (v?.length > 0) { | ||||
|             this.fileList = v | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
| @@ -128,7 +130,6 @@ export default { | ||||
|         this.$emit('manual', img) | ||||
|         uni.hideLoading() | ||||
|       } else { | ||||
|         console.log(this.$instance.defaults) | ||||
|         uni.uploadFile({ | ||||
|           url: this.$instance.defaults.baseURL + this.action, | ||||
|           filePath: img.path, | ||||
|   | ||||
| @@ -1,5 +1,21 @@ | ||||
| @import '~uview-ui/theme.scss'; | ||||
| @import "ckeditor"; | ||||
|  | ||||
| /** | ||||
| 常用内外边距样式 | ||||
|  */ | ||||
| @each $padMar, $pm in (mar:margin, pad:padding) { | ||||
|   @each $pos, $p in (l:left, r:right, t:top, b:bottom) { | ||||
|     @each $v in (8, 10, 16, 20, 32, 48, 64) { | ||||
|       .#{$padMar}-#{$pos+$v} { | ||||
|         #{$pm}-#{$p}: #{$v}px | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| .bg-fff{ | ||||
|   background-color: #fff; | ||||
| } | ||||
| @font-face { | ||||
|   font-family: 'iconfont'; | ||||
|   /* project id 1862352 */ | ||||
| @@ -47,9 +63,31 @@ page { | ||||
| .bg-hover { | ||||
|   background: #eee !important; | ||||
| } | ||||
|  | ||||
| .flex { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|  | ||||
|   &.spb { | ||||
|     justify-content: space-between; | ||||
|   } | ||||
|  | ||||
|   &.wrap { | ||||
|     flex-wrap: wrap; | ||||
|   } | ||||
|  | ||||
|   &.column { | ||||
|     flex-direction: column; | ||||
|   } | ||||
|  | ||||
|   &.start { | ||||
|     align-items: flex-start; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .fill { | ||||
|   flex: 1; | ||||
|   min-width: 0; | ||||
|   min-height: 0; | ||||
| } | ||||
|  | ||||
| .flex-align { | ||||
| @@ -489,263 +527,6 @@ button::after { | ||||
|   background-color: #fff; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * author: Di (微信小程序开发工程师) | ||||
|  * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||||
|  *         垂直微信小程序开发交流社区 | ||||
|  * | ||||
|  * github地址: https://github.com/icindy/wxParse | ||||
|  * | ||||
|  * for: 微信小程序富文本解析 | ||||
|  * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||||
|  */ | ||||
|  | ||||
| .wxParse { | ||||
|   width: 100%; | ||||
|   font-family: Helvetica, sans-serif; | ||||
|   font-size: 28px; | ||||
|   color: #666; | ||||
|   line-height: 1.8; | ||||
| } | ||||
|  | ||||
| .wxParse view { | ||||
|   word-break: hyphenate; | ||||
| } | ||||
|  | ||||
| .wxParse .inline { | ||||
|   display: inline; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
| } | ||||
|  | ||||
| .wxParse .div { | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
| } | ||||
|  | ||||
| .wxParse .h1 { | ||||
|   font-size: 2em; | ||||
|   margin: 0.67em 0; | ||||
| } | ||||
|  | ||||
| .wxParse .h2 { | ||||
|   font-size: 1.5em; | ||||
|   margin: 0.83em 0; | ||||
| } | ||||
|  | ||||
| .wxParse .h3 { | ||||
|   font-size: 1.17em; | ||||
|   margin: 1em 0; | ||||
| } | ||||
|  | ||||
| .wxParse .h4 { | ||||
|   margin: 1.33em 0; | ||||
| } | ||||
|  | ||||
| .wxParse .h5 { | ||||
|   font-size: 0.83em; | ||||
|   margin: 1.67em 0; | ||||
| } | ||||
|  | ||||
| .wxParse .h6 { | ||||
|   font-size: 0.67em; | ||||
|   margin: 2.33em 0; | ||||
| } | ||||
|  | ||||
| .wxParse .h1, | ||||
| .wxParse .h2, | ||||
| .wxParse .h3, | ||||
| .wxParse .h4, | ||||
| .wxParse .h5, | ||||
| .wxParse .h6, | ||||
| .wxParse .b, | ||||
| .wxParse .strong { | ||||
|   font-weight: bolder; | ||||
| } | ||||
|  | ||||
| .wxParse .p { | ||||
|   margin: 1em 0; | ||||
|   word-wrap: break-word; | ||||
| } | ||||
|  | ||||
| .wxParse .i, | ||||
| .wxParse .cite, | ||||
| .wxParse .em, | ||||
| .wxParse .var, | ||||
| .wxParse .address { | ||||
|   font-style: italic; | ||||
| } | ||||
|  | ||||
| .wxParse .pre, | ||||
| .wxParse .tt, | ||||
| .wxParse .code, | ||||
| .wxParse .kbd, | ||||
| .wxParse .samp { | ||||
|   font-family: monospace; | ||||
| } | ||||
|  | ||||
| .wxParse .pre { | ||||
|   overflow: auto; | ||||
|   background: #f5f5f5; | ||||
|   padding: 8px; | ||||
|   white-space: pre; | ||||
|   margin: 1em 0; | ||||
| } | ||||
|  | ||||
| .wxParse .code { | ||||
|   display: inline; | ||||
|   background: #f5f5f5; | ||||
| } | ||||
|  | ||||
| .wxParse .big { | ||||
|   font-size: 1.17em; | ||||
| } | ||||
|  | ||||
| .wxParse .small, | ||||
| .wxParse .sub, | ||||
| .wxParse .sup { | ||||
|   font-size: 0.83em; | ||||
| } | ||||
|  | ||||
| .wxParse .sub { | ||||
|   vertical-align: sub; | ||||
| } | ||||
|  | ||||
| .wxParse .sup { | ||||
|   vertical-align: super; | ||||
| } | ||||
|  | ||||
| .wxParse .s, | ||||
| .wxParse .strike, | ||||
| .wxParse .del { | ||||
|   text-decoration: line-through; | ||||
| } | ||||
|  | ||||
| .wxParse .strong, | ||||
| .wxParse .s { | ||||
|   display: inline; | ||||
| } | ||||
|  | ||||
| .wxParse .a { | ||||
|   color: deepskyblue; | ||||
| } | ||||
|  | ||||
| .wxParse .video { | ||||
|   text-align: center; | ||||
|   margin: 10px 0; | ||||
| } | ||||
|  | ||||
| .wxParse .video-video { | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .wxParse .img { | ||||
|   display: inline-block; | ||||
|   width: 0; | ||||
|   height: 0; | ||||
|   max-width: 100% !important; | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .wxParse .blockquote { | ||||
|   margin: 5px 0; | ||||
|   padding: 10px 0 10px 10px; | ||||
|   font-family: Courier, Calibri, "宋体"; | ||||
|   background: #f5f5f5; | ||||
|   border-left: 3px solid #dbdbdb; | ||||
| } | ||||
|  | ||||
| .wxParse .blockquote .p { | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .wxParse .ul, | ||||
| .wxParse .ol { | ||||
|   display: block; | ||||
|   margin: 1em 0; | ||||
|   padding-left: 16px; | ||||
| } | ||||
|  | ||||
| .wxParse .ol { | ||||
|   list-style-type: disc; | ||||
| } | ||||
|  | ||||
| .wxParse .ol { | ||||
|   list-style-type: decimal; | ||||
| } | ||||
|  | ||||
| .wxParse .li { | ||||
|   display: list-item; | ||||
|   align-items: baseline; | ||||
|   text-align: match-parent; | ||||
| } | ||||
|  | ||||
| .wxParse .ul .ul, | ||||
| .wxParse .ol .ul { | ||||
|   list-style-type: circle; | ||||
| } | ||||
|  | ||||
| .wxParse .ol .ol .ul, | ||||
| .wxParse .ol .ul .ul, | ||||
| .wxParse .ul .ol .ul, | ||||
| .wxParse .ul .ul .ul { | ||||
|   list-style-type: square; | ||||
| } | ||||
|  | ||||
| .wxParse .u { | ||||
|   text-decoration: underline; | ||||
| } | ||||
|  | ||||
| .wxParse .hide { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .wxParse .del { | ||||
|   display: inline; | ||||
| } | ||||
|  | ||||
| .wxParse .figure { | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .wxParse .table { | ||||
|   width: 100%; | ||||
|   overflow: auto; | ||||
| } | ||||
|  | ||||
| .wxParse .thead, | ||||
| .wxParse .tfoot, | ||||
| .wxParse .tr { | ||||
|   display: flex; | ||||
|   flex-direction: row; | ||||
| } | ||||
|  | ||||
| .wxParse .tr { | ||||
|   width: 100%; | ||||
|   display: flex; | ||||
|   /*border-right: 1px solid #e0e0e0;*/ | ||||
|   border-bottom: 1px solid #e0e0e0; | ||||
| } | ||||
|  | ||||
| .wxParse .th, | ||||
| .wxParse .td { | ||||
|   display: flex; | ||||
|   width: 260px; | ||||
|   overflow: auto; | ||||
|   padding: 5px; | ||||
|   /*border-left: 1px solid #e0e0e0;*/ | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| .wxParse .td:last-child { | ||||
|   border-top: 1px solid #e0e0e0; | ||||
| } | ||||
|  | ||||
| .wxParse .th { | ||||
|   background: #f0f0f0; | ||||
|   border-top: 1px solid #e0e0e0; | ||||
| } | ||||
|  | ||||
| .btn-wrapper { | ||||
|   position: fixed; | ||||
|   left: 50%; | ||||
| @@ -757,6 +538,18 @@ button::after { | ||||
|   background: #f3f6f9; | ||||
| } | ||||
|  | ||||
| .bottomBtn { | ||||
|   color: #fff; | ||||
|   font-size: 34px; | ||||
|   background: #4181FF; | ||||
|   border-radius: 16px; | ||||
|   height: 88px; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   margin: 8px 24px; | ||||
| } | ||||
|  | ||||
| .btn-wrapper { | ||||
|   .btn { | ||||
|     width: 686px; | ||||
|   | ||||
							
								
								
									
										65
									
								
								src/components/pages/submitEvaluation.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/components/pages/submitEvaluation.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| <template> | ||||
|   <section class="submitEvaluation"> | ||||
|     <AiGroup> | ||||
|       <AiItem label="评价分数" top-label required> | ||||
|         <u-rate v-model="form.score" :size="64" active-color="#F8B425" :min-count="1" inactive-icon="star-fill"/> | ||||
|       </AiItem> | ||||
|     </AiGroup> | ||||
|     <u-gap height="24"/> | ||||
|     <AiGroup> | ||||
|       <AiItem label="评价详情" top-label required> | ||||
|         <u-input type="textarea" v-model="form.content" placeholder="请简要描述..."/> | ||||
|       </AiItem> | ||||
|     </AiGroup> | ||||
|     <u-gap height="24"/> | ||||
|     <AiGroup> | ||||
|       <AiItem label="附件" top-label> | ||||
|         <AiUploader v-model="form.files" :limit="9" multiple/> | ||||
|       </AiItem> | ||||
|     </AiGroup> | ||||
|     <div class="fixed-bottom"> | ||||
|       <div class="bottomBtn" @click="submit">提交</div> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import AiUploader from "../AiUploader/AiUploader"; | ||||
|  | ||||
| export default { | ||||
|   name: "submitEvaluation", | ||||
|   components: {AiUploader}, | ||||
|   appName: "提交评价", | ||||
|   data() { | ||||
|     return { | ||||
|       form: { | ||||
|         files: [] | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     submit() { | ||||
|       if (!this.form.score) { | ||||
|         return this.$u.toast("请选择评价分数!") | ||||
|       } | ||||
|       if (!this.form.content) { | ||||
|         return this.$u.toast("请填写评价详情!") | ||||
|       } | ||||
|       this.$instance.post("/app/appbusinesscompletionevaluation/addOrUpdate", this.form).then(res => { | ||||
|         if (res?.code == 0) { | ||||
|           this.$u.toast("提交成功!") | ||||
|           setTimeout(() => uni.navigateBack({}), 1500) | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   onLoad(params) { | ||||
|     this.form.bizId = params.bid | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .submitEvaluation { | ||||
| } | ||||
| </style> | ||||
| @@ -1,27 +1,34 @@ | ||||
| <template> | ||||
|   <div class="photo-list"> | ||||
|     <div class="photo-list__wrapper"> | ||||
|       <div class="photo-item" v-for="(item, index) in list" :key="index" hover-class="bg-hover" @click="$linkTo('./PhotoDetail?id=' + item.id)"> | ||||
|         <div class="photo-item__top"> | ||||
|           <h2>{{ item.content }}</h2> | ||||
|           <div class="photo-item__top--info"> | ||||
|             <div class="photo-item__top--info-item"> | ||||
|               <label>事件类型</label> | ||||
|               <span>{{ item.groupName }}</span> | ||||
|             </div> | ||||
|             <div class="photo-item__top--info-item"> | ||||
|               <label>所属网格</label> | ||||
|               <span>{{ item.girdName }}</span> | ||||
|  | ||||
|       <div class="photo-item" v-for="(item, index) in list" :key="index"> | ||||
|         <u-swipe-action @content-click="$linkTo('./PhotoDetail?id=' + item.id)" :index="item.id" | ||||
|                         :options="itemOptions" @click="handleDelete"> | ||||
|           <div class="photo-item__top"> | ||||
|             <h2>{{ item.content }}</h2> | ||||
|             <div class="photo-item__top--info"> | ||||
|               <div class="photo-item__top--info-item"> | ||||
|                 <label>事件类型</label> | ||||
|                 <span>{{ item.groupName }}</span> | ||||
|               </div> | ||||
|               <div class="photo-item__top--info-item"> | ||||
|                 <label>所属网格</label> | ||||
|                 <span>{{ item.girdName }}</span> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="photo-item__bottom flex"> | ||||
|           <div class="flex fill"> | ||||
|             <i :class="'status-' + item.eventStatus"></i> | ||||
|             <span :class="'status-' + item.eventStatus">{{ item.statusName }}</span> | ||||
|           <div class="photo-item__bottom flex"> | ||||
|             <div class="flex fill"> | ||||
|               <i :class="'status-' + item.eventStatus"></i> | ||||
|               <span :class="'status-' + item.eventStatus">{{ item.statusName }}</span> | ||||
|             </div> | ||||
|             <AiEvaluation :bid="item.id" v-if="item.eventStatus>1"> | ||||
|               <div class="itemBtn">去评价</div> | ||||
|               <div slot="finish" class="finish">已评价</div> | ||||
|             </AiEvaluation> | ||||
|           </div> | ||||
|           <div class="color-red" @click.stop="handleDelete(item.id)">删除</div> | ||||
|         </div> | ||||
|         </u-swipe-action> | ||||
|       </div> | ||||
|       <AiEmpty v-if="!list.length"/> | ||||
|     </div> | ||||
| @@ -43,7 +50,10 @@ export default { | ||||
|       pageShow: false, | ||||
|       current: 1, | ||||
|       total: 0, | ||||
|       isMore: false | ||||
|       isMore: false, | ||||
|       itemOptions: [ | ||||
|         {text: '删除', style: {backgroundColor: '#f46'}} | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|  | ||||
| @@ -140,10 +150,11 @@ export default { | ||||
|  | ||||
|   .photo-item { | ||||
|     width: 686px; | ||||
|     margin: 0 auto 24px; | ||||
|     margin: 0 32px 24px; | ||||
|     background: #FFFFFF; | ||||
|     box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02); | ||||
|     border-radius: 16px; | ||||
|     overflow: hidden; | ||||
|  | ||||
|     .photo-item__top { | ||||
|       padding: 32px; | ||||
| @@ -198,6 +209,20 @@ export default { | ||||
|         background: #FF883C; | ||||
|       } | ||||
|  | ||||
|       .itemBtn { | ||||
|         border: 1px solid #4181FF; | ||||
|         border-radius: 8px; | ||||
|         color: #4181FF; | ||||
|         padding: 8px 22px; | ||||
|  | ||||
|  | ||||
|       } | ||||
|  | ||||
|       .finish { | ||||
|         color: #42D784; | ||||
|         font-size: 28px; | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         color: #FF883C; | ||||
|         font-size: 28px; | ||||
|   | ||||
| @@ -1,64 +1,89 @@ | ||||
| <template> | ||||
|   <div class="photo-detail" v-if="pageShow"> | ||||
|     <h2>{{ info.content }}</h2> | ||||
|     <div class="status-name" :class="'status-' + info.eventStatus"> | ||||
|       {{ $dict.getLabel('clapEventStatus', info.eventStatus) }} | ||||
|     </div> | ||||
|     <div class="photo-detail__info"> | ||||
|       <div class="photo-detail__item"> | ||||
|         <i>事件类型</i> | ||||
|         <span>{{ info.groupName }}</span> | ||||
|       </div> | ||||
|       <div class="photo-detail__item"> | ||||
|         <i>所属网格</i> | ||||
|         <span>{{ info.girdName }}</span> | ||||
|       </div> | ||||
|       <div class="photo-detail__item"> | ||||
|         <i>上报时间</i> | ||||
|         <span>{{ info.createTime }}</span> | ||||
|       </div> | ||||
|       <div class="photo-detail__img" style="border: none;"> | ||||
|         <i>照片</i> | ||||
|         <div class="photo-detail__img--imgs"> | ||||
|           <image v-for="(item, index) in info.files" @click="preview(item.url)" :key="index" :src="item.url"/> | ||||
|     <AiGroup noBorder> | ||||
|       <h2>{{ info.content }}</h2> | ||||
|       <div class="status-name" :class="detailStatus.cls" v-text="detailStatus.label"/> | ||||
|     </AiGroup> | ||||
|     <AiGroup description noBorder labelColor="#999"> | ||||
|       <AiItem label="事件类型" :value="info.groupName"/> | ||||
|       <AiItem label="所属网格" :value="info.girdName"/> | ||||
|       <AiItem label="上报时间" :value="info.createTime"/> | ||||
|       <AiItem label="照片" top-label> | ||||
|         <image v-for="(item, index) in info.files" @click="preview(item.url)" :key="index" :src="item.url"/> | ||||
|         <span v-if="!info.files.length">暂无照片</span> | ||||
|       </AiItem> | ||||
|     </AiGroup> | ||||
|     <u-gap height="24"/> | ||||
|     <AiGroup title="处理详情" v-if="info.eventStatus > 1" description noBorder labelColor="#999"> | ||||
|       <AiItem label="处理结果" top-label :value="result.doExplain"/> | ||||
|       <AiItem label="照片" top-label> | ||||
|         <image v-for="(item, index) in result.files" @click="preview(item.url)" :key="index" :src="item.url"/> | ||||
|         <span v-if="!result.files.length">暂无照片</span> | ||||
|       </AiItem> | ||||
|     </AiGroup> | ||||
|     <u-gap height="24"/> | ||||
|     <u-tabs :list="[{name:'办理进度'},{name:'我的评价'}]" :current="currentTab" @change="v=>currentTab=v"/> | ||||
|     <u-gap height="24"/> | ||||
|     <AiGroup noBorder v-if="currentTab=='0'"> | ||||
|       <AiStep v-for="(item,i) in process" :key="item.id" :index="i"> | ||||
|         <div class="flex start"> | ||||
|           <div class="fill stepTitle" v-text="item.systemExplain"/> | ||||
|           <div class="color-999 mar-r32" v-text="item.doTime"/> | ||||
|         </div> | ||||
|         <span v-if="info.files && !info.files.length">暂无照片</span> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="result" v-if="info.eventStatus > 1"> | ||||
|       <h2>处理详情</h2> | ||||
|       <div class="result-info"> | ||||
|         <h2>处理结果</h2> | ||||
|         <p>{{ result.doExplain || '-' }}</p> | ||||
|       </div> | ||||
|       <div class="photo-detail__img" v-if="result.files.length"> | ||||
|         <i>照片</i> | ||||
|         <div class="photo-detail__img--imgs"> | ||||
|           <image @click="previewResult(item.url)" v-for="(item, index) in result.files" :key="index" :src="item.url"/> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|         <div v-if="item.doExplain" class="stepContent mar-t8" v-text="item.doExplain"/> | ||||
|         <u-gap height="48"/> | ||||
|       </AiStep> | ||||
|     </AiGroup> | ||||
|     <AiEvaluation v-if="currentTab=='1'" :bid="info.id" type="show"/> | ||||
|     <AiEvaluation v-if="info.eventStatus > 1" v-model="evaluation" class="fixed-bottom bg-fff" :bid="info.id"> | ||||
|       <div class="bottomBtn">去评价</div> | ||||
|     </AiEvaluation> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import AiGroup from "../../../components/AiGroup/AiGroup"; | ||||
| import AiItem from "../../../components/AiItem/AiItem"; | ||||
| import AiStep from "../../../components/AiStep/AiStep"; | ||||
|  | ||||
| export default { | ||||
|   components: {AiStep, AiItem, AiGroup}, | ||||
|   appName: "随手拍详情", | ||||
|   data() { | ||||
|     return { | ||||
|       pageShow: false, | ||||
|       info: {}, | ||||
|       result: {} | ||||
|       result: {}, | ||||
|       currentTab: 0, | ||||
|       evaluation: {} | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     detailStatus: v => { | ||||
|       const status = !v.evaluation.id ? v.info.eventStatus : 'evaluation' | ||||
|       return { | ||||
|         cls: 'status-' + status, | ||||
|         label: !v.evaluation.id ? v.$dict.getLabel('clapEventStatus', v.info.eventStatus) : "已评价" | ||||
|       } | ||||
|     }, | ||||
|     process() { | ||||
|       const list = this.info.processList | ||||
|       if (this.evaluation.id) { | ||||
|         const {id, createUserName, score, createTime: doTime, rateText: doExplain} = this.evaluation | ||||
|         list.splice(0, 0, { | ||||
|           id, doTime, doExplain, | ||||
|           systemExplain: `${createUserName}完成评价 (${score}星评价)` | ||||
|         }) | ||||
|       } | ||||
|       return list | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   onLoad(query) { | ||||
|     this.$loading() | ||||
|     this.$dict.load(['clapEventStatus']).then(() => { | ||||
|       this.getInfo(query.id) | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     getInfo(id) { | ||||
|       this.$instance.post(`/app/appclapeventinfo/queryDetailById?id=${id}`).then(res => { | ||||
| @@ -71,11 +96,7 @@ export default { | ||||
|             this.pageShow = true | ||||
|           }) | ||||
|         } | ||||
|  | ||||
|         this.$hideLoading() | ||||
|       }).catch(() => { | ||||
|         this.$hideLoading() | ||||
|       }) | ||||
|       }).finally(() => this.$hideLoading()) | ||||
|     }, | ||||
|  | ||||
|     previewResult(url) { | ||||
| @@ -97,11 +118,11 @@ export default { | ||||
|  | ||||
| <style lang="scss"> | ||||
| .photo-detail { | ||||
|   padding: 32px; | ||||
|   padding: 32px 0 160px; | ||||
|   margin-bottom: 60px; | ||||
|   background: #fff; | ||||
|  | ||||
|   & > h2 { | ||||
|   h2 { | ||||
|     line-height: 1.3; | ||||
|     margin-bottom: 26px; | ||||
|     color: #333333; | ||||
| @@ -109,6 +130,17 @@ export default { | ||||
|     font-size: 40px; | ||||
|   } | ||||
|  | ||||
|   ::v-deep.stepTitle { | ||||
|     min-height: 44px; | ||||
|     font-family: PingFangSC-Regular; | ||||
|     font-weight: 400; | ||||
|     font-size: 32px; | ||||
|   } | ||||
|  | ||||
|   .stepContent { | ||||
|     color: #343D65; | ||||
|   } | ||||
|  | ||||
|   .status-name { | ||||
|     width: 96px; | ||||
|     height: 44px; | ||||
| @@ -120,7 +152,7 @@ export default { | ||||
|     font-size: 26px; | ||||
|     border-radius: 8px; | ||||
|  | ||||
|     &.status-1 { | ||||
|     &.status-1, &.status-evaluation { | ||||
|       background: #1AAAFF; | ||||
|     } | ||||
|  | ||||
| @@ -132,77 +164,5 @@ export default { | ||||
|       background: #FF4466; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .photo-detail__item { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     justify-content: space-between; | ||||
|     height: 112px; | ||||
|     font-size: 32px; | ||||
|     border-bottom: 1px solid #DDDDDD; | ||||
|  | ||||
|     i { | ||||
|       color: #999999; | ||||
|       font-size: 32px; | ||||
|     } | ||||
|  | ||||
|     span { | ||||
|       color: #333333; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .result { | ||||
|     & > h2 { | ||||
|       height: 116px; | ||||
|       line-height: 116px; | ||||
|       font-size: 38px; | ||||
|       color: #333; | ||||
|       font-weight: 600; | ||||
|       border-top: 1px solid #DDDDDD; | ||||
|     } | ||||
|  | ||||
|     .result-info { | ||||
|       h2 { | ||||
|         height: 112px; | ||||
|         line-height: 112px; | ||||
|         color: #999999; | ||||
|         font-size: 32px; | ||||
|       } | ||||
|  | ||||
|       p { | ||||
|         line-height: 1.3; | ||||
|         padding-bottom: 32px; | ||||
|         color: #333333; | ||||
|         font-size: 32px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .photo-detail__img { | ||||
|     border-top: 1px solid #DDDDDD; | ||||
|     padding: 32px 0; | ||||
|  | ||||
|     & > i { | ||||
|       display: block; | ||||
|       margin-bottom: 32px; | ||||
|       color: #999999; | ||||
|       font-size: 32px; | ||||
|     } | ||||
|  | ||||
|     .photo-detail__img--imgs { | ||||
|       display: flex; | ||||
|       flex-wrap: wrap; | ||||
|  | ||||
|       image { | ||||
|         width: 226px; | ||||
|         height: 226px; | ||||
|         margin: 0 9px 9px 0; | ||||
|  | ||||
|         &:nth-of-type(3n) { | ||||
|           margin-right: 0; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user