项目初始化
This commit is contained in:
183
pages/clerk/apply/components/formAvatar.vue
Normal file
183
pages/clerk/apply/components/formAvatar.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="form-item">
|
||||
<view class="label">上传头像</view>
|
||||
</view>
|
||||
<view class="upload-box">
|
||||
<!-- <button v-if="mp_is_new" class="avatar-box" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
||||
<u-avatar size="180" :src="avatarUrl"></u-avatar>
|
||||
<view class="icon">
|
||||
<u-icon name="camera" color="#fff" size="30"></u-icon>
|
||||
</view>
|
||||
</button> -->
|
||||
|
||||
<view class="avatar-box" @click="chooseImage">
|
||||
<u-avatar size="180" :src="avatarUrl"></u-avatar>
|
||||
<view class="icon">
|
||||
<u-icon name="camera" color="#fff" size="30"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FileApi from '@/sheep/api/infra/file';
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
mp_is_new: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// #ifdef MP-WEIXIN
|
||||
const version = uni.getSystemInfoSync().SDKVersion;
|
||||
if(this.compareVersion(version, '2.21.2') >= 0){
|
||||
this.mp_is_new = true;
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
computed: {
|
||||
avatarUrl() {
|
||||
return this.modelValue;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 小程序比较版本信息
|
||||
* @param v1 当前版本
|
||||
* @param v2 进行比较的版本
|
||||
* @return boolen
|
||||
*
|
||||
*/
|
||||
compareVersion(v1, v2) {
|
||||
v1 = v1.split('.')
|
||||
v2 = v2.split('.')
|
||||
const len = Math.max(v1.length, v2.length)
|
||||
|
||||
while (v1.length < len) {
|
||||
v1.push('0')
|
||||
}
|
||||
while (v2.length < len) {
|
||||
v2.push('0')
|
||||
}
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const num1 = parseInt(v1[i])
|
||||
const num2 = parseInt(v2[i])
|
||||
|
||||
if (num1 > num2) {
|
||||
return 1
|
||||
} else if (num1 < num2) {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
},
|
||||
//选照片 or 拍照
|
||||
chooseImage() {
|
||||
uni.chooseImage({
|
||||
count: 1, //默认9
|
||||
sourceType: ['album', 'camera'],
|
||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||||
success: (res) => {
|
||||
for (let i = 0; i < res.tempFilePaths.length; i++) {
|
||||
uni.getImageInfo({
|
||||
src: res.tempFilePaths[i],
|
||||
success: (image) => {
|
||||
this.uploadImage(image.path);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
uploadImage(path) {
|
||||
FileApi.uploadFile(path).then((res) => {
|
||||
this.$emit('update:modelValue', res.data);
|
||||
});
|
||||
},
|
||||
// 微信头像获取
|
||||
onChooseAvatar(e) {
|
||||
const {
|
||||
avatarUrl
|
||||
} = e.detail
|
||||
this.uploadImage(avatarUrl);
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 15px;
|
||||
|
||||
.label {
|
||||
font-size: 30rpx;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-top: 0;
|
||||
|
||||
.avatar-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 5px;
|
||||
background-color: var(--ui-BG-Main);
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
button{
|
||||
padding: unset;
|
||||
margin: unset;
|
||||
border: unset;
|
||||
position: relative;
|
||||
line-height: unset;
|
||||
background-color: unset;
|
||||
font-size: unset;
|
||||
color: unset;
|
||||
border-radius: unset;
|
||||
text-align: unset;
|
||||
text-decoration: unset;
|
||||
display: unset;
|
||||
overflow: unset;
|
||||
}
|
||||
button::after{
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
</style>
|
69
pages/clerk/apply/components/formCity.vue
Normal file
69
pages/clerk/apply/components/formCity.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="form-item">
|
||||
<view class="label">所在城市</view>
|
||||
<u-input @click="citySelect" input-align="right" type="select" placeholder="请选择所在的城市" v-model="city" />
|
||||
</view>
|
||||
<!-- 省市区弹窗 -->
|
||||
<su-region-picker :show="show" @cancel="show = false" @confirm="cityOk" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
params: {
|
||||
province: true,
|
||||
city: true,
|
||||
area: false
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
computed: {
|
||||
city() {
|
||||
return this.modelValue;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
citySelect() {
|
||||
this.show = true;
|
||||
},
|
||||
cityOk(e) {
|
||||
this.$emit('update:modelValue', e.city_name);
|
||||
this.show = false;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 15px;
|
||||
|
||||
.label {
|
||||
font-size: 30rpx;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
73
pages/clerk/apply/components/formImage.vue
Normal file
73
pages/clerk/apply/components/formImage.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="form-item">
|
||||
<view class="label">上传图片</view>
|
||||
<view>{{imgList.length}}/{{number}}</view>
|
||||
</view>
|
||||
<view class="upload-box">
|
||||
<shmily-drag-image :number="number" v-model="imgList"></shmily-drag-image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
number: {
|
||||
type: Number,
|
||||
default: 6
|
||||
},
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imgList: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.imgList = this.modelValue;
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
imgList: {
|
||||
handler: function(newVal, oldVal) {
|
||||
this.$emit('update:modelValue', newVal);
|
||||
}
|
||||
},
|
||||
modelValue: {
|
||||
handler: function(newVal, oldVal) {
|
||||
this.imgList = newVal;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 15px;
|
||||
|
||||
.label {
|
||||
font-size: 30rpx;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
padding: 15px;
|
||||
}
|
||||
</style>
|
90
pages/clerk/apply/components/formSex.vue
Normal file
90
pages/clerk/apply/components/formSex.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<view class="form-item">
|
||||
<view class="label">性别</view>
|
||||
<view class="radio-box">
|
||||
<view @click="change(item)" class="text" :class="item.value == valueDom ? 'active' : ''" v-for="(item,index) in list">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
name: '男',
|
||||
value: '0',
|
||||
},
|
||||
{
|
||||
name: '女',
|
||||
value: '1',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
computed: {
|
||||
valueDom() {
|
||||
return this.modelValue;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
change(e) {
|
||||
this.$emit('update:modelValue', e.value);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-item {
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 15px;
|
||||
|
||||
.label {
|
||||
font-size: 30rpx;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.radio-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.text {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #ececec;
|
||||
color: #949494;
|
||||
border-radius: 100%;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #fff;
|
||||
background-color: #949494;
|
||||
}
|
||||
}
|
||||
</style>
|
255
pages/clerk/apply/components/formVoice.vue
Normal file
255
pages/clerk/apply/components/formVoice.vue
Normal file
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<view class="form-bg">
|
||||
<view class="form-item">
|
||||
<view class="label">录音</view>
|
||||
<view class="bubble-box">
|
||||
<u-input @click="topBubble" input-align="right" type="select" :placeholder="voice.name" />
|
||||
<tui-bubble-popup :show="show" :mask="false" position="absolute" direction="right" triangleRight="-22rpx" triangleTop="30rpx" @close="topBubble" :flexEnd="false">
|
||||
<view @click="change(item)" class="tui-menu-item" v-for="(item,index) in list">{{item.name}}</view>
|
||||
</tui-bubble-popup>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="voice-box" v-if="voice.type == 'voice'">
|
||||
<view v-if="voiceUrl" @click="playAudio" class="upload-btn-box">
|
||||
<view class="icon">
|
||||
<u-icon v-if="play" name="pause" color="#fff" size="70"></u-icon>
|
||||
<u-icon v-else name="play-right-fill" color="#fff" size="70"></u-icon>
|
||||
</view>
|
||||
<view class="upload-btn" v-if="play">停止播放</view>
|
||||
<view class="upload-btn" v-else>播放录音</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<all-speech ref="speech" @okClick="voiceOk"></all-speech>
|
||||
</view>
|
||||
<view v-if="voiceUrl" @click="reloadBtn" class="reload-btn">
|
||||
<u-icon name="reload" size="30"></u-icon>
|
||||
<text class="text">重录</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="voice-box" v-if="voice.type == 'upload'">
|
||||
<view v-if="voiceUrl" @click="playAudio" class="upload-btn-box">
|
||||
<view class="icon">
|
||||
<u-icon v-if="play" name="pause" color="#fff" size="70"></u-icon>
|
||||
<u-icon v-else name="play-right-fill" color="#fff" size="70"></u-icon>
|
||||
</view>
|
||||
<view class="upload-btn" v-if="play">停止播放</view>
|
||||
<view class="upload-btn" v-else>播放录音</view>
|
||||
</view>
|
||||
<view v-else @click="chooseVoice" class="upload-btn-box">
|
||||
<view class="icon">
|
||||
<u-icon name="plus" color="#fff" size="70"></u-icon>
|
||||
</view>
|
||||
<view class="upload-btn">上传录音文件</view>
|
||||
</view>
|
||||
<view v-if="voiceUrl" @click="reloadBtn" class="reload-btn">
|
||||
<u-icon name="reload" size="30"></u-icon>
|
||||
<text class="text">重录</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FileApi from '@/sheep/api/infra/file';
|
||||
import tuiBubblePopup from "@/components/thorui/tui-bubble-popup/tui-bubble-popup.vue"
|
||||
const audio = uni.createInnerAudioContext();
|
||||
export default {
|
||||
components: {
|
||||
tuiBubblePopup,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
voice: {
|
||||
|
||||
},
|
||||
list: [
|
||||
{
|
||||
name: '直接录音',
|
||||
type: 'voice',
|
||||
},
|
||||
],
|
||||
current: 0,
|
||||
voicePath: '',
|
||||
show: false,
|
||||
play: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.voice = this.list[this.current];
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
var voiceType = {
|
||||
name: '上传手机音频',
|
||||
type: 'upload',
|
||||
};
|
||||
this.list.push(voiceType);
|
||||
// #endif
|
||||
},
|
||||
computed: {
|
||||
voiceUrl(){
|
||||
return this.modelValue;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
topBubble() {
|
||||
this.show = !this.show;
|
||||
},
|
||||
change(e) {
|
||||
this.reloadBtn();
|
||||
this.topBubble();
|
||||
this.voice = e;
|
||||
},
|
||||
reloadBtn() {
|
||||
this.play = false;
|
||||
this.$emit('update:modelValue', "");
|
||||
this.$emit('sec', "");
|
||||
},
|
||||
playAudio() {
|
||||
if(this.play){
|
||||
this.play = false;
|
||||
audio.stop();
|
||||
}else{
|
||||
this.play = true;
|
||||
//语音自然播放结束
|
||||
audio.onEnded((res) => {
|
||||
this.play = false;
|
||||
});
|
||||
audio.src = this.modelValue;
|
||||
audio.play();
|
||||
}
|
||||
},
|
||||
chooseVoice() {
|
||||
var that = this;
|
||||
uni.chooseFile({
|
||||
count: 1, //默认100
|
||||
extension:['.mp3','.mp4','.m4a'],
|
||||
success: function (res) {
|
||||
var fileSize = res.tempFiles[0].size;
|
||||
if (fileSize > 1024 * 1024 * 10) { // 假设设置的文件大小限制为5MB
|
||||
uni.showToast({
|
||||
title: '文件大小限制为10MB',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
that.voicePath = res.tempFilePaths[0];
|
||||
console.log(JSON.stringify(res.tempFilePaths));
|
||||
that.uploadVoice(that.voicePath);
|
||||
}
|
||||
});
|
||||
},
|
||||
uploadVoice(path) {
|
||||
FileApi.uploadFile(path).then((res) => {
|
||||
this.$emit('update:modelValue', res.data);
|
||||
});
|
||||
},
|
||||
voiceOk(e) {
|
||||
this.voicePath = e.path;
|
||||
this.uploadVoice(this.voicePath);
|
||||
this.$emit('sec', e.sec);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-bg {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 0;
|
||||
|
||||
.label {
|
||||
font-size: 30rpx;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.bubble-box {
|
||||
position: relative;
|
||||
|
||||
.tui-menu-item {
|
||||
width: 100%;
|
||||
padding: 30rpx 20rpx;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tui-menu-item:after {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
content: " ";
|
||||
pointer-events: none;
|
||||
top: 0%;
|
||||
right: 10%;
|
||||
bottom: 0%;
|
||||
left: 10%;
|
||||
border: 0 solid #ebedf0;
|
||||
border-color: #646566;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.tui-menu-item:last-child:after {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.voice-box {
|
||||
height: 400rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
background-color: #3cc9a4;
|
||||
border-radius: 100%;
|
||||
width: 170rpx;
|
||||
height: 170rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.upload-btn-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.upload-btn {
|
||||
font-size: 34rpx;
|
||||
color: #aaa;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.reload-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
font-size: 30rpx;
|
||||
color: #3cc9a4;
|
||||
|
||||
.text {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
213
pages/clerk/apply/edit.vue
Normal file
213
pages/clerk/apply/edit.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<view class="page-app theme-light main-green font-1">
|
||||
<su-navbar title="编辑资料" statusBar></su-navbar>
|
||||
|
||||
<view class="form-box">
|
||||
<form-avatar v-model="form.avatar"></form-avatar>
|
||||
</view>
|
||||
|
||||
<view class="form-box">
|
||||
<view class="form-item">
|
||||
<view class="label">昵称</view>
|
||||
<u-input input-align="right" placeholder="请输入昵称" v-model="form.nickname" />
|
||||
</view>
|
||||
<form-sex v-model="form.sex"></form-sex>
|
||||
<view class="form-item">
|
||||
<view class="label">年龄</view>
|
||||
<u-input input-align="right" placeholder="请输入年龄" type="number" v-model="form.age" />
|
||||
</view>
|
||||
<view class="form-item" v-if="isPass">
|
||||
<view class="label">微信</view>
|
||||
<u-input input-align="right" placeholder="请输入您的微信" v-model="form.weixin" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="label">手机号</view>
|
||||
<u-input input-align="right" placeholder="请输入手机号" type="number" v-model="form.mobile" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="label">相关经验</view>
|
||||
<u-input input-align="right" placeholder="是否有其它店铺的经验" v-model="form.experience" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="label">自我介绍</view>
|
||||
<u-input input-align="right" placeholder="请输入自我介绍" v-model="form.intro" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="label">所在城市</view>
|
||||
<u-input input-align="right" placeholder="请输入所在城市" v-model="form.city" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-box">
|
||||
<form-image :number="6" v-model="imgList"></form-image>
|
||||
</view>
|
||||
|
||||
<view class="form-box">
|
||||
<form-voice @sec="toSec" v-model="form.sound"></form-voice>
|
||||
</view>
|
||||
|
||||
<view class="submit-box">
|
||||
<view class="sub-btn" @click="saveApply">提交申请</view>
|
||||
</view>
|
||||
|
||||
<s-menu-tools />
|
||||
<s-auth-modal />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormAvatar from '@/pages/clerk/apply/components/formAvatar.vue';
|
||||
import FormSex from '@/pages/clerk/apply/components/formSex.vue';
|
||||
import FormVoice from '@/pages/clerk/apply/components/formVoice.vue';
|
||||
import FormImage from '@/pages/clerk/apply/components/formImage.vue';
|
||||
import ClerkApi from '@/sheep/api/worker/clerk';
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
FormAvatar,
|
||||
FormSex,
|
||||
FormVoice,
|
||||
FormImage,
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
id: 0,
|
||||
avatar: '',
|
||||
nickname: '',
|
||||
sex: '',
|
||||
age: '',
|
||||
weixin: '',
|
||||
mobile: '',
|
||||
experience: '',
|
||||
intro: '',
|
||||
city: '',
|
||||
albums: '',
|
||||
sound: '',
|
||||
soundTime: '',
|
||||
},
|
||||
imgList: [],
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.form.id = options.id;
|
||||
this.init();
|
||||
},
|
||||
computed: {
|
||||
isPass() {
|
||||
return sheep.$store('user').tradeConfig.weixinEnabled;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
ClerkApi.getClerkApply(this.form.id).then((res) => {
|
||||
this.form = res.data;
|
||||
if(this.form.albums){
|
||||
this.imgList = this.form.albums.split(',');
|
||||
}
|
||||
});
|
||||
},
|
||||
saveApply() {
|
||||
if(!this.form.avatar){
|
||||
sheep.$helper.toast('请上传头像');
|
||||
return;
|
||||
}
|
||||
if(!this.form.nickname){
|
||||
sheep.$helper.toast('请输入昵称');
|
||||
return;
|
||||
}
|
||||
if(!this.form.sex){
|
||||
sheep.$helper.toast('请选择性别');
|
||||
return;
|
||||
}
|
||||
if(!this.form.age){
|
||||
sheep.$helper.toast('请输入年龄');
|
||||
return;
|
||||
}
|
||||
if(this.isPass && !this.form.weixin){
|
||||
sheep.$helper.toast('请输入正确的微信号');
|
||||
return;
|
||||
}
|
||||
if(!this.form.mobile){
|
||||
sheep.$helper.toast('请输入正确的手机号');
|
||||
return;
|
||||
}
|
||||
if(!this.form.experience){
|
||||
sheep.$helper.toast('请输入相关经验');
|
||||
return;
|
||||
}
|
||||
if(!this.form.intro){
|
||||
sheep.$helper.toast('请输入自我介绍');
|
||||
return;
|
||||
}
|
||||
if(!this.form.city){
|
||||
sheep.$helper.toast('请输入所在城市');
|
||||
return;
|
||||
}
|
||||
if(this.imgList.length < 1){
|
||||
sheep.$helper.toast('请上传图片');
|
||||
return;
|
||||
}
|
||||
this.form.albums = this.imgList.join(',');
|
||||
ClerkApi.updateClerkApply(this.form).then((res) => {
|
||||
|
||||
});
|
||||
},
|
||||
toSec(e) {
|
||||
this.form.soundTime = e;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-app {
|
||||
background-color: #fafafa;
|
||||
padding-bottom: 140rpx;
|
||||
}
|
||||
.form-box {
|
||||
background-color: #fff;
|
||||
margin: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 15px;
|
||||
|
||||
.label {
|
||||
font-size: 30rpx;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.submit-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 140rpx;
|
||||
padding: 0 15px;
|
||||
z-index: 99;
|
||||
|
||||
.sub-btn {
|
||||
background-color: var(--ui-BG-Main);
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
border-radius: 40px;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
307
pages/clerk/apply/index.vue
Normal file
307
pages/clerk/apply/index.vue
Normal file
@@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<view class="page-app theme-light main-green font-1">
|
||||
<su-navbar title="达人申请" statusBar></su-navbar>
|
||||
|
||||
<!-- #ifdef MP -->
|
||||
<view v-if="showSubscribeBtn" class="subscribe-box">
|
||||
<u-icon name="bell-fill" color="var(--ui-BG-Main)" size="44"></u-icon>
|
||||
<view class="info">获取实时审核结果</view>
|
||||
<view class="sub-btn" @tap="subscribeMessage">立即订阅</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
<view class="form-box">
|
||||
<form-avatar v-model="form.avatar"></form-avatar>
|
||||
</view>
|
||||
|
||||
<view class="form-box">
|
||||
<view class="form-item">
|
||||
<view class="label">昵称</view>
|
||||
<u-input input-align="right" placeholder="请输入昵称" v-model="form.nickname" />
|
||||
</view>
|
||||
<form-sex v-model="form.sex"></form-sex>
|
||||
<view class="form-item">
|
||||
<view class="label">年龄</view>
|
||||
<u-input input-align="right" placeholder="请输入年龄" type="number" v-model="form.age" />
|
||||
</view>
|
||||
<view class="form-item" v-if="isPass">
|
||||
<view class="label">微信</view>
|
||||
<u-input input-align="right" placeholder="请输入您的微信" v-model="form.weixin" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="label">手机号</view>
|
||||
<u-input input-align="right" placeholder="请输入手机号" type="number" v-model="form.mobile" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="label">自我介绍</view>
|
||||
<u-input input-align="right" placeholder="请输入自我介绍" v-model="form.intro" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="label">所在城市</view>
|
||||
<u-input input-align="right" placeholder="请输入所在城市" v-model="form.city" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-box">
|
||||
<form-image :number="6" v-model="imgList"></form-image>
|
||||
</view>
|
||||
|
||||
<view class="form-box">
|
||||
<form-voice @sec="toSec" v-model="form.sound"></form-voice>
|
||||
</view>
|
||||
|
||||
<view class="check-box" @click="changeCheck">
|
||||
<u-icon size="44" v-if="check" name="checkmark-circle-fill" color="var(--ui-BG-Main)"></u-icon>
|
||||
<u-icon size="44" v-else name="checkmark-circle" color="var(--ui-BG-Main)"></u-icon>
|
||||
<text class="info">我已阅读并接受</text>
|
||||
<text @tap.stop="toAggre()" class="sub-btn">《达人申请协议》</text>
|
||||
</view>
|
||||
|
||||
<view class="submit-box">
|
||||
<view class="sub-btn" @click="saveApply">提交申请</view>
|
||||
</view>
|
||||
|
||||
<s-menu-tools />
|
||||
<s-auth-modal />
|
||||
<qrcode-modal />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormAvatar from '@/pages/clerk/apply/components/formAvatar.vue';
|
||||
import FormSex from '@/pages/clerk/apply/components/formSex.vue';
|
||||
import FormVoice from '@/pages/clerk/apply/components/formVoice.vue';
|
||||
import FormImage from '@/pages/clerk/apply/components/formImage.vue';
|
||||
import qrcodeModal from '@/components/qrcode-modal/qrcode-modal.vue';
|
||||
import ClerkApi from '@/sheep/api/worker/clerk';
|
||||
import test from '@/sheep/helper/test.js';
|
||||
import { WxaSubscribeTemplate } from '@/sheep/util/const';
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
FormAvatar,
|
||||
FormSex,
|
||||
FormVoice,
|
||||
FormImage,
|
||||
qrcodeModal,
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
avatar: '',
|
||||
nickname: '',
|
||||
sex: '',
|
||||
age: '',
|
||||
weixin: '',
|
||||
mobile: '',
|
||||
experience: '',
|
||||
intro: '',
|
||||
city: '',
|
||||
albums: '',
|
||||
sound: '',
|
||||
soundTime: '',
|
||||
},
|
||||
imgList: [],
|
||||
|
||||
showSubscribeBtn: false,
|
||||
|
||||
check: true,
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef MP
|
||||
// 订阅只能由用户主动触发,只能包一层 showModal 诱导用户点击
|
||||
this.autoSubscribeMessage();
|
||||
// #endif
|
||||
},
|
||||
computed: {
|
||||
isPass() {
|
||||
return sheep.$store('user').tradeConfig.weixinEnabled;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveApply() {
|
||||
// #ifdef MP
|
||||
// 订阅只能由用户主动触发,只能包一层 showModal 诱导用户点击
|
||||
this.autoSubscribeMessage();
|
||||
// #endif
|
||||
|
||||
if(!this.form.avatar){
|
||||
sheep.$helper.toast('请上传头像');
|
||||
return;
|
||||
}
|
||||
if(!this.form.nickname){
|
||||
sheep.$helper.toast('请输入昵称');
|
||||
return;
|
||||
}
|
||||
if(!this.form.sex){
|
||||
sheep.$helper.toast('请选择性别');
|
||||
return;
|
||||
}
|
||||
if(!this.form.age){
|
||||
sheep.$helper.toast('请输入年龄');
|
||||
return;
|
||||
}
|
||||
if(this.form.age < 18){
|
||||
sheep.$helper.toast('未成年禁止申请');
|
||||
return;
|
||||
}
|
||||
if(this.isPass && !this.form.weixin){
|
||||
sheep.$helper.toast('请输入正确的微信号');
|
||||
return;
|
||||
}
|
||||
if(!this.form.mobile || !test.mobile(this.form.mobile)){
|
||||
sheep.$helper.toast('请输入正确的手机号');
|
||||
return;
|
||||
}
|
||||
if(!this.form.intro){
|
||||
sheep.$helper.toast('请输入自我介绍');
|
||||
return;
|
||||
}
|
||||
if(!this.form.city){
|
||||
sheep.$helper.toast('请输入所在城市');
|
||||
return;
|
||||
}
|
||||
if(this.imgList.length < 1){
|
||||
sheep.$helper.toast('请上传图片');
|
||||
return;
|
||||
}
|
||||
if(this.imgList.length < 1){
|
||||
sheep.$helper.toast('请上传图片');
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this.check){
|
||||
sheep.$helper.toast('未同意协议');
|
||||
return;
|
||||
}
|
||||
|
||||
this.form.albums = this.imgList.join(',');
|
||||
ClerkApi.createClerkApply(this.form).then((res) => {
|
||||
if(res.data){
|
||||
sheep.$router.go('/pages/worker/levelList/index', {id: res.data});
|
||||
}
|
||||
});
|
||||
},
|
||||
toSec(e) {
|
||||
this.form.soundTime = e;
|
||||
},
|
||||
subscribeMessage() {
|
||||
const event = [WxaSubscribeTemplate.CLERK_APPLY_SUCCESS];
|
||||
event.push(WxaSubscribeTemplate.CLERK_BLIND);
|
||||
event.push(WxaSubscribeTemplate.CLERK_ORDER);
|
||||
sheep.$platform.useProvider('wechat').subscribeMessage(event, () => {
|
||||
// 订阅后记录一下订阅状态
|
||||
uni.removeStorageSync(WxaSubscribeTemplate.CLERK_APPLY_SUCCESS);
|
||||
uni.setStorageSync(WxaSubscribeTemplate.CLERK_APPLY_SUCCESS, '已订阅');
|
||||
// 隐藏订阅按钮
|
||||
this.showSubscribeBtn = false;
|
||||
});
|
||||
},
|
||||
async autoSubscribeMessage() {
|
||||
// 1. 校验是否手动订阅过
|
||||
const subscribeBtnStatus = uni.getStorageSync(WxaSubscribeTemplate.CLERK_APPLY_SUCCESS);
|
||||
if (!subscribeBtnStatus) {
|
||||
this.showSubscribeBtn = true;
|
||||
}
|
||||
|
||||
// 2. 订阅消息
|
||||
this.subscribeMessage();
|
||||
},
|
||||
changeCheck() {
|
||||
if(this.check){
|
||||
this.check = false;
|
||||
}else{
|
||||
this.check = true;
|
||||
}
|
||||
},
|
||||
toAggre() {
|
||||
sheep.$router.go('/pages/public/richtext', {title: '店员申请协议'})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-app {
|
||||
background-color: #fafafa;
|
||||
padding-bottom: 140rpx;
|
||||
}
|
||||
.form-box {
|
||||
background-color: #fff;
|
||||
margin: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 15px;
|
||||
|
||||
.label {
|
||||
font-size: 30rpx;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.submit-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 140rpx;
|
||||
padding: 0 15px;
|
||||
z-index: 99;
|
||||
|
||||
.sub-btn {
|
||||
background-color: var(--ui-BG-Main);
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
border-radius: 40px;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.subscribe-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
|
||||
.info {
|
||||
margin: 0 10rpx;
|
||||
}
|
||||
|
||||
.sub-btn {
|
||||
color: var(--ui-BG-Main);
|
||||
}
|
||||
}
|
||||
|
||||
.check-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
|
||||
.info{
|
||||
margin: 0 10rpx;
|
||||
}
|
||||
|
||||
.sub-btn {
|
||||
color: var(--ui-BG-Main);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
225
pages/clerk/detail/components/detail-navbar.vue
Normal file
225
pages/clerk/detail/components/detail-navbar.vue
Normal file
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<su-fixed alway :bgStyles="{ background: '#fff' }" :val="0" noNav opacity :placeholder="false">
|
||||
<su-status-bar />
|
||||
<view
|
||||
class="ui-bar ss-flex ss-col-center ss-row-between ss-p-x-20"
|
||||
:style="[{ height: sys_navBar - sys_statusBar + 'px' }]"
|
||||
>
|
||||
<!-- 左 -->
|
||||
<view class="icon-box ss-flex">
|
||||
<view class="icon-button icon-button-left ss-flex ss-row-center" @tap="onClickLeft">
|
||||
<text :class="tabOpacityVal > 0.4 ? 'black' : ''" class="sicon-back" v-if="hasHistory" />
|
||||
<text :class="tabOpacityVal > 0.4 ? 'black' : ''" class="sicon-home" v-else />
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="icon-button icon-button-right ss-flex ss-row-center" @tap="onClickRight">
|
||||
<text :class="tabOpacityVal > 0.4 ? 'black' : ''" class="sicon-more" />
|
||||
</view>
|
||||
</view>
|
||||
<!-- 中 -->
|
||||
<view class="detail-tab-card ss-flex-1" :style="[{ opacity: tabOpacityVal }]">
|
||||
<view class="tab-box ss-flex ss-col-center ss-row-around">
|
||||
<view
|
||||
class="tab-item ss-flex-1 ss-flex ss-row-center ss-col-center"
|
||||
v-for="item in tabList"
|
||||
:key="item.value"
|
||||
@tap="onTab(item)"
|
||||
>
|
||||
<view class="tab-title" :class="currentTab === item.value ? 'cur-tab-title' : ''">
|
||||
{{ item.label }}
|
||||
</view>
|
||||
<view v-show="currentTab === item.value" class="tab-line"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef MP -->
|
||||
<view :style="[capsuleStyle]"></view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</su-fixed>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import sheep from '@/sheep';
|
||||
import { showMenuTools, closeMenuTools } from '@/sheep/hooks/useModal';
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
//滚动条滚动距离
|
||||
scrollTop: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sys_navBar: sheep.$platform.navbar,
|
||||
sys_statusBar: sheep.$platform.device.statusBarHeight,
|
||||
hasHistory: sheep.$router.hasHistory(),
|
||||
tabList: [
|
||||
{
|
||||
label: '价格',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '动态',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '评价',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
capsuleStyle: {
|
||||
width: sheep.$platform.capsule.width + 'px',
|
||||
height: sheep.$platform.capsule.height + 'px',
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tabOpacityVal() {
|
||||
return this.scrollTop > sheep.$platform.navbar ? 1 : this.scrollTop * 0.01;;
|
||||
},
|
||||
currentTab() {
|
||||
return sheep.$store('sys').clerkTabIndex;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onClickLeft() {
|
||||
if (this.hasHistory) {
|
||||
sheep.$router.back();
|
||||
} else {
|
||||
sheep.$router.go('/pages/tabbar/index');
|
||||
}
|
||||
},
|
||||
onClickRight() {
|
||||
showMenuTools();
|
||||
},
|
||||
onTab(e) {
|
||||
this.$emit('onTab', e.value);
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icon-box {
|
||||
box-shadow: 0px 0px 4rpx rgba(51, 51, 51, 0.08), 0px 4rpx 6rpx 2rpx rgba(102, 102, 102, 0.12);
|
||||
border-radius: 30rpx;
|
||||
width: 134rpx;
|
||||
height: 56rpx;
|
||||
margin-left: 8rpx;
|
||||
border: 1px solid rgba(#fff, 0.4);
|
||||
.line {
|
||||
width: 2rpx;
|
||||
height: 24rpx;
|
||||
background: #e5e5e7;
|
||||
}
|
||||
.sicon-back {
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.sicon-home {
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.sicon-more {
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.black {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
width: 67rpx;
|
||||
height: 56rpx;
|
||||
&-left:hover {
|
||||
background: rgba(0, 0, 0, 0.16);
|
||||
border-radius: 30rpx 0px 0px 30rpx;
|
||||
}
|
||||
&-right:hover {
|
||||
background: rgba(0, 0, 0, 0.16);
|
||||
border-radius: 0px 30rpx 30rpx 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.left-box {
|
||||
position: relative;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.circle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
background: rgba(#fff, 0.6);
|
||||
border: 1rpx solid #ebebeb;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
position: relative;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.circle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
background: rgba(#ffffff, 0.6);
|
||||
border: 1rpx solid #ebebeb;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
.detail-tab-card {
|
||||
width: 50%;
|
||||
.tab-item {
|
||||
height: 80rpx;
|
||||
position: relative;
|
||||
z-index: 11;
|
||||
|
||||
.tab-title {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.cur-tab-title {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
.tab-line {
|
||||
width: 60rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 6rpx;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 10rpx;
|
||||
background-color: var(--ui-BG-Main);
|
||||
z-index: 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
150
pages/clerk/detail/components/gameBox.vue
Normal file
150
pages/clerk/detail/components/gameBox.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="option-box">
|
||||
<view class="tag-box">
|
||||
<u-icon name="tags" color="#f6f6f6" size="34"></u-icon>
|
||||
<view class="name">服务类型</view>
|
||||
</view>
|
||||
<view class="span-box">
|
||||
<view @click="changeGame(option)" class="span" :class="catId == option.id ? 'active': '' " v-for="(option,t) in optionList">{{option.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="option-box" v-if="categoryList.length > 0">
|
||||
<view class="tag-box">
|
||||
<u-icon name="tags" color="#f6f6f6" size="34"></u-icon>
|
||||
<view class="name">选项</view>
|
||||
</view>
|
||||
<view class="span-box">
|
||||
<view @click="changeCategory(option)" class="span" :class="gameId == option.id ? 'active': '' " v-for="(option,t) in categoryList">{{option.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="option-box" v-if="goodsList.length > 0">
|
||||
<view class="tag-box">
|
||||
<u-icon name="tags" color="#f6f6f6" size="34"></u-icon>
|
||||
<view class="name">选项</view>
|
||||
</view>
|
||||
<view class="span-box">
|
||||
<view @click="changeGoods(option)" class="span" :class="goodsId == option.id ? 'active': '' " v-for="(option,t) in goodsList">{{option.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
optionList: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
catId: -1,
|
||||
gameId: -1,
|
||||
goodsId: -1,
|
||||
categoryList: [],
|
||||
goodsList: [],
|
||||
goodsList: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeGame(e) {
|
||||
this.gameId = -1;
|
||||
this.goodsId = -1;
|
||||
|
||||
this.catId = e.id;
|
||||
if(e.categoryList){
|
||||
this.goodsList = [];
|
||||
this.categoryList = e.categoryList;
|
||||
}else{
|
||||
this.categoryList = [];
|
||||
this.goodsList = e.goodsList;
|
||||
}
|
||||
|
||||
var node = {
|
||||
catId: this.catId,
|
||||
gameId: this.gameId,
|
||||
goodsId: this.goodsId,
|
||||
price: 0,
|
||||
}
|
||||
this.$emit('update:modelValue', node);
|
||||
},
|
||||
changeCategory(e) {
|
||||
this.goodsId = -1;
|
||||
this.gameId = e.id;
|
||||
this.goodsList = e.goodsList;
|
||||
|
||||
var node = {
|
||||
catId: this.catId,
|
||||
gameId: this.gameId,
|
||||
goodsId: this.goodsId,
|
||||
price: 0,
|
||||
}
|
||||
this.$emit('update:modelValue', node);
|
||||
},
|
||||
changeGoods(e) {
|
||||
this.goodsId = e.id;
|
||||
var node = {
|
||||
catId: this.catId,
|
||||
gameId: this.gameId,
|
||||
goodsId: this.goodsId,
|
||||
price: e.price,
|
||||
}
|
||||
this.$emit('update:modelValue', node);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.option-box {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.tag-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.span-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
|
||||
.span {
|
||||
background-color: #f6f6f6;
|
||||
padding: 14rpx 20rpx;
|
||||
border-radius: 40px;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 12px;
|
||||
min-width: 140rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #949494;
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--ui-BG-Main);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
316
pages/clerk/detail/components/giftList.vue
Normal file
316
pages/clerk/detail/components/giftList.vue
Normal file
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<view v-show="showPop" class="gift-box">
|
||||
<scroll-view style="height: 100%;" scroll-y>
|
||||
<view class="top-box">
|
||||
<view class="title">选择礼物</view>
|
||||
<view class="btn-box" @click="close">
|
||||
<u-icon name="close"></u-icon>
|
||||
<view class="text">取消</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list-box">
|
||||
<view v-for="(item,index) in dataList" class="gift" @click="sendGift(item)">
|
||||
<view class="img-box">
|
||||
<img class="img" :src="item.img"></img>
|
||||
<view class="tag" v-if="item.giftType == 1">
|
||||
<text>特效</text>
|
||||
<text v-if="item.tag">·{{item.tag}}</text>
|
||||
</view>
|
||||
<view class="tag" v-if="item.giftType == 0 && item.tag">
|
||||
<text>{{item.tag}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="name">{{item.name}}</view>
|
||||
<view class="price">{{ fen2yuan(item.money) }} 钻石</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="svga-box" :class="giftFlag ? 'svga-show': 'svga-hide'">
|
||||
<c-svga ref="cSvgaRef" :canvasId='canvasId' :src="src" :loops='0' :auto-play="false" @frame='onFrame' @finished='onFinished' @percentage='onPercentage' @loaded='onLoaded'></c-svga>
|
||||
<view class="close-btn">
|
||||
<view class="bottom-box">
|
||||
<view class="title">{{gift.name}}</view>
|
||||
<view class="price">{{ fen2yuan(gift.money) }} 钻石</view>
|
||||
<view class="btn-box">
|
||||
<view class="btn" @click="cannel">取消</view>
|
||||
<view class="btn active" @click="ok">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
showPop: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
},
|
||||
emits: ["close", "update:modelValue"],
|
||||
data() {
|
||||
return {
|
||||
giftFlag: false,
|
||||
src: '',
|
||||
canvasId: 'myCanvas2',
|
||||
|
||||
gift: {},
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.$emit('close');
|
||||
},
|
||||
sendGift(e) {
|
||||
this.gift = e;
|
||||
|
||||
if(e.giftType == 0){
|
||||
// 普通礼物不播放
|
||||
this.close();
|
||||
this.$emit('update:modelValue', this.gift);
|
||||
return;
|
||||
}
|
||||
|
||||
this.src = e.pic;
|
||||
this.giftFlag = true;
|
||||
},
|
||||
onFinished() {
|
||||
this.giftFlag = false;
|
||||
console.log('动画停止播放时回调');
|
||||
},
|
||||
onFrame(frame) {//动画播放至某帧后回调
|
||||
// console.log(frame);
|
||||
},
|
||||
onPercentage(percentage) { //动画播放至某进度后回调
|
||||
// console.log(percentage);
|
||||
},
|
||||
onLoaded() {
|
||||
this.$refs.cSvgaRef.call('setContentMode', 'AspectFill');
|
||||
console.log('加载完成');
|
||||
this.$refs.cSvgaRef.call('startAnimation');
|
||||
},
|
||||
closeSvga() {
|
||||
this.src = "";
|
||||
this.$refs.cSvgaRef.call('stopAnimation');
|
||||
this.giftFlag = false;
|
||||
},
|
||||
fen2yuan(price) {
|
||||
var f = 0;
|
||||
var p = (price / 100.0).toFixed(0);
|
||||
var p1 = (price / 100.0).toFixed(1);
|
||||
var p2 = (price / 100.0).toFixed(2);
|
||||
if(p*100 == price){
|
||||
f = 0;
|
||||
}else if(p1*100 == price){
|
||||
f = 1;
|
||||
}else if(p2*100 == price){
|
||||
f = 2;
|
||||
}
|
||||
return (price / 100.0).toFixed(f)
|
||||
},
|
||||
cannel() {
|
||||
this.closeSvga();
|
||||
},
|
||||
ok() {
|
||||
this.closeSvga();
|
||||
this.close();
|
||||
this.$emit('update:modelValue', this.gift);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gift-box {
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
top: 200rpx;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 9999;
|
||||
padding: 15px;
|
||||
border-top-right-radius: 20rpx;
|
||||
border-top-left-radius: 20rpx;
|
||||
padding-bottom: 0;
|
||||
|
||||
.top-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
top: 200rpx;
|
||||
padding: 0 15px;
|
||||
border-top-right-radius: 20rpx;
|
||||
border-top-left-radius: 20rpx;
|
||||
height: 110rpx;
|
||||
z-index: 1;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
background-color: var(--ui-BG-Main);
|
||||
padding: 7px 15px;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
|
||||
.text {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 60rpx;
|
||||
|
||||
.gift {
|
||||
width: 25%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 20rpx 0px;
|
||||
|
||||
.img-box {
|
||||
position: relative;
|
||||
|
||||
.img{
|
||||
max-width: 160rpx;
|
||||
height: 160rpx;
|
||||
}
|
||||
|
||||
.tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 16rpx;
|
||||
color: #fff;
|
||||
background-color: var(--ui-BG-Main);
|
||||
border-radius: 40px;
|
||||
padding: 2rpx 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
max-width: 160rpx;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 20rpx;
|
||||
color: var(--ui-BG-Main);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.svga-box {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 999999999;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
|
||||
.close-btn {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
z-index: 999999999;
|
||||
padding: 5px 10px;
|
||||
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 100rpx;
|
||||
|
||||
.bottom-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
|
||||
.btn {
|
||||
border: 1px solid #fff;
|
||||
font-size: 28rpx;
|
||||
padding: 20rpx 110rpx;
|
||||
border-radius: 40px;
|
||||
margin: 15px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.active {
|
||||
border: 1px solid var(--ui-BG-Main);
|
||||
background-color: var(--ui-BG-Main);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.svga-hide {
|
||||
/* #ifdef MP */
|
||||
transform: translate(-100%, 0);
|
||||
/* #endif */
|
||||
|
||||
/* #ifndef MP */
|
||||
display: none;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.svga-show {
|
||||
/* #ifdef MP */
|
||||
transform: translate(0, 0);
|
||||
/* #endif */
|
||||
|
||||
/* #ifndef MP */
|
||||
display: block;
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
444
pages/clerk/detail/components/giftPopup.vue
Normal file
444
pages/clerk/detail/components/giftPopup.vue
Normal file
@@ -0,0 +1,444 @@
|
||||
<template>
|
||||
<tui-bottom-popup :zIndex="1002" :maskZIndex="1001" :show="popupShow" @close="hiddenPopup">
|
||||
<view class="order-box">
|
||||
<view class="avatar-box">
|
||||
<u-image width="140" height="140" border-radius="20" :src="clerk.avatar"></u-image>
|
||||
<view class="close-span" @click="hiddenPopup">
|
||||
<u-icon name="close-circle" color="#98a2a1" size="50"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view style="height: 700rpx;" scroll-y>
|
||||
<view class="page-box">
|
||||
|
||||
<view class="form-box">
|
||||
|
||||
<view class="input-box">
|
||||
<view class="tag-box">
|
||||
<view class="name">服务类型</view>
|
||||
</view>
|
||||
<view class="tab-span">
|
||||
<!-- <view @click="changeTab(0)" class="btn" :class="form.rewardType == 0 ? 'active' : ''">赠送</view> -->
|
||||
<view @click="changeTab(1)" class="btn" :class="form.rewardType == 1 ? 'active' : ''">赠礼</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="input-box" v-if="form.rewardType == 0">
|
||||
<view class="tag-box">
|
||||
<view class="name">打赏金额</view>
|
||||
</view>
|
||||
<view class="input-span">
|
||||
<u-input v-model="payMoney" type="number" :placeholder-style="`fontSize: 24rpx; color: #cbced5;`" placeholder="请输入赠送金额"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="input-box" v-if="form.rewardType == 1">
|
||||
<view class="tag-box">
|
||||
<view class="name">赠送礼物</view>
|
||||
</view>
|
||||
<view class="select-span" @click="openGift">
|
||||
<view v-if="gift.id > 0">已选【{{gift.name}}】</view>
|
||||
<view v-else>点击选择礼物</view>
|
||||
<u-icon name="arrow-right"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="input-box" v-if="gift.id > 0">
|
||||
<view class="tag-box">
|
||||
<view class="name">礼物数量</view>
|
||||
</view>
|
||||
<view class="step-span">
|
||||
<img class="img" :src="gift.img"></img>
|
||||
<tui-numberbox iconBgColor="var(--ui-BG-Main)" iconColor="#fff" backgroundColor="#fff" :min="1" :value="form.count" @change="change"></tui-numberbox>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="input-box">
|
||||
<view class="textarea-box">
|
||||
<view class="name">心动留言</view>
|
||||
</view>
|
||||
<view class="textarea-span">
|
||||
<u-input v-model="form.msg" type="textarea" :placeholder-style="`fontSize: 24rpx; color: #cbced5;`" placeholder="请输入心动留言"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="input-box" v-if="isPass">
|
||||
<view class="tag-box">
|
||||
<view class="name">您的微信号</view>
|
||||
</view>
|
||||
<view class="input-span">
|
||||
<u-input v-model="form.weixin" :placeholder-style="`fontSize: 24rpx; color: #cbced5;`" placeholder="请输入正确的微信号"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="bottom-box2" v-if="form.rewardType == 0">
|
||||
<view class="btn-box">
|
||||
<view class="pay-btn" @click="confirm">立即赠送</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom-box" v-if="form.rewardType == 1">
|
||||
<view class="price-box">
|
||||
<text>总价:</text>
|
||||
<text class="price">{{ fen2yuan(gift.money*form.count) }}</text>
|
||||
<text>钻石</text>
|
||||
</view>
|
||||
<view class="btn-box">
|
||||
<view class="pay-btn" @click="confirm">立即赠送</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</tui-bottom-popup>
|
||||
|
||||
<gift-list :showPop="giftFlag" :dataList="giftList" v-model="gift" @close="closeGift"></gift-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tuiBottomPopup from "@/components/thorui/tui-bottom-popup/tui-bottom-popup.vue"
|
||||
import tuiNumberbox from "@/components/thorui/tui-numberbox/tui-numberbox.vue"
|
||||
import GiftList from '@/pages/clerk/detail/components/giftList.vue';
|
||||
import RewardApi from '@/sheep/api/worker/reward';
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
tuiBottomPopup,
|
||||
tuiNumberbox,
|
||||
GiftList,
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
popupShow: false,
|
||||
|
||||
gift: {
|
||||
id: -1,
|
||||
money: 0,
|
||||
},
|
||||
|
||||
giftFlag: false,
|
||||
|
||||
giftList: [],
|
||||
|
||||
payMoney: '',
|
||||
|
||||
form: {
|
||||
rewardType: 1,
|
||||
count: 1,
|
||||
giftId: -1,
|
||||
money: '',
|
||||
weixin: '',
|
||||
msg: '',
|
||||
payMoney: '',
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
clerk() {
|
||||
return sheep.$store('sys').clerk;
|
||||
},
|
||||
userInfo() {
|
||||
return sheep.$store('user').userInfo;
|
||||
},
|
||||
isPass() {
|
||||
return sheep.$store('user').tradeConfig.weixinEnabled;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
//调用此方法显示弹层
|
||||
showPopup() {
|
||||
this.form.weixin = this.userInfo.weixin;
|
||||
RewardApi.getGiftList().then(res => {
|
||||
this.giftList = res.data;
|
||||
this.popupShow = true
|
||||
});
|
||||
},
|
||||
showGiftPopup(e) {
|
||||
this.gift = e;
|
||||
this.form.rewardType = 1;
|
||||
this.form.weixin = this.userInfo.weixin;
|
||||
RewardApi.getGiftList().then(res => {
|
||||
this.giftList = res.data;
|
||||
this.popupShow = true
|
||||
});
|
||||
},
|
||||
hiddenPopup() {
|
||||
this.popupShow = false
|
||||
},
|
||||
change(e) {
|
||||
this.form.count = e.value
|
||||
},
|
||||
changeTab(e) {
|
||||
this.form.rewardType = e;
|
||||
this.gift = {
|
||||
id: -1,
|
||||
money: 0,
|
||||
};
|
||||
},
|
||||
fen2yuan(price) {
|
||||
var f = 0;
|
||||
var p = (price / 100.0).toFixed(0);
|
||||
var p1 = (price / 100.0).toFixed(1);
|
||||
var p2 = (price / 100.0).toFixed(2);
|
||||
if(p*100 == price){
|
||||
f = 0;
|
||||
}else if(p1*100 == price){
|
||||
f = 1;
|
||||
}else if(p2*100 == price){
|
||||
f = 2;
|
||||
}
|
||||
return (price / 100.0).toFixed(f)
|
||||
},
|
||||
yuan2fen(price) {
|
||||
return (price * 100.0).toFixed(0)
|
||||
},
|
||||
openGift() {
|
||||
this.giftFlag = true;
|
||||
},
|
||||
closeGift() {
|
||||
this.form.count = 1;
|
||||
this.giftFlag = false;
|
||||
},
|
||||
confirm() {
|
||||
if(this.isPass && !this.form.weixin){
|
||||
sheep.$helper.toast('请输入正确的微信');
|
||||
return;
|
||||
}
|
||||
if(this.form.rewardType == 0){
|
||||
this.form.payMoney = this.yuan2fen(this.payMoney);
|
||||
if(this.form.payMoney < 1){
|
||||
sheep.$helper.toast('请输入打赏金额');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
this.form.giftId = this.gift.id;
|
||||
if(this.form.giftId < 1){
|
||||
sheep.$helper.toast('请选择打赏礼物');
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.form.workerClerkId = this.clerk.id;
|
||||
RewardApi.createRewardOrder(this.form).then(res => {
|
||||
// 跳转到支付页面
|
||||
this.$u.route({
|
||||
url: 'pages/pay/reward/index',
|
||||
params: {
|
||||
id: res.data.payOrderId,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.avatar-box {
|
||||
padding: 10px 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.close-span {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.page-box {
|
||||
padding: 15px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
.form-box {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.tag-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 180rpx;
|
||||
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.textarea-box {
|
||||
height: 20px;
|
||||
display: flex;
|
||||
width: 180rpx;
|
||||
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-box {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
align-items: center;
|
||||
|
||||
.input-span {
|
||||
background-color: #f6f6f6;
|
||||
margin-left: 15px;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding: 0 12px;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.select-span {
|
||||
font-size: 24rpx;
|
||||
background-color: #f6f6f6;
|
||||
margin-left: 15px;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding: 12px 12px;
|
||||
border-radius: 10rpx;
|
||||
color: #aaaaaa;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.tab-span {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding: 0 12px;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
background-color: #f6f6f6;
|
||||
font-size: 24rpx;
|
||||
padding: 7px 0;
|
||||
border-radius: 40px;
|
||||
min-width: 120rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #fff;
|
||||
background-color: var(--ui-BG-Main);
|
||||
}
|
||||
}
|
||||
|
||||
.textarea-span {
|
||||
background-color: #f6f6f6;
|
||||
margin-left: 15px;
|
||||
flex: 1;
|
||||
padding: 2px 12px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.step-span {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
padding-left: 12px;
|
||||
align-items: center;
|
||||
|
||||
.img {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 100%;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
box-shadow: 0 0 6px 0 #ccc;
|
||||
|
||||
.price-box {
|
||||
color: #fb932c;
|
||||
font-size: 28rpx;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.price {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
width: 50%;
|
||||
padding-left: 15px;
|
||||
|
||||
.pay-btn {
|
||||
background-color: var(--ui-BG-Main);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 40px;
|
||||
font-size: 28rpx;
|
||||
height: 70rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bottom-box2 {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
box-shadow: 0 0 6px 0 #ccc;
|
||||
|
||||
.price-box {
|
||||
color: #fb932c;
|
||||
font-size: 28rpx;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.price {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
width: 50%;
|
||||
|
||||
.pay-btn {
|
||||
background-color: var(--ui-BG-Main);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 40px;
|
||||
font-size: 28rpx;
|
||||
height: 70rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
263
pages/clerk/detail/components/layout.vue
Normal file
263
pages/clerk/detail/components/layout.vue
Normal file
@@ -0,0 +1,263 @@
|
||||
<!-- 虚拟列表演示(不使用内置列表)(vue) -->
|
||||
<!-- 写法较简单,在页面中对当前需要渲染的虚拟列表数据进行for循环,在vue3中兼容性良好 -->
|
||||
<!-- 在各平台兼容性请查阅https://z-paging.zxlee.cn/module/virtual-list.html -->
|
||||
<template>
|
||||
<view class="content">
|
||||
<!-- 如果页面中的cell高度是固定不变的,则不需要设置cell-height-mode,如果页面中高度是动态改变的,则设置cell-height-mode="dynamic" -->
|
||||
<!-- 原先的v-model修改为@virtualListChange="virtualListChange"并赋值处理后的虚拟列表 -->
|
||||
<z-paging ref="paging" :show-loading-more-no-more-view="showLoad" :show-default-loading-more-text="showLoad" use-virtual-list :force-close-inner-list="true" :paging-style="{ paddingTop: 0 + 'px', paddingBottom: paddingBottom + 'rpx' }" cell-height-mode="dynamic" @scroll="scroll" @virtualListChange="virtualListChange" @query="queryList">
|
||||
<!-- 需要固定在顶部不滚动的view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot="top" -->
|
||||
<template #top>
|
||||
<nav-bar :title="title" :scrollTop="scrollTop" @onTab="change" @initNav="initNav"></nav-bar>
|
||||
</template>
|
||||
|
||||
<view>
|
||||
<user-box :clerk="clerk" :clerkLevel="clerk.clerkLevel" :paddingTop="paddingTop"></user-box>
|
||||
<sticky-box :clerk="clerk" @change="change"></sticky-box>
|
||||
</view>
|
||||
|
||||
<!-- :id="`zp-id-${item.zp_index}`"和:key="item.zp_index" 必须写,必须写!!!! -->
|
||||
<!-- 这里for循环的index不是数组中真实的index了,请使用item.zp_index获取真实的index -->
|
||||
<view class="data-box">
|
||||
<star-list v-if="currentTab == 0" @openGift="openGift" :clerk="clerk" :virtualList="giftList"></star-list>
|
||||
<price-list v-if="currentTab == 1" :clerk="clerk"></price-list>
|
||||
<post-list v-if="currentTab == 2" :virtualList="virtualList"></post-list>
|
||||
<rate-list v-if="currentTab == 3" :clerk="clerk" :virtualList="virtualList"></rate-list>
|
||||
</view>
|
||||
|
||||
<template #bottom>
|
||||
<view v-if="isGift" class="bottom-box">
|
||||
<view class="order" @click="doOrder">立即下单</view>
|
||||
<view class="gift" @click="doGift">赠礼</view>
|
||||
</view>
|
||||
<view v-else class="bottom-box">
|
||||
<view class="order-btn" @click="doOrder">立即下单</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</z-paging>
|
||||
|
||||
<order-popup ref="orderPopup"></order-popup>
|
||||
|
||||
<gift-popup ref="giftPopup"></gift-popup>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserBox from '@/pages/clerk/detail/components/userBox.vue';
|
||||
import StickyBox from '@/pages/clerk/detail/components/stickyBox.vue';
|
||||
import StarList from '@/pages/clerk/detail/components/starList.vue';
|
||||
import PriceList from '@/pages/clerk/detail/components/priceList.vue';
|
||||
import PostList from '@/pages/clerk/detail/components/postList.vue';
|
||||
import RateList from '@/pages/clerk/detail/components/rateList.vue';
|
||||
import NavBar from '@/pages/clerk/detail/components/navBar.vue';
|
||||
import OrderPopup from '@/pages/clerk/detail/components/orderPopup.vue';
|
||||
import GiftPopup from '@/pages/clerk/detail/components/giftPopup.vue';
|
||||
import UserApi from '@/sheep/api/member/user';
|
||||
import ClerkApi from '@/sheep/api/worker/clerk';
|
||||
import TrendApi from '@/sheep/api/worker/trend';
|
||||
import RewardApi from '@/sheep/api/worker/reward';
|
||||
import CommentApi from '@/sheep/api/product/comment';
|
||||
import { showAuthModal } from '@/sheep/hooks/useModal';
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
UserBox,
|
||||
StickyBox,
|
||||
StarList,
|
||||
PriceList,
|
||||
PostList,
|
||||
RateList,
|
||||
NavBar,
|
||||
OrderPopup,
|
||||
GiftPopup,
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 虚拟列表数组,通过@virtualListChange监听获得最新数组
|
||||
virtualList: [],
|
||||
scrollTop: 0,
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
height: 0,
|
||||
|
||||
clerk: {},
|
||||
workerClerkId: 0,
|
||||
giftList: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentTab() {
|
||||
return sheep.$store('sys').clerkTabIndex;
|
||||
},
|
||||
showLoad() {
|
||||
return sheep.$store('sys').clerkTabIndex > 1;
|
||||
},
|
||||
isLogin: {
|
||||
get() {
|
||||
return sheep.$store('user').isLogin;
|
||||
},
|
||||
},
|
||||
userInfo: {
|
||||
get() {
|
||||
return sheep.$store('user').userInfo;
|
||||
},
|
||||
},
|
||||
isGift() {
|
||||
return sheep.$store('user').tradeConfig.giftEnabled;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
initNav(e) {
|
||||
this.height = e.height;
|
||||
this.paddingTop = this.height;
|
||||
},
|
||||
initData(options) {
|
||||
this.workerClerkId = options.id;
|
||||
ClerkApi.getClerk({
|
||||
id: options.id,
|
||||
userId: this.userInfo.id,
|
||||
}).then(res => {
|
||||
this.clerk = res.data;
|
||||
sheep.$store('sys').setClerk(res.data);
|
||||
});
|
||||
|
||||
RewardApi.getRewardGiftList({
|
||||
workerClerkId: options.id,
|
||||
}).then(res => {
|
||||
this.giftList = res.data;
|
||||
});
|
||||
},
|
||||
scroll(e) {
|
||||
this.scrollTop = e.detail.scrollTop;
|
||||
},
|
||||
// 监听虚拟列表数组改变并赋值给virtualList进行重新渲染
|
||||
virtualListChange(vList) {
|
||||
this.virtualList = vList;
|
||||
},
|
||||
queryList(pageNo, pageSize) {
|
||||
// 组件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
|
||||
// 这里的pageNo和pageSize会自动计算好,直接传给服务器即可
|
||||
// 模拟请求服务器获取分页数据,请替换成自己的网络请求
|
||||
const params = {
|
||||
pageNo: pageNo,
|
||||
pageSize: pageSize,
|
||||
workerClerkId: this.workerClerkId,
|
||||
}
|
||||
|
||||
if(this.currentTab == 0){
|
||||
|
||||
}else if(this.currentTab == 1){
|
||||
|
||||
}else if(this.currentTab == 2){
|
||||
TrendApi.getTrendPage(params).then(res => {
|
||||
// 将请求的结果数组传递给z-paging
|
||||
this.$refs.paging.complete(res.data.list);
|
||||
}).catch(res => {
|
||||
// 如果请求失败写this.$refs.paging.complete(false);
|
||||
// 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
|
||||
// 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
|
||||
this.$refs.paging.complete(false);
|
||||
})
|
||||
}else if(this.currentTab == 3){
|
||||
CommentApi.getCommentPage(this.workerClerkId,pageNo,pageSize,0).then(res => {
|
||||
// 将请求的结果数组传递给z-paging
|
||||
this.$refs.paging.complete(res.data.list);
|
||||
}).catch(res => {
|
||||
// 如果请求失败写this.$refs.paging.complete(false);
|
||||
// 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
|
||||
// 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
|
||||
this.$refs.paging.complete(false);
|
||||
})
|
||||
}
|
||||
},
|
||||
change(e) {
|
||||
sheep.$store('sys').setClerkTabIndex(e);
|
||||
this.scrollTop = 0;
|
||||
this.$refs.paging.reload();
|
||||
},
|
||||
doOrder() {
|
||||
if(this.isLogin){
|
||||
this.$refs.orderPopup.showPopup();
|
||||
}else{
|
||||
showAuthModal();
|
||||
}
|
||||
},
|
||||
doGift() {
|
||||
if(this.isLogin){
|
||||
this.$refs.giftPopup.showPopup();
|
||||
}else{
|
||||
showAuthModal();
|
||||
}
|
||||
},
|
||||
openGift(e) {
|
||||
if(this.isLogin){
|
||||
this.$refs.giftPopup.showGiftPopup(e);
|
||||
}else{
|
||||
showAuthModal();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.data-box {
|
||||
padding: 0 15px;
|
||||
}
|
||||
.bottom-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 10px 30px;
|
||||
box-shadow: 0 0 6px 0 #ccc;
|
||||
|
||||
.order {
|
||||
background-color: var(--ui-BG-Main);
|
||||
padding: 10px;
|
||||
border-top-left-radius: 40px;
|
||||
border-bottom-left-radius: 40px;
|
||||
color: #fff;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.order-btn {
|
||||
background-color: var(--ui-BG-Main);
|
||||
padding: 10px;
|
||||
border-radius: 40px;
|
||||
color: #fff;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.gift {
|
||||
background-color: #eef3f2;
|
||||
padding: 10px;
|
||||
border-top-right-radius: 40px;
|
||||
border-bottom-right-radius: 40px;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
color: #aaa;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
89
pages/clerk/detail/components/navBar.vue
Normal file
89
pages/clerk/detail/components/navBar.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<view>
|
||||
<tui-navigation-bar @init="initNavigation" @change="opacityChange" :scrollTop="scrollTop" backgroundColor="#fff" color="#333">
|
||||
<detailNavbar @onTab="onTab" :scrollTop="scrollTop" />
|
||||
</tui-navigation-bar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tuiNavigationBar from "@/components/thorui/tui-navigation-bar/tui-navigation-bar.vue";
|
||||
import detailNavbar from '@/pages/clerk/detail/components/detail-navbar.vue';
|
||||
export default {
|
||||
components: {
|
||||
tuiNavigationBar,
|
||||
detailNavbar,
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
//滚动条滚动距离
|
||||
scrollTop: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
top: 0, //标题图标距离顶部距离
|
||||
opacity: 0,
|
||||
height: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initNavigation(e) {
|
||||
this.height = e.height;
|
||||
this.opacity = e.opacity;
|
||||
this.top = e.top;
|
||||
this.$emit('initNav', e);
|
||||
},
|
||||
opacityChange(e) {
|
||||
this.opacity = e.opacity;
|
||||
},
|
||||
onTab(e) {
|
||||
this.$emit('onTab', e);
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content-bpx {
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
justify-content: center;
|
||||
|
||||
.left-box {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
position: absolute;
|
||||
width: 100px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
font-size: 15px;
|
||||
font-weight: bolder;
|
||||
color: #1f2122;
|
||||
}
|
||||
|
||||
.set-btn {
|
||||
padding: 0 15px;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
282
pages/clerk/detail/components/orderPopup.vue
Normal file
282
pages/clerk/detail/components/orderPopup.vue
Normal file
@@ -0,0 +1,282 @@
|
||||
<template>
|
||||
<tui-bottom-popup :zIndex="1002" :maskZIndex="1001" :show="popupShow" @close="hiddenPopup">
|
||||
<view class="order-box">
|
||||
<view class="avatar-box">
|
||||
<u-image width="140" height="140" border-radius="20" :src="clerk.avatar"></u-image>
|
||||
<view class="close-span" @click="hiddenPopup">
|
||||
<u-icon name="close-circle" color="#98a2a1" size="50"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view style="height: 700rpx;" scroll-y>
|
||||
<view class="page-box">
|
||||
|
||||
<game-box v-model="game" :optionList="clerk.goodsList"></game-box>
|
||||
|
||||
<view class="form-box">
|
||||
<!-- <view class="input-box">
|
||||
<view class="tag-box">
|
||||
<u-icon name="tags" color="#f6f6f6" size="34"></u-icon>
|
||||
<view class="name">你的微信号</view>
|
||||
</view>
|
||||
<view class="input-span">
|
||||
<u-input placeholder="请输入正确的微信号~"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="input-box">
|
||||
<view class="textarea-box">
|
||||
<u-icon name="tags" color="#f6f6f6" size="34"></u-icon>
|
||||
<view class="name">其它备注</view>
|
||||
</view>
|
||||
<view class="textarea-span">
|
||||
<u-input type="textarea" placeholder="请输入备注内容"></u-input>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<view class="input-box">
|
||||
<view class="tag-box">
|
||||
<u-icon name="tags" color="#f6f6f6" size="34"></u-icon>
|
||||
<view class="name">购买数量</view>
|
||||
</view>
|
||||
<view class="step-span">
|
||||
<tui-numberbox iconBgColor="var(--ui-BG-Main)" iconColor="#fff" backgroundColor="#fff" :min="1" :value="order.num" @change="change"></tui-numberbox>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <view class="input-box">
|
||||
<radio-box style="width: 100%;" v-model="payMethod" :optionList="optionList"></radio-box>
|
||||
</view> -->
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="bottom-box">
|
||||
<view class="price-box">
|
||||
<text>总价:</text>
|
||||
<text class="price">{{ fen2yuan(game.price*order.num) }}</text>
|
||||
<text>钻石</text>
|
||||
</view>
|
||||
<view class="btn-box">
|
||||
<view class="pay-btn" @click="confirm">立即下单</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</tui-bottom-popup>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tuiBottomPopup from "@/components/thorui/tui-bottom-popup/tui-bottom-popup.vue"
|
||||
import tuiNumberbox from "@/components/thorui/tui-numberbox/tui-numberbox.vue"
|
||||
import RadioBox from '@/pages/clerk/detail/components/radioBox.vue';
|
||||
import GameBox from '@/pages/clerk/detail/components/gameBox.vue';
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
tuiBottomPopup,
|
||||
tuiNumberbox,
|
||||
RadioBox,
|
||||
GameBox,
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
popupShow: false,
|
||||
optionList: [
|
||||
{
|
||||
name: '余额支付',
|
||||
value: '0',
|
||||
type: 'number',
|
||||
number: '1000',
|
||||
},
|
||||
{
|
||||
name: '微信支付',
|
||||
value: '1',
|
||||
type: 'icon',
|
||||
},
|
||||
],
|
||||
payMethod: '0',
|
||||
|
||||
game: {
|
||||
goodsId: -1,
|
||||
price: 0,
|
||||
},
|
||||
order: {
|
||||
num: 1,
|
||||
goodsId: -1,
|
||||
price: 0,
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
clerk() {
|
||||
return sheep.$store('sys').clerk;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
//调用此方法显示弹层
|
||||
showPopup() {
|
||||
this.popupShow = true
|
||||
},
|
||||
hiddenPopup() {
|
||||
this.popupShow = false
|
||||
},
|
||||
change(e) {
|
||||
this.order.num = e.value
|
||||
},
|
||||
// 选中某个单选框时,由radio时触发
|
||||
radioChange(e) {
|
||||
// console.log(e);
|
||||
},
|
||||
// 选中任一radio时,由radio-group触发
|
||||
radioGroupChange(e) {
|
||||
// console.log(e);
|
||||
},
|
||||
fen2yuan(price) {
|
||||
return (price / 100.0).toFixed(0)
|
||||
},
|
||||
confirm() {
|
||||
this.order.goodsId = this.game.goodsId,
|
||||
this.order.price = this.game.price*this.order.num
|
||||
if(this.order.goodsId < 0) {
|
||||
sheep.$helper.toast('请选择商品');
|
||||
return;
|
||||
}
|
||||
var data = {
|
||||
"clerkId": this.clerk.id,
|
||||
'items' : [{"skuId": this.order.goodsId, "count": this.order.num}]
|
||||
}
|
||||
this.$u.route({
|
||||
url: 'pages/order/worker/confirm',
|
||||
params: {
|
||||
data: JSON.stringify(data),
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.avatar-box {
|
||||
padding: 10px 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.close-span {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.page-box {
|
||||
padding: 15px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
.form-box {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.tag-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 200rpx;
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.textarea-box {
|
||||
height: 20px;
|
||||
display: flex;
|
||||
width: 200rpx;
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-box {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.input-span {
|
||||
background-color: #f6f6f6;
|
||||
margin-left: 15px;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding: 0 12px;
|
||||
border-radius: 40px;
|
||||
}
|
||||
|
||||
.textarea-span {
|
||||
background-color: #f6f6f6;
|
||||
margin-left: 15px;
|
||||
flex: 1;
|
||||
padding: 2px 12px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.step-span {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
box-shadow: 0 0 6px 0 #ccc;
|
||||
|
||||
.price-box {
|
||||
color: #fb932c;
|
||||
font-size: 28rpx;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.price {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
width: 50%;
|
||||
padding-left: 15px;
|
||||
|
||||
.pay-btn {
|
||||
background-color: var(--ui-BG-Main);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 40px;
|
||||
font-size: 28rpx;
|
||||
height: 70rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
50
pages/clerk/detail/components/photoBox.vue
Normal file
50
pages/clerk/detail/components/photoBox.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<view class="photo-box">
|
||||
<scroll-view scroll-x>
|
||||
<view class="scroll-box">
|
||||
<view class="img-box" @click="showImage(item)" v-for="(item,index) in dataList">
|
||||
<u-image border-radius="20" width="170rpx" height="170rpx" :src="item"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showImage(src) {
|
||||
uni.previewImage({
|
||||
indicator: "none",
|
||||
current: src,
|
||||
urls: this.dataList,
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.photo-box {
|
||||
.scroll-box {
|
||||
display: flex;
|
||||
}
|
||||
.img-box {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
342
pages/clerk/detail/components/postList.vue
Normal file
342
pages/clerk/detail/components/postList.vue
Normal file
@@ -0,0 +1,342 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="item" :id="`zp-id-${item.zp_index}`" :key="item.zp_index" v-for="(item,index) in orderList">
|
||||
<view class="card">
|
||||
<view class="right">
|
||||
<view class="card-header">
|
||||
<view class="box3">
|
||||
<view class="box1">
|
||||
<view class="tag-list">
|
||||
<!-- <view class="tag">Ta爱玩王者荣耀</view> -->
|
||||
<view class="tag">发布于 {{item.createTimeStr}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-content">
|
||||
<view class="text-box">
|
||||
<rich-text :nodes="item.content"></rich-text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="image-box" v-if="item.fileType == 0">
|
||||
<img-box :file="item.file"></img-box>
|
||||
</view>
|
||||
<view class="voice-box" v-if="item.fileType == 1">
|
||||
<voice-play :sec="item.seconds" @tap.stop="playAudio(item)" :isPlay="item.id == playId"></voice-play>
|
||||
</view>
|
||||
<view class="video-box" v-if="item.fileType == 2">
|
||||
<video-box :file="item.file"></video-box>
|
||||
</view>
|
||||
<view class="topic-list">
|
||||
<view class="topic">
|
||||
<u-icon name="map-fill" size="40" color="#3cc9a4"></u-icon>
|
||||
<view class="tag-text">{{item.city}}</view>
|
||||
<u-icon name="arrow-right" size="24" color="#3cc9a4"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-footer">
|
||||
<!-- <view class="toolbar">
|
||||
<u-icon color="#f880ab" name="presentfill" size="38" custom-prefix="iconfont"></u-icon>
|
||||
<view class="toolbar-text">3</view>
|
||||
</view> -->
|
||||
<!-- <view class="toolbar">
|
||||
<u-icon name="pinglun" size="38" custom-prefix="iconfont"></u-icon>
|
||||
<view class="toolbar-text">22</view>
|
||||
</view> -->
|
||||
<view class="toolbar" @click="thumb(item)">
|
||||
<u-icon v-if="item.like" name="thumb-up-fill" color="var(--ui-BG-Main)" size="40"></u-icon>
|
||||
<u-icon v-else name="thumb-up" size="40"></u-icon>
|
||||
<view class="toolbar-text" v-if="item.likeNum > 0">{{item.likeNum}}</view>
|
||||
<view class="text" v-else>点赞</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ImgBox from '@/pages/tabbar/components/trend/imgBox.vue';
|
||||
import VideoBox from '@/pages/tabbar/components/trend/videoBox.vue';
|
||||
import VoicePlay from '@/pages/tabbar/components/trend/voicePlay.vue';
|
||||
import sheep from '@/sheep';
|
||||
import TrendApi from '@/sheep/api/worker/trend';
|
||||
const audio = uni.createInnerAudioContext();
|
||||
export default {
|
||||
components: {
|
||||
ImgBox,
|
||||
VideoBox,
|
||||
VoicePlay,
|
||||
},
|
||||
props: {
|
||||
virtualList: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
playId: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
orderList() {
|
||||
this.virtualList.forEach((order) => order.createTimeStr = sheep.$helper.timeFormat(order.createTime, 'yyyy-mm-dd hh:MM'));
|
||||
return this.virtualList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
playAudio(e) {
|
||||
if(this.playId == e.id){
|
||||
this.playId = null;
|
||||
audio.stop();
|
||||
return;
|
||||
}
|
||||
this.playId = e.id;
|
||||
//语音自然播放结束
|
||||
audio.onEnded((res) => {
|
||||
this.playId = null;
|
||||
});
|
||||
audio.src = e.file;
|
||||
audio.play();
|
||||
},
|
||||
thumb(e) {
|
||||
TrendApi.createTrendLike({
|
||||
trendId: e.id,
|
||||
}).then((res) => {
|
||||
if(res) {
|
||||
if(e.like){
|
||||
e.like = false;
|
||||
e.likeNum = e.likeNum-1;
|
||||
sheep.$helper.toast('取消点赞');
|
||||
}else{
|
||||
e.like = true;
|
||||
e.likeNum = e.likeNum+1;
|
||||
sheep.$helper.toast('点赞成功');
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
fans(e) {
|
||||
TrendApi.createClerkFans({
|
||||
workerClerkId: e.workerClerkId,
|
||||
}).then((res) => {
|
||||
if(res){
|
||||
if(e.fans){
|
||||
sheep.$helper.toast('取消收藏');
|
||||
e.fans = false;
|
||||
}else{
|
||||
sheep.$helper.toast('收藏成功');
|
||||
e.fans = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
detail(e) {
|
||||
this.$u.route({
|
||||
url: 'pages/clerk/detail/index',
|
||||
params: {
|
||||
id: e.workerClerkId,
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 30rpx 20rpx;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
display: flex;
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-img{
|
||||
margin-right: 5px;
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 8rpx;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar{
|
||||
margin-right: 5px;
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.img {
|
||||
width: 75%;
|
||||
height: 75%;
|
||||
border-radius: 100%;
|
||||
}
|
||||
.gif {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.box1 {
|
||||
.tag-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 22rpx;
|
||||
margin-top: 4rpx;
|
||||
|
||||
.tag::after {
|
||||
content: '·';
|
||||
padding: 0 10rpx; /* 添加一些间隔 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.tag-list .tag:last-child::after {
|
||||
content: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.box2 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 40rpx;
|
||||
|
||||
.nickname {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.sex-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #d06b8d1f;
|
||||
border-radius: 20px;
|
||||
font-size: 20rpx;
|
||||
padding: 4rpx 10rpx;
|
||||
color: #d06b8d;
|
||||
line-height: 24rpx;
|
||||
margin: 0 5px;
|
||||
|
||||
.age {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.nan {
|
||||
background-color: #007aff1a;
|
||||
color: #007aff;
|
||||
}
|
||||
}
|
||||
|
||||
.box3 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fans {
|
||||
width: 60rpx;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
height: 60rpx;
|
||||
align-items: center;
|
||||
color: var(--ui-BG-Main);
|
||||
font-size: 24rpx;
|
||||
padding-right: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-content {
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
.text-box {
|
||||
font-size: 26rpx;
|
||||
line-height: 180%;
|
||||
white-space: pre-wrap;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.topic-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
|
||||
.topic {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
margin-right: 20rpx;
|
||||
color: var(--ui-BG-Main);
|
||||
font-weight: bold;
|
||||
|
||||
.tag-text {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 30rpx;
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
color: #666666;
|
||||
width: 80rpx;
|
||||
height: 40rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.toolbar-text {
|
||||
font-size: 26rpx;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 24rpx;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
50
pages/clerk/detail/components/priceList.vue
Normal file
50
pages/clerk/detail/components/priceList.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<view class="price-box">
|
||||
|
||||
|
||||
<table-list :tableList="clerk.goodsList"></table-list>
|
||||
|
||||
<view class="price-remark">
|
||||
<u-parse :html="content"></u-parse>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TableList from '@/pages/clerk/detail/components/tableList.vue';
|
||||
export default {
|
||||
components: {
|
||||
TableList,
|
||||
},
|
||||
props: {
|
||||
clerk: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: `
|
||||
<p>露从今夜白,月是故乡明</p>
|
||||
`
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.price-box {
|
||||
padding: 30rpx 20rpx;
|
||||
padding-top: 0px;
|
||||
|
||||
.price-remark {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
112
pages/clerk/detail/components/radioBox.vue
Normal file
112
pages/clerk/detail/components/radioBox.vue
Normal file
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<view class="check-box">
|
||||
<view class="check-option" @click="change(option)" v-for="(option,index) in optionList">
|
||||
<view class="icon-box">
|
||||
<view class="check-icon-span" v-if="option.value == valueDom">
|
||||
<u-icon name="checkmark-circle-fill" color="var(--ui-BG-Main)" size="50"></u-icon>
|
||||
</view>
|
||||
<text class="check-icon" v-else></text>
|
||||
<text class="check-label">{{option.name}}</text>
|
||||
</view>
|
||||
<view class="price-box" v-if="option.type == 'number'">
|
||||
<text class="num">{{option.number}}</text>
|
||||
<text>钻石</text>
|
||||
</view>
|
||||
<view v-if="option.type == 'icon'">
|
||||
<u-icon name="weixin-fill" color="#39b54a" size="50"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
optionList: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
valueDom() {
|
||||
return this.modelValue;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
change(e) {
|
||||
this.$emit('update:modelValue', e.value);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.check-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
.check-option {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.icon-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.check-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 100%;
|
||||
border: 1px solid var(--ui-BG-Main);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.check-icon-span {
|
||||
width: 40rpx;
|
||||
height: 44rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.check-label {
|
||||
font-size: 28rpx;
|
||||
color: var(--ui-BG-Main);
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.price-box {
|
||||
font-size: 26rpx;
|
||||
color: var(--ui-BG-Main);
|
||||
|
||||
.num {
|
||||
font-size: 40rpx;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.check-option:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
125
pages/clerk/detail/components/rateList.vue
Normal file
125
pages/clerk/detail/components/rateList.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<view :id="`zp-id-${item.zp_index}`" :key="item.zp_index" v-for="(item,index) in orderList" class="card-box">
|
||||
<view class="avatar-box">
|
||||
<u-avatar v-if="item.anonymous" size="80"></u-avatar>
|
||||
<u-avatar v-else size="80" :src="item.userAvatar"></u-avatar>
|
||||
<view class="nickname-box">
|
||||
<view class="nickname">
|
||||
<text class="text">{{item.userNickname}}</text>
|
||||
<uni-rate :readonly="true" v-model="item.scores" size="14" />
|
||||
</view>
|
||||
<view class="time">{{item.createTimeStr}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="spu-box">
|
||||
<text class="tag">{{clerk.nickname}}</text>
|
||||
<text class="tag">服务类型:{{item.skuName}}</text>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<rich-text :nodes="item.content"></rich-text>
|
||||
</view>
|
||||
|
||||
<view class="img-box" v-if="item.picUrls && item.picUrls.length > 0">
|
||||
<img-box :file="item.picUrls.join(',')"></img-box>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ImgBox from '@/pages/tabbar/components/trend/imgBox.vue';
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
ImgBox
|
||||
},
|
||||
props: {
|
||||
clerk: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
virtualList: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
orderList() {
|
||||
this.virtualList.forEach((order) => order.createTimeStr = sheep.$helper.timeFormat(order.createTime, 'yyyy-mm-dd'));
|
||||
this.virtualList.forEach(function(e){
|
||||
if(e.skuProperties){
|
||||
var skuNameList = [];
|
||||
e.skuProperties.forEach(function(sku){
|
||||
skuNameList.push(sku.valueName);
|
||||
});
|
||||
e.skuName = skuNameList.join('-');
|
||||
}
|
||||
});
|
||||
return this.virtualList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-box {
|
||||
padding: 30rpx 20rpx;
|
||||
border-bottom: 1rpx solid #eeeeee;
|
||||
}
|
||||
|
||||
.avatar-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.nickname-box {
|
||||
font-size: 24rpx;
|
||||
margin-left: 10px;
|
||||
|
||||
.nickname {
|
||||
letter-spacing: 0.0625rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.text {
|
||||
letter-spacing: 2rpx;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
color: rgb(164, 164, 164);
|
||||
font-size: 22rpx;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spu-box {
|
||||
font-size: 24rpx;
|
||||
color: rgb(164, 164, 164);
|
||||
margin: 10px 0;
|
||||
letter-spacing: 2rpx;
|
||||
|
||||
.tag {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 26rpx;
|
||||
line-height: 180%;
|
||||
white-space: pre-wrap;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
</style>
|
310
pages/clerk/detail/components/starList.vue
Normal file
310
pages/clerk/detail/components/starList.vue
Normal file
@@ -0,0 +1,310 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-if="isGift" class="star-box">
|
||||
<view class="title-box">
|
||||
<view class="title">礼物墙</view>
|
||||
<view class="num">(已点亮:{{starNum}}/{{total}})</view>
|
||||
</view>
|
||||
|
||||
<view class="list-box">
|
||||
<view @click="sendGift(item)" v-for="(item,index) in virtualList" :key="item.id" class="gift">
|
||||
<view class="img-box">
|
||||
<img class="img" :class="item.playStatus == 0 ? 'hui' : ''" :src="item.img"></img>
|
||||
<view class="tag" v-if="item.giftType == 1">
|
||||
<text>特效</text>
|
||||
<text v-if="item.tag">·{{item.tag}}</text>
|
||||
</view>
|
||||
<view class="tag" v-if="item.giftType == 0 && item.tag">
|
||||
<text>{{item.tag}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="name">{{item.name}}</view>
|
||||
<view class="price">x {{item.playNum}}</view>
|
||||
<view class="btn" @tap.stop="openGift(item)" v-if="item.playStatus == 0">点亮</view>
|
||||
<view class="btn" @tap.stop="openGift(item)" v-if="item.playStatus == 1">赠送</view>
|
||||
<view class="btn" v-if="item.playStatus == 2">已下架</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
<view class="svga-box" :class="giftFlag ? 'svga-show': 'svga-hide'">
|
||||
<c-svga ref="cSvgaRef" :canvasId='canvasId' :src="src" :loops='0' :auto-play="false" @frame='onFrame' @finished='onFinished' @percentage='onPercentage' @loaded='onLoaded'></c-svga>
|
||||
<view class="close-btn" @click="closeSvga">
|
||||
<view class="bottom-box">
|
||||
<view class="title">{{gift.name}}</view>
|
||||
<view class="price">{{ fen2yuan(gift.money) }} 钻石</view>
|
||||
<view class="btn-box">
|
||||
<view class="btn" @click="cannel">取消</view>
|
||||
<view v-if="gift.playStatus == 0" class="btn active" @click="ok">点亮</view>
|
||||
<view v-if="gift.playStatus == 1" class="btn active" @click="ok">赠送</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {
|
||||
virtualList: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
giftFlag: false,
|
||||
src: '',
|
||||
canvasId: 'myCanvas',
|
||||
|
||||
gift: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
starNum() {
|
||||
var count = 0;
|
||||
this.virtualList.forEach(e => {
|
||||
if(e.playStatus > 0){
|
||||
count ++;
|
||||
}
|
||||
});
|
||||
return count;
|
||||
},
|
||||
total() {
|
||||
return this.virtualList.length;
|
||||
},
|
||||
isGift() {
|
||||
return sheep.$store('user').tradeConfig.giftEnabled;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
sendGift(e) {
|
||||
this.gift = e;
|
||||
|
||||
if(e.giftType == 0){
|
||||
// 普通礼物不播放
|
||||
this.$emit('openGift', this.gift);
|
||||
return;
|
||||
}
|
||||
|
||||
this.src = e.pic;
|
||||
this.giftFlag = true;
|
||||
},
|
||||
onFinished() {
|
||||
this.giftFlag = false;
|
||||
console.log('动画停止播放时回调');
|
||||
},
|
||||
onFrame(frame) {//动画播放至某帧后回调
|
||||
// console.log(frame);
|
||||
},
|
||||
onPercentage(percentage) { //动画播放至某进度后回调
|
||||
// console.log(percentage);
|
||||
},
|
||||
onLoaded() {
|
||||
this.$refs.cSvgaRef.call('setContentMode', 'AspectFill');
|
||||
console.log('加载完成');
|
||||
this.$refs.cSvgaRef.call('startAnimation');
|
||||
},
|
||||
closeSvga() {
|
||||
this.src = "";
|
||||
this.$refs.cSvgaRef.call('stopAnimation');
|
||||
this.giftFlag = false;
|
||||
},
|
||||
fen2yuan(price) {
|
||||
var f = 0;
|
||||
var p = (price / 100.0).toFixed(0);
|
||||
var p1 = (price / 100.0).toFixed(1);
|
||||
var p2 = (price / 100.0).toFixed(2);
|
||||
if(p*100 == price){
|
||||
f = 0;
|
||||
}else if(p1*100 == price){
|
||||
f = 1;
|
||||
}else if(p2*100 == price){
|
||||
f = 2;
|
||||
}
|
||||
return (price / 100.0).toFixed(f)
|
||||
},
|
||||
cannel() {
|
||||
this.closeSvga();
|
||||
},
|
||||
ok() {
|
||||
this.closeSvga();
|
||||
this.$emit('openGift', this.gift);
|
||||
},
|
||||
openGift(e) {
|
||||
this.$emit('openGift', e);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.star-box {
|
||||
padding: 30rpx 20rpx;
|
||||
|
||||
.title-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 24rpx;
|
||||
color: var(--ui-BG-Main);
|
||||
}
|
||||
}
|
||||
|
||||
.list-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 30rpx;
|
||||
|
||||
.gift {
|
||||
width: 25%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 20rpx 0px;
|
||||
|
||||
.img-box {
|
||||
position: relative;
|
||||
|
||||
.img{
|
||||
max-width: 150rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
|
||||
.hui {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 16rpx;
|
||||
color: #fff;
|
||||
background-color: var(--ui-BG-Main);
|
||||
border-radius: 40px;
|
||||
padding: 2rpx 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 24rpx;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
max-width: 150rpx;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 20rpx;
|
||||
color: var(--ui-BG-Main);
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 1px solid var(--ui-BG-Main);
|
||||
border-radius: 40px;
|
||||
color: var(--ui-BG-Main);
|
||||
padding: 8rpx 20rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.svga-box {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 999999999;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
|
||||
.close-btn {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
z-index: 999999999;
|
||||
padding: 5px 10px;
|
||||
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 100rpx;
|
||||
|
||||
.bottom-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
|
||||
.btn {
|
||||
border: 1px solid #fff;
|
||||
font-size: 28rpx;
|
||||
padding: 20rpx 110rpx;
|
||||
border-radius: 40px;
|
||||
margin: 15px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.active {
|
||||
border: 1px solid var(--ui-BG-Main);
|
||||
background-color: var(--ui-BG-Main);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.svga-hide {
|
||||
/* #ifdef MP */
|
||||
transform: translate(-100%, 0);
|
||||
/* #endif */
|
||||
|
||||
/* #ifndef MP */
|
||||
display: none;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.svga-show {
|
||||
/* #ifdef MP */
|
||||
transform: translate(0, 0);
|
||||
/* #endif */
|
||||
|
||||
/* #ifndef MP */
|
||||
display: block;
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
64
pages/clerk/detail/components/stickyBox.vue
Normal file
64
pages/clerk/detail/components/stickyBox.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="sticky-box">
|
||||
<view>
|
||||
<tui-tabs :tabs="tabList" badgeBgColor="var(--ui-BG-Main)" selectedColor="var(--ui-BG-Main)" sliderBgColor="var(--ui-BG-Main)" :currentTab="currentTab" @change="change"></tui-tabs>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tuiTabs from "@/components/thorui/tui-tabs/tui-tabs.vue"
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
tuiTabs,
|
||||
},
|
||||
props: {
|
||||
clerk: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tabList() {
|
||||
var tabs = [{
|
||||
name: '礼物墙'
|
||||
},{
|
||||
name: '价格'
|
||||
}, {
|
||||
name: '动态',
|
||||
num: this.clerk.trendNum,
|
||||
}, {
|
||||
name: '评价',
|
||||
num: this.clerk.commentNum,
|
||||
}];
|
||||
return tabs;
|
||||
},
|
||||
currentTab() {
|
||||
return sheep.$store('sys').clerkTabIndex;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
change(e) {
|
||||
this.$emit('change', e.index);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.sticky-box {
|
||||
background-color: #fff;
|
||||
padding: 5px 0;
|
||||
}
|
||||
</style>
|
100
pages/clerk/detail/components/table-bd.vue
Normal file
100
pages/clerk/detail/components/table-bd.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<view class="tn-table-class tn-table" :class="[tableClass]" :style="[tableStyle]">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'table-bd',
|
||||
props: {
|
||||
// 边框宽度
|
||||
borderWidth: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
// 边框颜色
|
||||
borderColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 显示上边框
|
||||
borderTop: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 显示右边框
|
||||
borderRight: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 显示下边框
|
||||
borderBottom: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 显示左边框
|
||||
borderLeft: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
parentData() {
|
||||
return [this.borderWidth, this.borderColor]
|
||||
},
|
||||
tableClass() {
|
||||
let clazz = ''
|
||||
return clazz
|
||||
},
|
||||
tableStyle() {
|
||||
let style = {}
|
||||
if (this.borderWidth !== '') {
|
||||
style.borderWidth = this.borderWidth + 'rpx'
|
||||
}
|
||||
if (this.borderColor) {
|
||||
style.borderColor = this.borderColor
|
||||
}
|
||||
if (this.borderLeft) {
|
||||
style.borderLeftStyle = 'solid'
|
||||
}
|
||||
if (this.borderRight) {
|
||||
style.borderRightStyle = 'solid'
|
||||
}
|
||||
if (this.borderTop) {
|
||||
style.borderTopStyle = 'solid'
|
||||
}
|
||||
if (this.borderBottom) {
|
||||
style.borderBottomStyle = 'solid'
|
||||
}
|
||||
return style
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
created() {
|
||||
this.children = []
|
||||
},
|
||||
watch: {
|
||||
parentData() {
|
||||
// 更新子组件的数据
|
||||
if (this.children.length) {
|
||||
this.children.map((child) => {
|
||||
typeof(child.updateParentData) === 'function' && child.updateParentData()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tn-table {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
border-width: 1rpx;
|
||||
border-style: none;
|
||||
border-color: var(--ui-BG-Main);;
|
||||
}
|
||||
</style>
|
305
pages/clerk/detail/components/table-td.vue
Normal file
305
pages/clerk/detail/components/table-td.vue
Normal file
@@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<view class="tn-td-class tn-td" :class="[tdClass]" :style="[tdStyle]" @tap.stop="handleClick">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'table-td',
|
||||
options: {
|
||||
// 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
|
||||
virtualHost: true
|
||||
},
|
||||
props: {
|
||||
// 占整个表格的宽度跨度
|
||||
// [1-24]
|
||||
span: {
|
||||
type: Number,
|
||||
default: 24
|
||||
},
|
||||
// 宽度
|
||||
// 优先级比span高
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
// 高度
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
// 字体加粗
|
||||
bold: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 格内边距
|
||||
padding: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 边框颜色
|
||||
borderColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 边框宽度
|
||||
borderWidth: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
// 左边框
|
||||
borderLeft: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 下边框
|
||||
borderBottom: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 右边框
|
||||
borderRight: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 文字超出隐藏
|
||||
ellipsis: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 文本对齐方式
|
||||
// left center right
|
||||
textAlign: {
|
||||
type: String,
|
||||
default: 'left'
|
||||
},
|
||||
// 排列方式
|
||||
// left center right
|
||||
alignItems: {
|
||||
type: String,
|
||||
default: 'left'
|
||||
},
|
||||
// 收缩表格
|
||||
shrink: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 铺满剩余空间
|
||||
grow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 隐藏
|
||||
hidden: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 固定列数据
|
||||
fixed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// zIndex
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 列数
|
||||
index: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
// keys
|
||||
keys: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tdClass() {
|
||||
let clazz = ''
|
||||
clazz += `${this.ellipsis ? 'tn-td--ellipsis' : 'tn-td--normal'}`
|
||||
/* if (this.backgroundColorClass) {
|
||||
clazz += ` ${this.backgroundColorClass}`
|
||||
}
|
||||
if (this.fontColorClass) {
|
||||
clazz += ` ${this.fontColorClass}`
|
||||
} */
|
||||
if (this.alignItems) {
|
||||
clazz += ` tn-td--${this.alignItems}`
|
||||
}
|
||||
if (this.textAlign) {
|
||||
clazz += ` tn-td__text--${this.textAlign}`
|
||||
}
|
||||
if (!this.shrink) {
|
||||
clazz += ' tn-td--shrink'
|
||||
}
|
||||
if (this.grow) {
|
||||
clazz += ' tn-td--grow'
|
||||
}
|
||||
if (this.hidden) {
|
||||
clazz += ' tn-td--hidden'
|
||||
}
|
||||
return clazz
|
||||
},
|
||||
tdStyle() {
|
||||
let style = {}
|
||||
/* if (this.backgroundColorStyle) {
|
||||
style.backgroundColor = this.backgroundColorStyle
|
||||
} */
|
||||
/* if (this.fontColorStyle) {
|
||||
style.color = this.fontColorStyle
|
||||
} */
|
||||
/* if (this.fontSizeStyle) {
|
||||
style.fontSize = this.fontSizeStyle
|
||||
} */
|
||||
style.width = this.getWidth()
|
||||
if (this.height) {
|
||||
style.height = this.height + 'rpx';
|
||||
}
|
||||
style.fontWeight = this.bold ? 'bold' : 'normal'
|
||||
if (this.padding) {
|
||||
style.padding = this.padding
|
||||
}
|
||||
if (this.borderWidth !== '' || this.parentData.borderWidthValue !== '') {
|
||||
style.borderWidth = this.borderWidth !== '' ? this.borderWidth+'rpx' : this.parentData.borderWidthValue + 'rpx'
|
||||
}
|
||||
if (this.borderColor || this.parentData.borderColorValue) {
|
||||
style.borderColor = this.borderColor || this.parentData.borderColorValue
|
||||
}
|
||||
if (this.borderLeft) {
|
||||
style.borderLeftStyle = 'solid'
|
||||
}
|
||||
if (this.borderRight) {
|
||||
style.borderRightStyle = 'solid'
|
||||
}
|
||||
if (this.borderBottom) {
|
||||
style.borderBottomStyle = 'solid'
|
||||
}
|
||||
if (this.fixed) {
|
||||
style.zIndex = this.zIndex ? this.zIndex : 1000
|
||||
}
|
||||
return style
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
parentData: {
|
||||
borderColorValue: null,
|
||||
borderWidthValue: null
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.parent = false
|
||||
this.updateParentData()
|
||||
this.parent && this.parent.children.push(this)
|
||||
},
|
||||
methods: {
|
||||
// 获取表格宽度
|
||||
getWidth() {
|
||||
if (this.width) {
|
||||
return this.width + 'rpx'
|
||||
}
|
||||
return [
|
||||
'4.16666667%',
|
||||
'8.33333333%',
|
||||
'12.5%',
|
||||
'16.66666667%',
|
||||
'20.83333333%',
|
||||
'25%',
|
||||
'29.16666667%',
|
||||
'33.33333333%',
|
||||
'37.5%',
|
||||
'41.66666667%',
|
||||
'45.83333333%',
|
||||
'50%',
|
||||
'54.16666667%',
|
||||
'58.33333333%',
|
||||
'62.5%',
|
||||
'66.66666667%',
|
||||
'70.83333333%',
|
||||
'75%',
|
||||
'79.16666667%',
|
||||
'83.33333333%',
|
||||
'87.5%',
|
||||
'91.66666667%',
|
||||
'95.83333333%',
|
||||
'100%'
|
||||
][this.span - 1]
|
||||
},
|
||||
// 点击事件
|
||||
handleClick() {
|
||||
this.$emit('click', {
|
||||
index: this.index,
|
||||
key: this.keys
|
||||
})
|
||||
},
|
||||
// 更新父组件信息
|
||||
updateParentData() {
|
||||
this.getParentData('tn-tr')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tn-td {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
word-break: break-all;
|
||||
background-color: transparent;
|
||||
height: auto;
|
||||
padding: 12rpx;
|
||||
|
||||
border-width: 1rpx;
|
||||
border-style: none;
|
||||
border-color: var(--ui-BG-Main);
|
||||
|
||||
&--normal {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
&--ellipsis {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap !important;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&--shrink {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
&--grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
&--left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
&--center {
|
||||
justify-content: center;
|
||||
}
|
||||
&--right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&__text {
|
||||
&--left {
|
||||
text-align: left;
|
||||
}
|
||||
&--center {
|
||||
text-align: center;
|
||||
}
|
||||
&--right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
&--hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
208
pages/clerk/detail/components/table-tr.vue
Normal file
208
pages/clerk/detail/components/table-tr.vue
Normal file
@@ -0,0 +1,208 @@
|
||||
<template>
|
||||
<view class="tn-tr-class tn-tr" :class="[trClass]" :style="[trStyle]">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'table-tr',
|
||||
options: {
|
||||
// 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
|
||||
virtualHost: true
|
||||
},
|
||||
props: {
|
||||
// 宽度
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
// 边框颜色
|
||||
borderColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 边框宽度
|
||||
borderWidth: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
// 左边框
|
||||
borderLeft: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 上边框
|
||||
borderTop: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 换行显示
|
||||
wrap: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 固定表格
|
||||
fixed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// left偏移值
|
||||
left: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
// right偏移值
|
||||
right: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
// top偏移值(自定义顶部导航栏时用到)
|
||||
top: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
// 外边距
|
||||
margin: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// zIndex
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 行数索引
|
||||
index: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
// 参数
|
||||
params: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
borderWidthValue() {
|
||||
return this.borderWidth || this.parentData.borderWidth || ''
|
||||
},
|
||||
borderColorValue() {
|
||||
return this.borderColor || this.parentData.borderColor || ''
|
||||
},
|
||||
trClass() {
|
||||
let clazz = ''
|
||||
/* if (this.backgroundColorClass) {
|
||||
clazz += ` ${this.backgroundColorClass}`
|
||||
}
|
||||
if (this.fontColorClass) {
|
||||
clazz += ` ${this.fontColorClass}`
|
||||
} */
|
||||
if (this.wrap) {
|
||||
clazz += ' tn-tr--wrap'
|
||||
}
|
||||
if (this.fixed) {
|
||||
clazz += ' tn-tr--fixed'
|
||||
}
|
||||
return clazz
|
||||
},
|
||||
trStyle() {
|
||||
let style = {}
|
||||
if (this.width) {
|
||||
style.width = this.width + 'rpx'
|
||||
}
|
||||
/* if (this.backgroundColorStyle) {
|
||||
style.backgroundColor = this.backgroundColorStyle
|
||||
}
|
||||
if (this.fontColorStyle) {
|
||||
style.color = this.fontColorStyle
|
||||
}
|
||||
if (this.fontSizeStyle) {
|
||||
style.fontSize = this.fontSizeStyle
|
||||
} */
|
||||
if (this.borderWidth !== '' || this.parentData.borderWidth !== '') {
|
||||
style.borderWidth = this.borderWidth !== '' ? this.borderWidth + 'rpx' : this.parentData.borderWidth + 'rpx'
|
||||
}
|
||||
if (this.borderColor || this.parentData.borderColor) {
|
||||
style.borderColor = this.borderColor || this.parentData.borderColor
|
||||
}
|
||||
if (this.borderLeft) {
|
||||
style.borderLeftStyle = 'solid'
|
||||
}
|
||||
if (this.borderTop) {
|
||||
style.borderTopStyle = 'solid'
|
||||
}
|
||||
if (this.fixed) {
|
||||
style.left = this.left ? this.left + 'rpx' : 'auto'
|
||||
style.right = this.right ? this.right + 'rpx' : 'auto'
|
||||
style.top = this.top ? this.top + 'rpx' : 'auto'
|
||||
}
|
||||
if (this.margin) {
|
||||
style.margin = this.margin
|
||||
}
|
||||
style.zIndex = this.zIndex ? this.zIndex : 1000
|
||||
return style
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
parentData: {
|
||||
borderColor: null,
|
||||
borderWidth: null
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
parentData: {
|
||||
handler() {
|
||||
// 更新子组件的数据
|
||||
if (this.children.length) {
|
||||
this.children.map((child) => {
|
||||
typeof(child.updateParentData) === 'function' && child.updateParentData()
|
||||
})
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.children = []
|
||||
this.parent = false
|
||||
this.updateParentData()
|
||||
this.parent && this.parent.children.push(this)
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
this.$emit('click', {
|
||||
index: this.index,
|
||||
params: this.params
|
||||
})
|
||||
},
|
||||
// 更新父组件信息
|
||||
updateParentData() {
|
||||
this.getParentData('tn-table')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tn-tr {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
border-width: 1rpx;
|
||||
border-style: none none solid none;
|
||||
border-color: var(--ui-BG-Main);;
|
||||
|
||||
&--wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&--fixed {
|
||||
position: fixed;
|
||||
}
|
||||
}
|
||||
</style>
|
98
pages/clerk/detail/components/tableList.vue
Normal file
98
pages/clerk/detail/components/tableList.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
<table-bd style="width: 100%;">
|
||||
<table-tr>
|
||||
<table-td :span="18" height="80rpx" :fontSize="30" :bold="true" fontColor="#01BEFF" alignItems="center">服务项目</table-td>
|
||||
<table-td :span="6" height="80rpx" :fontSize="30" :bold="true" fontColor="#01BEFF" alignItems="center">价格</table-td>
|
||||
</table-tr>
|
||||
|
||||
<block v-for="(tb,t) in tableList">
|
||||
<table-tr>
|
||||
<table-td :span="6" alignItems="center">{{tb.name}}</table-td>
|
||||
|
||||
<block v-if="tb.goodsList">
|
||||
<table-td :span="12" :ellipsis="true" padding="0">
|
||||
<block v-for="(tb2,t2) in tb.goodsList">
|
||||
<table-tr :borderWidth="t2 == tb.goodsList.length-1 ? 0 : 1">
|
||||
<table-td :span="24" :borderRight="false" alignItems="center">{{tb2.name}}</table-td>
|
||||
</table-tr>
|
||||
</block>
|
||||
</table-td>
|
||||
<table-td :span="6" :ellipsis="true" padding="0">
|
||||
<block v-for="(tb2,t2) in tb.goodsList">
|
||||
<table-tr :borderWidth="t2 == tb.goodsList.length-1 ? 0 : 1">
|
||||
<table-td :span="24" borderWidth="1rpx" :borderRight="false" alignItems="center">{{ fen2yuan(tb2.price) }}</table-td>
|
||||
</table-tr>
|
||||
</block>
|
||||
</table-td>
|
||||
</block>
|
||||
|
||||
<block v-if="tb.categoryList">
|
||||
<table-td :span="12" :ellipsis="true" padding="0">
|
||||
<block v-for="(tb2,t2) in tb.categoryList">
|
||||
<table-tr :borderWidth="t2 == tb.categoryList.length-1 ? 0 : 1">
|
||||
<table-td :span="12" borderWidth="1rpx" alignItems="center">{{tb2.name}}</table-td>
|
||||
<table-td :span="12" :ellipsis="true" :borderRight="false" padding="0">
|
||||
<block v-for="(tb3,t3) in tb2.goodsList">
|
||||
<table-tr :borderWidth="t3 == tb2.goodsList.length-1 ? 0 : 1">
|
||||
<table-td :span="24" :borderRight="false" alignItems="center">{{tb3.name}}</table-td>
|
||||
</table-tr>
|
||||
</block>
|
||||
</table-td>
|
||||
</table-tr>
|
||||
</block>
|
||||
</table-td>
|
||||
|
||||
<table-td :span="6" :ellipsis="true" padding="0">
|
||||
<block v-for="(tb2,t2) in tb.categoryList">
|
||||
<block v-for="(tb3,t3) in tb2.goodsList">
|
||||
<table-tr :borderWidth="t2 == tb.categoryList.length-1 && t3 == tb2.goodsList.length-1 ? 0 : 1">
|
||||
<table-td :span="24" borderWidth="1rpx" :borderRight="false" alignItems="center">{{ fen2yuan(tb3.price) }}</table-td>
|
||||
</table-tr>
|
||||
</block>
|
||||
</block>
|
||||
</table-td>
|
||||
</block>
|
||||
|
||||
</table-tr>
|
||||
</block>
|
||||
|
||||
</table-bd>
|
||||
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TableBd from '@/pages/clerk/detail/components/table-bd.vue';
|
||||
import TableTd from '@/pages/clerk/detail/components/table-td.vue';
|
||||
import TableTr from '@/pages/clerk/detail/components/table-tr.vue';
|
||||
export default {
|
||||
components: {
|
||||
TableBd,
|
||||
TableTd,
|
||||
TableTr,
|
||||
},
|
||||
props: {
|
||||
tableList: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fen2yuan(price) {
|
||||
return (price / 100.0).toFixed(0)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
270
pages/clerk/detail/components/userBox.vue
Normal file
270
pages/clerk/detail/components/userBox.vue
Normal file
@@ -0,0 +1,270 @@
|
||||
<template>
|
||||
<view class="user-box" :style="`background-size: contain;background-image: url(${clerk.avatar});`">
|
||||
<view class="info-box" :style="{ paddingTop: paddingTop + 20 + 'px'}">
|
||||
<view class="avatar-box">
|
||||
<view class="avatar-span">
|
||||
<u-image width="100%" height="100%" shape="circle" :src="clerk.avatar"></u-image>
|
||||
<view class="fans-btn" @click="fans(clerk)">
|
||||
<u-icon v-if="clerk.isFans" color="var(--ui-BG-Main)" name="checkmark-circle-fill" size="46"></u-icon>
|
||||
<u-icon v-else color="var(--ui-BG-Main)" name="plus-circle-fill" size="46"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right-box">
|
||||
<view class="nickname-box">
|
||||
<view class="nickname">{{clerk.nickname}}</view>
|
||||
<view class="icon">
|
||||
<u-icon name="wode_duanwei" size="36" custom-prefix="iconfont"></u-icon>
|
||||
<text>{{clerkLevel.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="online" v-if="clerk.onlineStatus">可接单</view>
|
||||
<view class="online" v-else>休息中</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="sex-box">
|
||||
<view class="span" v-if="clerk.sex == 1">
|
||||
<u-icon name="ziyuan2" color="#f898c5" size="34" custom-prefix="iconfont"></u-icon>
|
||||
</view>
|
||||
<view class="span" v-if="clerk.sex == 0">
|
||||
<u-icon name="ziyuan3" color="#0081ff" size="34" custom-prefix="iconfont"></u-icon>
|
||||
</view>
|
||||
<view class="span">{{clerk.age}}</view>
|
||||
<!-- <view class="span">{{clerk.city}}</view> -->
|
||||
</view>
|
||||
<view class="sign-box">{{clerk.intro}}</view>
|
||||
<view class="voice-box" v-if="clerk.sound">
|
||||
<view class="voice-span">
|
||||
<voice-play :sec="clerk.soundTime" :src="clerk.sound"></voice-play>
|
||||
</view>
|
||||
<!-- <view class="span">全声线</view>
|
||||
<view class="span">御姐音</view>
|
||||
<view class="span">夹子音</view> -->
|
||||
</view>
|
||||
<view class="tag-list">
|
||||
<view class="tag-box">
|
||||
<span class="tag" v-for="(categoryName,index) in clerk.categoryNameList">{{categoryName}}</span>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <view class="tags-box">
|
||||
<view class="span">搞笑</view>
|
||||
<view class="span">风骚走位</view>
|
||||
<view class="span">乖巧懂事🍑 极致体验</view>
|
||||
</view> -->
|
||||
|
||||
<photo-box v-if="clerk.albums" :dataList="clerk.albums.split(',')"></photo-box>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VoicePlay from '@/pages/clerk/detail/components/voicePlay.vue';
|
||||
import PhotoBox from '@/pages/clerk/detail/components/photoBox.vue';
|
||||
import sheep from '@/sheep';
|
||||
import TrendApi from '@/sheep/api/worker/trend';
|
||||
export default {
|
||||
components: {
|
||||
VoicePlay,
|
||||
PhotoBox,
|
||||
},
|
||||
props: {
|
||||
paddingTop: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
clerk: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
clerkLevel: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
photo: 'http://cos.duopei.feiniaowangluo.com/34/clerk/1707236152609pJKyvtedS9.jpg,http://cos.duopei.feiniaowangluo.com/34/clerk/1720278125689P34fP9MU1c.jpg?imageView2/1/w/200/h/200',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fans(e) {
|
||||
TrendApi.createClerkFans({
|
||||
workerClerkId: e.id,
|
||||
}).then((res) => {
|
||||
if(res){
|
||||
if(e.isFans){
|
||||
sheep.$helper.toast('取消关注');
|
||||
e.isFans = false;
|
||||
}else{
|
||||
sheep.$helper.toast('关注成功');
|
||||
e.isFans = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.info-box {
|
||||
backdrop-filter: blur(10px);
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
padding: 15px;
|
||||
|
||||
.avatar-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.avatar-span {
|
||||
border-radius: 100%;
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
border: 2px solid #fff;
|
||||
position: relative;
|
||||
|
||||
.fans-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.right-box {
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
margin-left: 10px;
|
||||
|
||||
.nickname {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
max-width: 320rpx;
|
||||
}
|
||||
|
||||
.icon {
|
||||
background-color: #ff5ebd;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 40px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
font-size: 22rpx;
|
||||
line-height: 22rpx;
|
||||
padding: 5px 5px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.online {
|
||||
border-bottom: 1px solid #fff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sex-box {
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 30px;
|
||||
|
||||
.span {
|
||||
margin-right: 5px;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.sign-box {
|
||||
color: #cfcfcf;
|
||||
font-size: 28rpx;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.voice-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
|
||||
.voice-span {
|
||||
margin-bottom: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.span {
|
||||
padding: 10rpx 20rpx;
|
||||
background-color: rgba(132, 167, 164, .81);
|
||||
border-radius: 20px;
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.tags-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin: 5px 0;
|
||||
|
||||
.span {
|
||||
font-size: 20rpx;
|
||||
color: #fff;
|
||||
background-color: #000000;
|
||||
border-radius: 999px;
|
||||
padding: 3px 10px;
|
||||
margin: 0 10px 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tag-list {
|
||||
display: flex;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.tag-box {
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
background-color: #eef2f26e;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
padding: 5px 0;
|
||||
|
||||
.tag {
|
||||
white-space: nowrap;
|
||||
padding: 5px 5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tag:after {
|
||||
content: ' ';
|
||||
border-left: 1px solid #fff;
|
||||
display: inline-block;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.tag:last-child:after{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
183
pages/clerk/detail/components/voicePlay.vue
Normal file
183
pages/clerk/detail/components/voicePlay.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<view class="voice-btn" @click="playBtn" :class="play?'audioplaying':''">
|
||||
<img class="play-btn" src="@/static/images/audio.png"></img>
|
||||
<view class="audio-box">
|
||||
<view class="audio1 wave1"></view>
|
||||
<view class="audio2 wave2"></view>
|
||||
<view class="audio3 wave3"></view>
|
||||
<view class="audio2 wave2"></view>
|
||||
<view class="audio1 wave1"></view>
|
||||
<view class="audio2 wave2"></view>
|
||||
<view class="audio3 wave3"></view>
|
||||
<view class="audio2 wave2"></view>
|
||||
<view class="audio1 wave1"></view>
|
||||
<view class="audio2 wave2"></view>
|
||||
<view class="audio3 wave3"></view>
|
||||
<view class="audio2 wave2"></view>
|
||||
</view>
|
||||
<view>{{sec}}"</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const audio = uni.createInnerAudioContext();
|
||||
export default {
|
||||
emits: ['playAudio'],
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
sec: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
play: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
playBtn() {
|
||||
if(this.play){
|
||||
this.play = false;
|
||||
audio.stop();
|
||||
return;
|
||||
}
|
||||
this.play = true;
|
||||
//语音自然播放结束
|
||||
audio.onEnded((res) => {
|
||||
this.play = false;
|
||||
});
|
||||
audio.src = this.src;
|
||||
audio.play();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
view{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.voice-btn {
|
||||
background-color: #3cc9a4;
|
||||
width: 140rpx;
|
||||
border-radius: 20px;
|
||||
padding: 10rpx 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
|
||||
.audio-box {
|
||||
height: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.audio1{
|
||||
margin-right: 2rpx;
|
||||
width: 1px;
|
||||
height: 33.3%;
|
||||
border-radius: 50px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.audio2{
|
||||
margin-right: 2rpx;
|
||||
width: 1px;
|
||||
height: 66.6%;
|
||||
border-radius: 50px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.audio3{
|
||||
margin-right: 2rpx;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
border-radius: 50px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.audioplaying .wave1 {
|
||||
animation: wave1 1s linear 0s infinite;
|
||||
}
|
||||
|
||||
.audioplaying .wave2 {
|
||||
animation: wave2 1s linear 0s infinite;
|
||||
}
|
||||
|
||||
.audioplaying .wave3 {
|
||||
animation: wave3 1s linear 0s infinite;
|
||||
}
|
||||
|
||||
@keyframes wave1{
|
||||
0% {
|
||||
width: 1px;
|
||||
height: 33%;
|
||||
}
|
||||
25% {
|
||||
width: 1px;
|
||||
height: 66%;
|
||||
}
|
||||
50% {
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
75% {
|
||||
width: 1px;
|
||||
height: 66%;
|
||||
}
|
||||
100% {
|
||||
width: 1px;
|
||||
height: 33%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes wave2{
|
||||
0% {
|
||||
width: 1px;
|
||||
height: 66%;
|
||||
}
|
||||
25% {
|
||||
width: 1px;
|
||||
height: 33%;
|
||||
}
|
||||
50% {
|
||||
width: 1px;
|
||||
height: 66%;
|
||||
}
|
||||
75% {
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
100% {
|
||||
width: 1px;
|
||||
height: 66%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes wave3{
|
||||
0% {
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
50% {
|
||||
width: 1px;
|
||||
height: 33%;
|
||||
}
|
||||
100% {
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
61
pages/clerk/detail/index.vue
Normal file
61
pages/clerk/detail/index.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<view class="container page-app theme-light main-green font-1">
|
||||
<layout ref="skill" title="选人下单">
|
||||
|
||||
</layout>
|
||||
|
||||
<s-auth-modal />
|
||||
<s-menu-tools />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import layout from '@/pages/clerk/detail/components/layout.vue';
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
layout,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
// 分享小程序
|
||||
onShareAppMessage(res) {
|
||||
return {
|
||||
title: this.shareInfo.title,
|
||||
imageUrl: this.shareInfo.image,
|
||||
};
|
||||
},
|
||||
onShareTimeline() {
|
||||
return {
|
||||
title: this.shareInfo.title,
|
||||
imageUrl: this.shareInfo.image,
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.skill.initData(options);
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
shareInfo() {
|
||||
return sheep.$platform.share.getShareInfo();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #fff;
|
||||
height: calc(100vh);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
|
||||
</style>
|
82
pages/clerk/fans/components/layout.vue
Normal file
82
pages/clerk/fans/components/layout.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<!-- 虚拟列表演示(不使用内置列表)(vue) -->
|
||||
<!-- 写法较简单,在页面中对当前需要渲染的虚拟列表数据进行for循环,在vue3中兼容性良好 -->
|
||||
<!-- 在各平台兼容性请查阅https://z-paging.zxlee.cn/module/virtual-list.html -->
|
||||
<template>
|
||||
<view class="content">
|
||||
<!-- 如果页面中的cell高度是固定不变的,则不需要设置cell-height-mode,如果页面中高度是动态改变的,则设置cell-height-mode="dynamic" -->
|
||||
<!-- 原先的v-model修改为@virtualListChange="virtualListChange"并赋值处理后的虚拟列表 -->
|
||||
<z-paging ref="paging" :auto="true" use-virtual-list :force-close-inner-list="true" :paging-style="{ paddingTop: 0 + 'px', paddingBottom: paddingBottom + 'rpx' }" cell-height-mode="dynamic" @scroll="scroll" @virtualListChange="virtualListChange" @query="queryList">
|
||||
<!-- 需要固定在顶部不滚动的view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot="top" -->
|
||||
<template #top>
|
||||
<su-navbar :title="title" statusBar></su-navbar>
|
||||
</template>
|
||||
|
||||
<!-- :id="`zp-id-${item.zp_index}`"和:key="item.zp_index" 必须写,必须写!!!! -->
|
||||
<!-- 这里for循环的index不是数组中真实的index了,请使用item.zp_index获取真实的index -->
|
||||
<order-list :virtualList="virtualList"></order-list>
|
||||
|
||||
</z-paging>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import OrderList from '@/pages/clerk/fans/components/orderList.vue';
|
||||
import ClerkApi from '@/sheep/api/worker/clerk';
|
||||
import {
|
||||
fen2yuan,
|
||||
} from '@/sheep/hooks/useGoods';
|
||||
export default {
|
||||
components: {
|
||||
OrderList,
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '我收藏的店员',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 虚拟列表数组,通过@virtualListChange监听获得最新数组
|
||||
virtualList: [],
|
||||
scrollTop: 0,
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
height: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
scroll(e) {
|
||||
this.scrollTop = e.detail.scrollTop;
|
||||
},
|
||||
// 监听虚拟列表数组改变并赋值给virtualList进行重新渲染
|
||||
virtualListChange(vList) {
|
||||
this.virtualList = vList;
|
||||
},
|
||||
queryList(pageNo, pageSize) {
|
||||
// 组件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
|
||||
// 这里的pageNo和pageSize会自动计算好,直接传给服务器即可
|
||||
// 模拟请求服务器获取分页数据,请替换成自己的网络请求
|
||||
const params = {
|
||||
pageNo: pageNo,
|
||||
pageSize: pageSize,
|
||||
}
|
||||
ClerkApi.getClerkFansPage(params).then(res => {
|
||||
// 将请求的结果数组传递给z-paging
|
||||
this.$refs.paging.complete(res.data.list);
|
||||
}).catch(res => {
|
||||
// 如果请求失败写this.$refs.paging.complete(false);
|
||||
// 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
|
||||
// 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
|
||||
this.$refs.paging.complete(false);
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
212
pages/clerk/fans/components/orderList.vue
Normal file
212
pages/clerk/fans/components/orderList.vue
Normal file
@@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<view :id="`zp-id-${item.zp_index}`" :key="item.zp_index" v-for="(item,index) in orderList" class="order-card">
|
||||
|
||||
<view class="main-box" :class="index == orderList.length-1 ? '':'bt'">
|
||||
<view @click="detail(item)">
|
||||
<u-avatar mode="square" size="170" :src="item.avatar"></u-avatar>
|
||||
</view>
|
||||
<view class="right-box">
|
||||
<view class="nickname-box">
|
||||
<view class="nickname">{{item.nickname}}</view>
|
||||
<view class="oline" v-if="item.onlineStatus">
|
||||
<tui-badge :scaleRatio="0.8" type="green" dot></tui-badge>
|
||||
<text class="text">在线</text>
|
||||
</view>
|
||||
<view class="oline un" v-else>
|
||||
<tui-badge :scaleRatio="0.8" type="gray" dot></tui-badge>
|
||||
<text class="text">休息中</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="city">{{item.city}}</view>
|
||||
<view class="sex-box">
|
||||
<view class="sex-tag">
|
||||
<text class="tag" v-if="item.sex == 1">女</text>
|
||||
<text class="tag" v-if="item.sex == 0">男</text>
|
||||
<text class="tag">{{item.age}}岁</text>
|
||||
</view>
|
||||
<view class="fans-box" @click="fans(item)">
|
||||
<view class="fans">{{item.fansNum}}人收藏</view>
|
||||
<u-icon v-if="item.fans" name="star-fill" size="36" color="var(--ui-BG-Main)"></u-icon>
|
||||
<u-icon v-else name="star" size="36" color="#ddd"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info">{{item.intro}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TuiBadge from "@/components/thorui/tui-badge/tui-badge.vue";
|
||||
import TrendApi from '@/sheep/api/worker/trend';
|
||||
import sheep from '@/sheep';
|
||||
export default {
|
||||
components: {
|
||||
TuiBadge,
|
||||
},
|
||||
props: {
|
||||
virtualList: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
orderList() {
|
||||
return this.virtualList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fans(e) {
|
||||
TrendApi.createClerkFans({
|
||||
workerClerkId: e.workerClerkId,
|
||||
}).then((res) => {
|
||||
if(res){
|
||||
if(e.fans){
|
||||
sheep.$helper.toast('取消收藏');
|
||||
e.fans = false;
|
||||
}else{
|
||||
sheep.$helper.toast('收藏成功');
|
||||
e.fans = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
detail(e) {
|
||||
this.$u.route({
|
||||
url: 'pages/clerk/detail/index',
|
||||
params: {
|
||||
id: e.workerClerkId,
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order-card {
|
||||
padding: 0 10px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
.main-box {
|
||||
display: flex;
|
||||
padding: 10px 0;
|
||||
|
||||
.right-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
margin-left: 10px;
|
||||
flex-direction: column;
|
||||
|
||||
.nickname-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.nickname {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.oline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.text {
|
||||
font-size: 24rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.un {
|
||||
color: rgb(100, 101, 102);
|
||||
}
|
||||
}
|
||||
|
||||
.city {
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.sex-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 18rpx;
|
||||
|
||||
.sex-tag {
|
||||
font-size: 24rpx;
|
||||
|
||||
.tag {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.fans-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.fans {
|
||||
font-size: 22rpx;
|
||||
color: rgb(100, 101, 102);
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 24rpx;
|
||||
color: rgb(100, 101, 102);
|
||||
line-height: 22rpx;
|
||||
margin-bottom: 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.bt {
|
||||
border-bottom: 1px solid #fbf0f0;
|
||||
}
|
||||
|
||||
.bottom-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.btn-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background-color: #ddd;
|
||||
color: rgb(100, 101, 102);
|
||||
font-size: 22rpx;
|
||||
border-radius: 40px;
|
||||
padding: 5px 10px;
|
||||
margin-left: 10px;
|
||||
min-width: 140rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--ui-BG-Main);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
40
pages/clerk/fans/list.vue
Normal file
40
pages/clerk/fans/list.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<view class="page-app theme-light main-green font-1">
|
||||
<layout ref="order"></layout>
|
||||
|
||||
<s-menu-tools />
|
||||
<s-auth-modal />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import layout from '@/pages/clerk/fans/components/layout.vue';
|
||||
export default {
|
||||
components: {
|
||||
layout,
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-app {
|
||||
background-color: #fafafa;
|
||||
padding-bottom: 140rpx;
|
||||
height: calc(100vh);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user