放入基础模块

This commit is contained in:
唐明明
2021-09-24 11:36:42 +08:00
parent e0ee86e816
commit c50a9e3abc
132 changed files with 4149 additions and 5751 deletions

525
pages/instrument/basics.vue Normal file
View File

@@ -0,0 +1,525 @@
<template>
<view class="ios-bottom">
<view class="info">
<view class="item info-logo" @click="updImg('logo', '')">
<label>企业LOGO</label>
<image :src="logo" mode="aspectFill"></image>
<uni-icons class="icon" color="#999" size="18" type="arrowright"></uni-icons>
</view>
<view class="item info-text">
<label>企业简介</label>
<textarea v-model="description" placeholder="输入企业简介" />
</view>
<view class="item info-text">
<label>企业地址</label>
<input v-model="address" placeholder="输入企业地址" />
</view>
</view>
<block v-for="(module, moduleIndex) in modules" :key="moduleIndex">
<view class="module-item" v-if="module.type === 1">
<view class="module-title">
<input class="title-input" type="text" v-model="module.title" placeholder="输入标题" />
<view class="remove-btn" @click="removeModule(moduleIndex)">删除</view>
</view>
<view class="module-textarea">
<textarea placeholder="输入文字内容" v-model="module.content.content" />
</view>
</view>
<view class="module-item" v-if="module.type === 2">
<view class="module-title">
<input class="title-input" type="text" v-model="module.title" placeholder="输入标题" />
<view class="remove-btn" @click="removeModule(moduleIndex)">删除</view>
</view>
<view class="module-imgs">
<view
class="item"
v-for="(item, index) in module.content.image"
:key="index"
>
<image
class="cover"
:src="item.showpath"
mode="aspectFill"
@click="openImg(module.content.image, index, 'imgs')"
@longpress="removeImg('imgs', moduleIndex, index)"
/>
<view class="item-input">
<input type="text" v-model="item.title" placeholder="输入标题" />
</view>
</view>
<view class="item" @click="updImgs(moduleIndex)">
<view class="item-upd cover">
<uni-icons type="plus" size="20" color="#999"/>
<view>上传图片</view>
</view>
</view>
</view>
<view class="module-hint">点击查看图片长按删除图片</view>
</view>
<view class="module-item" v-if="module.type === 3">
<view class="module-title">
<input class="title-input" type="text" v-model="module.title" placeholder="输入标题" />
<view class="remove-btn" @click="removeModule(moduleIndex)">删除</view>
</view>
<view class="module-videos">
<view class="item">
<block v-if="module.content.video_image.showpath != ''">
<image
class="cover"
:src="module.content.video_image.showpath"
mode="aspectFill"
@click="openImg([module.content.video_image.showpath], 0, 'videos')"
@longpress="removeImg('videoCover', moduleIndex, '')"
/>
</block>
<block v-else>
<view class="item-upd" @click="updImg('videoCover', moduleIndex)">
<uni-icons type="plus" size="20" color="#999"/>
<view>上传视频封面</view>
</view>
</block>
</view>
<view class="item">
<video
class="cover"
v-if="module.content.video_url.showpath != ''"
:src="module.content.video_url.showpath"
@longpress="removeImg('video', moduleIndex, '')"
/>
<view class="item-upd" @click="updImg('video', moduleIndex)" v-else>
<uni-icons type="plus" size="20" color="#999"/>
<view>上传视频</view>
</view>
</view>
</view>
<view class="module-hint">点击查看封面/视频长按删除封面/视频</view>
</view>
</block>
<view class="add-modules" @click="addModule">
<uni-icons class="icon" type="plus" size="18" color="#c82626"/> 添加展示模块
</view>
</view>
</template>
<script>
import { basicsInfo, basicsConfig } from '@/apis/interfaces/store'
import { uploads } from '@/apis/interfaces/uploading'
export default {
data() {
return {
logo : '',
description : '',
address : '',
modules : [],
modulesType : []
};
},
created() {
Promise.all([basicsInfo('GET', {}), basicsConfig()]).then(res => {
console.log(res)
let info = res[0]
this.logo = info.base.cover
this.description = info.base.description
this.modules = info.extends
this.address = info.info.address
this.modulesType = res[1]
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
methods:{
// 图片预览
openImg(paths, index, type){
if(type === 'imgs'){
paths = paths.map(val => {
return val.showpath
})
}
uni.previewImage({
urls : paths,
current : index,
indicator: 'number'
})
},
// 删除图片
removeImg(type, moduleIndex, index){
let modulesObj = this.modules[moduleIndex]
if(type === 'videoCover'){
modulesObj.content.video_image.showpath = ''
modulesObj.content.video_image.path = ''
}
if(type === 'imgs'){
modulesObj.content.image.splice(index, 1)
}
if(type === 'video'){
modulesObj.content.video_url.showpath = ''
modulesObj.content.video_url.path = ''
}
this.$set(this.modules, moduleIndex, modulesObj)
},
// 单图上传
updImg(type, index){
switch(type){
case 'logo':
uni.chooseImage({
crop: {width: 300, height: 300},
success: path=> {
uploads([{
name: 'logo',
uri : path.tempFilePaths[0]
}]).then(res => {
this.logo = res.url[0]
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
})
break
case 'videoCover':
uni.chooseImage({
crop: {width: 500, height: 350},
success: path=> {
uploads([{
name: 'logo',
uri : path.tempFilePaths[0]
}]).then(res => {
let modulesObj = this.modules[index]
modulesObj.content.video_image.showpath = res.url[0]
modulesObj.content.video_image.path = res.path[0]
this.$set(this.modules, index, modulesObj)
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
})
break
case 'video':
uni.chooseVideo({
success: path=> {
uploads([{
name: 'video',
uri : path.tempFilePath
}]).then(res => {
let modulesObj = this.modules[index]
modulesObj.content.video_url.showpath = res.url[0]
modulesObj.content.video_url.path = res.path[0]
this.$set(this.modules, index, modulesObj)
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
})
break
}
},
// 批量上传图片
updImgs(index){
uni.chooseImage({
success: res=>{
let path = res.tempFiles.map((val, index) => {
return {
name: 'uploads' + index,
uri : val.path
}
})
uploads(path).then(pathRes => {
let modulesObj = this.modules[index],
paths = []
for(let i in pathRes.path){
paths.push({
showpath: pathRes.url[i],
path : pathRes.path[i],
title : ''
})
}
modulesObj.content.image = [...modulesObj.content.image, ...paths]
this.$set(this.modules, index, modulesObj)
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
})
},
// 添加展示模块
addModule(){
let modulesList = this.modulesType.map(val => {
return val.value
})
uni.showActionSheet({
itemList: modulesList,
success : res => {
let content
switch(this.modulesType[res.tapIndex].id){
case 1:
content = {
content: ''
}
break
case 2:
content = {
image: [{
showpath: '',
path : '',
title : ''
}]
}
break
case 3:
content = {
video_image: {
showpath: '',
path : ''
},
video_url : {
showpath: '',
path : ''
}
}
break
}
this.modules.push({
type : this.modulesType[res.tapIndex].id,
title : '',
content : content
})
}
})
},
// 删除展示模块
removeModule(index){
this.modules.splice(index, 1)
},
// 保存基础信息
onNavigationBarButtonTap(e){
basicsInfo('PUT', {
cover : this.logo,
description : this.description,
address : this.address,
extends : this.modules
}).then(res => {
uni.showModal({
title : '提示',
content : '基本信息已保存',
showCancel : false,
success : modalRes=> {
if(modalRes.confirm){
this.$Router.back()
}
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss" scoped>
// 基础信息
.info{
background: white;
padding: 0 $padding;
.item{
position: relative;
padding: $padding 0 $padding 200rpx;
&::after{
position: absolute;
left: 0;
bottom: 0;
right: -$padding;
content: " ";
height: 1rpx;
background: #eee;
}
&:last-child::after{
display: none;
}
}
.info-logo{
text-align: right;
padding-right: 40rpx;
label{
position: absolute;
left: 0;
height: 88rpx;
line-height: 88rpx;
}
image{
width: 88rpx;
height: 88rpx;
border-radius: 50%;
vertical-align: top;
background: $border-color-lg;
}
.icon{
position: absolute;
right: 0;
top: 50%;
margin-top: -10px;
}
}
.info-text{
label{
position: absolute;
left: 0;
height: 40rpx;
line-height: 40rpx;
}
textarea{
line-height: 40rpx;
width: 100%;
height: 160rpx;
}
input{
height: 40rpx;
width: 100%;
}
}
}
// 模块
.add-modules{
line-height: 90rpx;
text-align: center;
color: $text-price;
background: white;
margin-top: $margin;
.icon{
vertical-align: middle;
margin-right: $margin/3;
}
}
// 展示模块
.module-item{
background: white;
padding: $padding/2 $padding;
margin-top: $margin;
.module-title{
display: flex;
justify-content: space-between;
padding-bottom: $padding/2;
border-bottom: solid 1rpx $border-color;
.title-input{
width: calc(100% - 150rpx);
height: 70rpx;
font-size: $title-size;
}
.remove-btn{
line-height: 70rpx;
color: $text-price;
text-align: right;
font-size: $title-size-m;
}
}
.module-textarea{
padding: $padding 0 $padding/2;
width: 100%;
font-size: $title-size;
line-height: 50rpx;
height: 200rpx;
}
.module-imgs{
display: flex;
flex-wrap: wrap;
padding-top: $padding/2;
margin-left: -10rpx;
margin-right: -10rpx;
.item{
position: relative;
background: #F8F8F8;
width: calc(25% - 20rpx);
padding-top: calc(25% - 20rpx);
margin: 10rpx;
.cover{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.item-input{
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba($color: #000000, $alpha: .7);
input{
height: 50rpx;
line-height: 50rpx;
font-size: 28rpx;
text-align: center;
z-index: 4;
color: white;
}
}
.item-upd{
@extend .vertical;
text-align: center;
font-size: $title-size-m;
color: $text-gray-m;
}
}
}
.module-hint{
color: $text-gray;
font-size: $title-size-sm;
padding: $padding/2 0;
line-height: 50rpx;
}
.module-videos{
display: flex;
padding: $padding 0 ($padding/2);
margin-left: -10rpx;
margin-right: -10rpx;
.item{
position: relative;
width: calc(50% - #{$margin/2});
padding-top: calc(35% - #{$margin/2});
background: #f8f8f8;
margin: 0 10rpx;
.item-upd{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
font-size: $title-size-m;
color: $text-gray-m;
line-height: 40rpx;
@extend .vertical;
}
.cover{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
}
}
</style>

View File

@@ -0,0 +1,364 @@
<template>
<view class="content">
<!-- tabs -->
<view class="tabs">
<view class="item" :class="{'show': tabsIndex == 'day'}" @click="onTbas('day')">日成交</view>
<view class="item" :class="{'show': tabsIndex == 'month'}" @click="onTbas('month')">月成交</view>
<view class="item" :class="{'show': tabsIndex == 'year'}" @click="onTbas('year')">年成交</view>
</view>
<!-- 统计信息 -->
<view class="statistics">
<view class="statistics-flex">
<picker mode="date" :fields="tabsIndex" :value="dateValue" :end="endDate" @change="pickerDate">
<view class="statistics-date">
{{dateValue}}<uni-icons class="arrowdown" type="arrowdown" color="#555"></uni-icons>
</view>
</picker>
<view class="statistics-lay" :class="{ 'show' : sort != '' || payType != '' || channel != ''}" @click="onScreening">
筛选 <uni-icons class="arrowdown" type="settings" color="gray"></uni-icons>
</view>
</view>
<view class="statistics-text">
<text>成交产品数量 {{visitor.goods_count}} </text>
<text>成交产品金额 {{visitor.total}} </text>
</view>
</view>
<!-- 数据列表 -->
<view class="lists">
<block v-if="orders.length > 0">
<view class="item" v-for="(item, index) in orders" :key="index">
<image class="cover" :src="item.user.avatar" mode="aspectFill"></image>
<view class="title nowrap">
{{item.user.nickname}}
<view class="type">{{item.amount}}</view>
</view>
<view class="sub-title nowrap">订单号码: {{item.order_no}}</view>
<view class="sub-title nowrap">订单时间: {{item.created_at}}</view>
<view class="sub-tabs">
<text>{{item.driver}}</text>
<text>{{item.channel}}</text>
</view>
</view>
<!-- 分页 -->
<uni-load-more :status="pageStatus" :iconSize="16"></uni-load-more>
</block>
<block v-else>
<view class="list-null">
<image class="icon" src="@/static/icons/listnull-icon.png" mode="widthFix"></image>
<view class="sub-title">暂无相关成交客户记录</view>
</view>
</block>
</view>
<!-- 列表筛选 -->
<uni-popup ref="settingsPopup" background-color="#FFFFFF" @maskClick="onReset">
<view class="popup-content">
<view class="title">排序方式</view>
<view class="popup-choose-flex">
<view class="item" :class="{'show' : sort == 'money_asc'}" @click="sort = 'money_asc'">金额从低到高</view>
<view class="item" :class="{'show' : sort == 'money_desc'}" @click="sort = 'money_desc'">金额从高到低</view>
<view class="item" :class="{'show' : sort == 'sold_asc'}" @click="sort = 'sold_asc'">销量从低到高</view>
<view class="item" :class="{'show' : sort == 'sold_desc'}" @click="sort = 'sold_desc'">销量从高到低</view>
</view>
<view class="title">支付方式</view>
<view class="popup-choose-flex">
<view class="item" :class="{'show' : payType == 'eb'}" @click="payType = 'eb'">易币交易</view>
<view class="item" :class="{'show' : payType == 'money'}" @click="payType = 'money'">现金交易</view>
</view>
<view class="title">成交渠道</view>
<view class="popup-choose-flex">
<view class="item" :class="{'show' : channel == 'app'}" @click="channel = 'app'">APP</view>
<view class="item" :class="{'show' : channel == 'mini'}" @click="channel = 'mini'">自媒体</view>
</view>
<view class="popup-btns">
<view class="item" @click="onReset">重置</view>
<view class="item" @click="onSettings">确定</view>
</view>
</view>
<view class="ios-bottom"></view>
</uni-popup>
</view>
</template>
<script>
import getDate from '@/public/date'
import { orderUsers } from '@/apis/interfaces/store'
export default {
data() {
return {
tabsIndex : 'day',
dateValue : '',
endDate : '',
visitor : {
day: 0,
all: 0
},
orders : [],
sort : '',
payType : '',
channel : '',
// 分页
pageStatus : '',
page : 1
};
},
created() {
getDate().then(res => {
this.dateValue = res
this.endDate = res
this.getLists()
})
},
methods:{
// tabs筛选
onTbas(type){
getDate(type).then(res => {
this.tabsIndex = type
this.dateValue = res
this.page = 1
this.getLists()
})
},
onReset(){
this.sort = ''
this.payType = ''
this.channel = ''
},
onSettings(){
this.getLists()
this.$refs.settingsPopup.close()
},
// 日期筛选
pickerDate(e){
let dateValue = e.detail.value
this.dateValue = dateValue
this.getLists()
},
// 列表筛选
onScreening(){
this.$refs.settingsPopup.open('bottom')
},
// 获取列表
getLists(){
orderUsers({
type : this.tabsIndex,
date : this.dateValue,
sort : this.sort,
pay_type : this.payType,
channel : this.channel,
page : this.page
}).then(res => {
if(res.orders.page.current === 1){
this.orders = []
}
this.visitor = res.visitor
this.orders = this.orders.concat(res.orders.data)
this.page = res.orders.page.current
this.pageStatus = res.orders.page.has_more ? 'more': 'noMore'
}).catch(err => {
uni.showToast({
title: err,
icon : 'none'
})
})
}
},
onReachBottom() {
if(this.pageStatus == 'more'){
this.pageStatus = 'loading'
this.page += 1
this.getLists()
}
}
}
</script>
<style lang="scss">
// 筛选层
.popup-content{
padding: $padding * 2;
.title{
font-weight: bold;
font-size: $title-size;
color: $text-color;
margin-top: $margin;
}
.popup-choose-flex{
padding: $padding /2 0;
margin: 0 -($margin - 20rpx);
display: flex;
flex-wrap: wrap;
.item{
width: calc(33.33% - #{$margin - 10});
font-size: $title-size-sm;
text-align: center;
background: $border-color-lg;
line-height: 68rpx;
margin: $margin - 20;
color: $text-gray;
border:solid 1rpx $border-color-lg;
box-sizing: border-box;
&.show{
border:solid 1rpx $text-price;
color: $text-price;
}
}
}
.popup-btns{
padding-top: $padding*2;
display: flex;
justify-content: space-between;
margin: 0 -$margin/2;
.item{
margin: $margin/2;
color: $text-price;
background: rgba($color: $text-price, $alpha: .1);
width: calc(50% - #{$margin});
height: 80rpx;
line-height: 80rpx;
text-align: center;
&:last-child{
background-color: $text-price;
color: white;
}
}
}
}
// 空提示
.list-null{
width: 100vw;
height: 40vh;
background: white;
text-align: center;
@extend .vertical;
.sub-title{
color: $text-gray;
font-size: $title-size-m;
}
.icon{
width: 288rpx;
}
}
// content
.content{
padding-top: 80rpx;
}
// tabs
.tabs{
position: fixed;
z-index: 99;
top: 0;
left: 0;
width: 100%;
display: flex;
background: white;
justify-content: space-around;
line-height: 80rpx;
font-size: $title-size-m;
color: $text-gray;
.item.show{
color: $text-price;
font-weight: bold;
}
}
// 统计信息
.statistics{
margin-top: $margin;
background-color: white;
border-bottom: solid 1rpx $border-color;
padding: $padding;
.statistics-flex{
display: flex;
justify-content: space-between;
.statistics-date{
font-size: $title-size + 4;
font-weight: bold;
line-height: 60rpx;
.arrowdown{
margin-left: $margin/2;
}
}
.statistics-lay{
font-size: $title-size-sm;;
color: gray;
line-height: 50rpx;
&.show{
color: $text-price;
}
.arrowdown{
margin-left: $margin/2;
}
}
}
.statistics-text{
font-size: $title-size-sm;
color: gray;
line-height: 50rpx;
text{
margin-left: $margin;
&:first-child{
margin: 0;
}
}
}
}
// 客户列表
.lists{
padding: $padding/2 0;
background: white;
.item{
padding: ($padding - 10) $padding ($padding - 10) ($padding*2 + 68);
position: relative;
min-height: 68rpx;
&::after{
position: absolute;
left: $padding*2 + 68;
top: 0;
right: 0;
content: ' ';
border-bottom: solid 1rpx $border-color;
}
&:first-child::after{
display: none;
}
.cover{
position: absolute;
left: $padding;
top: $padding - 10;
width: 68rpx;
height: 68rpx;
border-radius: 50%;
background-color: #eee;
}
.title{
padding-right: 200rpx;
position: relative;
line-height: 58rpx;
font-size: $title-size-lg;
.type{
position: absolute;
right: 0;
top: 0;
width: 180rpx;
text-align: right;
color: $text-price;
}
}
.sub-title{
line-height: 40rpx;
font-size: $title-size-sm;
color: $text-gray;
}
.sub-tabs{
padding-top: $padding/2;
font-size: $title-size-sm;
text{
margin-right: $margin - 10;
background: $border-color-lg;
color: $text-gray;
padding: 0 ($padding/2);
}
}
}
}
</style>