增加我的评价
This commit is contained in:
parent
08b4626a36
commit
d81902ab71
|
@ -0,0 +1,205 @@
|
||||||
|
<template>
|
||||||
|
<view class="component-appraise-group">
|
||||||
|
<view class="group-cate-group">
|
||||||
|
<view
|
||||||
|
class="cate-item"
|
||||||
|
v-for="(item, index) in cate"
|
||||||
|
:key="index"
|
||||||
|
:class="{ active: currentCate == index }"
|
||||||
|
@click="changeCate(index)"
|
||||||
|
>
|
||||||
|
<text
|
||||||
|
>{{ item.name }} <text v-if="item.count > 0">({{ item.count }})</text></text
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="appraise-list-box">
|
||||||
|
<view v-show="currentCate == index" v-for="(item, index) in cate" :key="index">
|
||||||
|
<view class="appraise-item" :class="['tab' + index]" v-for="(v, k) in item.list" :key="k">
|
||||||
|
<view class="appraise-left">
|
||||||
|
<image class="avatar" :src="v.avatar" mode="aspectFill" />
|
||||||
|
</view>
|
||||||
|
<view class="appraise-right">
|
||||||
|
<view class="head">
|
||||||
|
<text class="nickname">{{ v.nickname }}</text>
|
||||||
|
<text class="date">{{ v.createTime }}</text>
|
||||||
|
<text class="desc">
|
||||||
|
<text class="area">{{ v.area }}</text>
|
||||||
|
<text class="worker">服务人员:{{ v.worker }}</text>
|
||||||
|
</text>
|
||||||
|
<view class="grade">
|
||||||
|
<uni-rate :readonly="true" :value="v.grade" :allowHalf="false" :size="utils.rpx2px(40)" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="tags">
|
||||||
|
<view class="tag" v-for="(tag, tagIdx) in v.tags" :key="tagIdx">{{ tag }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-show="v.content != ''" class="content">
|
||||||
|
<rich-text :nodes="v.content"></rich-text>
|
||||||
|
</view>
|
||||||
|
<view v-show="v.images.length > 0" class="image-group">
|
||||||
|
<view class="image-item" v-for="(image, imageIdx) in v.images" :key="imageIdx">
|
||||||
|
<image class="image" :src="image" mode="aspectFill" @click="previewImage(v.images, imageIdx)" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import UniRate from "@/uni_modules/uni-rate/components/uni-rate/uni-rate.vue";
|
||||||
|
export default {
|
||||||
|
name: "appraise-group",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
utils: this.$utils,
|
||||||
|
currentCate: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
cate: {
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
UniRate,
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
mounted() {},
|
||||||
|
destroyed() {},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 修改分类
|
||||||
|
*/
|
||||||
|
changeCate(index) {
|
||||||
|
this.currentCate = index;
|
||||||
|
this.$emit("changeCate", this.cate[index], index);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 预览图片
|
||||||
|
*/
|
||||||
|
previewImage(list, index) {
|
||||||
|
uni.previewImage({
|
||||||
|
urls: list,
|
||||||
|
current: index,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.component-appraise-group {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.group-cate-group {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
line-height: 32rpx;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
.cate-item {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #333333;
|
||||||
|
margin-right: 40rpx;
|
||||||
|
}
|
||||||
|
.cate-item.active {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.appraise-list-box {
|
||||||
|
width: 100%;
|
||||||
|
.appraise-item {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 30rpx;
|
||||||
|
border: 2rpx solid #d7d7d7;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 22rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.appraise-left {
|
||||||
|
.avatar {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 2rpx solid #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.appraise-right {
|
||||||
|
width: 525rpx;
|
||||||
|
.head {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.nickname,
|
||||||
|
.date,
|
||||||
|
.desc {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.nickname {
|
||||||
|
font-size: 30rpx;
|
||||||
|
line-height: 30rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.date {
|
||||||
|
font-size: 22rpx;
|
||||||
|
line-height: 22rpx;
|
||||||
|
color: #999999;
|
||||||
|
margin: 18rpx 0;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
font-size: 22rpx;
|
||||||
|
line-height: 22rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.area {
|
||||||
|
margin-right: 30rpx;
|
||||||
|
}
|
||||||
|
.tags {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
.tag {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
line-height: 22rpx;
|
||||||
|
color: #666666;
|
||||||
|
padding: 12rpx 24rpx;
|
||||||
|
background: #f6f6f6;
|
||||||
|
border-radius: 23rpx;
|
||||||
|
margin-right: 24rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.grade {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-size: #666666;
|
||||||
|
}
|
||||||
|
.image-group {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
.image-item {
|
||||||
|
display: inline-block;
|
||||||
|
width: 110rpx;
|
||||||
|
height: 110rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
.image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,86 @@
|
||||||
|
<template>
|
||||||
|
<view class="component-appraise-section">
|
||||||
|
<view class="appraise-total"> 累计 {{ total }} 条真实用户评价 </view>
|
||||||
|
<view class="appraise-tags-group">
|
||||||
|
<view class="tag-item" v-for="(item, index) in tags" :key="index">
|
||||||
|
<text>{{ item.name }}({{ item.count }})</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<div class="appraise-group-box">
|
||||||
|
<appraise-group :cate="cate" @changeCate="changeCate" />
|
||||||
|
</div>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import AppraiseGroup from "@/components/appraise/group";
|
||||||
|
export default {
|
||||||
|
name: "appraise-section",
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
total: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
tags: {
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
cate: {
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
AppraiseGroup,
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
mounted() {},
|
||||||
|
destroyed() {},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 修改分类
|
||||||
|
*/
|
||||||
|
changeCate(cate, index) {
|
||||||
|
this.$emit("changeCate", cate, index);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.component-appraise-section {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 30rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
.appraise-total {
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 24rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.appraise-tags-group {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 35rpx;
|
||||||
|
.tag-item {
|
||||||
|
background: #f6f7ff;
|
||||||
|
border-radius: 26rpx;
|
||||||
|
padding: 14rpx 10rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 24rpx;
|
||||||
|
color: #333333;
|
||||||
|
margin-right: 18rpx;
|
||||||
|
margin-top: 35rpx;
|
||||||
|
}
|
||||||
|
.tag-item:nth-child(3n) {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -72,6 +72,14 @@ const apis = {
|
||||||
showLoading: true,
|
showLoading: true,
|
||||||
auth: true,
|
auth: true,
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
appraise: {
|
||||||
|
count: {
|
||||||
|
url: "/wxapp/index/mysevaluation",
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
url: "/wxapp/index/seemyevaluation",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
service: {
|
service: {
|
||||||
|
|
|
@ -298,5 +298,47 @@ export default {
|
||||||
return reject(response.msg);
|
return reject(response.msg);
|
||||||
}).catch(e => { });
|
}).catch(e => { });
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
appraise: {
|
||||||
|
count() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
prototype.$request({
|
||||||
|
api: "user.appraise.count",
|
||||||
|
}).then(response => {
|
||||||
|
if (response.code == 1) {
|
||||||
|
return resolve(response.data);
|
||||||
|
}
|
||||||
|
return reject(response.msg);
|
||||||
|
}).catch(e => { });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
list() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
prototype.$request({
|
||||||
|
api: "user.appraise.list",
|
||||||
|
data: data
|
||||||
|
}).then(response => {
|
||||||
|
if (response.code == 1) {
|
||||||
|
let list = [];
|
||||||
|
response.data.forEach((data) => {
|
||||||
|
list.push({
|
||||||
|
id: data.id,
|
||||||
|
avatar: data.u_avatar,
|
||||||
|
nickname: data.u_name,
|
||||||
|
createTime: data.time,
|
||||||
|
tags: data.msg.split(","),
|
||||||
|
area: "-",
|
||||||
|
worker: data.wid,
|
||||||
|
grade: data.score,
|
||||||
|
images: data.img,
|
||||||
|
content: data.desc,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return resolve(list);
|
||||||
|
}
|
||||||
|
return reject(response.msg);
|
||||||
|
}).catch(e => { });
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,12 @@
|
||||||
"navigationBarTitleText": "设置"
|
"navigationBarTitleText": "设置"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/member/appraise",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的评价"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/get/index",
|
"path": "pages/get/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
<template>
|
||||||
|
<app-layout title="我的评价">
|
||||||
|
<view class="appraise-container">
|
||||||
|
<app-appraise-section
|
||||||
|
:total="appraise.total"
|
||||||
|
:tags="appraise.tags"
|
||||||
|
:cate="appraise.cate"
|
||||||
|
@changeCate="changeAppraiseCate"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</app-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import AppLayout from "@/components/layout/layout";
|
||||||
|
import AppAppraiseSection from "@/components/appraise/section";
|
||||||
|
export default {
|
||||||
|
name: "member-appraise",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
currentAppraiseCateIndex: 0,
|
||||||
|
appraise: {
|
||||||
|
total: 0,
|
||||||
|
tags: [],
|
||||||
|
cate: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
AppLayout,
|
||||||
|
AppAppraiseSection,
|
||||||
|
},
|
||||||
|
async onLoad() {
|
||||||
|
// 评价
|
||||||
|
await this.$models.user.appraise.count().then((data) => {
|
||||||
|
data.tags.forEach((item) => {
|
||||||
|
this.appraise.tags.push({
|
||||||
|
count: item.count,
|
||||||
|
name: item.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
data.cate.forEach((item) => {
|
||||||
|
this.appraise.cate.push({
|
||||||
|
name: item.name,
|
||||||
|
count: item.count,
|
||||||
|
status: item.status,
|
||||||
|
page: 1,
|
||||||
|
more: true,
|
||||||
|
list: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.appraise.total = this.appraise.cate[0].count;
|
||||||
|
this.changeAppraiseCate(this.appraise.cate[0], 0);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onShow() {},
|
||||||
|
onReady() {},
|
||||||
|
onHide() {},
|
||||||
|
onReachBottom() {
|
||||||
|
let currentCate = this.appraise.cate[this.currentAppraiseCateIndex];
|
||||||
|
if (currentCate.more) {
|
||||||
|
this.loadAppraiseData(currentCate);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPullDownRefresh() {},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 切换评价分类
|
||||||
|
*/
|
||||||
|
changeAppraiseCate(currentCate, index) {
|
||||||
|
this.currentAppraiseCateIndex = index;
|
||||||
|
currentCate.list = [];
|
||||||
|
currentCate.more = true;
|
||||||
|
currentCate.page = 1;
|
||||||
|
this.loadAppraiseData(currentCate);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 加载评价数据
|
||||||
|
*/
|
||||||
|
loadAppraiseData(currentCate) {
|
||||||
|
this.$models.user.appraise
|
||||||
|
.list({
|
||||||
|
status: currentCate.status,
|
||||||
|
page: currentCate.page,
|
||||||
|
})
|
||||||
|
.then((list) => {
|
||||||
|
if (list.length > 0) {
|
||||||
|
currentCate.page++;
|
||||||
|
currentCate.list = currentCate.list.concat(list);
|
||||||
|
} else {
|
||||||
|
currentCate.more = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
|
@ -87,7 +87,7 @@
|
||||||
<text class="title limit-line clamp-1">设置服务信息</text>
|
<text class="title limit-line clamp-1">设置服务信息</text>
|
||||||
<text class="iconfont icon-jinru"></text>
|
<text class="iconfont icon-jinru"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="widget-item">
|
<view class="widget-item" @click="toPage('/pages/member/appraise')">
|
||||||
<text class="title limit-line clamp-1">我的评价</text>
|
<text class="title limit-line clamp-1">我的评价</text>
|
||||||
<text class="iconfont icon-jinru"></text>
|
<text class="iconfont icon-jinru"></text>
|
||||||
</view>
|
</view>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
## 1.3.1(2022-02-25)
|
||||||
|
- 修复 条件判断 `NaN` 错误的 bug
|
||||||
|
## 1.3.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-rate](https://uniapp.dcloud.io/component/uniui/uni-rate)
|
||||||
|
## 1.2.2(2021-09-10)
|
||||||
|
- 优化 默认值修改为 0 颗星
|
||||||
|
## 1.2.1(2021-07-30)
|
||||||
|
- 优化 vue3下事件警告的问题
|
||||||
|
## 1.2.0(2021-07-13)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.1.2(2021-05-12)
|
||||||
|
- 新增 组件示例地址
|
||||||
|
## 1.1.1(2021-04-21)
|
||||||
|
- 修复 布局变化后 uni-rate 星星计算不准确的 bug
|
||||||
|
- 优化 添加依赖 uni-icons, 导入 uni-rate 自动下载依赖
|
||||||
|
## 1.1.0(2021-04-16)
|
||||||
|
- 修复 uni-rate 属性 margin 值为 string 组件失效的 bug
|
||||||
|
|
||||||
|
## 1.0.9(2021-02-05)
|
||||||
|
- 优化 组件引用关系,通过uni_modules引用组件
|
||||||
|
|
||||||
|
## 1.0.8(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
||||||
|
- 支持 pc 端
|
|
@ -0,0 +1,360 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view ref="uni-rate" class="uni-rate">
|
||||||
|
<view class="uni-rate__icon" :class="{'uni-cursor-not-allowed': disabled}"
|
||||||
|
:style="{ 'margin-right': marginNumber + 'px' }" v-for="(star, index) in stars" :key="index"
|
||||||
|
@touchstart.stop="touchstart" @touchmove.stop="touchmove" @mousedown.stop="mousedown"
|
||||||
|
@mousemove.stop="mousemove" @mouseleave="mouseleave">
|
||||||
|
<uni-icons :color="color" :size="size" :type="isFill ? 'star-filled' : 'star'" />
|
||||||
|
<!-- #ifdef APP-NVUE -->
|
||||||
|
<view :style="{ width: star.activeWitch.replace('%','')*size/100+'px'}" class="uni-rate__icon-on">
|
||||||
|
<uni-icons style="text-align: left;" :color="disabled?'#ccc':activeColor" :size="size"
|
||||||
|
type="star-filled" />
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef APP-NVUE -->
|
||||||
|
<view :style="{ width: star.activeWitch}" class="uni-rate__icon-on">
|
||||||
|
<uni-icons :color="disabled?disabledColor:activeColor" :size="size" type="star-filled" />
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const dom = uni.requireNativePlugin('dom');
|
||||||
|
// #endif
|
||||||
|
/**
|
||||||
|
* Rate 评分
|
||||||
|
* @description 评分组件
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=33
|
||||||
|
* @property {Boolean} isFill = [true|false] 星星的类型,是否为实心类型, 默认为实心
|
||||||
|
* @property {String} color 未选中状态的星星颜色,默认为 "#ececec"
|
||||||
|
* @property {String} activeColor 选中状态的星星颜色,默认为 "#ffca3e"
|
||||||
|
* @property {String} disabledColor 禁用状态的星星颜色,默认为 "#c0c0c0"
|
||||||
|
* @property {Number} size 星星的大小
|
||||||
|
* @property {Number} value/v-model 当前评分
|
||||||
|
* @property {Number} max 最大评分评分数量,目前一分一颗星
|
||||||
|
* @property {Number} margin 星星的间距,单位 px
|
||||||
|
* @property {Boolean} disabled = [true|false] 是否为禁用状态,默认为 false
|
||||||
|
* @property {Boolean} readonly = [true|false] 是否为只读状态,默认为 false
|
||||||
|
* @property {Boolean} allowHalf = [true|false] 是否实现半星,默认为 false
|
||||||
|
* @property {Boolean} touchable = [true|false] 是否支持滑动手势,默认为 true
|
||||||
|
* @event {Function} change uniRate 的 value 改变时触发事件,e={value:Number}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UniRate",
|
||||||
|
props: {
|
||||||
|
isFill: {
|
||||||
|
// 星星的类型,是否镂空
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
// 星星未选中的颜色
|
||||||
|
type: String,
|
||||||
|
default: "#ececec"
|
||||||
|
},
|
||||||
|
activeColor: {
|
||||||
|
// 星星选中状态颜色
|
||||||
|
type: String,
|
||||||
|
default: "#ffca3e"
|
||||||
|
},
|
||||||
|
disabledColor: {
|
||||||
|
// 星星禁用状态颜色
|
||||||
|
type: String,
|
||||||
|
default: "#c0c0c0"
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
// 星星的大小
|
||||||
|
type: [Number, String],
|
||||||
|
default: 24
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
// 当前评分
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
// 当前评分
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
// 最大评分
|
||||||
|
type: [Number, String],
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
margin: {
|
||||||
|
// 星星的间距
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
// 是否可点击
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
// 是否只读
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
allowHalf: {
|
||||||
|
// 是否显示半星
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
touchable: {
|
||||||
|
// 是否支持滑动手势
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
valueSync: "",
|
||||||
|
userMouseFristMove: true,
|
||||||
|
userRated: false,
|
||||||
|
userLastRate: 1
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(newVal) {
|
||||||
|
this.valueSync = Number(newVal);
|
||||||
|
},
|
||||||
|
modelValue(newVal) {
|
||||||
|
this.valueSync = Number(newVal);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
stars() {
|
||||||
|
const value = this.valueSync ? this.valueSync : 0;
|
||||||
|
const starList = [];
|
||||||
|
const floorValue = Math.floor(value);
|
||||||
|
const ceilValue = Math.ceil(value);
|
||||||
|
for (let i = 0; i < this.max; i++) {
|
||||||
|
if (floorValue > i) {
|
||||||
|
starList.push({
|
||||||
|
activeWitch: "100%"
|
||||||
|
});
|
||||||
|
} else if (ceilValue - 1 === i) {
|
||||||
|
starList.push({
|
||||||
|
activeWitch: (value - floorValue) * 100 + "%"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
starList.push({
|
||||||
|
activeWitch: "0"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return starList;
|
||||||
|
},
|
||||||
|
|
||||||
|
marginNumber() {
|
||||||
|
return Number(this.margin)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.valueSync = Number(this.value || this.modelValue);
|
||||||
|
this._rateBoxLeft = 0
|
||||||
|
this._oldValue = null
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this._getSize()
|
||||||
|
}, 100)
|
||||||
|
// #ifdef H5
|
||||||
|
this.PC = this.IsPC()
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
touchstart(e) {
|
||||||
|
// #ifdef H5
|
||||||
|
if (this.IsPC()) return
|
||||||
|
// #endif
|
||||||
|
if (this.readonly || this.disabled) return
|
||||||
|
const {
|
||||||
|
clientX,
|
||||||
|
screenX
|
||||||
|
} = e.changedTouches[0]
|
||||||
|
// TODO 做一下兼容,只有 Nvue 下才有 screenX,其他平台式 clientX
|
||||||
|
this._getRateCount(clientX || screenX)
|
||||||
|
},
|
||||||
|
touchmove(e) {
|
||||||
|
// #ifdef H5
|
||||||
|
if (this.IsPC()) return
|
||||||
|
// #endif
|
||||||
|
if (this.readonly || this.disabled || !this.touchable) return
|
||||||
|
const {
|
||||||
|
clientX,
|
||||||
|
screenX
|
||||||
|
} = e.changedTouches[0]
|
||||||
|
this._getRateCount(clientX || screenX)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容 PC @tian
|
||||||
|
*/
|
||||||
|
|
||||||
|
mousedown(e) {
|
||||||
|
// #ifdef H5
|
||||||
|
if (!this.IsPC()) return
|
||||||
|
if (this.readonly || this.disabled) return
|
||||||
|
const {
|
||||||
|
clientX,
|
||||||
|
} = e
|
||||||
|
this.userLastRate = this.valueSync
|
||||||
|
this._getRateCount(clientX)
|
||||||
|
this.userRated = true
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
mousemove(e) {
|
||||||
|
// #ifdef H5
|
||||||
|
if (!this.IsPC()) return
|
||||||
|
if (this.userRated) return
|
||||||
|
if (this.userMouseFristMove) {
|
||||||
|
this.userLastRate = this.valueSync
|
||||||
|
this.userMouseFristMove = false
|
||||||
|
}
|
||||||
|
if (this.readonly || this.disabled || !this.touchable) return
|
||||||
|
const {
|
||||||
|
clientX,
|
||||||
|
} = e
|
||||||
|
this._getRateCount(clientX)
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
mouseleave(e) {
|
||||||
|
// #ifdef H5
|
||||||
|
if (!this.IsPC()) return
|
||||||
|
if (this.readonly || this.disabled || !this.touchable) return
|
||||||
|
if (this.userRated) {
|
||||||
|
this.userRated = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.valueSync = this.userLastRate
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// #ifdef H5
|
||||||
|
IsPC() {
|
||||||
|
var userAgentInfo = navigator.userAgent;
|
||||||
|
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
|
||||||
|
var flag = true;
|
||||||
|
for (let v = 0; v < Agents.length - 1; v++) {
|
||||||
|
if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
||||||
|
flag = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取星星个数
|
||||||
|
*/
|
||||||
|
_getRateCount(clientX) {
|
||||||
|
this._getSize()
|
||||||
|
const size = Number(this.size)
|
||||||
|
if (isNaN(size)) {
|
||||||
|
return new Error('size 属性只能设置为数字')
|
||||||
|
}
|
||||||
|
const rateMoveRange = clientX - this._rateBoxLeft
|
||||||
|
let index = parseInt(rateMoveRange / (size + this.marginNumber))
|
||||||
|
index = index < 0 ? 0 : index;
|
||||||
|
index = index > this.max ? this.max : index;
|
||||||
|
const range = parseInt(rateMoveRange - (size + this.marginNumber) * index);
|
||||||
|
let value = 0;
|
||||||
|
if (this._oldValue === index && !this.PC) return;
|
||||||
|
this._oldValue = index;
|
||||||
|
if (this.allowHalf) {
|
||||||
|
if (range > (size / 2)) {
|
||||||
|
value = index + 1
|
||||||
|
} else {
|
||||||
|
value = index + 0.5
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = index + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
value = Math.max(0.5, Math.min(value, this.max))
|
||||||
|
this.valueSync = value
|
||||||
|
this._onChange()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发动态修改
|
||||||
|
*/
|
||||||
|
_onChange() {
|
||||||
|
|
||||||
|
this.$emit("input", this.valueSync);
|
||||||
|
this.$emit("update:modelValue", this.valueSync);
|
||||||
|
this.$emit("change", {
|
||||||
|
value: this.valueSync
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取星星距离屏幕左侧距离
|
||||||
|
*/
|
||||||
|
_getSize() {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
uni.createSelectorQuery()
|
||||||
|
.in(this)
|
||||||
|
.select('.uni-rate')
|
||||||
|
.boundingClientRect()
|
||||||
|
.exec(ret => {
|
||||||
|
if (ret) {
|
||||||
|
this._rateBoxLeft = ret[0].left
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
dom.getComponentRect(this.$refs['uni-rate'], (ret) => {
|
||||||
|
const size = ret.size
|
||||||
|
if (size) {
|
||||||
|
this._rateBoxLeft = size.left
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.uni-rate {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 0;
|
||||||
|
flex-direction: row;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-rate__icon {
|
||||||
|
position: relative;
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-rate__icon-on {
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
line-height: 1;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-cursor-not-allowed {
|
||||||
|
/* #ifdef H5 */
|
||||||
|
cursor: not-allowed !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,88 @@
|
||||||
|
{
|
||||||
|
"id": "uni-rate",
|
||||||
|
"displayName": "uni-rate 评分",
|
||||||
|
"version": "1.3.1",
|
||||||
|
"description": "Rate 评分组件,可自定义评分星星图标的大小、间隔、评分数。",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"评分"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"前端组件",
|
||||||
|
"通用组件"
|
||||||
|
],
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-icons"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
|
||||||
|
## Rate 评分
|
||||||
|
> **组件名:uni-rate**
|
||||||
|
> 代码块: `uRate`
|
||||||
|
> 关联组件:`uni-icons`
|
||||||
|
|
||||||
|
|
||||||
|
评分组件,多用于购买商品后,对商品进行评价等场景
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-rate)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
Loading…
Reference in New Issue