主管理员 9 months ago
parent
commit
a079eb75de
21 changed files with 1970 additions and 1759 deletions
  1. +1
    -0
      api/http.js
  2. +0
    -3
      api/model/center.js
  3. +71
    -72
      api/model/sharing.js
  4. +1
    -0
      common.scss
  5. +1
    -1
      components/base/tabbar.vue
  6. +84
    -94
      components/center/popupActivate.vue
  7. +71
    -75
      components/home/popupAuditMsg.vue
  8. +5
    -2
      config.js
  9. +1
    -1
      manifest.json
  10. +5
    -0
      mixins/list.js
  11. +109
    -55
      pages/index/center.vue
  12. +52
    -28
      pages/index/index.vue
  13. +319
    -279
      pages/index/record.vue
  14. +1
    -1
      pages_order/auth/wxLogin.vue
  15. +46
    -50
      pages_order/components/popupUnlock.vue
  16. +293
    -311
      pages_order/record/videoSharing.vue
  17. +222
    -206
      pages_order/sharing/article.vue
  18. +220
    -202
      pages_order/sharing/group.vue
  19. +214
    -196
      pages_order/sharing/personal.vue
  20. +216
    -158
      pages_order/sharing/video.vue
  21. +38
    -25
      utils/shareLog.js

+ 1
- 0
api/http.js View File

@ -35,6 +35,7 @@ function http(uri, data, callback, method = 'GET', showLoading, title) {
if(res.statusCode == 401 ||
res.data.message == '操作失败,token非法无效!' ||
res.data.message == '操作失败,用户不存在!'){
uni.removeStorageSync('token')
store.commit('logout')
console.error('登录过期');
utils.toLogin()


+ 0
- 3
api/model/center.js View File

@ -6,7 +6,6 @@ const api = {
getNotice: {
url: '/all_login/getNotice',
method: 'GET',
auth: true,
},
/**
* 获取动态列表
@ -14,7 +13,6 @@ const api = {
getNews: {
url: '/all_login/getNews',
method: 'GET',
auth: true,
},
/**
* 获取新闻动态详情的接口
@ -22,7 +20,6 @@ const api = {
getNewsById: {
url: '/all_login/getNewsById',
method: 'GET',
auth: true,
},
}

+ 71
- 72
api/model/sharing.js View File

@ -1,11 +1,10 @@
const api = {
/**
* 获取个人分享记录详情
*/
/**
* 获取个人分享记录详情
*/
getShareInfo: {
url: '/fen/getShareInfo',
method: 'GET',
auth: true,
debounce: 500,
},
/**
@ -14,130 +13,130 @@ const api = {
addLogShareInfo: {
url: '/fen/addLog',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
limit: 500,
showLoading: true,
},
/**
* 删除分享记录
*/
/**
* 删除分享记录
*/
deleteLog: {
url: '/fen/deleteLog',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
auth: true,
limit: 500,
showLoading: true,
},
/**
* 增加或者修改个人分享
*/
/**
* 增加或者修改个人分享
*/
saveOrUpdateShare: {
url: '/fen/saveOrUpdateShare',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
auth: true,
limit: 500,
showLoading: true,
},
/**
* 获取视频分享记录详情
*/
/**
* 获取视频分享记录详情
*/
getVideoShareInfo: {
url: '/fen/getVideoShareInfo',
method: 'GET',
auth: true,
debounce: 500,
},
/**
* 增加或者修改视频分享
*/
/**
* 增加或者修改视频分享
*/
saveOrUpdateVideoShare: {
url: '/fen/saveOrUpdateVideoShare',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
auth: true,
limit: 500,
showLoading: true,
},
/**
* 获取群分享记录详情
*/
/**
* 获取群分享记录详情
*/
getGroupShareInfo: {
url: '/fen/getGroupShareInfo',
method: 'GET',
auth: true,
debounce: 500,
},
/**
* 增加或者修改群分享
*/
/**
* 增加或者修改群分享
*/
saveOrUpdateGroupShare: {
url: '/fen/saveOrUpdateGroupShare',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
auth: true,
limit: 500,
showLoading: true,
},
/**
* 获取文章分享记录详情
*/
/**
* 获取文章分享记录详情
*/
getArticleShareInfo: {
url: '/fen/getArticleShareInfo',
method: 'GET',
auth: true,
debounce: 500,
},
/**
* 增加或者修改文章分享
*/
/**
* 增加或者修改文章分享
*/
saveOrUpdateArticleShare: {
url: '/fen/saveOrUpdateArticleShare',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
auth: true,
limit: 500,
showLoading: true,
},
/**
* 获取分享记录列表带分页
*/
/**
* 获取分享记录列表带分页
*/
getSharePage: {
url: '/fen/getSharePage',
method: 'GET',
auth: true,
},
/**
* 校验个人转发是否达标
*/
/**
* 校验个人转发是否达标
*/
checkShare: {
url: '/fen/checkShare',
method: 'POST',
auth: true,
showLoading : true,
showLoading: true,
},
/**
* 校验视频转发是否达标
*/
/**
* 校验视频转发是否达标
*/
checkVideoShare: {
url: '/fen/checkVideoShare',
method: 'POST',
auth: true,
showLoading : true,
showLoading: true,
},
/**
* 校验群转发是否达标
*/
/**
* 校验群转发是否达标
*/
checkGroupShare: {
url: '/fen/checkGroupShare',
method: 'POST',
auth: true,
showLoading : true,
showLoading: true,
},
/**
* 校验文章转发是否达标
*/
/**
* 校验文章转发是否达标
*/
checkArticleShare: {
url: '/fen/checkArticleShare',
method: 'POST',
auth: true,
showLoading : true,
showLoading: true,
},
/**
* 查询当前用户分享审核通过的记录条数
*/
queryShareCount: {
url: '/fen/queryShareCount',
method: 'GET',
showLoading: true,
},
}

+ 1
- 0
common.scss View File

@ -29,6 +29,7 @@
justify-content: center !important;
align-items: center !important;
font-size: 26rpx;
line-height: unset;
}
.share::after{
border: none;


+ 1
- 1
components/base/tabbar.vue View File

@ -80,7 +80,7 @@
flex-direction: row;
height: 120rpx;
padding-bottom: env(safe-area-inset-bottom);
z-index: 999999;
z-index: 999;
bottom: 0;
left: 0;
color: #CCCCCC;


+ 84
- 94
components/center/popupActivate.vue View File

@ -1,121 +1,111 @@
<template>
<uv-popup
ref="popup"
:overlayOpacity="0.8"
:customStyle="{
backgroundColor: 'transparent',
}"
>
<view class="flex content">
<template v-if="mode === 'activate'">
<image class="popup-bg" src="@/pages_order/static/center/activate-code.png"></image>
<uv-popup ref="popup" :overlayOpacity="0.8" :customStyle="{
backgroundColor: 'transparent',
}">
<view class="flex content">
<template v-if="mode === 'activate'">
<image class="popup-bg" src="@/pages_order/static/center/activate-code.png"></image>
<view class="flex popup-btns">
<button plain class="btn-simple" @click="close">
<image class="popup-btn" src="@/pages_order/static/center/cancel.png"></image>
</button>
<button plain class="btn-simple" @click="onConfirm">
<image class="popup-btn" src="@/pages_order/static/center/confirm.png"></image>
</button>
</view>
<view class="flex popup-btns">
<button plain class="btn-simple" @click="close">
<image class="popup-btn" src="@/pages_order/static/center/cancel.png"></image>
</button>
<button plain class="btn-simple" @click="onConfirm">
<image class="popup-btn" src="@/pages_order/static/center/confirm.png"></image>
</button>
</view>
<uv-input
v-model="code"
:focus="true"
inputAlign="center"
color="#3DFEE0"
fontSize="45rpx"
border="none"
:customStyle="{
backgroundColor: 'transparent',
width: '250rpx',
height: '63rpx',
position: 'absolute',
top: '216rpx',
left: '160rpx',
}"
></uv-input>
</template>
<template v-else>
<image class="popup-bg" src="@/pages_order/static/center/not-agent.png"></image>
<view class="flex popup-btns">
<button plain class="btn-simple" @click="close">
<image class="popup-btn" src="@/pages_order/static/center/cancel.png"></image>
</button>
<button plain class="btn-simple" @click="mode = 'activate'" >
<image class="popup-btn" src="@/pages_order/static/center/activate.png"></image>
</button>
<uv-input v-model="code" :focus="true" inputAlign="center" color="#3DFEE0" fontSize="45rpx"
border="none" :customStyle="{
backgroundColor: 'transparent',
width: '250rpx',
height: '63rpx',
position: 'absolute',
top: '216rpx',
left: '160rpx',
}"></uv-input>
</template>
<template v-else>
<image class="popup-bg" src="@/pages_order/static/center/not-agent.png"></image>
<view class="flex popup-btns">
<button plain class="btn-simple" @click="close">
<image class="popup-btn" src="@/pages_order/static/center/cancel.png"></image>
</button>
<button plain class="btn-simple" @click="mode = 'activate'">
<image class="popup-btn" src="@/pages_order/static/center/activate.png"></image>
</button>
</view>
</template>
</view>
</template>
</view>
</uv-popup>
</uv-popup>
</template>
<script>
export default {
export default {
props: {
role: {
default: null
}
role: {
default: null
},
},
data() {
return {
mode: '',
code: '',
}
data() {
return {
mode: '',
code: '',
}
},
methods: {
open(role) {
this.mode = role ? 'activate' : ''
this.$refs.popup.open();
},
close() {
this.$refs.popup.close();
},
async onConfirm() {
try {
open(role) {
this.mode = role ? 'activate' : ''
this.$refs.popup.open();
},
close() {
this.$refs.popup.close();
},
async onConfirm() {
await this.$fetch('openVip', { code: this.code })
this.$store.commit('getUserInfo')
try {
uni.showToast({
title: '激活成功',
icon: 'none'
})
this.close()
} catch (err) {
await this.$fetch('openVip', { code: this.code })
}
this.$store.commit('getUserInfo')
uni.showToast({
title: '激活成功',
icon: 'none'
})
}
this.close()
} catch (err) {
}
}
},
}
}
</script>
<style scoped lang="scss">
.content {
position: relative;
flex-direction: column;
width: 570rpx;
position: relative;
flex-direction: column;
width: 570rpx;
}
.popup {
&-bg {
width: 514rpx; height: 355rpx;
}
&-bg {
width: 514rpx;
height: 355rpx;
}
&-btns {
justify-content: space-between;
margin-top: 56rpx;
width: 100%;
}
&-btns {
justify-content: space-between;
margin-top: 56rpx;
width: 100%;
}
&-btn {
width: 265rpx;
height: 84rpx;
}
&-btn {
width: 265rpx;
height: 84rpx;
}
}
</style>

+ 71
- 75
components/home/popupAuditMsg.vue View File

@ -1,94 +1,90 @@
<template>
<uv-popup
ref="popup"
:overlayOpacity="0.8"
:customStyle="{
<uv-popup ref="popup" :overlayOpacity="0.8" :customStyle="{
backgroundColor: 'transparent',
}"
>
<view class="popup">
<image class="popup-bg" src="@/static/image/home/bg-audit-pass.png"></image>
<view class="popup-content flex">
<text class="value">{{ count }}</text>
<image class="unit" src="@/static/image/home/text-share.png"></image>
</view>
<view class="flex popup-btns">
<button plain class="btn-simple" @click="close">
<image class="popup-btn" src="@/static/image/home/cancel.png"></image>
</button>
<button plain class="btn-simple" @click="go">
<image class="popup-btn" src="@/static/image/home/go.png"></image>
</button>
</view>
</view>
</uv-popup>
}">
<view class="popup">
<image class="popup-bg" src="@/static/image/home/bg-audit-pass.png"></image>
<view class="popup-content flex">
<text class="value">{{ count }}</text>
<image class="unit" src="@/static/image/home/text-share.png"></image>
</view>
<view class="flex popup-btns">
<button plain class="btn-simple" @click="close">
<image class="popup-btn" src="@/static/image/home/cancel.png"></image>
</button>
<button plain class="btn-simple" @click="go">
<image class="popup-btn" src="@/static/image/home/go.png"></image>
</button>
</view>
</view>
</uv-popup>
</template>
<script>
export default {
props: {
count: {
type: Number,
default: 15
}
},
props: {
count: {
type: Number,
default: 15
}
},
data() {
return {
}
},
methods: {
open() {
this.$refs.popup.open();
},
close() {
this.$refs.popup.close();
},
go() {
uni.navigateTo({
return {}
},
methods: {
open() {
this.$refs.popup.open();
},
close() {
this.$refs.popup.close();
},
go() {
uni.reLaunch({
url: `/pages/index/record`
})
},
},
}
},
},
}
</script>
<style scoped lang="scss">
.popup {
position: relative;
width: 578rpx;
.popup {
position: relative;
width: 578rpx;
&-bg {
width: 578rpx; height: 317rpx;
}
&-bg {
width: 578rpx;
height: 317rpx;
}
&-content {
position: absolute;
top: 123rpx;
left: 50%;
transform: translateX(-50%);
&-content {
position: absolute;
top: 123rpx;
left: 50%;
transform: translateX(-50%);
.value {
color: #FF2323;
font-size: 102rpx;
font-weight: 700;
line-height: 125rpx;
}
.value {
color: #FF2323;
font-size: 102rpx;
font-weight: 700;
line-height: 125rpx;
}
.unit {
width: 299rpx;
height: 77rpx;
margin-left: 9rpx;
}
}
.unit {
width: 299rpx;
height: 77rpx;
margin-left: 9rpx;
}
}
&-btns {
justify-content: space-between;
margin-top: 56rpx;
}
&-btns {
justify-content: space-between;
margin-top: 56rpx;
}
&-btn {
width: 265rpx;
height: 84rpx;
}
}
&-btn {
width: 265rpx;
height: 84rpx;
}
}
</style>

