Commit 83536d60 by honghong

初版

parents
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}
<script>
export default {
onLaunch: function() {
console.log('App Launch');
wx.hideShareMenu();
uni.hideShareMenu(); //去除分享
},
onShow: function() {
console.log('App Show');
this.phone();
this.configuration();
wx.hideShareMenu();
uni.hideShareMenu(); //去除分享
// if(uni.getStorageSync("token")) {
// }else{
// uni.reLaunch({
// url: `/pages/login/index`
// })
// }
},
onHide: function() {
console.log('App Hide');
},
methods: {
phone() {
// 获取手机系统信息
const info = uni.getSystemInfoSync();
// 设置状态栏高度(H5顶部无状态栏小程序有状态栏需要撑起高度)
// 除了h5 app mp-alipay的情况下执行
// #ifndef H5 || APP-PLUS || MP-ALIPAY
// 获取胶囊的位置
const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// console.log(menuButtonInfo);
// (胶囊底部高度 - 状态栏的高度) + (胶囊顶部高度 - 状态栏内的高度) = 导航栏的高度
this.globalData.navBarHeight = menuButtonInfo.bottom - info.statusBarHeight + (menuButtonInfo.top - info
.statusBarHeight) + info.statusBarHeight;
this.globalData.navBarHeightRpx = this.globalData.navBarHeight / info.screenWidth * 750;
// 底部安全距离,单位px
// #endif
},
configuration() {
let hostUrl = "";
switch (process.env.UNI_BASE_ENV) {
case "development":
hostUrl = process.env.UNI_BASE_URL;
break;
case "uat":
hostUrl = process.env.UNI_BASE_URL;
break;
case "production":
hostUrl = process.env.UNI_BASE_URL;
break;
}
console.log(
"app.vue配置:",
process.env.UNI_BASE_ENV,
process.env.UNI_BASE_URL
);
},
},
globalData: {
navBarHeight: null,
navBarHeightRpx:null
}
};
</script>
<style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
@import "uview-ui/index.scss";
@import url("common/both.css");
@import url("common/common.css");
/*每个页面公共css */
// @import 'static/both.css';
page {
background-color: #F7F8FA;
}
</style>
\ No newline at end of file
import {
ApiHttp
} from '@/utils/request.js'
const login = (params) => {
return ApiHttp('/system/xcxLogin', params, 'POST')
}
const loginPhone = (params) => {
return ApiHttp('/system/getPhone', params, 'POST')
}
const loginOut = (params) => {
}
const loginUserInfo = (params) => {
return ApiHttp('/app-fund/my/info', params, 'GET')
}
const getDealerPhone = (params) => {
return ApiHttp('/system/getDealerPhone', params, 'POST')
}
const getUserProfile = () => {
return new Promise((resolve, reject) => {
uni.getUserProfile({
//获取微信信息
desc: '用于获取您的个人信息', // 声明获取用户个人信息后的用途,不超过30个字符
success: obj => {
console.log('getUserInfo', obj);
//接口调用成功的回调
resolve(obj);
},
fail: (err) => {
uni.showToast({
title: '授权已取消',
icon: 'error',
mask: true
});
console.log(err, '授权已取消==============')
}
});
});
}
const axiosloginAccount = (params) => {
return ApiHttp('/app-fund/staffLogin', params, 'POST')
}
export {
login,
loginOut,
getUserProfile,
loginPhone,
loginUserInfo,
getDealerPhone,
axiosloginAccount
}
import {
ApiHttp
} from '@/utils/request.js'
//查询我的邀请
const invitationInfoGET = (params) => {
return ApiHttp('/app-fund/my/invitationInfo', params, 'GET')
}
//查询App合同信息列表
const findInviteContractGET = (params) => {
return ApiHttp('/app-fund/contract/findInviteContract', params, 'GET')
}
//邀请
const myPosterGET = (params) => {
return ApiHttp('/app-fund/poster/myPoster', params, 'GET')
}
// 查询OSS对象基于id串
const listByIds = (ossId) => {
return ApiHttp('/system/oss/listByIds/' + ossId, '', 'GET')
}
//我的总金额
const walletGET = (params) => {
return ApiHttp('/app-fund/my/wallet/total', params, 'GET')
}
//余额明细列表
const balanceGET = (params) => {
return ApiHttp('/app-fund/my/wallet/balance', params, 'GET')
}
export {
invitationInfoGET,
findInviteContractGET,
myPosterGET,
listByIds,
walletGET,
balanceGET
}
\ No newline at end of file
page {
font-family: AlibabaPuHuiTi-Regular, AlibabaPuHuiTi;
}
text {
white-space: pre-wrap;
word-break: break-all;
}
ul,
li {
list-style: none;
}
.d-flex {
display: flex;
}
.row {
box-sizing: border-box !important;
display: flex !important;
flex-direction: row;
flex-wrap: wrap;
}
.py-two {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
/* 宽高 */
.w-100 {
width: 100%;
}
.w-50 {
width: 50%;
}
.h-100 {
height: 1250rpx;
}
.h-100 {
height: 625rpx;
}
/* 字体 */
.font {
font-size: 24rpx;
}
.font-28 {
font-size: 28rpx;
}
.font-sm {
font-size: 20rpx;
}
.font-md {
font-size: 30rpx;
}
.font-32 {
font-size: 32rpx;
}
.font-lg {
font-size: 36rpx;
}
.font-big {
font-size: 60rpx;
}
.font-weight {
font-weight: bold !important;
}
.font-weight-100 {
font-weight: 100 !important;
}
.font-white {
color: #FFFFFF;
}
/* 栅栏二 */
.span-one-half {
width: 5%;
}
.span-one {
width: 10%;
}
.span-two-half {
width: 15%;
}
.span-two {
width: 20%;
}
.span-three-half {
width: 25%;
}
.span-three-average {
width: 33.3%;
}
.span-four-half {
width: 35%;
}
.span-four {
width: 40%;
}
.span-five-half {
width: 45%;
}
.span-five {
width: 50%;
}
.span-six-half {
width: 55%;
}
.span-six {
width: 60%;
}
.span-seven-half {
width: 65%;
}
.span-seven {
width: 70%;
}
.span-eight-half {
width: 75%;
}
.span-five {
width: 80%;
}
.span-nine-half {
width: 85%;
}
.span-five {
width: 90%;
}
.span-ten-half {
width: 95%;
}
.span-full {
width: 100%;
}
.d-block {
display: block;
}
.d-inline-block {
display: inline-block;
}
.flex-1 {
flex: 1;
}
/* 设置主轴方向 */
.flex-column {
flex-direction: column;
}
/* 竖(向右) */
.flex-row {
flex-direction: row;
}
/* 横(向左) */
.flex-wrap {
flex-wrap: wrap;
}
/* (换行) */
.flex-nowarp {
flex-wrap: nowarp;
}
/*(不换行) */
/* 设置主轴上的排列方式 */
.j-start {
justify-content: flex-start;
}
/*起点对齐 */
.j-center {
justify-content: center;
}
/* 中间 */
.j-end {
justify-content: flex-end;
}
/*中点对齐 */
.j-sb {
justify-content: space-between;
}
/*两端对齐 */
.j-sa {
justify-content: space-around;
}
/*空间一样 */
/* 设置交叉轴上的排列方式 */
.a-start {
align-items: flex-start;
}
/* 起点 */
.a-center {
align-items: center;
}
/* 中间 */
.a-end {
align-items: flex-end;
}
/* 终点 */
.a-strect {
align-items: stretch
}
/* 充满交叉轴 */
/* 外边距 */
.m-0 {
margin: 0;
}
.m {
margin: 5rpx;
}
.m-1 {
margin: 10rpx;
}
.m-2 {
margin: 20rpx;
}
.m-3 {
margin: 30rpx;
}
.m-4 {
margin: 40rpx;
}
.m-5 {
margin: 50rpx;
}
.ml-one {
margin-left: 10rpx;
}
.ml-two {
margin-left: 20rpx;
}
.ml-three {
margin-left: 30rpx;
}
.ml-four{
margin-left: 40rpx;
}
.mr-2 {
margin-right: 20rpx;
}
.mt-one {
margin-top: 10rpx;
}
.mt-two {
margin-top: 20rpx;
}
.mt-three {
margin-top: 30rpx;
}
.mt-four {
margin-top: 40rpx;
}
.mx-0 {
margin-left: 0;
margin-right: 0;
}
.mx {
margin-left: 5rpx;
margin-right: 5rpx;
}
.mx-1 {
margin-left: 10rpx;
margin-right: 10rpx;
}
.mx-2 {
margin-left: 20rpx;
margin-right: 20rpx;
}
.mx-3 {
margin-left: 30rpx;
margin-right: 30rpx;
}
.mx-4 {
margin-left: 40rpx;
margin-right: 40rpx;
}
.mx-5 {
margin-left: 50rpx;
margin-right: 50rpx;
}
.my-0 {
margin-top: 0;
margin-bottom: 0;
}
.my {
margin-top: 5rpx;
margin-bottom: 5rpx;
}
.my-1 {
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.my-two {
margin-top: 20rpx;
margin-bottom: 20rpx;
}
.my-three {
margin-top: 30rpx;
margin-bottom: 30rpx;
}
.my-four {
margin-top: 40rpx;
margin-bottom: 40rpx;
}
.my-5 {
margin-top: 50rpx;
margin-bottom: 50rpx;
}
/* 内边距 */
.p-0 {
padding: 0;
}
.p {
padding: 5rpx;
}
.p-1 {
padding: 10rpx;
}
.p-two {
padding: 20rpx;
}
.p-three {
padding: 30rpx;
}
.p-four {
padding: 40rpx;
}
.p-5 {
padding: 50rpx;
}
.pt-1 {
padding-top: 10rpx;
}
.pt-2 {
padding-top: 20rpx;
}
.pt-3 {
padding-top: 30rpx;
}
.pl-two {
padding-left: 20rpx;
}
.pl-three{
padding-left: 30rpx;
}
.px-0 {
padding-left: 0;
padding-right: 0;
}
.px {
padding-left: 5rpx;
padding-right: 5rpx;
}
.px-one {
padding-left: 10rpx;
padding-right: 10rpx;
}
.px-two {
padding-left: 20rpx;
padding-right: 20rpx;
}
.px-three {
padding-left: 30rpx;
padding-right: 30rpx;
}
.px-four {
padding-left: 40rpx;
padding-right: 40rpx;
}
.px-five-harf {
padding-left: 45rpx;
padding-right: 45rpx;
}
.px-5 {
padding-left: 50rpx;
padding-right: 50rpx;
}
.py-0 {
padding-top: 0;
padding-bottom: 0;
}
.py {
padding-top: 5rpx;
padding-bottom: 5rpx;
}
.py-1 {
padding-top: 10rpx;
padding-bottom: 10rpx;
}
.py-two {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
.py-three {
padding-top: 30rpx;
padding-bottom: 30rpx;
}
.py-four {
padding-top: 40rpx;
padding-bottom: 40rpx;
}
.py-5 {
padding-top: 50rpx;
padding-bottom: 50rpx;
}
.pb-two{
padding-bottom: 20rpx;
}
.pb-four{
padding-bottom: 40rpx;
}
.font-bold {
font-weight: bold;
}
/* 底部安全距离 */
.tabbar-secure {
width: 100%;
height: 100rpx;
margin-top: 50rpx;
/* 兼容 IOS<11.2 去除底部横条影响 */
padding-bottom: constant(safe-area-inset-bottom) !important;
/* 兼容 IOS>11.2 去除底部横条影响 */
padding-bottom: env(safe-area-inset-bottom) !important;
}
.padding-secure {
/* 兼容 IOS<11.2 去除底部横条影响 */
padding-bottom: constant(safe-area-inset-bottom);
/* 兼容 IOS>11.2 去除底部横条影响 */
padding-bottom: env(safe-area-inset-bottom);
}
.text-overflow-one {
/* 超出的文本隐藏 */
overflow: hidden;
/* 溢出用省略号显示 */
text-overflow: ellipsis !important;
/* 溢出不换行 */
white-space: nowrap !important;
}
.text-overflow-two {
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis !important;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
}
.text-overflow-three {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
white-space: normal;
}
.bgWhite {
background: #FFFFFF;
}
.swiper {
width: 100%;
height: 372rpx;
}
.swiper-item {
width: 100%;
height: 100%;
}
.text-center {
text-align: center;
}
.isOver {
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
font-size: 28rpx;
}
.text-justify {
text-align: justify;
}
.j-se {
justify-content: space-evenly;
}
.noData-text {
color: #989898;
text-align: center;
margin: 20rpx 0;
}
.wu {
width: 100%;
text-align: center;
}
.wu image {
width: 480upx;
height: 244upx;
}
.wu view {
font-size: 28upx;
font-weight: 500;
color: #9A9AA8;
}
\ No newline at end of file
.full-button {
width: 630rpx;
height: 90rpx;
background: #1572FF;
border-radius: 45rpx;
line-height: 90rpx;
font-size: 30rpx;
color: #FFFFFF;
font-weight: bold;
margin: 0 auto;
}
.small-button{
width: 178rpx;
height: 70rpx;
background: #1572FF;
border-radius: 35rpx;
line-height: 70rpx;
font-size: 26rpx;
color: #FFFFFF;
font-weight: bold;
text-align: center;
}
.fixed {
background: #fff;
height: 130rpx;
position: fixed;
bottom: 0;
width: 100%;
z-index: 11;
}
.placeholder {
width: 100%;
height: 130rpx;
}
.button-plain {
padding: 0 33rpx;
/* height: 58rpx;
line-height: 58rpx; */
border-radius: 28rpx;
font-size: 24rpx;
margin: 0;
margin-left: 20rpx;
border: 1rpx solid #999999;
background: #fff;
}
.plain-orange {
border: 1rpx solid #0352A7;
color: #0352A7;
}
\ No newline at end of file
<template>
<view class="btn_container">
<button class="btn">
{{content}}
</button>
</view>
</template>
<script>
export default {
props:{
content:{
type: String,
default:''
}
}
}
</script>
<style lang="scss" scoped>
.btn_container {
width: 100%;
margin: 0 auto;
z-index: 9999;
.btn {
width: 670rpx;
height: 80rpx;
background: #FD0100;
border-radius: 16rpx;
color: #fff;
font-size: 28rpx;
text-align: center;
line-height: 80rpx;
font-weight: bold;
}
}
</style>
<template>
<view>
<u-popup :show="show" mode="bottom" @close="close" @open="open" v-if="show">
<view class="p-three">
<view class="com-textarea-box">
<u--textarea :cursorSpacing="100" class="com-textarea" :focus="focus" placeholder="友善评论"
:customStyle="{
'background':'#F6F7F8',
'font-size':'28rpx',
'fontWeight':'bold',
'color':'#333 !important',
'padding':'20rpx'
}" autoHeigh border="none"></u--textarea>
<view class="picture" v-if="!isReply">
<com-upload ref="upload" imgType="takePictures" @changeList="changeList"></com-upload>
</view>
</view>
<view class="d-flex a-center j-sb send">
<image class="camera" src="@/static/images/camera.png" mode=""></image>
<view class="small-button" @click="postComments">发送</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
props:{
isReply:{
type:Boolean,
default:false,
}
},
data() {
return {
show: false,
focus: true, //是否自动获取焦点弹出系统键盘
}
},
methods: {
open() {
this.show = true;
console.log('open');
},
close() {
this.show = false
console.log('close');
},
// 发送按钮点击事件
postComments() {
console.log("发布评论");
this.show = false;
},
blur() {
this.focus = false
}
}
}
</script>
<style lang="scss" scoped>
.camera {
width: 44rpx;
height: 44rpx;
}
.com-textarea-box{
padding-bottom: 20rpx;
background: #F6F7F8;
}
.send{
height: 110rpx;
}
.picture{
padding: 0 20rpx;
}
</style>
\ No newline at end of file
<template>
<view>
<view class="dynamic">
<view class="dynamic-title">动态标题动态标题动态标题动态标题动态标题动态标题动态标题动态标题动态标题动态标题</view>
<view v-if="showAuthor" class="d-flex a-center" style="margin-top: 16rpx;">
<image class="dynamic-avatar" src="https://img0.baidu.com/it/u=1893171979,2260795920&fm=253&fmt=auto&app=120&f=JPEG?w=506&h=500"
mode="widthFix"></image>
<view class="dynamic-name">刘佳怡</view>
</view>
<view class="dynamic-content text-overflow-two">评价内容评价内容评价内容评价内容, 评价内容评价内容评价内容评价内容评价内容评价内容评价内容评价内容,
评价内容评价内容评价内容评价内容</view>
<view class="d-flex flex-wrap dynamic-picture">
<image @click="previewImage(item.picUrl)" v-for="(info,ix) in 3" class="dynamic-picture-item"
src="https://img0.baidu.com/it/u=1893171979,2260795920&fm=253&fmt=auto&app=120&f=JPEG?w=506&h=500"
mode="widthFix"></image>
</view>
<view class="dynamic-date">2024.02.15 10:26:45</view>
<view class="d-flex a-center j-sb mt-two">
<view class="d-flex a-center ">
<view class="d-flex a-center dynamic-operate">
<image src="@/static/images/zan.png" mode=""></image>
<!-- <image src="@/static/images/zan-selected.png" mode=""></image> -->
<view>124</view>
</view>
<view class="d-flex a-center dynamic-operate">
<image src="@/static/images/collect.png" mode=""></image>
<!-- <image src="@/static/images/collect-selected.png" mode=""></image> -->
<view>124</view>
</view>
<view class="d-flex a-center dynamic-operate">
<image src="@/static/images/message.png" mode=""></image>
<view>124</view>
</view>
</view>
<view v-if="isDelete" class="dynamic-delete">删除</view>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
showAuthor:{
type:Boolean,
default:false
},
isDelete:{
type:Boolean,
default:false
}
},
methods: {
// 预览图片
previewImage() {}
}
}
</script>
<style lang="scss" scoped>
.dynamic {
&-title {
font-size: 26rpx;
color: #303949;
font-weight: bold;
}
&-avatar{
width: 48rpx;
height: 48rpx;
background: #F83D3D;
border-radius: 50%;
}
&-name{
font-size: 26rpx;
color: #303949;
font-weight: bold;
margin: 0 8rpx;
}
&-content {
font-size: 24rpx;
color: #666666;
line-height: 32rpx;
margin-top: 12rpx;
}
&-picture {
&-item {
width: 200rpx;
height: 200rpx;
background: linear-gradient(180deg, #EEEEEE 0%, #D8D8D8 100%);
border-radius: 12rpx;
margin-top: 16rpx;
}
// 除了3倍数以外的元素
&-item:not(:nth-child(3n+3)) {
margin-right: 16rpx;
}
}
&-operate {
>image {
width: 36rpx;
height: 36rpx;
}
>view {
font-size: 24rpx;
color: #666666;
margin-left: 8rpx;
}
}
&-operate:not(:first-child) {
margin-left: 40rpx;
}
&-picture:after {
content: '';
width: 200rpx;
}
&-date {
font-size: 22rpx;
color: #999999;
margin-top: 16rpx;
}
&-delete{
font-size: 24rpx;
color: #FF3141;
}
}
</style>
\ No newline at end of file
<template>
<view>
<!-- 居中 -->
<view class="inv-h-w" style="background: #F8F9FA;" v-if="isfixed">
<block v-for="(item,index) in list" :key="item.value">
<view :class="['inv-h flex-1',Inv == item.value?'inv-h-center':'']" @click="changeTab(item.value)">{{item.label}}</view>
</block>
</view>
<!-- 靠左 -->
<view class="inv-h-w" v-else>
<block v-for="(item,index) in list" :key="item.value">
<view :class="['inv-h',Inv == item.value?'inv-h-se':'']" @click="changeTab(item.value)">{{item.label}}</view>
</block>
</view>
</view>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: () => []
},
isfixed:{
type: Boolean,
default:false
},
checked:{
type:[Number,String],
default:0
}
},
data() {
return {
Inv: this.checked,
}
},
watch:{
checked(newVal,oldVal){
if(newVal != oldVal){
this.Inv = newVal
}
}
},
methods: {
changeTab(Inv) {
this.Inv = Inv
this.$emit('change',this.Inv)
},
}
}
</script>
<style lang="scss" scoped>
.inv-h-w {
width: 100%;
background-color: #fff;
height: 100rpx;
display: flex;
}
.inv-h {
font-size: 24rpx;
text-align: center;
color: #666666;
height: 100rpx;
line-height: 100rpx;
position: relative;
}
.inv-h:not(:first-child){
margin-left: 60rpx;
}
.inv-h-se,.inv-h-center {
font-size: 30rpx;
font-family: PingFang SC;
font-weight: bold;
color: #242424;
}
.inv-h-center:after {
content: '';
position: absolute;
bottom: 20rpx;
top: auto;
left: 45%;
height: 4rpx;
width: 32rpx;
background-color: #1572FF;
}
.inv-h-se:after {
content: '';
position: absolute;
bottom: 20rpx;
top: auto;
// left: 30%;
left: 20%;
height: 4rpx;
width: 67%;
background-color: #1572FF;
}
page {
background-color: #F2F2F2;
}
</style>
\ No newline at end of file
<template>
<view class="evaluate">
<view class="evaluate-box">
<view class="evaluate-box-item d-flex">
<image
src="https://img0.baidu.com/it/u=1893171979,2260795920&fm=253&fmt=auto&app=120&f=JPEG?w=506&h=500"
mode="aspectFill" class="avatar-parent"></image>
<view class="evaluate-box-item-main ml-two flex-1">
<!-- 父评论体-start -->
<view class="d-flex a-center j-sb">
<view class="d-flex">
<view class="evaluate-box-item-main-nickname">
李哈哈
</view>
<view class="evaluate-box-item-main-state" v-if="showState">
已下单
</view>
</view>
<view class="evaluate-box-item-main-zan d-flex a-center">
<image
src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/A0gxSGwrgBvn890d208d4d79baec3a208abafd2096ee.png" />
<view>20</view>
</view>
</view>
<view class="evaluate-box-item-main-content">
评价内容评价内容评价内容评价内容, 评价内容评价内容评价内容评价内容
<view @click="prviewImage(item.picUrl)" class="d-flex flex-wrap j-sb picture">
<image v-for="(info,ix) in 3" class="picture-item"
src="https://img0.baidu.com/it/u=1893171979,2260795920&fm=253&fmt=auto&app=120&f=JPEG?w=506&h=500"
mode="widthFix"></image>
</view>
</view>
<view class="evaluate-box-item-main-foot d-flex a-center">
<view class="evaluate-box-item-main-foot-time">2024.02.15 10:26:45</view>
<view class="evaluate-box-item-main-foot-btn" @click="handleReply">回复</view>
</view>
<!-- 父评论体-end -->
<!-- 子评论列表-start -->
<view>
<view v-for="(each, index) in 2" :key="index" style="margin-top: 28rpx;">
<view class="d-flex">
<image class="avatar-parent"
src="https://img2.baidu.com/it/u=3677186369,786366007&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500"
mode=""></image>
<view class="evaluate-box-item-main ml-two flex-1">
<view class="d-flex a-center j-sb">
<view class="evaluate-box-item-main-nickname">
哥萨克 回复 刘佳怡
</view>
<view class="evaluate-box-item-main-zan d-flex a-center">
<image
src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/A0gxSGwrgBvn890d208d4d79baec3a208abafd2096ee.png" />
<view>20</view>
</view>
</view>
<view class="evaluate-box-item-main-content">
评价内容评价内容评价内容评价内容, 评价内容评价内容评价内容评价内容
</view>
<view class="evaluate-box-item-main-foot d-flex a-center">
<view class="evaluate-box-item-main-foot-time">2024.02.15 10:26:45</view>
<view class="evaluate-box-item-main-foot-btn">回复</view>
</view>
</view>
</view>
</view>
<!-- <view class="fold-more d-flex a-center">
<view>展开更多回复</view>
<u-icon size="20" name="arrow-down" color="#333333"></u-icon>
</view> -->
</view>
</view>
</view>
</view>
<commentPopup ref="childPopup" :isReply="true"></commentPopup>
</view>
</template>
<script>
import commentPopup from '@/components/custom/comment.vue'
export default {
components: {
commentPopup
},
props:{
showState:{
type:Boolean,
default:false,
}
},
data() {
return {
isFold: true,
}
},
methods: {
handleReply(){
this.$refs.childPopup.show = true;
},
// 预览图片
prviewImage() {}
}
}
</script>
<style lang="scss" scoped>
.evaluate {
&-box {
&-item {
.avatar-parent {
width: 60rpx;
height: 60rpx;
background: #F83D3D;
border-radius: 50%;
}
&-main {
&-nickname {
font-size: 26rpx;
color: #303949;
font-weight: bold;
}
&-state{
height: 32rpx;
background: #e2edff;
border-radius: 8rpx;
padding: 0 5rpx;
font-size: 20rpx;
color: #1572FF;
margin-left: 12rpx;
}
&-zan {
>image {
width: 28rpx;
height: 28rpx;
}
>view {
font-size: 24rpx;
color: #666666;
margin-left: 12rpx;
}
}
&-content {
font-size: 24rpx;
color: #666666;
margin: 16rpx 0;
.picture {
margin-top: 16rpx;
&-item {
width: 190rpx;
height: 190rpx;
background: linear-gradient(180deg, #EEEEEE 0%, #D8D8D8 100%);
border-radius: 12rpx;
}
}
.picture:after {
content: '';
width: 190rpx;
}
}
&-foot {
&-time {
font-size: 22rpx;
color: #999999;
}
&-btn {
font-size: 22rpx;
color: #333333;
margin-left: 20rpx;
}
}
}
}
}
}
.fold-more {
font-size: 22rpx;
color: #333333;
}
</style>
\ No newline at end of file
<template>
<view class="index">
<u-navbar
leftText="返回"
:title="title"
:safeAreaInsetTop="true"
:placeholder="true"
:bgColor="titleStyle.scrollTopHeader ? scrollTopHeaderBgColor : bgColor"
:titleStyle="{ color: titleStyle.color, fontSize: titleStyle.fontSize,scrollTopHeader:titleStyle.scrollTopHeader }"
>
<view class="u-nav-slot" slot="left">
<u-icon v-if="leftIcon" @click="leftClick" name="arrow-left" size="40" color="#000" :bold="true"></u-icon>
<u-line v-if="homeShow" direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon v-if="homeShow" @click="rightClick" name="home" size="30"></u-icon>
<view class="city" v-if="showLocation">
<image :src="imgBgUrl+'sydw.png'" mode=""></image>
{{address}}
</view>
</view>
</u-navbar>
</view>
</template>
<script>
import apiBaseConfig from '@/config/index.js';
export default {
props: {
homeShow: {
type: Boolean,
default: false
},
bgColor: {
type: String,
default: '#ffffff'
},
title: {
type: String,
default: '标题'
},
leftIcon: {
type: Boolean,
default: true
},
titleStyle: {
type: Object,
default: () => {
return {};
}
},
scrollTopHeaderBgColor: {
type: String,
default: '#1572ff'
},
address:{
type: String,
default:''
},
showLocation:{
type: Boolean,
default: false
}
},
data() {
return {
imgBgUrl: apiBaseConfig.imgBgUrl,
globalData: getApp().globalData
};
},
onLoad() {},
methods: {
leftClick() {
console.log('====leftClick');
this.$uniGo.navigateBack({
delta: 1
});
},
rightClick() {
console.log('====rightClick');
uni.reLaunch({
url: `/superAdministrator/homePage/index`
})
}
}
};
</script>
<style lang="scss" scoped>
.index {
z-index: 99999;
}
.u-nav-slot {
@include flex;
align-items: center;
justify-content: space-between;
border-width: 1rpx;
border-radius: 100rpx;
border-color: $uni-border-color;
padding: 3rpx 7rpx;
opacity: 0.8;
}
.city{
display: flex;
align-items: center;
font-weight: 500;
font-size: 28rpx;
color: #FFFFFF;
>image {
width: 48rpx;
height: 48rpx;
margin-right: 4rpx;
}
}
</style>
<!--
* @Author: ‘巴博尔’ 2164119982@qq.com
* @Date: 2023-02-04 16:31:03
* @LastEditors: ‘巴博尔’ 2164119982@qq.com
* @LastEditTime: 2023-02-04 16:32:37
* @FilePath: \big-black-column\components\tabbar\tabbar.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<view class="index">
<u-tabbar :value="value" @change="name => (valueS = name)" :fixed="true" :placeholder="true" activeColor="#333333" inactiveColor="#333333" :safeAreaInsetBottom="true">
<u-tabbar-item :text="item.title" @click="clickJumpL($event, item)" v-for="(item, index) in list" :key="index">
<image class="u-page__item__slot-icon" style="width: 54rpx;height: 54rpx;" slot="active-icon" :src="item.iconA"></image>
<image class="u-page__item__slot-icon" style="width: 54rpx;height: 54rpx;" slot="inactive-icon" :src="item.iconB"></image>
</u-tabbar-item>
</u-tabbar>
</view>
</template>
<script>
import apiBaseConfig from '@/config/index.js';
export default {
props: {
list: {
type: Array,
default: () => {
return [
{
title: '首页',
iconA: '../../static/icon/syxz.png',
iconB: '../../static/icon/sywxz.png',
url: '/pages/index/index'
},
{
title: '商家',
iconA: '../../static/icon/sjxz.png',
iconB: '../../static/icon/sjwxz.png',
url: '/pages/shop/index'
},
{
title: '论坛',
iconA: '../../static/icon/ltxz.png',
iconB: '../../static/icon/ltwxz.png',
url: '/pages/forum/index'
},
{
title: '合同',
iconA: '../../static/icon/htxz.png',
iconB: '../../static/icon/htwxz.png',
url: '/pages/contract/index'
},
{
title: '我的',
iconA: '../../static/icon/wdxz.png',
iconB: '../../static/icon/wdwxz.png',
url: '/pages/my/index'
}
];
}
},
value: {
default: 0,
}
},
data() {
return {
valueS: this.value
};
},
methods: {
clickJumpL(e, item) {
// console.log(e,item,'e=======pppppppppppppp')
let self = this;
self.$emit('clickJumpL', e, item);
if (item && item.url) {
self.$uniGo.redirectTo({
url: item.url
});
}
}
}
};
</script>
<style lang="scss" scoped>
.index {
}
.u-nav-slot {
@include flex;
align-items: center;
justify-content: space-between;
border-width: 1rpx;
border-radius: 100rpx;
border-color: $uni-border-color;
padding: 3rpx 7rpx;
opacity: 0.8;
}
</style>
<template>
<view class="index">
<u-upload :fileList="fileList6" @afterRead="afterRead" @delete="deletePic" name="6" multiple
:maxCount="maxCount" :width="width" :height="height" :disabled="disabled" :previewFullImage="true">
<view v-if="imgType === 'takePictures'" class="index-upload baiyin-flex baiyin-flex-c-t baiyin-flex-c-b" style="text-align: center;line-height: 170rpx;">
<image class="index-upload-tlo-lp" src="@/static/icon/zp4.png" mode="widthFix"></image>
</view>
<view v-else class="index-upload baiyin-flex baiyin-flex-c-t baiyin-flex-c-b" style="text-align: center;">
<!-- <image v-if="imgType === 'camera'" class="index-upload-tlo-lp" src="@/static/icon/zp4.png" mode="widthFix"></image> -->
<view class="index-upload-tlo baiyin-flex baiyin-flex-wrap baiyin-flex-c-t baiyin-flex-c-b"
style="text-align: center;">
<image :class="index-upload-tlo-lp" src="@/static/icon/zp4.png" mode="">
</image>
<view class="" v-if="crossTextShow">上传</view>
</view>
</view>
</u-upload>
</view>
</template>
<script>
import apiBaseConfig from '@/config/index.js';
import {
orderStatisticsPOST
} from '@/api/upload.js';
export default {
props: {
disabled: {
type: Boolean,
default: false
},
imgType: {
type: String,
default: 'camera' //camera cross
},
crossTextShow: {
type: Boolean,
default: true
},
maxCount: {
type: Number,
default: 10
},
width: {
type: Number,
default: 170
},
height: {
type: Number,
default: 170
}
},
data() {
return {
imgBgUrl: apiBaseConfig.imgBgUrl,
globalData: getApp().globalData,
fileList6: []
};
},
watch: {
fileList6: {
handler(val,old) {
let self = this,
are = [];
if (self.fileList6 && self.fileList6.length) {
// self.fileList6.forEach(item => {
// are.push({url:item.url});
// });
self.$emit('changeList', val);
}
},
immediate: true,
deep: true
}
},
onLoad() {},
methods: {
initle(list, index) {
let self = this;
// console.log(list, index, '=====initle');
let arr = [];
if (list && list.length) {
list.forEach((fk, fl) => {
arr.push({
url: fk,
status: 'success'
});
});
self.fileList6 = arr;
}
},
// 删除图片
deletePic(event) {
this[`fileList${event.name}`].splice(event.index, 1);
},
// 新增图片
async afterRead(event) {
let self = this;
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
lists.forEach((item, index) => {
console.log(item.thumb.split('.')[item.thumb.split('.').length - 1]);
if (!['jpg', 'jpeg', 'png', 'JPG', 'JPEG', 'PNG'].includes(item.thumb.split('.')[item.thumb
.split('.').length - 1])) {
self.$toast('只支持jpg/jpeg/png格式');
self.$delete(lists, index);
}
});
let fileListLen = this[`fileList${event.name}`].length;
lists.map(item => {
this[`fileList${event.name}`].push({
...item,
status: 'uploading',
message: '上传中'
});
});
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url);
let item = this[`fileList${event.name}`][fileListLen];
this[`fileList${event.name}`].splice(
fileListLen,
1,
Object.assign(item, {
status: 'success',
message: '',
url: result
})
);
fileListLen++;
self.$forceUpdate();
}
},
uploadFilePromise(url) {
let token = uni.getStorageSync("token")
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: orderStatisticsPOST, // 仅为示例,非真实的接口地址
filePath: url,
name: 'file',
formData: {
user: 'test'
},
header: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': `Bearer ${token}`
},
// success: res => {
// setTimeout(() => {
// resolve(res.data.data);
// }, 1000);
// }
success: ({
data
}) => {
const dat = JSON.parse(data)
const {
url
} = dat.data;
setTimeout(() => {
resolve(url);
}, 1000);
}
// success(res) {
// console.log('上传文件成功', res)
// //do something
// },
// fail(error) {
// console.log('上传文件失败', error)
// }
});
});
}
}
};
</script>
<style lang="scss" scoped>
.index {
&-upload {
width: 170rpx;
height: 170rpx;
background-color: #f3f3f3;
>image {
width: 48rpx;
height: 48rpx;
}
&-tlo {
width: 100%;
height: 100%;
image {
width: 40rpx;
height: 40rpx;
}
view {
width: 100%;
text-align: center;
font-size: 24rpx;
font-weight: 400;
color: #000000;
// margin-top: -45rpx;
}
&-lp {
margin-top: 43rpx;
}
}
}
}
::v-deep .u-upload__wrap {
display: flex;
justify-content: center;
}
</style>
\ No newline at end of file
<template>
<view class="index">
<u-upload :fileList="fileList6" @afterRead="afterRead" @delete="deletePic" name="6" multiple
:maxCount="maxCount" :width="width" :height="height" :disabled="disabled" :previewFullImage="true">
<view class="index-upload-tlo baiyin-flex baiyin-flex-wrap baiyin-flex-c-t baiyin-flex-c-b"
style="text-align: center;width: 630rpx;height: 370rpx;background-color: rgba(143, 146, 161, 0.08);display: flex;align-items: center;">
<view class="">
<image :class="index-upload-tlo-lp" :src="imgBgUrl+'jh.png'" mode="">
</image>
<view class="" v-if="crossTextShow">{{crossText}}</view>
</view>
</view>
</u-upload>
</view>
</template>
<script>
import apiBaseConfig from '@/config/index.js';
import {
orderStatisticsPOST
} from '@/api/upload.js';
export default {
props: {
disabled: {
type: Boolean,
default: false
},
crossText: {
type: String,
default: '点击上传人像面' //camera cross
},
imgType: {
type: String,
default: 'camera' //camera cross
},
crossTextShow: {
type: Boolean,
default: true
},
maxCount: {
type: Number,
default: 1
},
width: {
type: Number,
default: 630
},
height: {
type: Number,
default: 370
}
},
data() {
return {
imgBgUrl: apiBaseConfig.imgBgUrl,
globalData: getApp().globalData,
fileList6: []
};
},
watch: {
fileList6: {
handler(val,old) {
let self = this,
are = [];
if (val && val.length) {
// self.fileList6.forEach(item => {
// are.push({url:item.url});
// });
self.$emit('changeList', val);
}else{
self.$emit('changeList', []);
}
},
immediate: true,
deep: true
}
},
onLoad() {},
methods: {
initle(list, index) {
let self = this;
console.log(list, index, '=====initle');
let arr = [];
if (list && list.length) {
list.forEach((fk, fl) => {
arr.push({
url: fk,
status: 'success'
});
});
self.fileList6 = arr;
}
},
// 删除图片
deletePic(event) {
this[`fileList${event.name}`].splice(event.index, 1);
},
// 新增图片
async afterRead(event) {
let self = this;
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
lists.forEach((item, index) => {
console.log(item.thumb.split('.')[item.thumb.split('.').length - 1]);
if (!['jpg', 'jpeg', 'png', 'JPG', 'JPEG', 'PNG'].includes(item.thumb.split('.')[item.thumb
.split('.').length - 1])) {
self.$toast('只支持jpg/jpeg/png格式');
self.$delete(lists, index);
}
});
let fileListLen = this[`fileList${event.name}`].length;
lists.map(item => {
this[`fileList${event.name}`].push({
...item,
status: 'uploading',
message: '上传中'
});
});
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url);
console.log(result,'result========')
let item = this[`fileList${event.name}`][fileListLen];
this[`fileList${event.name}`].splice(
fileListLen,
1,
Object.assign(item, {
status: 'success',
message: '',
url: result
})
);
fileListLen++;
self.$forceUpdate();
}
},
uploadFilePromise(url) {
let token = uni.getStorageSync("token")
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: orderStatisticsPOST, // 仅为示例,非真实的接口地址
filePath: url,
name: 'file',
formData: {
user: 'test'
},
header: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': `Bearer ${token}`
},
// success: res => {
// setTimeout(() => {
// resolve(res.data.data);
// }, 1000);
// }
success: ({
data
}) => {
const dat = JSON.parse(data)
const {
url
} = dat.data;
setTimeout(() => {
resolve(url);
}, 1000);
}
// success(res) {
// console.log('上传文件成功', res)
// //do something
// },
// fail(error) {
// console.log('上传文件失败', error)
// }
});
});
}
}
};
</script>
<style lang="scss" scoped>
.index {
&-upload {
width: 170rpx;
height: 170rpx;
background-color: #f3f3f3;
>image {
width: 48rpx;
height: 48rpx;
}
&-tlo {
width: 100%;
height: 100%;
image {
width: 96rpx;
height: 96rpx;
}
view {
width: 100%;
text-align: center;
font-weight: 400;
font-size: 28rpx;
color: #333333;
// margin-top: -45rpx;
}
&-lp {
margin-top: 43rpx;
}
}
}
}
::v-deep .u-upload__wrap {
display: flex;
justify-content: center;
}
</style>
\ No newline at end of file
<template>
<view class="index">
<u-loading-icon text="上传中..." textSize="24" size="66" :show="show"></u-loading-icon>
<view v-if="!show" @click="clickUpopup" class="index-upload baiyin-flex baiyin-flex-c-t baiyin-flex-c-b"
style="text-align: center;line-height: 170rpx;">
<image class="index-upload-tlo-lp" src="@/static/icon/zp4.png" mode="widthFix"></image>
</view>
<view class="fdsa" v-if="!show">
请上传PDF文件
</view>
</view>
</template>
<script>
import apiBaseConfig from '@/config/index.js';
import {
orderStatisticsPOST
} from '@/api/upload.js';
export default {
props: {
disabled: {
type: Boolean,
default: false
},
imgType: {
type: String,
default: 'camera' //camera cross
},
crossTextShow: {
type: Boolean,
default: true
},
maxCount: {
type: Number,
default: 10
},
width: {
type: Number,
default: 170
},
height: {
type: Number,
default: 170
},
},
data() {
return {
imgBgUrl: apiBaseConfig.imgBgUrl,
globalData: getApp().globalData,
fileList6: [],
show:false
};
},
watch: {
fileList6: {
handler(val, old) {
this.fileList6 = val || []
this.$emit('changeList', val);
// console.log(val,old,'============')
},
immediate: true,
deep: true
},
},
onLoad() {},
methods: {
// 微信选取
clickUpopup() {
let that = this //保留vue实例
wx.chooseMessageFile({
count: 10, //限制选择的文件数量
type: 'file', //非图片和视频的文件,不选默认为all
success(res) {
let lists = [].concat(res.tempFiles);
// console.log(lists, res, 'fileType===============')
lists.forEach((item, index) => {
// console.log(item.thumb.split('.')[item.thumb.split('.').length - 1]);
if (!['pdf'].includes(item.path.split('.')[item.path
.split('.').length - 1])) {
// that.show = false
that.$toast('只支持pdf格式');
that.$delete(lists, index);
}
});
for (let i = 0; i < lists.length; i++) {
that.uploadFilePromise(lists[i].path, lists[i].name);
}
},
fail(err){
console.log(err, 'errfileType===============')
}
})
},
uploadFilePromise(url, name) {
console.log(url, name,"url, name")
let token = uni.getStorageSync("token")
let that = this //保留vue实例
that.show = true
uni.uploadFile({
url: orderStatisticsPOST,
filePath: url,
name: 'file',
formData: {
'name': name,
},
header: {
'Content-Type': 'application/json;charset=UTF-8',
'Authorization': `Bearer ${token}`
},
success: (uploadFileRes) => {
let obj = JSON.parse(uploadFileRes.data)
// console.log(obj,'obj========')
let temp = {}
temp = {
name: obj.data.fileName,
// name: name,
url: obj.data.url
}
this.fileList6.push(temp)
that.show = false
}
});
},
}
};
</script>
<style lang="scss" scoped>
.index {
&-top{
background: #FFFFFF;
border-radius: 20rpx;
padding: 30rpx;
}
&-upload {
width: 170rpx;
height: 170rpx;
background-color: #f3f3f3;
>image {
width: 48rpx;
height: 48rpx;
}
&-tlo {
width: 100%;
height: 100%;
image {
width: 40rpx;
height: 40rpx;
}
view {
width: 100%;
text-align: center;
font-size: 24rpx;
font-weight: 400;
color: #000000;
// margin-top: -45rpx;
}
&-lp {
margin-top: 43rpx;
}
}
}
}
.fdsa {
font-weight: 400;
font-size: 22rpx;
color: #666666;
}
::v-deep .u-upload__wrap {
display: flex;
justify-content: center;
}
</style>
\ No newline at end of file
let hostUrl = 'https://fundapi.yyinhong.cn',
api = '/prod-api',
imgApi = '/img/';
switch (process.env.UNI_BASE_ENV) {
case 'development':
hostUrl = process.env.UNI_BASE_URL;
api = process.env.UNI_BASE_API;
break;
case 'uat':
hostUrl = process.env.UNI_BASE_URL;
api = process.env.UNI_BASE_API;
break;
case 'production':
hostUrl = process.env.UNI_BASE_URL;
api = process.env.UNI_BASE_API;
break;
}
console.log(
"config/index.js配置:",
process.env.UNI_BASE_ENV,
process.env.UNI_BASE_URL
);
// 基础配置
const apiBaseConfig = {
// 微信小程序
// #ifdef MP-WEIXIN
domain: hostUrl + api,
upload: hostUrl + api + '/group-buy/by-file/uploadOne',
imgBgUrl: 'http://fundapi.yyinhong.cn' + imgApi,
benWrChatAPPID: 'wx8920d1dae8894242',
hygAPPID: 'wx626a1ea9888b0e0f',
hygPATH: '/pages/bsChannel/login?channel=bs',
hygType: 'release', // develop(开发版),trial(体验版),release(正式版)
key:'MBYBZ-KUS6R-ADMWU-WKZXF-ZBZIK-LJFH7', // 逆地址解析腾讯地图key
url:'https://apis.map.qq.com/ws/geocoder/v1/?location=location', // 逆地址解析腾讯官方逆解析接口
//#endif
}
export default apiBaseConfig
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
import App from './App'
import store from './store';
import uView from 'uview-ui'
Vue.use(uView)
// 如此配置即可
uni.$u.config.unit = 'rpx'
import comNavBar from '@/components/navBar/aIndex';
Vue.component('com-navbar', comNavBar)
import uniGo from '@/utils/unIGO.js';
Vue.prototype.$uniGo = uniGo;
import utilsMethods from '@/utils/utils.js';
Vue.prototype.$utilsMethods = utilsMethods;
import {
toast
} from '@/utils/toast.js';
Vue.prototype.$toast = toast;
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App,
store
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app,
store
}
}
// #endif
\ No newline at end of file
{
"name" : "uni-zijinjianguan-staff-wechat",
"appid" : "__UNI__29053FA",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules" : {},
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios" : {},
/* SDK配置 */
"sdkConfigs" : {}
}
},
/* 快应用特有相关 */
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "wx81b59b65bfdfca3b",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}
<template>
<view class="index">
<view class="index-cent" v-for="v in findInviteList" :key="v.userId">
<view class="index-cent-top">
<view class="">
订单号:{{v.contractNo}}
</view>
<view class="index-cent-top-rig">
{{v.contractStatusIng | filterOrderStatus}}
</view>
</view>
<view class="index-cent-xian"></view>
<view class="index-cent-ct">
<image :src="v.url" mode=""></image>
<view class="index-cent-ct-right">
<view class="">
{{v.businessName}}
</view>
<view class="tp">
公司名称:{{v.companyName}}
</view>
<view class="tp">
营业地址:{{v.businessAddressContent}}{{v.businessAddressInfo}}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import apiBaseConfig from '@/config/index.js';
import {
findInviteContractGET
} from '@/api/workbench/index.js';
export default {
data() {
return {
imgBgUrl: apiBaseConfig.imgBgUrl,
globalData: getApp().globalData,
findInviteList: [],
totalSize: 0,
pageNum: 1,
userId: "",
currentRole: 'app_user'
};
},
filters: {
filterOrderStatus(val) {
// -1=定金待支付 0=待签约,1=待确认,2=待付款,3=图纸待上传,4=图纸待确认,5=材料待到厂,6=到厂待验收,7=材料待到家,8=到家待验收,9=待安装,10=完成待验收,11=已完成,12=终止待退款,13=终止已退款
switch (val) {
case '-1':
return '定金待支付';
break;
case '0':
return '合同待签约';
break;
case '1':
return '合同待确认';
break;
case '2':
return '待付款';
break;
case '3':
return '图纸待上传';
break;
case '4':
return '图纸待确认';
break;
case '5':
return '材料待到厂';
break;
case '6':
return '到厂待验收';
break;
case '7':
return '材料待到家';
break;
case '8':
return '到家待验收';
break;
case '9':
return '待完成安装';
break;
case '10':
return '完成待验收';
break;
case '11':
return '已完成';
break;
case '12':
return '终止待退款';
break;
case '13':
return '终止已退款';
break;
case '14':
return '待评价';
break;
default:
return val;
break;
}
}
},
onLoad(option) {
this.userId = option.userId
console.log(option.role, 'role===')
this.currentRole = option.role
this.pageNum = 1
this.findInviteList = []
this.findInvite()
},
onReachBottom() {
console.log('触底了-------')
if (this.totalSize > this.pageNum) {
this.pageNum++
this.findInvite()
}
},
methods: {
findInvite(userId) {
let self = this
let roleData = {}
switch (self.currentRole) {
case 'merchant':
roleData = {
businessId: self.userId
}
break;
case 'app_user':
case 'promoter':
roleData = {
userId: self.userId
}
break
default:
roleData = {
userId: self.userId
}
}
findInviteContractGET({
...roleData,
pageSize: 10,
pageNum: this.pageNum
}).then((res) => {
self.findInviteList = self.findInviteList.concat(res.rows)
self.findInviteList.forEach((item) => {
item.url = JSON.parse(item.businessImg)[0].url
// console.log(JSON.parse(item.businessImg),'item.url=====')
})
self.totalSize = Math.ceil(Number(res.total) / 10)
// console.log(self.totalSize,'触底了-------111')
})
},
}
};
</script>
<style>
page {
background-color: #F7F8FA;
}
</style>
<style lang="scss" scoped>
.index {
padding: 22rpx 30rpx;
&-cent {
padding: 24rpx 30rpx;
background-color: #fff;
border-radius: 20rpx;
margin-bottom: 22rpx;
&-top {
display: flex;
align-items: center;
justify-content: space-between;
font-weight: 400;
font-size: 24rpx;
color: #666666;
&-rig {
font-weight: 400;
font-size: 24rpx;
color: #1572FF;
}
}
&-xian {
width: 100%;
height: 1rpx;
background: #ECECEC;
margin: 20rpx 0;
}
&-ct {
display: flex;
align-items: center;
>image {
width: 156rpx;
height: 156rpx;
margin-right: 16rpx;
}
&-right {
width: calc(100% - 172rpx);
font-weight: 400;
font-size: 24rpx;
color: #1A1A1A;
>view:nth-child(1) {
font-weight: 500;
font-size: 26rpx;
color: #1A1A1A;
}
}
}
}
}
.tp {
margin-top: 20rpx;
}
</style>
\ No newline at end of file
<template>
<view class="index">
<view class="index-top">
<view class="index-top-tit">
<view class="index-top-tit-lef">
<view class="">
{{walletInfo.expect}}
</view>
<view class="">
预计收入(元)
</view>
</view>
<view class="index-top-tit-lef">
<view class="">
{{walletInfo.balance}}
</view>
<view class="">
我的钱包(元)
</view>
</view>
</view>
</view>
<view class="index-cet">
<view class="index-cet-tp">
<view @click="clickDj(0)" :class="particulars == 0?'xz':'wxz'" style="margin-right: 60rpx;">
预计收入明细
</view>
<view @click="clickDj(1)" :class="particulars == 1?'xz':'wxz'">
余额明细
</view>
</view>
<view v-if="particulars == 0">
<view class="index-cet-ct" v-for="(v,index) in balanceList" :key="index">
<view class="">
<view class="index-cet-ct-tit">
{{v.balanceType}}
</view>
<view class="index-cet-ct-tim">
{{v.createTime}}
</view>
</view>
<view class="index-cet-ct-mony">
{{v.amountTx}}
</view>
</view>
</view>
<view class="" v-else>
<view class="" v-for="(v,index) in balanceList" :key="index">
<view class="index-cet-ct" :style="{'margin-bottom':v==1? '8rpx':'30rpx'}">
<view class="">
<view class="index-cet-ct-tit">
{{v.balanceType}}
</view>
<view class="index-cet-ct-tim">
{{v.createTime}}
</view>
</view>
<view class="index-cet-ct-mony">
{{v.amountTx}}
</view>
</view>
<view class="yy" v-if="v.rejection">
驳回原因: {{v.rejection}}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import apiBaseConfig from '@/config/index.js';
import {
walletGET,
balanceGET
} from '@/api/workbench/index.js';
export default {
data() {
return {
imgBgUrl: apiBaseConfig.imgBgUrl,
globalData: getApp().globalData,
particulars: 0,
walletInfo:{},
balanceList:[]
};
},
onLoad() {},
onShow() {
this.wallet()
this.balance()
},
methods: {
wallet(){
walletGET().then((res)=>{
this.walletInfo = res.data
})
},
balance(){
this.balanceList = []
balanceGET({
particularsType:this.particulars
}).then((res)=>{
this.balanceList = res.data
})
},
clickDj(v) {
this.particulars = v
this.balance()
},
// 申请提现
jump() {
this.$uniGo.navigateTo({
url: `/my/withdrawal/index?balance=${this.walletInfo.balance}`
});
}
}
};
</script>
<style>
page {
background: #fff;
}
</style>
<style lang="scss" scoped>
.index {
&-top {
background: #1572FF;
padding: 80rpx 120rpx 100rpx;
&-tit {
display: flex;
align-items: center;
justify-content: space-between;
&-lef {
font-weight: 600;
font-size: 48rpx;
color: #FFFFFF;
text-align: center;
>view:nth-child(2) {
font-weight: 400;
font-size: 24rpx;
color: #FFFFFF;
margin-top: 8rpx;
}
}
}
&-cent {
background: #FFFFFF;
border-radius: 26rpx;
width: 148rpx;
height: 52rpx;
font-weight: 500;
font-size: 24rpx;
color: #1572FF;
text-align: center;
line-height: 52rpx;
margin-top: 52rpx;
}
}
&-cet {
position: relative;
top: -38rpx;
background-color: #FFFFFF;
border-radius: 40rpx 40rpx 0rpx 0rpx;
padding: 40rpx 50rpx;
&-tp {
display: flex;
align-items: flex-end;
margin-bottom: 40rpx;
}
&-ct {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 30rpx;
&-tit {
font-weight: 600;
font-size: 30rpx;
color: #242424;
}
&-tim {
font-weight: 400;
font-size: 24rpx;
color: #BCBCBC;
line-height: 48rpx;
margin-top: 8rpx;
}
&-mony {
font-weight: 600;
font-size: 32rpx;
color: #242424;
}
}
}
}
.yy {
font-weight: 400;
font-size: 24rpx;
color: #FF3141;
margin-bottom: 30rpx;
}
.xz {
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
.wxz {
font-weight: 400;
font-size: 28rpx;
color: #666666;
}
</style>
\ No newline at end of file
<template>
<view class="index">
<view class="index-img">
<!-- <image style="width: 100%;height: 100%;" src="../../static/logo.png" mode=""></image> -->
<template>
<canvas class="jimfds" style="width: 100%;height: 100%;"
canvas-id="myCanvas">
</canvas>
</template>
</view>
<view class="index-btm">
<button open-type="share" class="btn">
<view class="index-btm-lef">
转发好友
</view>
</button>
<view class="index-btm-rig"
@click="downloadFile(downFile)">
保存图片
</view>
</view>
</view>
</template>
<script>
import apiBaseConfig from '@/config/index.js';
import {
myPosterGET,
listByIds
} from '@/api/workbench/index.js';
export default {
data() {
return {
imgBgUrl: apiBaseConfig.imgBgUrl,
globalData: getApp().globalData,
imgpath: '',
screenHeight: '',
screenWidth: '',
lefWidth: '',
topHeig: '',
downFile:'',
userInfo:{}
};
},
onShareAppMessage() { // 分享到微信好友
// 更多参数配置,参考文档
let self = this;
return {
title: '全屋定制管家-白名单小程序',
path: `/pages/login/index?spread=${this.userInfo.userId}`,
}
},
onLoad() {
this.userInfo = JSON.parse(uni.getStorageSync('userInfo'))
this.screenHeight = uni.getSystemInfoSync().windowHeight;
this.screenWidth = uni.getSystemInfoSync().windowWidth - 30;
this.lefWidth = (this.screenWidth + 60)/ 4
this.topHeig = this.screenHeight - 350
console.log(this.screenHeight, this.screenWidth, this.lefWidth, this.topHeig, 'screen_height');
this.myPoster()
},
methods: {
myPoster() {
myPosterGET().then((res) => {
this.listBy(res.data.posterContent)
this.getImage(res.data.qrCode)
})
},
listBy(posterContent) {
listByIds(posterContent).then((res) => {
this.getImageInfo(res.data[0].url)
})
},
//获取背景图,将网络图片转成本地图片,
getImageInfo(src) {
let self = this
wx.getImageInfo({
src: src,
success(res) {
// console.log('3333333333')
self.mergeImages(res.path)
}
})
},
// 获取二维码,将网络图片转成本地图片,
getImage(src) {
let self = this
wx.getImageInfo({
src: src,
success(res) {
self.imgpath = res.path
}
})
},
mergeImages(v) {
let that = this
// console.log('v', v)
const ctx = uni.createCanvasContext('myCanvas');
// 绘制第一张图片
ctx.drawImage(v, 0, 0, this.screenWidth, this.screenHeight);
// 绘制第二张图片,调整位置和大小
ctx.drawImage(that.imgpath, this.lefWidth, this.topHeig, 150, 150);
// 完成绘制,将结果导出为图片
ctx.draw(); // true表示导出时使用canvas的宽高,不进行缩放
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success: function(res) {
console.log('合并后的图片路径:', res.tempFilePath);
that.setData(res.tempFilePath)
// 在这里你可以将合并后的图片保存到本地或进行其他处理
}
});
},
setData(v) {
this.downFile = v
// console.log(v, '11111111111111222222')
// this.parth.push(v)
},
downloadFile(url) {
// this.uploadFilePr(this.ewmLink)
uni.saveImageToPhotosAlbum({
filePath: url,
success: () => {
uni.showToast({
title: '保存成功!',
})
},
fail: () => {
uni.showToast({
title: '保存失败',
icon: 'none'
})
},
})
return
uni.downloadFile({
url,
fail: function(res) {
uni.showModal({
title: '提示',
content: '保存失败',
})
},
success: function(res) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功!',
})
},
fail: () => {
uni.showToast({
title: '保存失败',
icon: 'none'
})
},
})
},
})
},
// 退出登录
jump() {
uni.clearStorageSync();
uni.reLaunch({
url: '/pages/login/index'
});
}
}
};
</script>
<style>
page {
background: #F7F8FA;
height: 100%;
}
</style>
<style lang="scss" scoped>
.index {
height: 100%;
&-img {
padding: 30rpx 30rpx 220rpx;
height: calc(100% - 250rpx);
}
&-btm {
position: fixed;
bottom: 0rpx;
background: #FFFFFF;
width: calc(100% - 80rpx);
padding: 24rpx 40rpx 62rpx;
display: flex;
align-items: center;
justify-content: space-between;
&-lef {
width: 320rpx;
height: 90rpx;
border-radius: 45rpx;
border: 2rpx solid #1572FF;
font-weight: 500;
font-size: 30rpx;
color: #1572FF;
text-align: center;
line-height: 90rpx;
}
&-rig {
width: 320rpx;
height: 90rpx;
background: #1572FF;
border-radius: 45rpx;
font-weight: 500;
font-size: 30rpx;
color: #FFFFFF;
text-align: center;
line-height: 90rpx;
}
}
}
.btn {
background: #fff;
border: none;
padding: 0rpx;
margin: 0rpx;
}
button::after {
border: none
}
</style>
\ No newline at end of file
MIT License
Copyright (c) 2023 www.uviewui.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<p align="center">
<img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
</p>
<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView 2.0</h3>
<h3 align="center">多平台快速开发的UI框架</h3>
[![stars](https://img.shields.io/github/stars/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
[![forks](https://img.shields.io/github/forks/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
[![issues](https://img.shields.io/github/issues/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0/issues)
[![Website](https://img.shields.io/badge/uView-up-blue?style=flat-square)](https://uviewui.com)
[![release](https://img.shields.io/github/v/release/umicro/uView2.0?style=flat-square)](https://gitee.com/umicro/uView2.0/releases)
[![license](https://img.shields.io/github/license/umicro/uView2.0?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)
## 说明
uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
## [官方文档:https://uviewui.com](https://uviewui.com)
## 预览
您可以通过**微信**扫码,查看最佳的演示效果。
<br>
<br>
<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
## 链接
- [官方文档](https://www.uviewui.com/)
- [更新日志](https://www.uviewui.com/components/changelog.html)
- [升级指南](https://www.uviewui.com/components/changeGuide.html)
- [关于我们](https://www.uviewui.com/cooperation/about.html)
## 交流反馈
欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uviewui.com/components/addQQGroup.html)
## 关于PR
> 我们非常乐意接受各位的优质PR,但在此之前我希望您了解uView2.0是一个需要兼容多个平台的(小程序、h5、ios app、android app)包括nvue页面、vue页面。
> 所以希望在您修复bug并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢!
## 安装
#### **uni-app插件市场链接** —— [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593)
请通过[官网安装文档](https://www.uviewui.com/components/install.html)了解更详细的内容
## 快速上手
请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容
## 使用方法
配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
```html
<template>
<u-button text="按钮"></u-button>
</template>
```
## 版权信息
uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
<template>
<uvForm
ref="uForm"
:model="model"
:rules="rules"
:errorType="errorType"
:borderBottom="borderBottom"
:labelPosition="labelPosition"
:labelWidth="labelWidth"
:labelAlign="labelAlign"
:labelStyle="labelStyle"
:customStyle="customStyle"
>
<slot />
</uvForm>
</template>
<script>
/**
* 此组件存在的理由是,在nvue下,u-form被uni-app官方占用了,u-form在nvue中相当于form组件
* 所以在nvue下,取名为u--form,内部其实还是u-form.vue,只不过做一层中转
*/
import uvForm from '../u-form/u-form.vue';
import props from '../u-form/props.js'
export default {
// #ifdef MP-WEIXIN
name: 'u-form',
// #endif
// #ifndef MP-WEIXIN
name: 'u--form',
// #endif
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
components: {
uvForm
},
created() {
this.children = []
},
methods: {
// 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
setRules(rules) {
this.$refs.uForm.setRules(rules)
},
validate() {
/**
* 在微信小程序中,通过this.$parent拿到的父组件是u--form,而不是其内嵌的u-form
* 导致在u-form组件中,拿不到对应的children数组,从而校验无效,所以这里每次调用u-form组件中的
* 对应方法的时候,在小程序中都先将u--form的children赋值给u-form中的children
*/
// #ifdef MP-WEIXIN
this.setMpData()
// #endif
return this.$refs.uForm.validate()
},
validateField(value, callback, event) {
// #ifdef MP-WEIXIN
this.setMpData()
// #endif
return this.$refs.uForm.validateField(value, callback, event)
},
resetFields() {
// #ifdef MP-WEIXIN
this.setMpData()
// #endif
return this.$refs.uForm.resetFields()
},
clearValidate(props) {
// #ifdef MP-WEIXIN
this.setMpData()
// #endif
return this.$refs.uForm.clearValidate(props)
},
setMpData() {
this.$refs.uForm.children = this.children
}
},
}
</script>
<template>
<uvImage
:src="src"
:mode="mode"
:width="width"
:height="height"
:shape="shape"
:radius="radius"
:lazyLoad="lazyLoad"
:showMenuByLongpress="showMenuByLongpress"
:loadingIcon="loadingIcon"
:errorIcon="errorIcon"
:showLoading="showLoading"
:showError="showError"
:fade="fade"
:webp="webp"
:duration="duration"
:bgColor="bgColor"
:customStyle="customStyle"
@click="$emit('click')"
@error="$emit('error')"
@load="$emit('load')"
>
<template v-slot:loading>
<slot name="loading"></slot>
</template>
<template v-slot:error>
<slot name="error"></slot>
</template>
</uvImage>
</template>
<script>
/**
* 此组件存在的理由是,在nvue下,u-image被uni-app官方占用了,u-image在nvue中相当于image组件
* 所以在nvue下,取名为u--image,内部其实还是u-iamge.vue,只不过做一层中转
*/
import uvImage from '../u-image/u-image.vue';
import props from '../u-image/props.js';
export default {
name: 'u--image',
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
components: {
uvImage
},
}
</script>
\ No newline at end of file
<template>
<uvInput
:value="value"
:type="type"
:fixed="fixed"
:disabled="disabled"
:disabledColor="disabledColor"
:clearable="clearable"
:password="password"
:maxlength="maxlength"
:placeholder="placeholder"
:placeholderClass="placeholderClass"
:placeholderStyle="placeholderStyle"
:showWordLimit="showWordLimit"
:confirmType="confirmType"
:confirmHold="confirmHold"
:holdKeyboard="holdKeyboard"
:focus="focus"
:autoBlur="autoBlur"
:disableDefaultPadding="disableDefaultPadding"
:cursor="cursor"
:cursorSpacing="cursorSpacing"
:selectionStart="selectionStart"
:selectionEnd="selectionEnd"
:adjustPosition="adjustPosition"
:inputAlign="inputAlign"
:fontSize="fontSize"
:color="color"
:prefixIcon="prefixIcon"
:suffixIcon="suffixIcon"
:suffixIconStyle="suffixIconStyle"
:prefixIconStyle="prefixIconStyle"
:border="border"
:readonly="readonly"
:shape="shape"
:customStyle="customStyle"
:formatter="formatter"
:ignoreCompositionEvent="ignoreCompositionEvent"
@focus="$emit('focus')"
@blur="e => $emit('blur', e)"
@keyboardheightchange="$emit('keyboardheightchange')"
@change="e => $emit('change', e)"
@input="e => $emit('input', e)"
@confirm="e => $emit('confirm', e)"
@clear="$emit('clear')"
@click="$emit('click')"
>
<!-- #ifdef MP -->
<slot name="prefix"></slot>
<slot name="suffix"></slot>
<!-- #endif -->
<!-- #ifndef MP -->
<slot name="prefix" slot="prefix"></slot>
<slot name="suffix" slot="suffix"></slot>
<!-- #endif -->
</uvInput>
</template>
<script>
/**
* 此组件存在的理由是,在nvue下,u-input被uni-app官方占用了,u-input在nvue中相当于input组件
* 所以在nvue下,取名为u--input,内部其实还是u-input.vue,只不过做一层中转
*/
import uvInput from '../u-input/u-input.vue';
import props from '../u-input/props.js'
export default {
name: 'u--input',
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
components: {
uvInput
},
}
</script>
\ No newline at end of file
<template>
<uvText
:type="type"
:show="show"
:text="text"
:prefixIcon="prefixIcon"
:suffixIcon="suffixIcon"
:mode="mode"
:href="href"
:format="format"
:call="call"
:openType="openType"
:bold="bold"
:block="block"
:lines="lines"
:color="color"
:decoration="decoration"
:size="size"
:iconStyle="iconStyle"
:margin="margin"
:lineHeight="lineHeight"
:align="align"
:wordWrap="wordWrap"
:customStyle="customStyle"
@click="$emit('click')"
></uvText>
</template>
<script>
/**
* 此组件存在的理由是,在nvue下,u-text被uni-app官方占用了,u-text在nvue中相当于input组件
* 所以在nvue下,取名为u--input,内部其实还是u-text.vue,只不过做一层中转
* 不使用v-bind="$attrs",而是分开独立写传参,是因为微信小程序不支持此写法
*/
import uvText from "../u-text/u-text.vue";
import props from "../u-text/props.js";
export default {
name: "u--text",
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
components: {
uvText,
},
};
</script>
<template>
<uvTextarea
:value="value"
:placeholder="placeholder"
:height="height"
:confirmType="confirmType"
:disabled="disabled"
:count="count"
:focus="focus"
:autoHeight="autoHeight"
:fixed="fixed"
:cursorSpacing="cursorSpacing"
:cursor="cursor"
:showConfirmBar="showConfirmBar"
:selectionStart="selectionStart"
:selectionEnd="selectionEnd"
:adjustPosition="adjustPosition"
:disableDefaultPadding="disableDefaultPadding"
:holdKeyboard="holdKeyboard"
:maxlength="maxlength"
:border="border"
:customStyle="customStyle"
:formatter="formatter"
:ignoreCompositionEvent="ignoreCompositionEvent"
@focus="e => $emit('focus')"
@blur="e => $emit('blur')"
@linechange="e => $emit('linechange', e)"
@confirm="e => $emit('confirm')"
@input="e => $emit('input', e)"
@keyboardheightchange="e => $emit('keyboardheightchange')"
></uvTextarea>
</template>
<script>
/**
* 此组件存在的理由是,在nvue下,u--textarea被uni-app官方占用了,u-textarea在nvue中相当于textarea组件
* 所以在nvue下,取名为u--textarea,内部其实还是u-textarea.vue,只不过做一层中转
*/
import uvTextarea from '../u-textarea/u-textarea.vue';
import props from '../u-textarea/props.js'
export default {
name: 'u--textarea',
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
components: {
uvTextarea
},
}
</script>
export default {
props: {
// 操作菜单是否展示 (默认false)
show: {
type: Boolean,
default: uni.$u.props.actionSheet.show
},
// 标题
title: {
type: String,
default: uni.$u.props.actionSheet.title
},
// 选项上方的描述信息
description: {
type: String,
default: uni.$u.props.actionSheet.description
},
// 数据
actions: {
type: Array,
default: uni.$u.props.actionSheet.actions
},
// 取消按钮的文字,不为空时显示按钮
cancelText: {
type: String,
default: uni.$u.props.actionSheet.cancelText
},
// 点击某个菜单项时是否关闭弹窗
closeOnClickAction: {
type: Boolean,
default: uni.$u.props.actionSheet.closeOnClickAction
},
// 处理底部安全区(默认true)
safeAreaInsetBottom: {
type: Boolean,
default: uni.$u.props.actionSheet.safeAreaInsetBottom
},
// 小程序的打开方式
openType: {
type: String,
default: uni.$u.props.actionSheet.openType
},
// 点击遮罩是否允许关闭 (默认true)
closeOnClickOverlay: {
type: Boolean,
default: uni.$u.props.actionSheet.closeOnClickOverlay
},
// 圆角值
round: {
type: [Boolean, String, Number],
default: uni.$u.props.actionSheet.round
}
}
}
<template>
<u-popup
:show="show"
mode="bottom"
@close="closeHandler"
:safeAreaInsetBottom="safeAreaInsetBottom"
:round="round"
>
<view class="u-action-sheet">
<view
class="u-action-sheet__header"
v-if="title"
>
<text class="u-action-sheet__header__title u-line-1">{{title}}</text>
<view
class="u-action-sheet__header__icon-wrap"
@tap.stop="cancel"
>
<u-icon
name="close"
size="17"
color="#c8c9cc"
bold
></u-icon>
</view>
</view>
<text
class="u-action-sheet__description"
:style="[{
marginTop: `${title && description ? 0 : '18px'}`
}]"
v-if="description"
>{{description}}</text>
<slot>
<u-line v-if="description"></u-line>
<view class="u-action-sheet__item-wrap">
<template v-for="(item, index) in actions">
<!-- #ifdef MP -->
<button
:key="index"
class="u-reset-button"
:openType="item.openType"
@getuserinfo="onGetUserInfo"
@contact="onContact"
@getphonenumber="onGetPhoneNumber"
@error="onError"
@launchapp="onLaunchApp"
@opensetting="onOpenSetting"
:lang="lang"
:session-from="sessionFrom"
:send-message-title="sendMessageTitle"
:send-message-path="sendMessagePath"
:send-message-img="sendMessageImg"
:show-message-card="showMessageCard"
:app-parameter="appParameter"
@tap="selectHandler(index)"
:hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
>
<!-- #endif -->
<view
class="u-action-sheet__item-wrap__item"
@tap.stop="selectHandler(index)"
:hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
:hover-stay-time="150"
>
<template v-if="!item.loading">
<text
class="u-action-sheet__item-wrap__item__name"
:style="[itemStyle(index)]"
>{{ item.name }}</text>
<text
v-if="item.subname"
class="u-action-sheet__item-wrap__item__subname"
>{{ item.subname }}</text>
</template>
<u-loading-icon
v-else
custom-class="van-action-sheet__loading"
size="18"
mode="circle"
/>
</view>
<!-- #ifdef MP -->
</button>
<!-- #endif -->
<u-line v-if="index !== actions.length - 1"></u-line>
</template>
</view>
</slot>
<u-gap
bgColor="#eaeaec"
height="6"
v-if="cancelText"
></u-gap>
<view hover-class="u-action-sheet--hover">
<text
@touchmove.stop.prevent
:hover-stay-time="150"
v-if="cancelText"
class="u-action-sheet__cancel-text"
@tap="cancel"
>{{cancelText}}</text>
</view>
</view>
</u-popup>
</template>
<script>
import openType from '../../libs/mixin/openType'
import button from '../../libs/mixin/button'
import props from './props.js';
/**
* ActionSheet 操作菜单
* @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
* @tutorial https://www.uviewui.com/components/actionSheet.html
*
* @property {Boolean} show 操作菜单是否展示 (默认 false )
* @property {String} title 操作菜单标题
* @property {String} description 选项上方的描述信息
* @property {Array<Object>} actions 按钮的文字数组,见官方文档示例
* @property {String} cancelText 取消按钮的提示文字,不为空时显示按钮
* @property {Boolean} closeOnClickAction 点击某个菜单项时是否关闭弹窗 (默认 true )
* @property {Boolean} safeAreaInsetBottom 处理底部安全区 (默认 true )
* @property {String} openType 小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
* @property {Boolean} closeOnClickOverlay 点击遮罩是否允许关闭 (默认 true )
* @property {Number|String} round 圆角值,默认无圆角 (默认 0 )
* @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
* @property {String} sessionFrom 会话来源,openType="contact"时有效
* @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
* @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
* @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
* @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
* @property {String} appParameter 打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
*
* @event {Function} select 点击ActionSheet列表项时触发
* @event {Function} close 点击取消按钮时触发
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
* @event {Function} contact 客服消息回调,openType="contact"时有效
* @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效
* @event {Function} error 当使用开放能力时,发生错误的回调,openType="error"时有效
* @event {Function} launchapp 打开 APP 成功的回调,openType="launchApp"时有效
* @event {Function} opensetting 在打开授权设置页后回调,openType="openSetting"时有效
* @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
*/
export default {
name: "u-action-sheet",
// 一些props参数和methods方法,通过mixin混入,因为其他文件也会用到
mixins: [openType, button, uni.$u.mixin, props],
data() {
return {
}
},
computed: {
// 操作项目的样式
itemStyle() {
return (index) => {
let style = {};
if (this.actions[index].color) style.color = this.actions[index].color
if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)
// 选项被禁用的样式
if (this.actions[index].disabled) style.color = '#c0c4cc'
return style;
}
},
},
methods: {
closeHandler() {
// 允许点击遮罩关闭时,才发出close事件
if(this.closeOnClickOverlay) {
this.$emit('close')
}
},
// 点击取消按钮
cancel() {
this.$emit('close')
},
selectHandler(index) {
const item = this.actions[index]
if (item && !item.disabled && !item.loading) {
this.$emit('select', item)
if (this.closeOnClickAction) {
this.$emit('close')
}
}
},
}
}
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
$u-action-sheet-reset-button-width:100% !default;
$u-action-sheet-title-font-size: 16px !default;
$u-action-sheet-title-padding: 12px 30px !default;
$u-action-sheet-title-color: $u-main-color !default;
$u-action-sheet-header-icon-wrap-right:15px !default;
$u-action-sheet-header-icon-wrap-top:15px !default;
$u-action-sheet-description-font-size:13px !default;
$u-action-sheet-description-color:14px !default;
$u-action-sheet-description-margin: 18px 15px !default;
$u-action-sheet-item-wrap-item-padding:15px !default;
$u-action-sheet-item-wrap-name-font-size:16px !default;
$u-action-sheet-item-wrap-subname-font-size:13px !default;
$u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
$u-action-sheet-item-wrap-subname-margin-top:10px !default;
$u-action-sheet-cancel-text-font-size:16px !default;
$u-action-sheet-cancel-text-color:$u-content-color !default;
$u-action-sheet-cancel-text-font-size:15px !default;
$u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
.u-reset-button {
width: $u-action-sheet-reset-button-width;
}
.u-action-sheet {
text-align: center;
&__header {
position: relative;
padding: $u-action-sheet-title-padding;
&__title {
font-size: $u-action-sheet-title-font-size;
color: $u-action-sheet-title-color;
font-weight: bold;
text-align: center;
}
&__icon-wrap {
position: absolute;
right: $u-action-sheet-header-icon-wrap-right;
top: $u-action-sheet-header-icon-wrap-top;
}
}
&__description {
font-size: $u-action-sheet-description-font-size;
color: $u-tips-color;
margin: $u-action-sheet-description-margin;
text-align: center;
}
&__item-wrap {
&__item {
padding: $u-action-sheet-item-wrap-item-padding;
@include flex;
align-items: center;
justify-content: center;
flex-direction: column;
&__name {
font-size: $u-action-sheet-item-wrap-name-font-size;
color: $u-main-color;
text-align: center;
}
&__subname {
font-size: $u-action-sheet-item-wrap-subname-font-size;
color: $u-action-sheet-item-wrap-subname-color;
margin-top: $u-action-sheet-item-wrap-subname-margin-top;
text-align: center;
}
}
}
&__cancel-text {
font-size: $u-action-sheet-cancel-text-font-size;
color: $u-action-sheet-cancel-text-color;
text-align: center;
padding: $u-action-sheet-cancel-text-font-size;
}
&--hover {
background-color: $u-action-sheet-cancel-text-hover-background-color;
}
}
</style>
export default {
props: {
// 图片地址,Array<String>|Array<Object>形式
urls: {
type: Array,
default: uni.$u.props.album.urls
},
// 指定从数组的对象元素中读取哪个属性作为图片地址
keyName: {
type: String,
default: uni.$u.props.album.keyName
},
// 单图时,图片长边的长度
singleSize: {
type: [String, Number],
default: uni.$u.props.album.singleSize
},
// 多图时,图片边长
multipleSize: {
type: [String, Number],
default: uni.$u.props.album.multipleSize
},
// 多图时,图片水平和垂直之间的间隔
space: {
type: [String, Number],
default: uni.$u.props.album.space
},
// 单图时,图片缩放裁剪的模式
singleMode: {
type: String,
default: uni.$u.props.album.singleMode
},
// 多图时,图片缩放裁剪的模式
multipleMode: {
type: String,
default: uni.$u.props.album.multipleMode
},
// 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量
maxCount: {
type: [String, Number],
default: uni.$u.props.album.maxCount
},
// 是否可以预览图片
previewFullImage: {
type: Boolean,
default: uni.$u.props.album.previewFullImage
},
// 每行展示图片数量,如设置,singleSize和multipleSize将会无效
rowCount: {
type: [String, Number],
default: uni.$u.props.album.rowCount
},
// 超出maxCount时是否显示查看更多的提示
showMore: {
type: Boolean,
default: uni.$u.props.album.showMore
}
}
}
export default {
props: {
// 显示文字
title: {
type: String,
default: uni.$u.props.alert.title
},
// 主题,success/warning/info/error
type: {
type: String,
default: uni.$u.props.alert.type
},
// 辅助性文字
description: {
type: String,
default: uni.$u.props.alert.description
},
// 是否可关闭
closable: {
type: Boolean,
default: uni.$u.props.alert.closable
},
// 是否显示图标
showIcon: {
type: Boolean,
default: uni.$u.props.alert.showIcon
},
// 浅或深色调,light-浅色,dark-深色
effect: {
type: String,
default: uni.$u.props.alert.effect
},
// 文字是否居中
center: {
type: Boolean,
default: uni.$u.props.alert.center
},
// 字体大小
fontSize: {
type: [String, Number],
default: uni.$u.props.alert.fontSize
}
}
}
<template>
<u-transition
mode="fade"
:show="show"
>
<view
class="u-alert"
:class="[`u-alert--${type}--${effect}`]"
@tap.stop="clickHandler"
:style="[$u.addStyle(customStyle)]"
>
<view
class="u-alert__icon"
v-if="showIcon"
>
<u-icon
:name="iconName"
size="18"
:color="iconColor"
></u-icon>
</view>
<view
class="u-alert__content"
:style="[{
paddingRight: closable ? '20px' : 0
}]"
>
<text
class="u-alert__content__title"
v-if="title"
:style="[{
fontSize: $u.addUnit(fontSize),
textAlign: center ? 'center' : 'left'
}]"
:class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
>{{ title }}</text>
<text
class="u-alert__content__desc"
v-if="description"
:style="[{
fontSize: $u.addUnit(fontSize),
textAlign: center ? 'center' : 'left'
}]"
:class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
>{{ description }}</text>
</view>
<view
class="u-alert__close"
v-if="closable"
@tap.stop="closeHandler"
>
<u-icon
name="close"
:color="iconColor"
size="15"
></u-icon>
</view>
</view>
</u-transition>
</template>
<script>
import props from './props.js';
/**
* Alert 警告提示
* @description 警告提示,展现需要关注的信息。
* @tutorial https://www.uviewui.com/components/alertTips.html
*
* @property {String} title 显示的文字
* @property {String} type 使用预设的颜色 (默认 'warning' )
* @property {String} description 辅助性文字,颜色比title浅一点,字号也小一点,可选
* @property {Boolean} closable 关闭按钮(默认为叉号icon图标) (默认 false )
* @property {Boolean} showIcon 是否显示左边的辅助图标 ( 默认 false )
* @property {String} effect 多图时,图片缩放裁剪的模式 (默认 'light' )
* @property {Boolean} center 文字是否居中 (默认 false )
* @property {String | Number} fontSize 字体大小 (默认 14 )
* @property {Object} customStyle 定义需要用到的外部样式
* @event {Function} click 点击组件时触发
* @example <u-alert :title="title" type = "warning" :closable="closable" :description = "description"></u-alert>
*/
export default {
name: 'u-alert',
mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
data() {
return {
show: true
}
},
computed: {
iconColor() {
return this.effect === 'light' ? this.type : '#fff'
},
// 不同主题对应不同的图标
iconName() {
switch (this.type) {
case 'success':
return 'checkmark-circle-fill';
break;
case 'error':
return 'close-circle-fill';
break;
case 'warning':
return 'error-circle-fill';
break;
case 'info':
return 'info-circle-fill';
break;
case 'primary':
return 'more-circle-fill';
break;
default:
return 'error-circle-fill';
}
}
},
methods: {
// 点击内容
clickHandler() {
this.$emit('click')
},
// 点击关闭按钮
closeHandler() {
this.show = false
}
}
}
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
.u-alert {
position: relative;
background-color: $u-primary;
padding: 8px 10px;
@include flex(row);
align-items: center;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
&--primary--dark {
background-color: $u-primary;
}
&--primary--light {
background-color: #ecf5ff;
}
&--error--dark {
background-color: $u-error;
}
&--error--light {
background-color: #FEF0F0;
}
&--success--dark {
background-color: $u-success;
}
&--success--light {
background-color: #f5fff0;
}
&--warning--dark {
background-color: $u-warning;
}
&--warning--light {
background-color: #FDF6EC;
}
&--info--dark {
background-color: $u-info;
}
&--info--light {
background-color: #f4f4f5;
}
&__icon {
margin-right: 5px;
}
&__content {
@include flex(column);
flex: 1;
&__title {
color: $u-main-color;
font-size: 14px;
font-weight: bold;
color: #fff;
margin-bottom: 2px;
}
&__desc {
color: $u-main-color;
font-size: 14px;
flex-wrap: wrap;
color: #fff;
}
}
&__title--dark,
&__desc--dark {
color: #FFFFFF;
}
&__text--primary--light,
&__text--primary--light {
color: $u-primary;
}
&__text--success--light,
&__text--success--light {
color: $u-success;
}
&__text--warning--light,
&__text--warning--light {
color: $u-warning;
}
&__text--error--light,
&__text--error--light {
color: $u-error;
}
&__text--info--light,
&__text--info--light {
color: $u-info;
}
&__close {
position: absolute;
top: 11px;
right: 10px;
}
}
</style>
export default {
props: {
// 头像图片组
urls: {
type: Array,
default: uni.$u.props.avatarGroup.urls
},
// 最多展示的头像数量
maxCount: {
type: [String, Number],
default: uni.$u.props.avatarGroup.maxCount
},
// 头像形状
shape: {
type: String,
default: uni.$u.props.avatarGroup.shape
},
// 图片裁剪模式
mode: {
type: String,
default: uni.$u.props.avatarGroup.mode
},
// 超出maxCount时是否显示查看更多的提示
showMore: {
type: Boolean,
default: uni.$u.props.avatarGroup.showMore
},
// 头像大小
size: {
type: [String, Number],
default: uni.$u.props.avatarGroup.size
},
// 指定从数组的对象元素中读取哪个属性作为图片地址
keyName: {
type: String,
default: uni.$u.props.avatarGroup.keyName
},
// 头像之间的遮挡比例
gap: {
type: [String, Number],
validator(value) {
return value >= 0 && value <= 1
},
default: uni.$u.props.avatarGroup.gap
},
// 需额外显示的值
extraValue: {
type: [Number, String],
default: uni.$u.props.avatarGroup.extraValue
}
}
}
<template>
<view class="u-avatar-group">
<view
class="u-avatar-group__item"
v-for="(item, index) in showUrl"
:key="index"
:style="{
marginLeft: index === 0 ? 0 : $u.addUnit(-size * gap)
}"
>
<u-avatar
:size="size"
:shape="shape"
:mode="mode"
:src="$u.test.object(item) ? keyName && item[keyName] || item.url : item"
></u-avatar>
<view
class="u-avatar-group__item__show-more"
v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)"
@tap="clickHandler"
>
<u--text
color="#ffffff"
:size="size * 0.4"
:text="`+${extraValue || urls.length - showUrl.length}`"
align="center"
customStyle="justify-content: center"
></u--text>
</view>
</view>
</view>
</template>
<script>
import props from './props.js';
/**
* AvatarGroup 头像组
* @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
* @tutorial https://www.uviewui.com/components/avatar.html
*
* @property {Array} urls 头像图片组 (默认 [] )
* @property {String | Number} maxCount 最多展示的头像数量 ( 默认 5 )
* @property {String} shape 头像形状( 'circle' (默认) | 'square' )
* @property {String} mode 图片裁剪模式(默认 'scaleToFill' )
* @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
* @property {String | Number} size 头像大小 (默认 40 )
* @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址
* @property {String | Number} gap 头像之间的遮挡比例(0.4代表遮挡40%) (默认 0.5 )
* @property {String | Number} extraValue 需额外显示的值
* @event {Function} showMore 头像组更多点击
* @example <u-avatar-group:urls="urls" size="35" gap="0.4" ></u-avatar-group:urls=>
*/
export default {
name: 'u-avatar-group',
mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
data() {
return {
}
},
computed: {
showUrl() {
return this.urls.slice(0, this.maxCount)
}
},
methods: {
clickHandler() {
this.$emit('showMore')
}
},
}
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
.u-avatar-group {
@include flex;
&__item {
margin-left: -10px;
position: relative;
&--no-indent {
// 如果你想质疑作者不会使用:first-child,说明你太年轻,因为nvue不支持
margin-left: 0;
}
&__show-more {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.3);
@include flex;
align-items: center;
justify-content: center;
border-radius: 100px;
}
}
}
</style>
export default {
props: {
// 头像图片路径(不能为相对路径)
src: {
type: String,
default: uni.$u.props.avatar.src
},
// 头像形状,circle-圆形,square-方形
shape: {
type: String,
default: uni.$u.props.avatar.shape
},
// 头像尺寸
size: {
type: [String, Number],
default: uni.$u.props.avatar.size
},
// 裁剪模式
mode: {
type: String,
default: uni.$u.props.avatar.mode
},
// 显示的文字
text: {
type: String,
default: uni.$u.props.avatar.text
},
// 背景色
bgColor: {
type: String,
default: uni.$u.props.avatar.bgColor
},
// 文字颜色
color: {
type: String,
default: uni.$u.props.avatar.color
},
// 文字大小
fontSize: {
type: [String, Number],
default: uni.$u.props.avatar.fontSize
},
// 显示的图标
icon: {
type: String,
default: uni.$u.props.avatar.icon
},
// 显示小程序头像,只对百度,微信,QQ小程序有效
mpAvatar: {
type: Boolean,
default: uni.$u.props.avatar.mpAvatar
},
// 是否使用随机背景色
randomBgColor: {
type: Boolean,
default: uni.$u.props.avatar.randomBgColor
},
// 加载失败的默认头像(组件有内置默认图片)
defaultUrl: {
type: String,
default: uni.$u.props.avatar.defaultUrl
},
// 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
colorIndex: {
type: [String, Number],
// 校验参数规则,索引在0-19之间
validator(n) {
return uni.$u.test.range(n, [0, 19]) || n === ''
},
default: uni.$u.props.avatar.colorIndex
},
// 组件标识符
name: {
type: String,
default: uni.$u.props.avatar.name
}
}
}
<template>
<view
class="u-avatar"
:class="[`u-avatar--${shape}`]"
:style="[{
backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : $u.random(0, 19)] : bgColor) : 'transparent',
width: $u.addUnit(size),
height: $u.addUnit(size),
}, $u.addStyle(customStyle)]"
@tap="clickHandler"
>
<slot>
<!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU -->
<open-data
v-if="mpAvatar && allowMp"
type="userAvatarUrl"
:style="[{
width: $u.addUnit(size),
height: $u.addUnit(size)
}]"
/>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU -->
<template v-if="mpAvatar && allowMp"></template>
<!-- #endif -->
<u-icon
v-else-if="icon"
:name="icon"
:size="fontSize"
:color="color"
></u-icon>
<u--text
v-else-if="text"
:text="text"
:size="fontSize"
:color="color"
align="center"
customStyle="justify-content: center"
></u--text>
<image
class="u-avatar__image"
v-else
:class="[`u-avatar__image--${shape}`]"
:src="avatarUrl || defaultUrl"
:mode="mode"
@error="errorHandler"
:style="[{
width: $u.addUnit(size),
height: $u.addUnit(size)
}]"
></image>
</slot>
</view>
</template>
<script>
import props from './props.js';
const base64Avatar =
"data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx//wAARCADIAMgDAREAAhEBAxEB/8QAcQABAQEAAwEBAAAAAAAAAAAAAAUEAQMGAgcBAQAAAAAAAAAAAAAAAAAAAAAQAAIBAwICBgkDBQAAAAAAAAABAhEDBCEFMVFBYXGREiKBscHRMkJSEyOh4XLxYjNDFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A/fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHbHFyZ/Dam+yLA+Z2L0Pjtyj2poD4AAAAAAAAAAAAAAAAAAAAAAAAKWFs9y6lcvvwQeqj8z9wFaziY1n/HbUX9XF97A7QAGXI23EvJ1goyfzR0YEfN269jeZ+a03pNe0DIAAAAAAAAAAAAAAAAAAAACvtO3RcVkXlWutuL9YFYAAAAAOJRjKLjJVi9GmB5/csH/mu1h/in8PU+QGMAAAAAAAAAAAAAAAAAAaMDG/6MmMH8C80+xAelSSVFolwQAAAAAAAHVlWI37ErUulaPk+hgeYnCUJuElSUXRrrQHAAAAAAAAAAAAAAAAABa2Oz4bM7r4zdF2ICmAAAAAAAAAg7zZ8GX41wuJP0rRgYAAAAAAAAAAAAAAAAAD0m2R8ODaXU33tsDSAAAAAAAAAlb9HyWZcnJd9PcBHAAAAAAAAAAAAAAAAAPS7e64Vn+KA0AAAAAAAAAJm+v8Ftf3ewCKAAAAAAAAAAAAAAAAAX9muqeGo9NttP06+0DcAAAAAAAAAjb7dTu2ra+VOT9P8AQCWAAAAAAAAAAAAAAAAAUNmyPt5Ltv4bui/kuAF0AAAAAAADiUlGLlJ0SVW+oDzOXfd/Ind6JPRdS0QHSAAAAAAAAAAAAAAAAAE2nVaNcGB6Lbs6OTao9LsF51z60BrAAAAAABJ3jOVHjW3r/sa9QEgAAAAAAAAAAAAAAAAAAAPu1duWriuW34ZR4MC9hbnZyEoy8l36XwfYBsAAADaSq9EuLAlZ+7xSdrGdW9Hc5dgEdtt1erfFgAAAAAAAAAAAAAAAAADVjbblX6NR8MH80tEBRs7HYivyzlN8lovaBPzduvY0m6eK10TXtAyAarO55lpJK54orolr+4GqO/Xaea1FvqbXvA+Z77kNeW3GPbV+4DJfzcm/pcm3H6Vou5AdAFLC2ed2Pjv1txa8sV8T6wOL+yZEKu1JXFy4MDBOE4ScZxcZLinoB8gAAAAAAAAAAAB242LeyJ+C3GvN9C7QLmJtePYpKS+5c+p8F2IDYAANJqj1T4oCfk7Nj3G5Wn9qXJax7gJ93Z82D8sVNc4v30A6Xg5i42Z+iLfqARwcyT0sz9MWvWBps7LlTf5Grce9/oBTxdtxseklHxT+uWr9AGoAB138ezfj4bsFJdD6V2MCPm7RdtJzs1uW1xXzL3gTgAAAAAAAAADRhYc8q74I6RWs5ckB6GxYtWLat21SK731sDsAAAAAAAAAAAAAAAASt021NO/YjrxuQXT1oCOAAAAAAABzGLlJRSq26JAelwsWONYjbXxcZvmwO8AAAAAAAAAAAAAAAAAAef3TEWPkVivx3NY9T6UBiAAAAAABo2+VmGXblddIJ8eivRUD0oAAAAAAAAAAAAAAAAAAAYt4tKeFKVNYNSXfRgefAAAAAAAAr7VuSSWPedKaW5v1MCsAAAAAAAAAAAAAAAAAAIe6bj96Ts2n+JPzSXzP3ATgAAAAAAAAFbbt1UUrOQ9FpC4/UwK6aaqtU+DAAAAAAAAAAAAAAA4lKMIuUmoxWrb4ARNx3R3q2rLpa4Sl0y/YCcAAAAAAAAAAANmFud7G8r89r6X0dgFvGzLGRGtuWvTF6NAdwAAAAAAAAAAAy5W442PVN+K59EePp5ARMvOv5MvO6QXCC4AZwAAAAAAAAAAAAAcxlKLUotprg1owN+PvORborq+7Hnwl3gUbO74VzRydt8pKn68ANcJwmqwkpLmnUDkAAAAfNy9atqtyagut0AxXt5xIV8Fbj6lRd7Am5G65V6qUvtwfyx94GMAAAAAAAAAAAAAAAAAAAOU2nVOj5gdsc3LiqRvTpyqwOxbnnrhdfpSfrQB7pnv/AGvuS9gHXPMy5/Fem1yq0v0A6W29XqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//Z";
/**
* Avatar 头像
* @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
* @tutorial https://www.uviewui.com/components/avatar.html
*
* @property {String} src 头像路径,如加载失败,将会显示默认头像(不能为相对路径)
* @property {String} shape 头像形状 ( circle (默认) | square)
* @property {String | Number} size 头像尺寸,可以为指定字符串(large, default, mini),或者数值 (默认 40 )
* @property {String} mode 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 (默认 'scaleToFill' )
* @property {String} text 用文字替代图片,级别优先于src
* @property {String} bgColor 背景颜色,一般显示文字时用 (默认 '#c0c4cc' )
* @property {String} color 文字颜色 (默认 '#ffffff' )
* @property {String | Number} fontSize 文字大小 (默认 18 )
* @property {String} icon 显示的图标
* @property {Boolean} mpAvatar 显示小程序头像,只对百度,微信,QQ小程序有效 (默认 false )
* @property {Boolean} randomBgColor 是否使用随机背景色 (默认 false )
* @property {String} defaultUrl 加载失败的默认头像(组件有内置默认图片)
* @property {String | Number} colorIndex 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
* @property {String} name 组件标识符 (默认 'level' )
* @property {Object} customStyle 定义需要用到的外部样式
*
* @event {Function} click 点击组件时触发 index: 用户传递的标识符
* @example <u-avatar :src="src" mode="square"></u-avatar>
*/
export default {
name: 'u-avatar',
mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
data() {
return {
// 如果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色
colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
'#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
'#73d1f1',
'#80a7dc'
],
avatarUrl: this.src,
allowMp: false
}
},
watch: {
// 监听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值
// 而组件内部不能直接修改props的值,所以需要一个中间变量
src: {
immediate: true,
handler(newVal) {
this.avatarUrl = newVal
// 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
if(!newVal) {
this.errorHandler()
}
}
}
},
computed: {
imageStyle() {
const style = {}
return style
}
},
created() {
this.init()
},
methods: {
init() {
// 目前只有这几个小程序平台具有open-data标签
// 其他平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑
// 故目前自动获取小程序头像只支持这几个平台
// #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
this.allowMp = true
// #endif
},
// 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
isImg() {
return this.src.indexOf('/') !== -1
},
// 图片加载时失败时触发
errorHandler() {
this.avatarUrl = this.defaultUrl || base64Avatar
},
clickHandler() {
this.$emit('click', this.name)
}
}
}
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
.u-avatar {
@include flex;
align-items: center;
justify-content: center;
&--circle {
border-radius: 100px;
}
&--square {
border-radius: 4px;
}
&__image {
&--circle {
border-radius: 100px;
overflow: hidden;
}
&--square {
border-radius: 4px;
}
}
}
</style>
export default {
props: {
// 返回顶部的形状,circle-圆形,square-方形
mode: {
type: String,
default: uni.$u.props.backtop.mode
},
// 自定义图标
icon: {
type: String,
default: uni.$u.props.backtop.icon
},
// 提示文字
text: {
type: String,
default: uni.$u.props.backtop.text
},
// 返回顶部滚动时间
duration: {
type: [String, Number],
default: uni.$u.props.backtop.duration
},
// 滚动距离
scrollTop: {
type: [String, Number],
default: uni.$u.props.backtop.scrollTop
},
// 距离顶部多少距离显示,单位px
top: {
type: [String, Number],
default: uni.$u.props.backtop.top
},
// 返回顶部按钮到底部的距离,单位px
bottom: {
type: [String, Number],
default: uni.$u.props.backtop.bottom
},
// 返回顶部按钮到右边的距离,单位px
right: {
type: [String, Number],
default: uni.$u.props.backtop.right
},
// 层级
zIndex: {
type: [String, Number],
default: uni.$u.props.backtop.zIndex
},
// 图标的样式,对象形式
iconStyle: {
type: Object,
default: uni.$u.props.backtop.iconStyle
}
}
}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment