随手拍改造完成

This commit is contained in:
aixianling
2022-10-20 16:35:10 +08:00
parent f8989e4b3c
commit 5775c244cb
10 changed files with 472 additions and 440 deletions

View 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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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,

View File

@@ -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;

View 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>