+ 5
- 2
config.js View File

@ -8,13 +8,16 @@ import uvUI from '@/uni_modules/uv-ui-tools'
Vue.use(uvUI);
// 当前环境
const type = 'prod'
const type = 'dev'
// 环境配置
const config = {
dev : {
baseUrl : 'http://h5.xzaiyp.top/fission-star-api',
baseUrl : 'http://h5.xzaiyp.top/lbx-api',
},
test : {
baseUrl : 'https://fission-star-api.hhlm1688.com/lbx-api',
},
prod : {
baseUrl : 'https://www.liebianxing.site/lbx-api',


+ 1
- 1
manifest.json View File

@ -1,6 +1,6 @@
{
"name" : "unapp模板",
"appid" : "__UNI__A010721",
"appid" : "__UNI__197A38F",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",


+ 5
- 0
mixins/list.js View File

@ -46,6 +46,11 @@ export default {
* @returns {Promise} 返回Promise对象
*/
getData(queryParams){
if(this.authApi && !uni.getStorageSync('token')){
return
}
return new Promise((success, error) => {
if(!this.mixinsListApi){
return console.error('mixinsListApi 缺失');


+ 109
- 55
pages/index/center.vue View File

@ -4,27 +4,28 @@
<navbar title="个人中心" bgColor="#001B3C" color="#FFFFFF" />
<view class="head">
<view class="headImage" @click="goToEditUserInfo">
<image :src="userInfo.headImage" mode=""></image>
<view class="headImage" @click="goToEditUserInfo">
<image :src="userInfo.headImage || '../../static/image/default-avatar.png'" mode=""></image>
</view>
<view class="info">
<view class="name" @click="goToEditUserInfo">
{{ userInfo.nickName }}
<view class="name" @click="goToEditUserInfo">
{{ userInfo.nickName || '未登录' }}
</view>
<view class="tags">
<view class="tag">
<view class="tag" v-if="userInfo.intentionCode">
<text class="tag-label">ID:</text>
<text>{{ userInfo.intentionCode }}</text>
</view>
<view v-if="role" style="display: inline-block; width: 172rpx; height: 63rpx; vertical-align: top; margin-top: -6rpx;">
<view v-if="role"
style="display: inline-block; width: 172rpx; height: 63rpx; vertical-align: top; margin-top: -6rpx;">
<image src="@/pages_order/static/center/agent-icon.png"></image>
</view>
<!-- <view v-else class="tag" >
代理商:{{userInfo.endTime}} 到期
</view> -->
<view v-else class="tag">
<view v-else-if="userInfo.id" class="tag">
普通会员
</view>
<view v-else class="tag" @click="goToLogin">
点击登录
</view>
</view>
</view>
<view class="setting" @click="$utils.navigateTo('/pages_order/mine/setting')">
@ -39,7 +40,8 @@
<view class="activate-tips" style="padding-left: 27rpx;">
<view>代理商权益</view>
<view>
将于<text class="activate-highlight">{{ userInfo.endTime ? $dayjs(userInfo.endTime).format('YYYY年M月D日') : '-'}}</text>到期
将于<text class="activate-highlight">{{ userInfo.endTime ?
$dayjs(userInfo.endTime).format('YYYY年M月D日') : '-'}}</text>到期
</view>
</view>
<view class="btn-activate" @click="onActivate">
@ -68,18 +70,42 @@
</view>
<text>激活码</text>
</view>
<view class="tool" @click="$utils.navigateTo('/pages_order/mine/wallet')">
<view class="tool-icon">
<image src="@/pages_order/static/center/tool-wallet.png"></image>
<!-- <button open-type="contact" class="share">
<view class="tool">
<view class="tool-icon tool-icon-bg">
<uv-icon name="server-fill" color="#05d9a2" size="56rpx" />
</view>
<text>联系客服</text>
</view>
<text>我的钱包</text>
</button> -->
<view class="tool" @click="$utils.navigateTo('/pages_order/mine/service')">
<view class="tool-icon tool-icon-bg">
<uv-icon name="server-fill" color="#05d9a2" size="56rpx" />
</view>
<text>联系客服</text>
</view>
<view class="tool" @click="$utils.navigateTo('/pages_order/mine/team')">
<view class="tool-icon">
<image src="@/pages_order/static/center/tool-team.png"></image>
<view class="tool" @click="$refs.configPopup.open('user_ys')">
<view class="tool-icon tool-icon-bg">
<uv-icon name="question-circle" color="#05d9a2" size="56rpx" />
</view>
<text>我的团队</text>
<text>隐私政策</text>
</view>
<!-- <view class="tool" @click="$utils.navigateTo('/pages_order/mine/wallet')">
<view class="tool-icon">
<image src="@/pages_order/static/center/tool-wallet.png"></image>
</view>
<text>我的钱包</text>
</view>
<view class="tool" @click="$utils.navigateTo('/pages_order/mine/team')">
<view class="tool-icon">
<image src="@/pages_order/static/center/tool-team.png"></image>
</view>
<text>我的团队</text>
</view> -->
</view>
</view>
@ -88,16 +114,10 @@
<view class="notice-icon">
<image src="@/pages_order/static/center/notice.png"></image>
</view>
<uv-notice-bar
:text="notice"
bgColor="transparent"
color="#001B3C"
:icon="false"
fontSize="28rpx"
<uv-notice-bar :text="notice" bgColor="transparent" color="#001B3C" :icon="false" fontSize="28rpx"
:customStyle="{
padding: '6rpx 0',
}"
></uv-notice-bar>
padding: '6rpx 0',
}"></uv-notice-bar>
</view>
<view class="card updates">
@ -110,43 +130,44 @@
</view>
</view>
<view class="updates-content">
<view class="card updates-item"
v-for="item in list"
:key="item.id"
@click="goToNewsDetail(item.id)"
>
<view class="card updates-item" v-for="item in list" :key="item.id"
@click="goToNewsDetail(item.id)">
<view class="updates-item-img">
<image :src="item.image"></image>
</view>
<view class="updates-item-info">
<view class="updates-item-title">{{ item.title || '' }}</view>
<view class="updates-item-desc text-ellipsis">{{ getDesc(item.details) }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="service" @click="$utils.navigateTo('/pages_order/mine/service')">
<!-- <view class="service" @click="$utils.navigateTo('/pages_order/mine/service')">
<image src="@/pages_order/static/center/service.png" mode=""></image>
</view>
</view> -->
<popupActivate ref="popupActivate"></popupActivate>
<popupSharing ref="popupSharing"></popupSharing>
<configPopup ref="configPopup" />
<tabber select="center" />
</view>
</template>
<script>
import { mapState } from 'vuex'
import {
mapState
} from 'vuex'
import mixinsList from '@/mixins/list.js'
import popupActivate from '@/components/center/popupActivate.vue'
import tabber from '@/components/base/tabbar.vue'
export default {
mixins : [mixinsList],
mixins: [mixinsList],
components: {
tabber,
popupActivate,
@ -154,30 +175,40 @@
data() {
return {
notice: '',
mixinsListApi : 'getNews',
mixinsListApi: 'getNews',
authApi: false,
isLoggedIn: uni.getStorageSync('token'),
}
},
computed: {
...mapState(['userInfo', 'userInfoVip']),
role() {
return this.userInfo.isPay
}
},
},
onShow() {
this.fetchNotice()
this.$store.commit('getUserInfo')
this.$store.commit('getUserInfoVip')
this.isLoggedIn = uni.getStorageSync('token')
if (this.isLoggedIn) {
this.$store.commit('getUserInfo')
this.$store.commit('getUserInfoVip')
}
},
methods: {
async fetchNotice() {
try {
try {
// todo: check
this.notice = (await this.$fetch('getNotice'))?.[0]?.title
} catch (err) {
}
this.notice = (await this.$fetch('getNotice'))?.[0]?.title
} catch (err) {
}
},
onActivate() {
if (!this.isLoggedIn) {
this.goToLogin()
return
}
this.$refs.popupActivate.open(this.role)
},
getDesc(str) {
@ -193,10 +224,19 @@
})
},
goToEditUserInfo() {
if (!this.isLoggedIn) {
this.goToLogin()
return
}
uni.navigateTo({
url: '/pages_order/auth/wxUserInfo?mode=edit'
})
},
goToLogin() {
uni.navigateTo({
url: '/pages_order/auth/wxLogin'
})
},
}
}
</script>
@ -234,9 +274,7 @@
margin-bottom: 12rpx;
}
.tags {
}
.tags {}
}
.setting {
@ -245,7 +283,7 @@
top: 37rpx;
}
}
.tag {
display: inline-block;
padding: 6rpx 21rpx;
@ -276,10 +314,26 @@
width: calc(100vw - 69rpx*2);
left: 69rpx;
bottom: 64rpx;
justify-content: space-between;
.tool{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.tool-icon-bg {
width: 90rpx;
height: 90rpx;
background-color: #001B3C;
border-radius: 15rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
.activate {
position: absolute;
@ -289,7 +343,7 @@
right: 37rpx;
&-tips {
flex: 1;
flex: 1;
color: #976224;
font-size: 28rpx;
}
@ -327,6 +381,7 @@
.notice {
padding: 22rpx 21rpx;
display: flex;
&-icon {
width: 49rpx;
height: 49rpx;
@ -391,5 +446,4 @@
width: 149rpx;
height: 158rpx;
}
</style>

+ 52
- 28
pages/index/index.vue View File

@ -5,45 +5,40 @@
<view class="content">
<navbar title="首页" bgColor="transparent" color="#FFFFFF" />
<view class="btns">
<button
v-for="item in list"
:key="item.title"
class="btn"
plain
@click="onClick(item.path)"
>
<button v-for="item in list" :key="item.title" class="btn" plain @click="onClick(item.path)">
{{ item.title }}
</button>
</view>
</view>
<popupAuditMsg ref="popupAuditMsgRef"></popupAuditMsg>
<popupAuditMsg ref="popupAuditMsgRef" :count="count"></popupAuditMsg>
<popupActivate ref="popupActivate"></popupActivate>
<tabber select="home"/>
<tabber select="home" />
</view>
</template>
<script>
import { mapState } from 'vuex'
<script>
import {
mapState
} from 'vuex'
import tabber from '@/components/base/tabbar.vue'
import popupAuditMsg from '@/components/home/popupAuditMsg.vue'
import popupActivate from '@/components/center/popupActivate.vue'
export default {
components : {
components: {
tabber,
popupAuditMsg,
popupActivate,
},
data() {
return {
list: [
{
list: [{
title: '个人分享',
path: '/pages_order/record/personalSharing'
},
@ -59,29 +54,38 @@
title: '文章分享',
path: '/pages_order/record/articleSharing'
},
// {
// title: '',
// path: '/pages_order/sharing/video?id=1922875315630133249'
// },
],
count : 0,
}
},
computed: {
computed: {
...mapState(['userInfo']),
},
onLoad(option) {
const { id, state, shareId } = option
const {
id,
state,
shareId
} = option
if (shareId) {
uni.setStorageSync('shareId', shareId)
}
if (state) {
uni.setStorageSync('state', state)
}
if (id) {
uni.setStorageSync('id', id)
}
if (shareId && !uni.getStorageSync('token')) {
uni.navigateTo({
url: '/pages_order/auth/wxLogin'
})
@ -91,9 +95,21 @@
if (uni.getStorageSync('token') && !this.userInfo?.id) {
this.$store.commit('getUserInfo')
this.queryShareCount()
}
},
onShow() {
},
methods: {
queryShareCount(){
this.$fetch('queryShareCount')
.then(result => {
if(result > 0){
this.count = result
this.$refs.popupAuditMsgRef.open()
}
})
},
onClick(url) {
if (!uni.getStorageSync('token')) {
uni.navigateTo({
@ -106,22 +122,31 @@
this.$refs.popupActivate.open()
return
}
if(this.$dayjs(this.userInfo.endTime).isBefore(this.$dayjs())){
uni.showToast({
title: '代理已过期',
icon: 'none'
})
this.$refs.popupActivate.open(true)
return
}
this.$utils.navigateTo(url)
}
},
},
}
</script>
<style scoped lang="scss">
.page{
& /deep/ .uv-icon__icon{
.page {
& /deep/ .uv-icon__icon {
font-size: 30rpx !important;
}
position: relative;
height: 100vh;
overflow: hidden;
overflow: hidden;
.btns {
display: grid;
@ -154,5 +179,4 @@
height: 100vh;
top: 0;
}
</style>
</style>

+ 319
- 279
pages/index/record.vue View File

@ -1,287 +1,327 @@
<template>
<view class="page">
<navbar title="分享记录" />
<view class="content">
<view class="card" style="padding-left: 0; padding-right: 10rpx;">
<uv-tabs
:list="tabs"
@click="clickTabs"
:inactiveStyle="{
color: '#999999',
fontSize: '30rpx',
fontWeight: 500,
whiteSpace: 'nowrap',
}"
:activeStyle="{
color: '#1B1B1B',
fontSize: '38rpx',
fontWeight: 900,
whiteSpace: 'nowrap',
}"
lineHeight="13rpx"
lineWidth="77rpx"
:lineColor="`url(${sliderBgUrl}) 100% 100%`"
:scrollable="false"
>
<template v-slot:right>
<suspendDropdown
v-model="status"
:options="auditStatusOptions"
@change="onAuditStatusChange"
></suspendDropdown>
</template>
</uv-tabs>
</view>
<view v-if="list.length" class="card list">
<view class="list-item"
v-for="item in list"
@click="toSharingDetail(item.id)"
:key="item.id"
>
<!-- todo: video? -->
<image class="left" :src="item.indexImage || item.headImage"></image>
<view class="right">
<view class="title">{{ item.headTitle || '' }}</view>
<view class="desc">{{ item.textDetails || '' }}</view>
<view class="bottom">
<text class="desc">{{ item.createTime || '' }}</text>
<button plain class="btn-simple btn-delete flex" @click.stop="onDelete(item.id)">
<image src="../../static/image/record/delete.png" style="width: 24rpx; height: 24rpx;"></image>
<text style="margin-left: 10rpx;">删除</text>
</button>
</view>
<view class="mark">
<image
:src="auditStatusImgMapping[item.status]"
style="width: 100rpx; height: 100rpx;"
></image>
</view>
</view>
</view>
</view>
<!-- todo: empty -->
</view>
<popupActivate ref="popupActivate"></popupActivate>
<tabber select="record"/>
</view>
<view class="page">
<navbar title="分享记录" />
<view class="content">
<view class="card" style="padding-left: 0; padding-right: 10rpx;">
<uv-tabs :list="tabs" @click="clickTabs" :inactiveStyle="{
color: '#999999',
fontSize: '30rpx',
fontWeight: 500,
whiteSpace: 'nowrap',
}" :activeStyle="{
color: '#1B1B1B',
fontSize: '38rpx',
fontWeight: 900,
whiteSpace: 'nowrap',
}" lineHeight="13rpx" lineWidth="77rpx" :lineColor="`url(${sliderBgUrl}) 100% 100%`" :scrollable="false">
<template v-slot:right>
<suspendDropdown v-model="status" :options="auditStatusOptions" @change="onAuditStatusChange">
</suspendDropdown>
</template>
</uv-tabs>
</view>
<view v-if="!isLoggedIn" class="card login-tip">
<view class="login-tip-text">登录后查看分享记录</view>
<button class="btn-login" @click="goToLogin">立即登录</button>
</view>
<view v-else-if="list.length" class="card list">
<view class="list-item" v-for="item in list" @click="toSharingDetail(item.id)" :key="item.id">
<!-- todo: video? -->
<image class="left" :src="item.indexImage || item.headImage"></image>
<view class="right">
<view class="title">{{ item.headTitle || '' }}</view>
<view class="desc">{{ item.textDetails || '' }}</view>
<view class="bottom">
<text class="desc">{{ item.createTime || '' }}</text>
<button plain class="btn-simple btn-delete flex" @click.stop="onDelete(item.id)">
<image src="../../static/image/record/delete.png" style="width: 24rpx; height: 24rpx;">
</image>
<text style="margin-left: 10rpx;">删除</text>
</button>
</view>
<view class="mark">
<image :src="auditStatusImgMapping[item.status]" style="width: 100rpx; height: 100rpx;">
</image>
</view>
</view>
</view>
</view>
<!-- todo: empty -->
</view>
<popupActivate ref="popupActivate"></popupActivate>
<tabber select="record" />
</view>
</template>
<script>
import { mapGetters } from 'vuex'
import mixinsList from '@/mixins/list.js'
import tabber from '@/components/base/tabbar.vue'
import suspendDropdown from '@/components/base/suspendDropdown.vue'
import popupActivate from '@/components/center/popupActivate.vue'
const URL_MAPPING = { // state -> url
'0': '/pages_order/record/personalSharing',
'1': '/pages_order/record/videoSharing',
'2': '/pages_order/record/groupSharing',
'3': '/pages_order/record/articleSharing',
}
export default {
mixins : [mixinsList],
components : {
tabber,
suspendDropdown,
popupActivate,
},
computed : {
...mapGetters(['userShop']),
},
data() {
return {
tabs: [{
name: '个人分享'
},
{
name: '视频分享'
},
{
name: '群分享'
},
{
name: '文章分享'
},
],
auditStatusOptions: [
{
label: '审核中',
value: 0,
},
{
label: '已通过',
value: 1,
},
{
label: '未通过',
value: 2,
},
],
queryParams: {
pageNo: 1,
pageSize: 10,
state: 0,
},
status: null,
recordList : { //
records : [],
total : 0,
},
auditStatusImgMapping: {
0: '../../static/image/record/audit.png', //
1: '../../static/image/record/pass.png', //
2: '../../static/image/record/fail.png', //
},
// todo
sliderBgUrl: '',
mixinsListApi : 'getSharePage',
}
},
methods: {
//tab
clickTabs(e) {
this.queryParams.state = e.index
this.queryParams.pageNo = 1
this.queryParams.pageSize = 10
this.getData()
},
onAuditStatusChange(status) {
this.status = status
this.queryParams.pageNo = 1
this.queryParams.pageSize = 10
if (status === null) {
delete this.queryParams.status
} else {
this.queryParams.status = status
}
this.getData()
},
//
toSharingDetail(id) {
if (!this.userInfo.isPay) {
this.$refs.popupActivate.open()
return
}
uni.navigateTo({
url: `${URL_MAPPING[this.queryParams.state]}?id=${id}`
})
},
onDelete(id) {
uni.showModal({
title: '确认删除该分享吗',
success: async (r) => {
if(r.confirm){
await this.$fetch('deleteLog', { id, state: this.queryParams.state })
this.getData()
}
}
})
},
}
}
import { mapGetters } from 'vuex'
import mixinsList from '@/mixins/list.js'
import tabber from '@/components/base/tabbar.vue'
import suspendDropdown from '@/components/base/suspendDropdown.vue'
import popupActivate from '@/components/center/popupActivate.vue'
const URL_MAPPING = { // state -> url
'0': '/pages_order/record/personalSharing',
'1': '/pages_order/record/videoSharing',
'2': '/pages_order/record/groupSharing',
'3': '/pages_order/record/articleSharing',
}
export default {
mixins: [mixinsList],
components: {
tabber,
suspendDropdown,
popupActivate,
},
computed: {
...mapGetters(['userShop']),
},
data() {
return {
tabs: [{
name: '个人分享'
},
{
name: '视频分享'
},
{
name: '群分享'
},
{
name: '文章分享'
},
],
auditStatusOptions: [
{
label: '审核中',
value: 0,
},
{
label: '已通过',
value: 1,
},
{
label: '未通过',
value: 2,
},
],
queryParams: {
pageNo: 1,
pageSize: 10,
state: 0,
},
status: null,
recordList: { //
records: [],
total: 0,
},
auditStatusImgMapping: {
0: '../../static/image/record/audit.png', //
1: '../../static/image/record/pass.png', //
2: '../../static/image/record/fail.png', //
},
// todo
sliderBgUrl: '',
mixinsListApi: 'getSharePage',
authApi : true,
isLoggedIn : uni.getStorageSync('token'),
}
},
onShow(){
this.isLoggedIn = uni.getStorageSync('token')
},
methods: {
//tab
clickTabs(e) {
if (!this.isLoggedIn) {
this.goToLogin()
return
}
this.queryParams.state = e.index
this.queryParams.pageNo = 1
this.queryParams.pageSize = 10
this.getData()
},
onAuditStatusChange(status) {
if (!this.isLoggedIn) {
this.goToLogin()
return
}
this.status = status
this.queryParams.pageNo = 1
this.queryParams.pageSize = 10
if (status === null) {
delete this.queryParams.status
} else {
this.queryParams.status = status
}
this.getData()
},
//
toSharingDetail(id) {
if (!this.isLoggedIn) {
this.goToLogin()
return
}
if (!this.userInfo.isPay) {
this.$refs.popupActivate.open()
return
}
uni.navigateTo({
url: `${URL_MAPPING[this.queryParams.state]}?id=${id}`
})
},
onDelete(id) {
if (!this.isLoggedIn) {
this.goToLogin()
return
}
uni.showModal({
title: '确认删除该分享吗',
success: async (r) => {
if (r.confirm) {
await this.$fetch('deleteLog', { id, state: this.queryParams.state })
this.getData()
}
}
})
},
goToLogin() {
uni.navigateTo({
url: '/pages_order/auth/wxLogin'
})
},
}
}
</script>
<style scoped lang="scss">
.page{
}
.content {
padding: 20rpx;
}
.list {
margin-top: 20rpx;
padding: 40rpx 59rpx 40rpx 43rpx;
&-item {
font-size: 0;
display: flex;
& + & {
margin-top: 40rpx;
}
.left {
width: 220rpx;
height: 148rpx;
}
.right {
flex: 1;
width: calc(100% - 220rpx);
padding-left: 20rpx;
box-sizing: border-box;
position: relative;
}
}
.title {
color: #1B1B1B;
font-size: 28rpx;
}
.desc {
color: #999999;
font-size: 24rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}
.title + .desc {
margin-top: 18rpx;
}
.bottom {
position: absolute;
bottom: 0;
width: calc(100% - 20rpx);
}
.btn-delete {
float: right;
color: #05D9A2;
font-size: 20rpx;
}
.mark {
position: absolute;
top: 10rpx;
right: 5rpx;
}
}
.popup {
&-options {
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
padding: 16rpx 40rpx;
}
&-option {
color: #999999;
font-size: 28rpx;
&.is-active {
color: #1B1B1B;
font-weight: 700;
}
& + & {
margin-top: 16rpx;
}
}
}
.page {}
.content {
padding: 20rpx;
}
.list {
margin-top: 20rpx;
padding: 40rpx 59rpx 40rpx 43rpx;
&-item {
font-size: 0;
display: flex;
&+& {
margin-top: 40rpx;
}
.left {
width: 220rpx;
height: 148rpx;
}
.right {
flex: 1;
width: calc(100% - 220rpx);
padding-left: 20rpx;
box-sizing: border-box;
position: relative;
}
}
.title {
color: #1B1B1B;
font-size: 28rpx;
overflow:hidden; //
text-overflow:ellipsis; //
white-space:nowrap; //
}
.desc {
color: #999999;
font-size: 24rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}
.title+.desc {
margin-top: 18rpx;
}
.bottom {
position: absolute;
bottom: 0;
width: calc(100% - 20rpx);
}
.btn-delete {
float: right;
color: #05D9A2;
font-size: 20rpx;
}
.mark {
position: absolute;
top: 10rpx;
right: 5rpx;
}
}
.popup {
&-options {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
padding: 16rpx 40rpx;
}
&-option {
color: #999999;
font-size: 28rpx;
&.is-active {
color: #1B1B1B;
font-weight: 700;
}
&+& {
margin-top: 16rpx;
}
}
}
.login-tip {
margin-top: 20rpx;
padding: 40rpx;
text-align: center;
&-text {
color: #999999;
font-size: 28rpx;
margin-bottom: 20rpx;
}
}
.btn-login {
width: 240rpx;
height: 80rpx;
line-height: 80rpx;
background: #04D6A3;
color: #FFFFFF;
font-size: 28rpx;
border-radius: 40rpx;
margin: 0 auto;
}
</style>

+ 1
- 1
pages_order/auth/wxLogin.vue View File

@ -17,7 +17,7 @@
class="btn"
@click="wxLogin"
>
微信登录
授权登录
</button>
<button class="btn btn-cancel" :plain="true" :hairline="false" @click="onCancel">


+ 46
- 50
pages_order/components/popupUnlock.vue View File

@ -1,63 +1,59 @@
<template>
<uv-popup
ref="popup"
:overlayOpacity="0.8"
:customStyle="{
<uv-popup ref="popup" :overlayOpacity="0.8" :customStyle="{
backgroundColor: 'transparent',
}"
>
<view>
<image class="popup-bg" :src="src"></image>
<view class="flex popup-btns">
<button plain class="btn-simple" @click="close">
<image class="popup-btn" src="../static/sharing/cancel.png"></image>
</button>
<button plain class="btn-simple" open-type="share">
<image class="popup-btn" src="../static/sharing/forward.png"></image>
</button>
</view>
</view>
</uv-popup>
}">
<view>
<image class="popup-bg" :src="src"></image>
<view class="flex popup-btns">
<button plain class="btn-simple" @click="close">
<image class="popup-btn" src="../static/sharing/cancel.png"></image>
</button>
<button plain class="btn-simple" open-type="share">
<image class="popup-btn" src="../static/sharing/forward.png"></image>
</button>
</view>
</view>
</uv-popup>
</template>
<script>
export default {
props: {
src: {
type: String,
default: null
}
},
props: {
src: {
type: String,
default: null
}
},
data() {
return {
}
},
methods: {
open() {
this.$refs.popup.open();
},
close() {
console.log('--close popup')
this.$refs.popup.close();
},
},
}
return {}
},
methods: {
open() {
this.$refs.popup.open();
},
close() {
console.log('--close popup')
this.$refs.popup.close();
},
},
}
</script>
<style scoped lang="scss">
.popup {
&-bg {
width: 578rpx; height: 317rpx;
}
.popup {
&-bg {
width: 578rpx;
height: 317rpx;
}
&-btns {
justify-content: space-between;
margin-top: 56rpx;
}
&-btns {
justify-content: space-between;
margin-top: 56rpx;
}
&-btn {
width: 265rpx;
height: 84rpx;
}
}
&-btn {
width: 265rpx;
height: 84rpx;
}
}
</style>

+ 293
- 311
pages_order/record/videoSharing.vue View File

@ -1,158 +1,138 @@
<template>
<view class="page">
<view class="page">
<navbar title="视频分享" leftClick @leftClick="$utils.navigateBack" />
<view class="content">
<uv-form
ref="form"
:model="form"
:rules="rules"
labelPosition="left"
labelWidth="340rpx"
:labelStyle="{
<view class="content">
<uv-form ref="form" :model="form" :rules="rules" labelPosition="left" labelWidth="340rpx" :labelStyle="{
color: '#1B1B1B',
fontSize: '32rpx',
fontWeight: 'bold',
}"
errorType="toast"
>
<view class="flex upload__view">
<view class="upload upload-cover">
<uv-form-item labelWidth="0" prop="indexImage">
<formUpload v-model="form.indexImage">
<template v-slot="{ value }">
<!-- todo: 默认 -->
<image
:src="value"
mode="aspectFill"
style="width: 344rpx; height: 344rpx;"
radius="14rpx"
/>
</template>
</formUpload>
<view class="upload-cover-text flex">设置封面</view>
</uv-form-item>
</view>
<view class="upload upload-video">
<uv-form-item labelWidth="0" prop="vio">
<formUpload v-model="form.vio" accept="video">
<template v-slot>
<video v-if="form.vio"
:src="form.vio"
style="width: 344rpx; height: 344rpx;"
radius="14rpx"
:controls="false"
:autoplay="false"
:show-center-play-btn="false"
></video>
<view v-else class="flex flex-column" style="width: 344rpx; height: 344rpx;">
<image src="../static/record/icon-camera.png" style="width: 130rpx; height: 105rpx;" ></image>
<text class="upload-video-text">上传视频</text>
</view>
</template>
</formUpload>
</uv-form-item>
</view>
</view>
<view class="form-item">
<uv-form-item label="标题" labelWidth="84rpx" prop="headTitle">
<view class="form-item-content">
<formInput v-model="form.headTitle" placeholder="请输入你的视频名称" width="584rpx"></formInput>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item label="设置广告弹出时间(s)" prop="timeNum">
<view class="form-item-content">
<formNumberBox v-model="form.timeNum" ></formNumberBox>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item label="设置转发次数(次)" prop="num">
<view class="form-item-content">
<formNumberBox v-model="form.num" ></formNumberBox>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item label="选择二维码" prop="wxCodeImage">
<view class="form-item-content">
<formUpload v-model="form.wxCodeImage">
<template v-slot="{ value }">
<view class="flex" style="min-width: 93rpx; height: 45rpx;">
<image
:src="value"
mode="aspectFill"
style="width: 45rpx; height: 45rpx;"
radius="14rpx"
/>
<uv-icon style="margin-left: 20rpx" name="arrow-right" color="#000000" size="28rpx"></uv-icon>
</view>
</template>
</formUpload>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item label="视频描述" prop="textDetails" labelPosition="top">
<view style="margin-top: 32rpx;">
<formTextarea
v-model="form.textDetails"
placeholder="请描述你的视频"
></formTextarea>
</view>
</uv-form-item>
</view>
</uv-form>
</view>
<!-- 审核通过 -->
<button v-if="status === 1" class="button-submit" open-type="share">
发布
</button>
<!-- 不是 审核中 已发布 -> 创建分享 审核不通过 -->
<button v-else-if="![0,1].includes(status)" class="button-submit" @click="preSubmit">
提交审核
</button>
<autoCrop ref="autoCropRef" @change="onSubmit"></autoCrop>
</view>
}" errorType="toast">
<view class="flex upload__view">
<view class="upload upload-cover">
<uv-form-item labelWidth="0" prop="indexImage">
<formUpload v-model="form.indexImage">
<template v-slot="{ value }">
<!-- todo: 默认 -->
<image :src="value" mode="aspectFill" style="width: 344rpx; height: 344rpx;"
radius="14rpx" />
</template>
</formUpload>
<view class="upload-cover-text flex">设置封面</view>
</uv-form-item>
</view>
<view class="upload upload-video">
<uv-form-item labelWidth="0" prop="vio">
<formUpload v-model="form.vio" accept="video">
<template v-slot>
<video v-if="form.vio" :src="form.vio" style="width: 344rpx; height: 344rpx;"
radius="14rpx" :controls="false" :autoplay="false"
:show-center-play-btn="false"></video>
<view v-else class="flex flex-column" style="width: 344rpx; height: 344rpx;">
<image src="../static/record/icon-camera.png"
style="width: 130rpx; height: 105rpx;"></image>
<text class="upload-video-text">上传视频</text>
</view>
</template>
</formUpload>
</uv-form-item>
</view>
</view>
<view class="form-item">
<uv-form-item label="标题" labelWidth="84rpx" prop="headTitle">
<view class="form-item-content">
<formInput v-model="form.headTitle" placeholder="请输入你的视频名称" width="584rpx"></formInput>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item label="设置广告弹出时间(s)" prop="timeNum">
<view class="form-item-content">
<formNumberBox v-model="form.timeNum"></formNumberBox>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item label="设置转发次数(次)" prop="num">
<view class="form-item-content">
<formNumberBox v-model="form.num"></formNumberBox>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item label="选择二维码" prop="wxCodeImage">
<view class="form-item-content">
<formUpload v-model="form.wxCodeImage">
<template v-slot="{ value }">
<view class="flex" style="min-width: 93rpx; height: 45rpx;">
<image :src="value" mode="aspectFill" style="width: 45rpx; height: 45rpx;"
radius="14rpx" />
<uv-icon style="margin-left: 20rpx" name="arrow-right" color="#000000"
size="28rpx"></uv-icon>
</view>
</template>
</formUpload>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item label="视频描述" prop="textDetails" labelPosition="top">
<view style="margin-top: 32rpx;">
<formTextarea v-model="form.textDetails" placeholder="请描述你的视频"></formTextarea>
</view>
</uv-form-item>
</view>
</uv-form>
</view>
<!-- 审核通过 -->
<button v-if="status === 1" class="button-submit" open-type="share">
发布
</button>
<!-- 不是 审核中 已发布 -> 创建分享 审核不通过 -->
<button v-else-if="![0,1].includes(status)" class="button-submit" @click="preSubmit">
提交审核
</button>
<autoCrop ref="autoCropRef" @change="onSubmit"></autoCrop>
</view>
</template>
<script>
import { mapState } from 'vuex'
import shareLog from '@/utils/shareLog'
import {
mapState
} from 'vuex'
import shareLog from '@/utils/shareLog'
import formUpload from '../components/formUpload.vue'
import formInput from '../components/formInput.vue'
import formNumberBox from '../components/formNumberBox.vue'
import formTextarea from '../components/formTextarea.vue'
import autoCrop from '../components/autoCrop.vue'
import formUpload from '../components/formUpload.vue'
import formInput from '../components/formInput.vue'
import formNumberBox from '../components/formNumberBox.vue'
import formTextarea from '../components/formTextarea.vue'
import autoCrop from '../components/autoCrop.vue'
export default {
components: {
formUpload,
formInput,
formNumberBox,
formTextarea,
autoCrop,
},
components: {
formUpload,
formInput,
formNumberBox,
formTextarea,
autoCrop,
},
data() {
return {
id: null,
status: null,
form: {
headTitle: null,
indexImage: null,
vio: null,
timeNum: 0,
num: 0,
wxCodeImage: null,
textDetails: null,
},
rules: {
return {
id: null,
status: null,
form: {
headTitle: null,
indexImage: null,
vio: null,
timeNum: 0,
num: 0,
wxCodeImage: null,
textDetails: null,
},
rules: {
'indexImage': {
type: 'string',
required: true,
@ -172,11 +152,11 @@
type: 'number',
required: true,
message: '请设置广告弹出时间(大于1)',
validator: (rule, value, callback) => {
if (value > 1) {
return true
}
validator: (rule, value, callback) => {
if (value > 1) {
return true
}
return false;
},
},
@ -184,11 +164,11 @@
type: 'number',
required: true,
message: '请设置转发次数(大于0)',
validator: (rule, value, callback) => {
if (value > 0) {
return true
}
validator: (rule, value, callback) => {
if (value > 0) {
return true
}
return false;
},
},
@ -203,177 +183,179 @@
message: '请描述你的视频',
},
},
}
},
}
},
computed: {
...mapState(['userInfo']),
},
onLoad(option) {
const { id } = option
const {
id
} = option
if (!id) {
return
}
if (!id) {
return
}
this.id = id
this.id = id
this.fetchDetails(id)
this.fetchDetails(id)
},
onReady() {
this.$refs.form.setRules(this.rules);
},
onShareAppMessage(res) {
const {
headTitle,
indexImage,
} = this.form
let o = {
title : headTitle,
imageUrl: indexImage,
path: `/pages_order/sharing/video?id=${this.id}&state=1&shareId=${this.userInfo.id}`
}
//
const params = {
id:this.id,
state:"1",
}
this.$fetch('addLogShareInfo', params)
// todo: get times and check is unlocked
shareLog.insert(this.id)
this.isLocked = false
return o
},
methods: {
async fetchDetails(id) {
try {
const result = await this.$fetch('getVideoShareInfo', { id })
const {
headTitle,
indexImage,
vio,
timeNum,
num,
wxCodeImage,
textDetails,
status,
} = result || {}
this.form = {
headTitle,
indexImage,
vio,
timeNum,
num,
wxCodeImage,
textDetails,
}
this.status = status
} catch (err) {
}
},
async preSubmit() {
try {
await this.$refs.form.validate()
this.$refs.autoCropRef.set(this.form.indexImage)
} catch (err) {
}
},
async onSubmit(indexImage) {
try {
await this.$refs.form.validate()
const {
headTitle,
vio,
timeNum,
num,
wxCodeImage,
textDetails,
} = this.form
const params = {
headTitle,
indexImage,
vio,
timeNum,
num,
wxCodeImage,
textDetails,
}
if (this.id) {
params.id = this.id
}
await this.$fetch('saveOrUpdateVideoShare', params)
uni.showToast({
title: '提交成功',
icon: 'none'
})
setTimeout(uni.navigateBack, 1000, -1)
} catch (err) {
}
},
onPublish() {
// todo
},
}
}
onShareAppMessage(res) {
const {
headTitle,
indexImage,
} = this.form
let o = {
title: headTitle,
imageUrl: indexImage,
path: `/pages_order/sharing/video?id=${this.id}&state=1&shareId=${this.userInfo.id}`
}
//
const params = {
id: this.id,
state: "1",
}
this.$fetch('addLogShareInfo', params)
// todo: get times and check is unlocked
shareLog.insert(this.id)
this.isLocked = false
return o
},
methods: {
async fetchDetails(id) {
try {
const result = await this.$fetch('getVideoShareInfo', {
id
})
const {
headTitle,
indexImage,
vio,
timeNum,
num,
wxCodeImage,
textDetails,
status,
} = result || {}
this.form = {
headTitle,
indexImage,
vio,
timeNum,
num,
wxCodeImage,
textDetails,
}
this.status = status
} catch (err) {
}
},
async preSubmit() {
try {
await this.$refs.form.validate()
this.$refs.autoCropRef.set(this.form.indexImage)
} catch (err) {
}
},
async onSubmit(indexImage) {
try {
await this.$refs.form.validate()
const {
headTitle,
vio,
timeNum,
num,
wxCodeImage,
textDetails,
} = this.form
const params = {
headTitle,
indexImage,
vio,
timeNum,
num,
wxCodeImage,
textDetails,
}
if (this.id) {
params.id = this.id
}
await this.$fetch('saveOrUpdateVideoShare', params)
uni.showToast({
title: '提交成功',
icon: 'none'
})
setTimeout(uni.navigateBack, 1000, -1)
} catch (err) {
}
},
onPublish() {
// todo
},
}
}
</script>
<style scoped lang="scss">
@import '../styles/pageForm.scss';
.upload__view {
justify-content: space-between;
margin-bottom: 20rpx;
}
.upload {
background-color: $uni-fg-color;
border-radius: 12rpx;
overflow: hidden;
/deep/ .uv-form-item__body {
padding: 0 !important;
}
}
.upload-video {
&-text {
color: #1B1B1B;
font-size: 32rpx;
font-weight: 700;
margin-top: 35rpx;
}
}
.upload-cover {
position: relative;
&-text {
position: absolute;
bottom: 0;
width: 100%;
background-color: rgba($color: #000000, $alpha: 0.6);
color: #FFFFFF;
padding: 21rpx 0;
}
}
@import '../styles/pageForm.scss';
.upload__view {
justify-content: space-between;
margin-bottom: 20rpx;
}
.upload {
background-color: $uni-fg-color;
border-radius: 12rpx;
overflow: hidden;
/deep/ .uv-form-item__body {
padding: 0 !important;
}
}
.upload-video {
&-text {
color: #1B1B1B;
font-size: 32rpx;
font-weight: 700;
margin-top: 35rpx;
}
}
.upload-cover {
position: relative;
&-text {
position: absolute;
bottom: 0;
width: 100%;
background-color: rgba($color: #000000, $alpha: 0.6);
color: #FFFFFF;
padding: 21rpx 0;
}
}
</style>

+ 222
- 206
pages_order/sharing/article.vue View File

@ -1,237 +1,253 @@
<template>
<view>
<view class="content">
<view class="title">{{ detail.headTitle || '' }}</view>
<view class="desc">{{ detail.createTime ? `发布于${detail.createTime}` : '' }}</view>
<editor id="editor" class="editor"
:read-only="true"
@ready="onEditorReady"
></editor>
</view>
<uv-overlay :show="true" :opacity="0" zIndex="998">
<navbar leftClick @leftClick="$utils.navigateBack" />
<button class="btn" type="success" @click="onJoin">查看更多</button>
<popupUnlock ref="popupUnlock" src="../static/sharing/unlock-article.png"></popupUnlock>
<popupQrCode ref="popupQrCode" :src="detail.wxCodeImage"></popupQrCode>
</uv-overlay>
</view>
<view>
<view class="content">
<view class="title">{{ detail.headTitle || '' }}</view>
<view class="desc">{{ detail.createTime ? `发布于${detail.createTime}` : '' }}</view>
<editor id="editor" class="editor" :read-only="true" @ready="onEditorReady"></editor>
</view>
<uv-overlay :show="true" :opacity="0" zIndex="998">
<navbar leftClick @leftClick="$utils.navigateBack" />
<button class="btn" type="success" @click="onJoin">查看更多</button>
<popupUnlock ref="popupUnlock" src="../static/sharing/unlock-article.png"></popupUnlock>
<popupQrCode ref="popupQrCode" :src="detail.wxCodeImage"></popupQrCode>
</uv-overlay>
</view>
</template>
<script>
import { mapState } from 'vuex'
import shareLog from '@/utils/shareLog'
import {
mapState
} from 'vuex'
import shareLog from '@/utils/shareLog'
import popupUnlock from '../components/popupUnlock.vue'
import popupQrCode from '../components/popupQrCode.vue'
import popupUnlock from '../components/popupUnlock.vue'
import popupQrCode from '../components/popupQrCode.vue'
export default {
components: {
popupUnlock,
popupQrCode,
},
components: {
popupUnlock,
popupQrCode,
},
data() {
return {
id: null,
detail: {
id: null,
userId: null,
headImage: null,
headTitle: null,
num: 0,
wxCodeImage: null,
textDetails: null,
},
isLocked: true,
}
},
id: null,
detail: {
id: null,
userId: null,
headImage: null,
headTitle: null,
num: 0,
wxCodeImage: null,
textDetails: null,
},
isLocked: true,
}
},
computed: {
...mapState(['userInfo']),
},
onShow() {
// if (this.id && uni.getStorageSync('token')) {
// this.detail.id ? this.refreshLockStatus() : this.initData()
// }
if (this.detail.id) { //
this.refreshLockStatus()
}
},
async onLoad(option) {
const { id, state, shareId } = option
onShow() {
// if (this.id && uni.getStorageSync('token')) {
// this.detail.id ? this.refreshLockStatus() : this.initData()
// }
if (this.detail.id) { //
this.refreshLockStatus()
}
},
async onLoad(option) {
const {
id,
state,
shareId
} = option
if (shareId) {
uni.setStorageSync('shareId', shareId)
}
if (state) {
uni.setStorageSync('state', state)
}
if (id) {
uni.setStorageSync('id', id)
}
this.id = id
// if (uni.getStorageSync('token')) {
// this.initData()
// } else {
// uni.navigateTo({
// url: '/pages_order/auth/wxLogin'
// })
// }
this.initData()
},
onShareAppMessage(res) {
const {
headTitle,
headImage,
} = this.detail
let o = {
title : headTitle,
imageUrl: headImage,
query: `id=${this.id}&state=3&shareId=${this.userInfo.id}`,
}
//
const params = {
id:this.id,
state:"3",
}
this.$fetch('addLogShareInfo', params)
shareLog.insert(this.id)
return o
},
methods: {
onEditorReady() {
this.id = id
// if (uni.getStorageSync('token')) {
// this.initData()
// } else {
// uni.navigateTo({
// url: '/pages_order/auth/wxLogin'
// })
// }
this.initData()
shareLog.clear()
},
onShareAppMessage(res) {
const {
headTitle,
headImage,
} = this.detail
let o = {
title: headTitle,
imageUrl: headImage,
query: `id=${this.id}&state=3&shareId=${this.userInfo.id}`,
}
//
const params = {
id: this.id,
state: "3",
}
// this.$fetch('addLogShareInfo', params)
shareLog.insert(this.id)
return o
},
methods: {
onEditorReady() {
uni.createSelectorQuery().select('#editor').context((res) => {
this.editorCtx = res.context
}).exec()
},
initEditor(html) {
if (!this.editorCtx) {
setTimeout(() => {
this.initEditor(html)
}, 200)
return
}
this.editorCtx.setContents({ html })
},
async fetchDetails(id) {
try {
this.detail = await this.$fetch('getArticleShareInfo', { id })
} catch (err) {
}
},
async initData() {
await this.fetchDetails(this.id)
this.initEditor(this.detail.textDetails)
},
async fetchCheckShare() {
try {
return shareLog.check(this.id, this.detail.num)
} catch (err) {
return {}
}
},
async refreshLockStatus() {
const result = await this.fetchCheckShare()
const { title, open } = result
console.log('--open', open)
this.$refs.popupUnlock.close();
if (open) {
this.isLocked = false
this.$refs.popupQrCode.open()
return
}
title && uni.showToast({
title,
icon: 'none',
duration: 3000
})
},
async onJoin() {
if (!this.isLocked) {
this.$refs.popupQrCode.open()
return
}
const result = await this.fetchCheckShare()
const { open, need_num, num } = result
console.log('--open', open)
if (open) { //
this.isLocked = false
this.$refs.popupQrCode.open()
} else {
uni.showToast({
title: `还需转发${need_num - num}`,
icon: 'none',
})
this.$refs.popupUnlock.open();
}
},
}
}
initEditor(html) {
if (!this.editorCtx) {
setTimeout(() => {
this.initEditor(html)
}, 200)
return
}
this.editorCtx.setContents({
html
})
},
async fetchDetails(id) {
try {
this.detail = await this.$fetch('getArticleShareInfo', {
id
})
} catch (err) {
}
},
async initData() {
await this.fetchDetails(this.id)
this.initEditor(this.detail.textDetails)
},
async fetchCheckShare() {
try {
return shareLog.check(this.id, this.detail.num)
} catch (err) {
return {}
}
},
async refreshLockStatus() {
const result = await this.fetchCheckShare()
const {
title,
open
} = result
console.log('--open', open)
this.$refs.popupUnlock.close();
if (open) {
this.isLocked = false
this.$refs.popupQrCode.open()
return
}
title && uni.showToast({
title,
icon: 'none',
duration: 3000
})
},
async onJoin() {
if (!this.isLocked) {
this.$refs.popupQrCode.open()
return
}
const result = await this.fetchCheckShare()
const {
open,
need_num,
num
} = result
console.log('--open', open)
if (open) { //
this.isLocked = false
this.$refs.popupQrCode.open()
} else {
uni.showToast({
title: `还需转发${need_num - num}`,
icon: 'none',
})
this.$refs.popupUnlock.open();
}
},
}
}
</script>
<style scoped lang="scss">
.content {
padding: 40rpx 20rpx;
padding-top: calc(#{$navbar-height} + var(--status-bar-height) + 20rpx + 40rpx);
}
.title {
color: #474747;
font-size: 36rpx;
font-weight: 700;
}
.desc {
color: #A2A2A2;
font-size: 24rpx;
margin-top: 6rpx;
}
.editor {
margin-top: 22rpx;
height: 40vh;
}
.btn {
position: absolute;
width: calc(100% - 60rpx*2);
height: auto;
left: 60rpx;
bottom: 292rpx;
background-color: #07C160;
border: none;
color: #FFFFFF;
font-size: 28rpx;
line-height: 1;
border-radius: 45rpx;
padding: 25rpx 0;
box-sizing: border-box;
}
.content {
padding: 40rpx 20rpx;
padding-top: calc(#{$navbar-height} + var(--status-bar-height) + 20rpx + 40rpx);
}
.title {
color: #474747;
font-size: 36rpx;
font-weight: 700;
}
.desc {
color: #A2A2A2;
font-size: 24rpx;
margin-top: 6rpx;
}
.editor {
margin-top: 22rpx;
height: 40vh;
}
.btn {
position: absolute;
width: calc(100% - 60rpx*2);
height: auto;
left: 60rpx;
bottom: 292rpx;
background-color: #07C160;
border: none;
color: #FFFFFF;
font-size: 28rpx;
line-height: 1;
border-radius: 45rpx;
padding: 25rpx 0;
box-sizing: border-box;
}
</style>

+ 220
- 202
pages_order/sharing/group.vue View File

@ -1,234 +1,252 @@
<template>
<view class="page">
<view class="page">
<navbar leftClick @leftClick="$utils.navigateBack" />
<view class="content">
<image class="avatar" :src="detail.headImage"></image>
<text class="nick-name">{{ `${detail.headTitle || ''}${detail.memberNum || 0}` }}</text>
<view class="content">
<image class="avatar" :src="detail.headImage"></image>
<text class="nick-name">{{ `${detail.headTitle || ''}${detail.memberNum || 0}` }}</text>
<template v-if="isLocked">
<button class="btn" type="success" @click="onAdd">加入</button>
</template>
<view v-else class="group-info flex">
<text>扫一扫加群主审核进群</text>
<image class="qr" :src="detail.wxCodeImage" :show-menu-by-longpress="true"></image>
</view>
</view>
<template v-if="isLocked">
<button class="btn" type="success" @click="onAdd">加入</button>
</template>
<view v-else class="group-info flex">
<text>扫一扫加群主审核进群</text>
<image class="qr" :src="detail.wxCodeImage" :show-menu-by-longpress="true"></image>
</view>
</view>
<popupUnlock ref="popupUnlock" src="../static/sharing/unlock-group.png"></popupUnlock>
<popupUnlock ref="popupUnlock" src="../static/sharing/unlock-group.png"></popupUnlock>
</view>
</view>
</template>
<script>
import { mapState } from 'vuex'
import shareLog from '@/utils/shareLog'
import {
mapState
} from 'vuex'
import shareLog from '@/utils/shareLog'
import popupUnlock from '../components/popupUnlock.vue'
import popupUnlock from '../components/popupUnlock.vue'
export default {
components: {
popupUnlock,
},
components: {
popupUnlock,
},
data() {
return {
id: null,
detail: {
id: null,
avatarUrl: null,
nickName: null,
imageUrl: null,
times: 0,
qrCode: null,
description: null,
},
isLocked: true,
}
},
id: null,
detail: {
id: null,
avatarUrl: null,
nickName: null,
imageUrl: null,
times: 0,
qrCode: null,
description: null,
},
isLocked: true,
}
},
computed: {
...mapState(['userInfo']),
},
onShow() {
// if (this.id && uni.getStorageSync('token')) {
// this.detail.id ? this.refreshLockStatus() : this.fetchDetails()
// }
if (this.detail.id) { //
this.refreshLockStatus()
}
},
onLoad(option) {
const { id, state, shareId } = option
onShow() {
// if (this.id && uni.getStorageSync('token')) {
// this.detail.id ? this.refreshLockStatus() : this.fetchDetails()
// }
if (this.detail.id) { //
this.refreshLockStatus()
}
},
onLoad(option) {
const {
id,
state,
shareId
} = option
if (shareId) {
uni.setStorageSync('shareId', shareId)
}
if (state) {
uni.setStorageSync('state', state)
}
if (id) {
uni.setStorageSync('id', id)
}
this.id = id
// if (uni.getStorageSync('token')) {
// this.fetchDetails()
// } else {
// uni.navigateTo({
// url: '/pages_order/auth/wxLogin'
// })
// }
this.fetchDetails()
},
onShareAppMessage(res) {
const {
textDetails,
indexImage,
} = this.detail
let o = {
title : textDetails,
imageUrl: indexImage,
query: `id=${this.id}&state=2&shareId=${this.userInfo.id}`,
}
//
const params = {
id:this.id,
state:"2",
}
this.$fetch('addLogShareInfo', params)
shareLog.insert(this.id)
return o
},
methods: {
async fetchDetails() {
try {
this.detail = await this.$fetch('getGroupShareInfo', { id: this.id })
} catch (err) {
}
},
async fetchCheckShare() {
try {
return await shareLog.check(this.id, this.detail.num)
} catch (err) {
return {}
}
},
async refreshLockStatus() {
const result = await this.fetchCheckShare()
const { title, open } = result
console.log('--open', open)
this.$refs.popupUnlock.close();
if (open) {
this.isLocked = false
return
}
title && uni.showToast({
title,
icon: 'none',
duration: 3000
})
},
openPopup() {
this.$refs.popupUnlock.open();
},
async onAdd() {
const result = await this.fetchCheckShare()
const { open, need_num, num } = result
console.log('--open', open)
if (open) { //
this.isLocked = false
return
}
uni.showToast({
title: `还需转发${need_num - num}`,
icon: 'none',
})
this.openPopup()
}
},
}
this.id = id
// if (uni.getStorageSync('token')) {
// this.fetchDetails()
// } else {
// uni.navigateTo({
// url: '/pages_order/auth/wxLogin'
// })
// }
this.fetchDetails()
shareLog.clear()
},
onShareAppMessage(res) {
const {
textDetails,
indexImage,
} = this.detail
let o = {
title: textDetails,
imageUrl: indexImage,
query: `id=${this.id}&state=2&shareId=${this.userInfo.id}`,
}
//
const params = {
id: this.id,
state: "2",
}
// this.$fetch('addLogShareInfo', params)
shareLog.insert(this.id)
return o
},
methods: {
async fetchDetails() {
try {
this.detail = await this.$fetch('getGroupShareInfo', {
id: this.id
})
} catch (err) {
}
},
async fetchCheckShare() {
try {
return await shareLog.check(this.id, this.detail.num)
} catch (err) {
return {}
}
},
async refreshLockStatus() {
const result = await this.fetchCheckShare()
const {
title,
open
} = result
console.log('--open', open)
this.$refs.popupUnlock.close();
if (open) {
this.isLocked = false
return
}
title && uni.showToast({
title,
icon: 'none',
duration: 3000
})
},
openPopup() {
this.$refs.popupUnlock.open();
},
async onAdd() {
const result = await this.fetchCheckShare()
const {
open,
need_num,
num
} = result
console.log('--open', open)
if (open) { //
this.isLocked = false
return
}
uni.showToast({
title: `还需转发${need_num - num}`,
icon: 'none',
})
this.openPopup()
}
},
}
</script>
<style scoped lang="scss">
.page {
position: relative;
height: 100vh;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
}
.avatar {
width: 180rpx;
height: 180rpx;
margin-top: 127rpx;
}
.nick-name {
color: #1B1B1B;
font-size: 32rpx;
margin-top: 30rpx;
}
.desc {
margin-top: 30rpx;
}
.btn, .group-info {
position: absolute;
}
.btn {
width: calc(100% - 60rpx*2);
height: auto;
left: 60rpx;
bottom: 292rpx;
background-color: #07C160;
border: none;
color: #FFFFFF;
font-size: 28rpx;
line-height: 1;
border-radius: 45rpx;
padding: 25rpx 0;
box-sizing: border-box;
}
.group-info {
bottom: 269rpx;
flex-direction: column;
color: #1B1B1B;
font-size: 32rpx;
}
.qr {
margin-top: 40rpx;
width: 350rpx;
height: 350rpx;
}
.page {
position: relative;
height: 100vh;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
}
.avatar {
width: 180rpx;
height: 180rpx;
margin-top: 127rpx;
}
.nick-name {
color: #1B1B1B;
font-size: 32rpx;
margin-top: 30rpx;
}
.desc {
margin-top: 30rpx;
}
.btn,
.group-info {
position: absolute;
}
.btn {
width: calc(100% - 60rpx*2);
height: auto;
left: 60rpx;
bottom: 292rpx;
background-color: #07C160;
border: none;
color: #FFFFFF;
font-size: 28rpx;
line-height: 1;
border-radius: 45rpx;
padding: 25rpx 0;
box-sizing: border-box;
}
.group-info {
bottom: 269rpx;
flex-direction: column;
color: #1B1B1B;
font-size: 32rpx;
}
.qr {
margin-top: 40rpx;
width: 350rpx;
height: 350rpx;
}
</style>

+ 214
- 196
pages_order/sharing/personal.vue View File

@ -1,228 +1,246 @@
<template>
<view class="page">
<view class="page">
<navbar leftClick @leftClick="$utils.navigateBack" />
<view class="content">
<image class="avatar" :src="detail.headImage"></image>
<text class="nick-name">{{ detail.headTitle || '' }}</text>
<view class="content">
<image class="avatar" :src="detail.headImage"></image>
<text class="nick-name">{{ detail.headTitle || '' }}</text>
<template v-if="isLocked">
<button class="btn" type="success" @click="onAdd">添加</button>
</template>
<view v-else class="flex flex-column qr-popup">
<text class="tips">长按识别二维码了解更多内容</text>
<image class="qr" :src="detail.wxCodeImage" :show-menu-by-longpress="true"></image>
</view>
</view>
<template v-if="isLocked">
<button class="btn" type="success" @click="onAdd">添加</button>
</template>
<view v-else class="flex flex-column qr-popup">
<text class="tips">长按识别二维码了解更多内容</text>
<image class="qr" :src="detail.wxCodeImage" :show-menu-by-longpress="true"></image>
</view>
</view>
<popupUnlock ref="popupUnlock" src="../static/sharing/unlock-user.png"></popupUnlock>
<popupUnlock ref="popupUnlock" src="../static/sharing/unlock-user.png"></popupUnlock>
</view>
</view>
</template>
<script>
import { mapState } from 'vuex'
import shareLog from '@/utils/shareLog'
import {
mapState
} from 'vuex'
import shareLog from '@/utils/shareLog'
import popupUnlock from '../components/popupUnlock.vue'
import popupUnlock from '../components/popupUnlock.vue'
export default {
components: {
popupUnlock,
},
components: {
popupUnlock,
},
data() {
return {
id: null,
detail: {
id: null,
userId: null,
headImage: null,
headTitle: null,
indexImage: null,
num: 0,
wxCodeImage: null,
textDetails: null,
},
isLocked: true,
}
},
id: null,
detail: {
id: null,
userId: null,
headImage: null,
headTitle: null,
indexImage: null,
num: 0,
wxCodeImage: null,
textDetails: null,
},
isLocked: true,
}
},
computed: {
...mapState(['userInfo']),
},
onShow() {
// if (this.id && uni.getStorageSync('token')) {
// this.detail.id ? this.refreshLockStatus() : this.fetchDetails()
// }
if (this.detail.id) { //
this.refreshLockStatus()
}
},
onLoad(option) {
const { id, state, shareId } = option
onShow() {
// if (this.id && uni.getStorageSync('token')) {
// this.detail.id ? this.refreshLockStatus() : this.fetchDetails()
// }
if (this.detail.id) { //
this.refreshLockStatus()
}
},
onLoad(option) {
const {
id,
state,
shareId
} = option
if (shareId) {
uni.setStorageSync('shareId', shareId)
}
if (state) {
uni.setStorageSync('state', state)
}
if (id) {
uni.setStorageSync('id', id)
}
this.id = id
// if (uni.getStorageSync('token')) {
// this.fetchDetails()
// } else {
// uni.navigateTo({
// url: '/pages_order/auth/wxLogin'
// })
// }
this.fetchDetails()
},
onShareAppMessage(res) {
const {
textDetails,
indexImage,
} = this.detail
let o = {
title : textDetails,
imageUrl: indexImage,
query: `id=${this.id}&state=0&shareId=${this.userInfo.id}`,
}
//
const params = {
id:this.id,
state:"0",
}
this.$fetch('addLogShareInfo', params)
shareLog.insert(this.id)
return o
},
methods: {
async fetchDetails() {
try {
this.detail = await this.$fetch('getShareInfo', { id: this.id })
} catch (err) {
}
},
async fetchCheckShare() {
try {
return await shareLog.check(this.id, this.detail.num)
} catch (err) {
return {}
}
},
async refreshLockStatus() {
const result = await this.fetchCheckShare()
const { title, open } = result
console.log('--open', open)
this.$refs.popupUnlock.close();
if (open) {
this.isLocked = false
return
}
title && uni.showToast({
title,
icon: 'none',
duration: 3000
})
},
openPopup() {
this.$refs.popupUnlock.open();
},
async onAdd() {
const result = await this.fetchCheckShare()
const { open, need_num, num } = result
console.log('--open', open)
if (open) { //
this.isLocked = false
return
}
uni.showToast({
title: `还需转发${need_num - num}`,
icon: 'none',
})
this.openPopup()
}
},
}
this.id = id
// if (uni.getStorageSync('token')) {
// this.fetchDetails()
// } else {
// uni.navigateTo({
// url: '/pages_order/auth/wxLogin'
// })
// }
this.fetchDetails()
shareLog.clear()
},
onShareAppMessage(res) {
const {
textDetails,
indexImage,
} = this.detail
let o = {
title: textDetails,
imageUrl: indexImage,
query: `id=${this.id}&state=0&shareId=${this.userInfo.id}`,
}
//
const params = {
id: this.id,
state: "0",
}
// this.$fetch('addLogShareInfo', params)
shareLog.insert(this.id)
return o
},
methods: {
async fetchDetails() {
try {
this.detail = await this.$fetch('getShareInfo', {
id: this.id
})
} catch (err) {
}
},
async fetchCheckShare() {
try {
return await shareLog.check(this.id, this.detail.num)
} catch (err) {
return {}
}
},
async refreshLockStatus() {
const result = await this.fetchCheckShare()
const {
title,
open
} = result
console.log('--open', open)
this.$refs.popupUnlock.close();
if (open) {
this.isLocked = false
return
}
title && uni.showToast({
title,
icon: 'none',
duration: 3000
})
},
openPopup() {
this.$refs.popupUnlock.open();
},
async onAdd() {
const result = await this.fetchCheckShare()
const {
open,
need_num,
num
} = result
console.log('--open', open)
if (open) { //
this.isLocked = false
return
}
uni.showToast({
title: `还需转发${need_num - num}`,
icon: 'none',
})
this.openPopup()
}
},
}
</script>
<style scoped lang="scss">
.page {
position: relative;
height: 100vh;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
}
.avatar {
width: 180rpx;
height: 180rpx;
margin-top: 127rpx;
}
.nick-name {
color: #1B1B1B;
font-size: 32rpx;
margin-top: 30rpx;
}
.btn, .qr-popup {
position: absolute;
}
.btn {
width: calc(100% - 60rpx*2);
height: auto;
left: 60rpx;
bottom: 292rpx;
background-color: #07C160;
border: none;
color: #FFFFFF;
font-size: 28rpx;
line-height: 1;
border-radius: 45rpx;
padding: 25rpx 0;
box-sizing: border-box;
}
.qr-popup {
width: 100vw;
bottom: 269rpx;
.tips {
color: #1B1B1B;
font-size: 32rpx;
}
}
.qr {
margin-top: 40rpx;
width: 350rpx;
height: 350rpx;
}
.page {
position: relative;
height: 100vh;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
}
.avatar {
width: 180rpx;
height: 180rpx;
margin-top: 127rpx;
}
.nick-name {
color: #1B1B1B;
font-size: 32rpx;
margin-top: 30rpx;
}
.btn,
.qr-popup {
position: absolute;
}
.btn {
width: calc(100% - 60rpx*2);
height: auto;
left: 60rpx;
bottom: 292rpx;
background-color: #07C160;
border: none;
color: #FFFFFF;
font-size: 28rpx;
line-height: 1;
border-radius: 45rpx;
padding: 25rpx 0;
box-sizing: border-box;
}
.qr-popup {
width: 100vw;
bottom: 269rpx;
.tips {
color: #1B1B1B;
font-size: 32rpx;
}
}
.qr {
margin-top: 40rpx;
width: 350rpx;
height: 350rpx;
}
</style>

+ 216
- 158
pages_order/sharing/video.vue View File

@ -1,189 +1,247 @@
<template>
<view class="page">
<view class="page">
<navbar leftClick @leftClick="$utils.navigateBack" />
<view class="content">
<video class="video"
id="video"
:src="detail.vio"
autoplay
play-btn-position="center"
:controls="!timeIsUp"
:show-fullscreen-btn="false"
:show-center-play-btn="true"
@timeupdate="onTimeupdate"
@ended="onTimeEnd"
></video>
<view class="info">
<view class="author">{{ detail.author || '' }}</view>
<view class="title">{{ detail.headTitle || '' }}</view>
<view class="desc">{{ detail.textDetails || '' }}</view>
</view>
</view>
<uv-overlay :show="timeIsUp" @click="onPlay" zIndex="998">
<popupUnlock ref="popupUnlock" src="../static/sharing/unlock-video.png"></popupUnlock>
</uv-overlay>
<popupQrCode ref="popupQrCode" :src="detail.wxCodeImage"></popupQrCode>
</view>
<view class="content">
<video class="video" id="video" :src="detail.vio" autoplay play-btn-position="center" :controls="!timeIsUp"
:show-fullscreen-btn="false" :show-center-play-btn="true" @timeupdate="onTimeupdate"
@ended="onTimeEnd"></video>
<view class="info">
<view class="author">{{ detail.author || '' }}</view>
<view class="title">{{ detail.headTitle || '' }}</view>
<view class="desc">{{ detail.textDetails || '' }}</view>
</view>
</view>
<uv-overlay :show="timeIsUp" @click="onPlay" zIndex="998">
<popupUnlock ref="popupUnlock" src="../static/sharing/unlock-video.png"></popupUnlock>
</uv-overlay>
<popupQrCode ref="popupQrCode" :src="detail.wxCodeImage"></popupQrCode>
</view>
</template>
<script>
import { mapState } from 'vuex'
import {
mapState
} from 'vuex'
import popupUnlock from '../components/popupUnlock.vue'
import popupQrCode from '../components/popupQrCode.vue'
import popupUnlock from '../components/popupUnlock.vue'
import popupQrCode from '../components/popupQrCode.vue'
import shareLog from '@/utils/shareLog'
export default {
components: {
popupUnlock,
popupQrCode,
},
components: {
popupUnlock,
popupQrCode,
},
data() {
return {
id: null,
detail: {
id: null,
headTitle: null,
indexImage: null,
vio: null,
timeNum: 0,
num: 0,
wxCodeImage: null,
textDetails: null,
},
timeIsUp: false,
isLocked: true,
videoContext: null,
}
},
id: null,
detail: {
id: null,
headTitle: null,
indexImage: null,
vio: null,
timeNum: 0,
num: 0,
wxCodeImage: null,
textDetails: null,
},
timeIsUp: false,
isLocked: true,
videoContext: null,
}
},
computed: {
...mapState(['userInfo']),
},
onShow() {
// if (this.id && uni.getStorageSync('token')) {
// this.detail.id ? this.refreshLockStatus() : this.initData()
// }
if (this.detail.id) { //
this.refreshLockStatus()
}
},
async onLoad(option) {
const { id, state, shareId } = option
onShow() {
// if (this.id && uni.getStorageSync('token')) {
// this.detail.id ? this.refreshLockStatus() : this.initData()
// }
if (this.detail.id) { //
this.refreshLockStatus()
}
},
async onLoad(option) {
const {
id,
state,
shareId
} = option
if (shareId) {
uni.setStorageSync('shareId', shareId)
}
if (state) {
uni.setStorageSync('state', state)
}
if (id) {
uni.setStorageSync('id', id)
}
this.id = id
// if(uni.getStorageSync('token')){
// this.initData()
// }else{
// uni.navigateTo({
// url: '/pages_order/auth/wxLogin'
// })
// }
this.initData()
},
onShareAppMessage(res) {
const {
headTitle,
indexImage,
} = this.detail
let o = {
title : headTitle,
imageUrl: indexImage,
query: `id=${this.id}&state=1&shareId=${this.userInfo.id}`,
}
//
const params = {
id:this.id,
state:"1",
}
this.$fetch('addLogShareInfo', params)
return o
},
methods: {
async fetchDetails(id) {
try {
this.detail = await this.$fetch('getVideoShareInfo', { id })
} catch (err) {
}
},
async initData() {
this.isLocked = true
await this.fetchDetails(this.id)
this.videoContext = uni.createVideoContext('video');
},
refreshLockStatus() {
this.isLocked = false
this.timeIsUp = false
setTimeout(() => {
this.videoContext.play()
console.log('--play')
})
},
async onPlay() {
if (!this.isLocked) {
return
}
this.videoContext.pause()
this.timeIsUp = true
this.$refs.popupUnlock.open();
},
async onTimeupdate(e) {
const { currentTime } = e.target
if (currentTime >= this.detail.timeNum && this.isLocked) {
this.videoContext.pause()
this.timeIsUp = true
this.onPlay()
}
},
onTimeEnd() {
this.$refs.popupQrCode.open()
},
},
}
</script>
this.id = id
<style scoped lang="scss">
.video {
width: 100%;
height: calc(100vh - #{$navbar-height} - var(--status-bar-height) - 20rpx);
}
// if(uni.getStorageSync('token')){
// this.initData()
// }else{
// uni.navigateTo({
// url: '/pages_order/auth/wxLogin'
// })
// }
.info {
color: #FFFFFF;
font-size: 28rpx;
this.initData()
shareLog.clear()
},
onShareAppMessage(res) {
const {
headTitle,
indexImage,
} = this.detail
let o = {
title: headTitle,
imageUrl: indexImage,
query: `id=${this.id}&state=1&shareId=${this.userInfo.id}`,
}
position: fixed;
left: 40rpx;
bottom: 100rpx;
.title {
font-size: 32rpx;
margin: 5rpx 0;
}
}
//
const params = {
id: this.id,
state: "1",
}
// this.$fetch('addLogShareInfo', params)
//
shareLog.insert(this.id)
return o
},
methods: {
async fetchDetails(id) {
try {
this.detail = await this.$fetch('getVideoShareInfo', {
id
})
// numtimeNum
if (this.detail) {
this.detail.num = parseInt(this.detail.num) || 0;
this.detail.timeNum = parseFloat(this.detail.timeNum) || 0;
}
} catch (err) {
}
},
async initData() {
this.isLocked = true
await this.fetchDetails(this.id)
this.videoContext = uni.createVideoContext('video');
//
const result = await this.fetchCheckShare()
if (result.open) {
this.isLocked = false
this.timeIsUp = false
}
},
async refreshLockStatus() {
// timeIsUp = false
// this.timeIsUp = false
setTimeout(async () => {
const result = await this.fetchCheckShare()
const {
open,
need_num,
num
} = result
if (open) { //
this.videoContext.play()
this.isLocked = false
this.timeIsUp = false //
return
}else{
if(this.timeIsUp){
this.onPlay()
}
}
//
uni.showToast({
title: `还需转发${need_num - num}`,
icon: 'none',
})
})
},
async fetchCheckShare() {
try {
// detail.numAPI
const numValue = parseInt(this.detail.num) || 0;
return await shareLog.check(this.id, numValue)
} catch (err) {
return {}
}
},
async onPlay() {
if (!this.isLocked) {
return
}
//
const result = await this.fetchCheckShare()
if (result.open) {
this.isLocked = false
this.timeIsUp = false
this.videoContext.play()
return
}
//
this.videoContext.pause()
this.timeIsUp = true
this.$refs.popupUnlock.open();
},
async onTimeupdate(e) {
const {
currentTime
} = e.target
if (currentTime >= this.detail.timeNum && this.isLocked) {
this.onPlay()
}
},
onTimeEnd() {
this.$refs.popupQrCode.open()
},
},
}
</script>
<style scoped lang="scss">
.video {
width: 100%;
height: calc(100vh - #{$navbar-height} - var(--status-bar-height) - 20rpx);
}
.info {
color: #FFFFFF;
font-size: 28rpx;
position: fixed;
left: 40rpx;
bottom: 100rpx;
.title {
font-size: 32rpx;
margin: 5rpx 0;
}
}
</style>

+ 38
- 25
utils/shareLog.js View File

@ -1,41 +1,54 @@
import fetch from '@/api/fetch.js'
let slog = {}
const get = () => {
try {
return JSON.parse(uni.getStorageSync('shareLog')) || {}
} catch (err) {
return {}
}
try {
return slog
// return JSON.parse(uni.getStorageSync('shareLog')) || {}
} catch (err) {
return {}
}
}
const clear = () => {
slog = {}
}
const insert = (id) => {
const log = get()
const log = get()
let bef = log[id] || 0
let bef = log[id] || 0
log[id] = bef + 1
log[id] = bef + 1
uni.setStorageSync('shareLog', JSON.stringify(log))
uni.setStorageSync('shareLog', JSON.stringify(log))
}
const check = async (id, need_num) => {
try {
const log = get()
const num = log[id] || 0
const open = num >= need_num
return { open, need_num, num, title: `已转发${num}` }
} catch (err) {
console.error('--校验达标异常', err)
return {}
}
try {
const log = get()
const num = parseInt(log[id]) || 0
const safeNeedNum = parseInt(need_num) || 0
const open = num >= safeNeedNum
return {
open,
need_num: safeNeedNum,
num,
title: `已转发${num}`
}
} catch (err) {
console.error('--校验达标异常', err)
return {}
}
}
export default {
get,
insert,
check,
get,
insert,
check,
clear,
}

Loading…
Cancel
Save