Browse Source

出版

master
jianglong 3 years ago
parent
commit
0d2f5d2967
  1. 8
      .idea/.gitignore
  2. 8
      .idea/modules.xml
  3. 19
      .idea/php.xml
  4. 8
      .idea/uniapp-shbcqz.iml
  5. 6
      .idea/vcs.xml
  6. 184
      bundle/pages/forget_pwd/forget_pwd.vue
  7. 92
      bundle/pages/get_coupon/get_coupon.vue
  8. 169
      bundle/pages/register/register.vue
  9. 777
      bundle/pages/resource_details/resource_details.vue
  10. 416
      bundle/pages/shop_cart/shop_cart.vue
  11. 213
      bundle/pages/user/complain.vue
  12. 97
      bundle/pages/user/complain_recode.vue
  13. 165
      bundle/pages/user/complain_result.vue
  14. 927
      bundle/pages/user/vip.vue
  15. 100
      components/components/explore.vue
  16. 413
      components/components/follow.vue
  17. 110
      components/components/like-header.vue
  18. 103
      components/components/lists.vue
  19. 250
      components/components/organ.vue
  20. 246
      components/components/team.vue
  21. 101
      components/components/xuqiu.vue
  22. 109
      pages/community/organ_team_details.vue

8
.idea/.gitignore

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/modules.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/uniapp-shbcqz.iml" filepath="$PROJECT_DIR$/.idea/uniapp-shbcqz.iml" />
</modules>
</component>
</project>

19
.idea/php.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MessDetectorOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
<option name="highlightLevel" value="WARNING" />
<option name="transferred" value="true" />
</component>
<component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PsalmOptionsConfiguration">
<option name="transferred" value="true" />
</component>
</project>

8
.idea/uniapp-shbcqz.iml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

184
bundle/pages/forget_pwd/forget_pwd.vue

@ -0,0 +1,184 @@
<template>
<view class="forget-pwd bg-white">
<view class="input-container">
<view class="input-item flex">
<view class="input-label flex normal">手机号</view>
<u-input v-model="mobile" class="input" placeholder="请输入手机号码" />
</view>
<view class="input-item flex">
<view class="input-label flex normal">短信验证码</view>
<u-input v-model="smsCode" style="width: 300rpx" placeholder="请输入验证码" />
<button class="bd-primary xs primary br60 flex row-center" @click="sendSmsFun">
<!-- 获取验证码 -->
<u-verification-code unique-key="forget-pwd" ref="uCode" @change="codeChange">
</u-verification-code>
<view class="xs">{{codeTips}}</view>
</button>
</view>
<view class="input-item flex">
<view class="input-label flex normal">重置密码</view>
<u-input type="password" v-model="resetPwd" placeholder="6-20位数字+字母或符号组合" />
</view>
<view class="input-item flex">
<view class="input-label flex normal">确认密码</view>
<u-input type="password" v-model="comfirmPwd" placeholder="请再次输入密码" />
</view>
</view>
<view class="btn white bg-primary br60 flex row-center" @click="forgetPwdFun">
确认
</view>
</view>
</template>
<script>
import {
forgetPwd,
sendSms
} from '@/api/app.js'
import {
ACCESS_TOKEN
} from '@/config/app.js'
import {
SMSType
} from '@/utils/type.js'
import {
mapMutations
} from 'vuex'
export default {
name: 'forgetPwd',
data() {
return {
mobile: '',
smsCode: '',
resetPwd: '',
comfirmPwd: '',
time: 59,
codeTips: '',
}
},
onLoad() {
},
methods: {
...mapMutations(['login']),
codeChange(tip) {
this.codeTips = tip
},
forgetPwdFun() {
let {
mobile,
smsCode,
resetPwd,
comfirmPwd
} = this;
if (!mobile) {
this.$toast({
title: '请填写手机号'
});
return;
}
if (!smsCode) {
this.$toast({
title: '请填写短信验证码'
});
return;
}
if (!resetPwd) {
this.$toast({
title: '请填写重置密码'
});
return;
}
if (!comfirmPwd) {
this.$toast({
title: '请填写确认密码'
});
return;
}
if (resetPwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
});
return;
}
let data = {
mobile: mobile,
code: smsCode,
password: resetPwd,
repassword: comfirmPwd
};
forgetPwd(data).then(res => {
if (res.code == 1) {
this.login(data);
this.$toast({
title: res.msg
});
//
setTimeout(() => {
uni.navigateBack()
}, 1000)
}
})
},
sendSmsFun() {
if(!this.$refs.uCode.canGetCode) return
if (!this.mobile) {
this.$toast({
title: '请填写手机号信息'
})
return;
}
sendSms({
mobile: this.mobile,
key: SMSType.FINDPWD
}).then(res => {
if (res.code == 1) {
this.$toast({title:res.msg});
this.$refs.uCode.start();
}
})
}
},
}
</script>
<style lang="scss">
page {
padding: 0;
}
.forget-pwd {
min-height: 100vh;
padding: 40px 20px 0;
padding: 80rpx 40rpx 0;
.input-container {
.input-item {
padding: 0 20rpx;
height: 88rpx;
margin-bottom: 30rpx;
border-bottom: 1px solid #D7D7D7;
.input-label {
width: 180rpx;
flex: none;
}
.bd-primary {
height: 56rpx;
width: 176rpx;
flex: none;
border: 1px solid $-color-primary;
.seconds {
color: $-color-primary;
}
}
}
}
.btn {
margin-top: 60rpx;
padding: 20rpx 0;
}
}
</style>

92
bundle/pages/get_coupon/get_coupon.vue

@ -0,0 +1,92 @@
<template>
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
:up="upOption">
<view class="get-coupon">
<view>
<image class="banner" src="/static/images/banner_coupon.jpg"></image>
</view>
<view class="bg-body main">
<coupon-list :list="couponList" :btn-type="3" @refresh="refresh"></coupon-list>
</view>
</view>
</mescroll-body>
</template>
<script>
import {
getCouponList,
getCoupon
} from '@/api/activity';
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins";
export default {
mixins: [MescrollMixin],
data() {
return {
active: 0,
upOption: {
empty: {
icon: '/static/images/coupon_null.png',
tip: "暂无优惠券",
}
},
tabList: [{
name: '全部',
type: 'all'
},{
name: '店铺券',
type: 'shop'
},{
name: '通用券',
type: 'platform'
}],
couponList: []
};
},
onLoad(options) {
},
methods: {
upCallback(page) {
const {tabList, active} = this
getCouponList({
page_size:page.size,
page_no:page.num,
type: tabList[active].type
}).then(({
data
}) => {
if (page.num == 1) this.couponList = [];
const curPageData = data.lists;
const curPageLen = curPageData.length;
const hasNext = !!data.more;
this.couponList = this.couponList.concat(curPageData);
this.mescroll.endSuccess(curPageLen, hasNext);
}).catch(() => {
this.mescroll.endErr()
})
},
changeActive(index) {
this.active = index
this.refresh()
},
refresh() {
this.couponList = [] // ,
this.mescroll.resetUpScroll() //
}
}
};
</script>
<style>
.banner {
width: 100%;
height: 340rpx;
}
.main {
border-radius: 20rpx 20rpx 0 0;
margin-top: -20rpx;
overflow: hidden;
position: relative;
}
</style>

169
bundle/pages/register/register.vue

@ -0,0 +1,169 @@
<template>
<view class="register">
<view class="input-container">
<view class="input-item flex">
<view class="input-label flex normal">手机号</view>
<u-input v-model="mobile" class="input" placeholder="请输入手机号码" />
</view>
<view class="input-item flex" v-if="appConfig.register_setting">
<view class="input-label flex normal">短信验证码</view>
<u-input v-model="smsCode" style="width: 300rpx" placeholder="请输入验证码" />
<button class="bd-primary xs primary br60 flex row-center" hover-class="none" @click="sendSmsFun">
<!-- 获取验证码 -->
<u-verification-code unique-key="register" ref="uCode" @change="codeChange" >
</u-verification-code>
<view class="xs">{{codeTips}}</view>
</button>
</view>
<view class="input-item flex">
<view class="input-label flex normal">设置密码</view>
<u-input type="password" v-model="password" placeholder="6-20位数字+字母或符号组合" />
</view>
<view class="input-item flex">
<view class="input-label flex normal">确认密码</view>
<u-input type="password" v-model="passwordConfirm" placeholder="6-20位数字+字母或符号组合" />
</view>
</view>
<view class="btn white bg-primary br60 flex row-center" @click="registerFun">
立即注册
</view>
<view class="m-t-40 sm flex row-center">
<u-checkbox v-model="isAgreement" shape="circle">
<div class="flex">
已阅读并同意
<router-link to="/bundle/pages/server_explan/server_explan?type=0">
<view class="primary">服务协议</view>
</router-link>
<router-link to="/bundle/pages/server_explan/server_explan?type=1">
<view class="primary">隐私协议</view>
</router-link>
</div>
</u-checkbox>
</view>
</view>
</view>
</template>
<script>
import {register, sendSms} from '@/api/app.js'
import { ACCESS_TOKEN } from '@/config/app.js'
import {SMSType} from '@/utils/type.js'
import {
mapMutations,
mapGetters
} from 'vuex'
export default {
name: 'register',
created() {
},
data() {
return {
isAgreement: false,
mobile: '',
smsCode: '',
password: '',
passwordConfirm: "",
canSendSms: true,
codeTips: ''
}
},
onLoad() {
// console.log(this.appConfig)
},
methods: {
...mapMutations(['login']),
codeChange(tip) {
this.codeTips = tip
},
registerFun() {
let {isAgreement, mobile, password, smsCode, passwordConfirm} = this;
if(!isAgreement) return this.$toast({ title: '请先勾选\"已阅读并同意《服务协议》和《隐私协议》\"' })
if(!mobile) {
this.$toast({title: '请填写手机号'});
return;
}
if(!password) {
this.$toast({title: "请设置密码"})
return;
}
if(password != passwordConfirm) {
this.$toast({title: "两次密码输入不一致"})
return;
}
let data = {mobile: mobile, password: password, code: smsCode, client: 2}
register(data).then(res => {
if(res.code == 1) {
this.login(data)
this.$toast({title: res.msg});
//
setTimeout(() => {
uni.navigateBack()
}, 1000)
}
})
},
countDownFinish() {
this.canSendSms = true;
},
sendSmsFun() {
if(!this.$refs.uCode.canGetCode) return
if(!this.mobile) {
this.$toast({title: '请填写手机号信息~'})
return;
}
sendSms({mobile: this.mobile, key: SMSType.REGISTER}).then(res => {
if(res.code == 1) {
this.$toast({title:res.msg});
this.$refs.uCode.start();
}
})
}
},
computed: {
...mapGetters(['appConfig']),
}
}
</script>
<style lang="scss">
page {
background-color: white;
}
.register {
padding: 80rpx 40rpx 0;
.input-container {
.input-item {
padding: 0 20rpx;
height: 88rpx;
margin-bottom: 30rpx;
border-bottom: 1px solid #D7D7D7;
.input-label {
width: 180rpx;
flex: none;
}
.bd-primary {
height: 56rpx;
width: 176rpx;
flex: none;
border: 1px solid $-color-primary;
.seconds {
color: $-color-primary;
}
}
}
}
.btn {
margin-top: 60rpx;
padding: 20rpx 0;
}
}
</style>

777
bundle/pages/resource_details/resource_details.vue

@ -0,0 +1,777 @@
<template>
<view class="goods-details">
<u-navbar id="navbar" :border-bottom="false"
:background="{ background: 'rgba(256,256,256, '+ navStyle.backgroundBg +')', }"
:back-bg="'rgba(0,0,0,' + navStyle.backBg + ')'" :back-icon-color="navStyle.backColor" :immersive="true">
<tabs sticky-bg-color="transparent" v-if="navStyle.backgroundBg > 0.1" :show-bar="true" :bar-width="60"
:is-scroll="false" :current="active" bg-color="transparent"
:style="{width: '100%', opacity: navStyle.backgroundBg}" @change="changeActive">
<tab name="资料"></tab>
<tab name="详情"></tab>
</tabs>
</u-navbar>
<view class="contain" v-if="!isNull" id="goods" @touchstart="isTouchStart = true">
<bubble-tips top="200rpx"></bubble-tips>
<product-swiper :imgUrls="swiperList" ></product-swiper>
<view class="goods-info bg-white">
<view class="info-header flex">
<view class="price flex flex-1">
<view class="primary m-r-10">
<text style="font-weight: 500" class="price-format">
<text style="font-size: 46rpx;margin-right: 1rpx" >{{resourceDetail.price_str}}</text>
</text>
</view>
</view>
<!-- <image class="icon-share" src="/static/images/icon_share.png" @tap="showShareBtn = true"></image> -->
</view>
<view class="flex">
<view class="name lg bold">{{ resourceDetail.title }}</view>
</view>
<view class="flex row-between xs lighter" style="padding: 0 24rpx 20rpx">
<text>区域: {{ resourceDetail.address }}</text>
<text>下载量: {{ resourceDetail.download }}</text>
<text>浏览量: {{ resourceDetail.visit }}</text>
</view>
</view>
<view>
<get-coupon :wrap-style="{'margin-top': '20rpx'}" :goods-id="resourceDetail.id"></get-coupon>
</view>
<view class="details m-t-20 bg-white" id="details">
<view class="title lg">资料简介</view>
<view class="content">
<u-parse :html="resourceDetail.content" :lazy-load="true" :show-with-animation="true"></u-parse>
</view>
</view>
<view class="footer flex bg-white fixed">
<template>
<view class="right-buy br60 white m-r-20 m-l-10 md" @click="doFun()" >{{ btnText.red }}</view>
</template>
</view>
</view>
<view v-else>
<view class="details-null flex-col col-center">
<image class="img-null" src="/static/images/goods_null.png"></image>
<view class="xs muted">该资料已经去星球外啦去看看别的吧~</view>
</view>
<goods-column></goods-column>
</view>
<share-popup :show="showShareBtn" @close="showShareBtn = false" :goods-id="id" :img-url="resourceDetail.image"
:summary="resourceDetail.intro" :share-title="resourceDetail.title"></share-popup>
<!-- 悬浮按钮 -->
<float-tab></float-tab>
<loading-view v-if="isFirstLoading"></loading-view>
</view>
</template>
team_min_price
<script>
import {
resourceOrderBuy
} from '@/api/order';
import {
prepay,
getMnpNotice,
getPayway
} from '@/api/app';
import {
getResourceDetail,
getGoodsDetail,
resourcedownload
} from '@/api/store';
import {
collectGoods
} from '@/api/user';
import {
getCouponList,
teamCheck
} from '@/api/activity';
import {
mapActions,
mapGetters
} from 'vuex';
import {
toLogin
} from '@/utils/login';
import Cache from '@/utils/cache';
import {
strToParams,
arraySlice,
getRect,
getcu
} from '@/utils/tools'
const app = getApp()
export default {
data() {
return {
active: 0,
isTouchStart: false,
topArr: [],
isFirstLoading: true,
isNull: false,
isGroup: 0,
showSpec: false,
showCoupon: false,
showShareBtn: false,
showCommission: true,
popupType: '',
swiperList: [],
goodsDetail: {},
goodsType: 0,
checkedGoods: {},
comment: {},
countTime: 0,
team: {},
teamFound: [],
showtxt:[],
resourceDetail:{},
navStyle: {
backBg: 0.4,
backgroundBg: 0,
backColor: 'rgba(256,256,256,1)'
},
id: '',
shop: {},
//
distribution: {}
};
},
onLoad() {
const options = this.$Route.query;
if (options && options.scene) {
const scene = strToParams(decodeURIComponent(options.scene));
options.id = scene.id;
}
this.id = options.id;
this.getResourceDetailFun();
},
onShow() {
},
onPageScroll(e) {
const top = uni.upx2px(500)
const {
scrollTop
} = e
const percent = scrollTop / top
this.navStyle.backgroundBg = percent
this.navStyle.backBg = 0.4 * (0.5 - percent)
this.navStyle.backColor = percent < 0.5 ? 'rgba(256,256,256,' + (0.5 - percent) * 2 + ')' : 'rgba(0,0,0,' +
(
percent - 0.5) * 2 + ')'
if (!this.isTouchStart) return
const topList = this.topArr.map((item, index) => ({
index,
top: item
}))
.filter(item => item.top <= scrollTop)
if (topList.length) {
const index = topList.sort((a, b) => b.top - a.top)[0].index
if (this.active == index) return
this.active = index
}
},
methods: {
...mapActions([ 'wxShare']),
doFun(){
console.log(1111)
const {
goodsType,
isLogin
} = this
if (!isLogin) {
uni.navigateTo({
url: '/pages/login/login'
});
return true;
}
//
if(goodsType == 0){
let msg = "下载中...";
this.showLoading = false
uni.showLoading({
title: msg
});
let that = this;
uni.downloadFile({
url: this.resourceDetail.path, //
success: (res) => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath,
success: function (res2) {
that.downloadLog(that.resourceDetail.id);
var savedFilePath = res2.savedFilePath;
let msg = "文件存储到"+savedFilePath;
uni.showLoading({
title: msg
});
setTimeout(function () {
uni.hideLoading()
}, 2000);
},
fail: function(err) {
uni.showLoading({
title: "下载失败"
});
setTimeout(function () {
uni.hideLoading()
}, 2000);
}
});
}
}
});
// uni.downloadFile({
// url: this.resourceDetail.path,//
// success(res) {
// //
// uni.saveFile({
// tempFilePath: res.tempFilePath,//
// success: function(res) {
// const savedFilePath = res.savedFilePath;
// //
// uni.openDocument({
// filePath: savedFilePath,
// success: function(res) {
// uni.hideLoading()
// },
// fail: function(res) {},
// complete: function(res) {
// setTimeout(uni.hideLoading(), 4000)
// },
// });
// },
// fail: function(err) { }
// });
// },
// fail(res) {}
// })
}else if(goodsType == 1){ //vip
uni.navigateTo({
url: '/pages/user/vip'
});
}else if(goodsType == 2){ //
console.log('购买页')
this.onSubmitOrder();
}
},
async downloadLog(id){
console.log("id:",id)
await resourcedownload({
id: id
});
setTimeout(() => {
this.getResourceDetailFun();
}, 500)
},
changeActive(index) {
this.isTouchStart = false
uni.pageScrollTo({
scrollTop: this.topArr[index],
duration: 200
});
},
getRectInfo() {
if (this.topArr.length) return
getRect('#goods').then((res) => {
this.topArr[0] = res.top - this.navHeight
})
getRect('#evaluation').then((res) => {
this.topArr[1] = res.top - this.navHeight
})
getRect('#details').then((res) => {
this.topArr[2] = res.top - this.navHeight
})
},
async getResourceDetailFun() {
const {
data,
code
} = await getResourceDetail({
id: this.id
});
if (code == 1) {
const {
image,
title,
content,
visit,
likes,
intro,
path,
price_str,
type,
goodsType,
address
} = data;
this.intro = intro || {}
this.image = image
this.resourceDetail = data;
this.swiperList = [{id:data.id,uri:image}];
console.log(this.swiperList)
this.goodsType = goodsType;
console.log(goodsType)
this.$nextTick(() => {
// h5
uni.pageScrollTo({
scrollTop: 0,
duration: 0,
});
this.isFirstLoading = false;
this.getRectInfo()
});
// #ifdef H5
const options = {
shareTitle: data.title,
shareImage: data.image,
shareDesc: data.intro
};
this.wxShare(options);
// #endif
} else {
this.isNull = true
this.isFirstLoading = false;
}
},
showCouponFun() {
if (!this.isLogin) return toLogin();
this.showCoupon = true;
},
showSpecFun(type) {
this.popupType = type;
this.showSpec = true;
},
getAuthMsg() {
return new Promise(resolve => {
getMnpNotice({
scene: 1
}).then(res => {
if (res.code == 1) {
uni.requestSubscribeMessage({
tmplIds: res.data,
fail(res) {
console.log(res.errMsg);
},
complete() {
resolve();
}
});
} else {
resolve();
}
});
});
},
onSubmitOrder() {
uni.showModal({
title: '温馨提示',
content: '是否确认购买?',
confirmColor: '#FF2C3C',
confirmText:"前往支付",
success: async res => {
let {
confirm
} = res;
if (confirm) {
// #ifdef MP-WEIXIN
await this.getAuthMsg();
//#endif
this.showLoading = true
this.orderBuyFun('submit');
}
}
});
},
async orderBuyFun() {
const submitObj = {
org_id: this.id //id
};
let {
data: orderData,
code: orderCode,
msg: orderMsg
} = await resourceOrderBuy(submitObj)
if (orderCode !== 1) return this.showLoading = false
this.showLoading = false
let order_id = orderData.trade_id;
uni.$on('payment', params => {
setTimeout(() => {
if (params.result) {
console.log('Jason', this)
this.$Router.replace({
path: '/pages/pay_result/pay_result',
query: {
id: params.order_id,
type:2,
org_id:this.id,
from: "trade"
}
})
} else {
location.reload()
}
}, 1 * 500)
})
uni.navigateTo({
url: `/pages/payment/payment?from=trade&order_id=${order_id}`
})
}
},
async onShareAppMessage() {
const {
resourceDetail,
inviteCode,
team
} = this;
return {
title: resourceDetail.title,
imageUrl: resourceDetail.image,
path: '/bundle/pages/resource_details/resource_details?id=' + this.id
};
},
computed: {
...mapGetters(['cartNum', 'inviteCode', 'sysInfo', 'appConfig', 'userInfo']),
btnText() {
const {
goodsType
} = this;
console.log(goodsType,222333)
switch (goodsType) {
case 0:
return {
red: '立即下载'
};
case 1:
return {
red: '开通vip'
};
default:
return {
red: '立即购买'
};
}
},
getTeamCountTime() {
return time => time - Date.now() / 1000;
},
navHeight() {
return this.sysInfo.navHeight
},
enableCommission() {
const {
goodsType,
distribution: {
earnings,
is_show
}
} = this
return goodsType == 0 && earnings > 0 && is_show == 1
}
}
};
</script>
<style lang="scss" scoped>
@import '@/styles/base.scss';
.goods-details {
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
.seckill {
height: 100rpx;
background: #ffd4d8;
.price {
width: 504rpx;
height: 100%;
background: url(../../../static/images/bg_seckill.png) no-repeat;
background-size: 100%;
}
.down {
flex: 1;
}
}
.group {
height: 100rpx;
width: 100%;
background-image: url(../../../static/images/pintuan_bg.png);
background-size: 100%;
.group-num {
border: 1px solid #ffffff;
border-radius: 4rpx;
.group-icon {
background: #fff;
padding: 3rpx 7rpx;
}
}
.down {
height: 100%;
background-color: #fff5e1;
padding: 0 20rpx;
}
}
.goods-info {
position: relative;
.info-header {
padding: 20rpx 0 0rpx 24rpx;
.price {
align-items: baseline;
}
}
.name {
padding: 20rpx 24rpx;
flex: 1;
}
.icon-share {
width: 134rpx;
height: 60rpx;
}
.vip-price {
margin: 0 24rpx;
background-color: #FFE9BA;
line-height: 36rpx;
border-radius: 6rpx;
overflow: hidden;
.price-name {
background-color: #101010;
padding: 3rpx 12rpx;
color: #FFD4B7;
position: relative;
overflow: hidden;
&::after {
content: '';
display: block;
width: 20rpx;
height: 20rpx;
position: absolute;
right: -15rpx;
background-color: #FFE9BA;
border-radius: 50%;
top: 50%;
transform: translateY(-50%);
box-sizing: border-box;
}
}
}
}
.details-null {
padding-top: 140rpx;
margin-bottom: 100rpx;
}
.spec {
padding: 24rpx 24rpx;
.text {
width: 100rpx;
}
}
.evaluation {
.title {
height: 100rpx;
border-bottom: $-solid-border;
padding: 0 24rpx;
}
.con {
padding: 30rpx 24rpx;
}
.user-info .avatar {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
}
}
.details {
// overflow: hidden;
.title {
line-height: 88rpx;
text-align: center;
}
&>.content {
padding: 0 20rpx 20rpx;
::v-deep image {
vertical-align: middle;
}
// #ifdef H5
::v-deep img {
vertical-align: middle;
}
// #endif
// #ifdef MP-WEIXIN || APP-PLUS
::v-deep ._img {
display: block;
}
// #endif
}
}
.footer {
height: 100rpx;
position: fixed;
bottom: 0;
left: 0;
right: 0;
box-sizing: content-box;
padding-bottom: env(safe-area-inset-bottom);
.btn {
width: 100rpx;
height: 100rpx;
position: relative;
line-height: 1.3;
}
.cart-num {
position: absolute;
left: 60rpx;
top: 6rpx;
}
.add-cart,
.right-buy,
.consult-btn{
flex: 1;
text-align: center;
padding: 16rpx 0;
}
.add-cart {
background-color: #ffa630;
}
.right-buy {
background-color: $-color-primary;
}
.consult-btn {
background: linear-gradient(to right, #ff8e00 0%, #ff2c3c 100%);
}
}
.group-play {
.title {
padding: 20rpx 28rpx;
border-bottom: $-solid-border;
}
.steps {
padding: 20rpx 28rpx;
.step {
flex: none;
}
.line {
flex: 1;
border: 1px dashed #999999;
margin: 0 20rpx;
}
.number {
border: 1rpx solid #707070;
width: 28rpx;
height: 28rpx;
border-radius: 50%;
line-height: 28rpx;
text-align: center;
margin-right: 6rpx;
}
}
}
.group-list {
.group-item {
padding: 20rpx 24rpx;
&:not(:last-of-type) {
border-bottom: $-solid-border;
}
.group-btn {
background: linear-gradient(90deg, #f95f2f 0%, #ff2c3c 100%);
height: 58rpx;
padding-left: 28rpx;
padding-right: 28rpx;
margin-left: 30rpx;
box-shadow: 0px 6rpx 12rpx rgba(249, 47, 138, 0.4);
}
}
}
.share-money {
position: fixed;
left: 20rpx;
bottom: calc(130rpx + env(safe-area-inset-bottom));
transform: scale(0);
transition: all .3s;
&.show {
transform: scale(1);
}
.share-close {
width: 34rpx;
height: 34rpx;
background: #a7a7a7;
border-radius: 50%;
}
.share-con {
background: url('../../../static/images/bg_packet_img.png');
width: 241rpx;
height: 208rpx;
background-size: 100%;
padding-top: 20rpx;
text-align: center;
}
}
}
</style>

416
bundle/pages/shop_cart/shop_cart.vue

@ -0,0 +1,416 @@
<template>
<view class="shop-cart">
<view class="main " :style="{'padding-bottom': (cartType == 1 ? '100rpx' : 0)}">
<view class="cart-list m-b-20" v-show="cartType==1">
<view class="cart-item bg-white" v-for="(items, index) in cartLists" :key="index">
<view class="flex select">
<u-checkbox :disabled="shopInvalid(items)" @change="changeSelect($event, 1, index)"
shape="circle" :value="items.is_selected == 1">
</u-checkbox>
<shop-title :shop="items.shop"></shop-title>
<view class="xs muted flex-none" v-if="items.shop.is_pay == 0">该店铺未开启支付功能</view>
</view>
<view>
<u-swipe-action :show="openCartId == item.cart_id" btn-width="150" v-for="item in items.cart"
:key="item.cart_id" :index="item.cart_id" @click="deleteOneCart($event, item.cart_id)"
:options="options" @open="openSwipe">
<view class="flex p-20">
<u-checkbox :disabled="cartInvalid(item)"
@change="changeSelect($event, 2, item.cart_id)" shape="circle"
:value="item.selected == 1">
</u-checkbox>
<router-link class="flex-1"
:to="{path: '/pages/goods_details/goods_details', query: {id: item.goods_id}}">
<view class="flex">
<view class="goods-img m-r-20">
<u-image width="180rpx" height="180rpx" border-radius="10rpx"
:src="item.image" />
<view v-if="item.goods_status == 0 || item.goods_del == 1 || !item.stock" class="invalid sm white text-center">已失效
</view>
</view>
<view class="info flex-1">
<view class="line-2 nr">{{item.goods_name}}</view>
<view class="muted line-1 xs m-t-10">
{{item.spec_value_str}}
</view>
<view class="flex row-between m-t-20">
<view class="price flex primary">
<price-format :price="item.price" :first-size="32" :second-size="32"
:subscript-size="24" :weight="500">
</price-format>
</view>
<view class="cartNum" @tap.stop="">
<u-number-box :disabled="cartInvalid(item)" :value="item.goods_num"
:min="1" :max="item.stock"
@change="countChange($event, item.cart_id)" />
</view>
</view>
</view>
</view>
</router-link>
</view>
</u-swipe-action>
</view>
</view>
</view>
<view class="cart-null flex-col col-center row-center bg-white m-b-20" style="padding: 80rpx 0 50rpx"
v-show="cartType == 2">
<image class="img-null" src="/static/images/cart_null.png"></image>
<view class="muted m-b-20">购物车暂无任何商品~</view>
<router-link to="/pages/index/index" navType="pushTab">
<view class="primary br60 btn flex row-center">去逛逛</view>
</router-link>
</view>
<view v-if="!isLogin" class="login flex-col col-center row-center">
<image class="img-null" src="/static/images/cart_null.png"></image>
<view class="muted mt20">登录后才能查看购物车哦</view>
<router-link to="/pages/login/login">
<view class="white br60 flex row-center btn">
<image class="mr10" src="/static/images/icon_wechat.png"></image>
<text>去登录</text>
</view>
</router-link>
</view>
<goods-column v-if="showMoreGoods" ref="mescrollItem"></goods-column>
</view>
<view class="footer flex bg-white" v-show="cartType == 1">
<u-checkbox :disabled="allInvalid()" @change="changeSelect($event,3)" shape="circle" :value="isSelectedAll">
全选
</u-checkbox>
<view class="primary" @tap="deleteSelectCart">删除</view>
<view class="all-price flex lg m-r-20 row-right">
<view>合计</view>
<view class="primary">{{totalPrice || 0}}</view>
</view>
<view class="right-btn br60 white" :style="' ' + (nullSelect ? 'background: #d7d7d7' : '')"
@tap="goToConfirm">去结算</view>
</view>
<u-modal v-model="showDelTips" :show-cancel-button="true" comfirm-text="狠心删除"
:confirm-color="colorConfig.primary" :show-title="false" @confirm="deleteCart">
<view class="flex-col col-center tips-dialog" style="padding-top: 40rpx">
<image class="icon-lg" src="/static/images/icon_warning.png" />
<view style="margin:30rpx 0;">确认删除选中商品吗</view>
</view>
</u-modal>
<tabbar></tabbar>
</view>
</template>
<script>
import {
getCartList,
changeCartSelect,
changeGoodsCount,
deleteGoods
} from '@/api/store';
import {
getUser
} from '@/api/user';
import {
mapGetters,
mapActions
} from 'vuex'
import Cache from '@/utils/cache'
import MescrollCompMixin from "@/components/mescroll-uni/mixins/mescroll-comp";
export default {
mixins: [MescrollCompMixin],
data() {
return {
// 1 2 0
cartType: 0,
showMoreGoods: false,
cartLists: [],
showDelTips: false,
totalPrice: '',
options: [{
text: '删除',
style: {
backgroundColor: '#FF2C3C'
}
}],
openCartId: 0
};
},
computed: {
...mapGetters(['cartNum', 'inviteCode']),
//
nullSelect() {
const {
cartLists
} = this
let nullS = true
cartLists.forEach((item) => {
item.cart.forEach(goods => {
if (goods.selected) nullS = false
})
})
return nullS
},
//
isSelectedAll() {
const {
cartLists
} = this
if (!cartLists.length) return false
if (this.allInvalid()) return false
let index = cartLists.findIndex(item => item.is_selected == 0);
return index == -1 ? true : false
},
},
onLoad() {
},
onShow() {
this.getCartListFun();
},
methods: {
...mapActions(['getCartNum']),
//
deleteCart() {
// console.log(this.cartId)
if(!this.cartId) return this.$toast({ title: '请选择商品' })
this.showDelTips = false
deleteGoods({
cart_id: this.cartId
}).then(res => {
if (res.code == 1) {
this.getCartListFun();
}
});
},
openSwipe(index) {
this.openCartId = index
},
cartInvalid(item) {
return item.goods_status == 0 || item.goods_del == 1 || item.is_pay == 0 || item.has_item == 0 ? true : false || item.stock == 0
},
shopInvalid(item) {
return item.cart.every(citem => this.cartInvalid(citem))
},
allInvalid() {
return this.cartLists.every(item => this.shopInvalid(item))
},
//
deleteSelectCart() {
this.cartId = this.getSelectCart()
this.showDelTips = !this.showDelTips;
},
//
deleteOneCart(e, cartId) {
if (cartId) {
this.cartId = cartId;
}
this.showDelTips = !this.showDelTips;
},
async getCartListFun() {
const {
data: {
lists,
total_amount
},
code
} = await getCartList()
if (code == 1) {
let cartType = 0;
if (lists.length == 0) {
cartType = 2;
} else {
cartType = 1;
}
this.showMoreGoods = true
this.cartLists = lists;
this.cartType = cartType;
this.totalPrice = total_amount;
this.getCartNum()
} else {
this.cartType = 0
}
},
// type1/2/3
changeSelect({
value
}, type, number) {
let cartId = []
const {
cartLists
} = this
switch (type) {
case 1:
cartId = cartLists[number].cart.map(item => item.cart_id)
break;
case 2:
cartId.push(number)
break;
case 3:
cartId = cartLists.reduce((pre, item) => {
return pre.concat(item.cart.map(i => i.cart_id))
}, cartId)
break;
}
this.changeCartSelectFun(cartId, value);
},
changeCartSelectFun(cartId, selected) {
changeCartSelect({
cart_id: cartId,
selected: selected ? 1 : 0
}).then(res => {
if (res.code == 1) {
this.getCartListFun();
}
});
},
//
countChange({
value
}, cartId) {
console.log(value)
let cartid = cartId;
changeGoodsCount({
cart_id: cartid,
goods_num: value
}).then(res => {
this.getCartListFun();
})
},
getSelectCart() {
const {
cartLists
} = this
return cartLists.reduce((pre, item) => {
return pre.concat(item.cart.filter(i => i.selected && !this.cartInvalid(i)).map(i => i
.cart_id))
}, [])
},
goToConfirm() {
let {
cartLists
} = this;
let goods = [];
let carts = this.getSelectCart()
if (carts.length == 0) return this.$toast({
title: '您还没有选择商品哦'
});
//
cartLists.forEach(item => {
if (item.cart.length != 0) {
item.cart.forEach((el, i) => {
//
if(el.selected == 1) {
goods.push({
item_id: el.item_id,
num: el.goods_num,
goods_id: el.goods_id,
shop_id: item.shop.shop_id,
delivery_type: 0
})
}
})
}
})
const params = {
carts: carts,
goods: goods,
type: 'cart'
};
this.$Router.push({
path: '/pages/confirm_order/confirm_order',
query: {
data: params
}
})
},
},
};
</script>
<style lang="scss">
.shop-cart {
.main {
padding-bottom: 100rpx;
}
.cart-list {
.cart-item {
margin: 20rpx 20rpx 0;
border-radius: 10rpx;
.goods-img {
position: relative;
border-radius: 10rpx;
overflow: hidden;
.invalid {
position: absolute;
width: 100%;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
}
}
.info {
max-width: 400rpx;
}
}
.select {
height: 80rpx;
padding: 0 20rpx;
border-bottom: $-solid-border;
}
}
.cart-null {
.btn {
border: 1px solid $-color-primary;
width: 184rpx;
margin-left: auto;
margin-right: auto;
padding: 8rpx 24rpx;
}
}
.footer {
position: fixed;
padding: 0 24rpx;
width: 100%;
height: 100rpx;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.1);
bottom: calc(var(--window-bottom) + 50px);
margin-bottom: env(safe-area-inset-bottom);
z-index: 20;
.all-price {
text-align: right;
flex: 1;
}
.right-btn {
padding: 13rpx 45rpx;
background: linear-gradient(90deg, rgba(249, 95, 47, 1) 0%, rgba(255, 44, 60, 1) 100%);
}
}
.login {
height: calc(100vh - var(--window-bottom));
background: #fff;
text-align: center;
.btn {
background-color: #09BB07;
width: 280rpx;
line-height: 70rpx;
margin: 40rpx auto 0;
image {
width: 50rpx;
height: 50rpx;
}
}
}
}
</style>

213
bundle/pages/user/complain.vue

@ -0,0 +1,213 @@
<template>
<view class="store-settled">
<view class="content">
<view class="apply-form bg-white">
<!-- 投诉类型 -->
<view class="apply-form-item" @tap="showPop=true">
<u-field label="投诉类型" v-model="form.clabel" label-width="160" style="flex: 1;" placeholder="请选择投诉类型"
required disabled>
<u-icon name="arrow-right" slot="right" size="28" />
</u-field>
</view>
<!-- 联系人姓名 -->
<!-- <view class="apply-form-item">
<u-field label="联系人姓名" v-model="form.nickname" label-width="160" placeholder="请输入联系人姓名" required />
</view> -->
<!-- 手机号码 -->
<!-- <view class="apply-form-item">
<u-field label="手机号码" v-model="form.mobile" label-width="160" placeholder="请输入手机号码" required />
</view> -->
<!-- 问题截图 -->
<view class="apply-form-item">
<u-field label="投诉截图" label-width="160" placeholder="请上传投诉截图证明" :border-bottom="false"
required disabled />
<view>
<u-upload ref="uUpload" :show-progress="false" :header="{token: $store.getters.token}"
:max-count="10" width="150" height="150" :action="action" upload-text="上传图片"
@on-success="onSuccess" @on-remove="onRemove" />
</view>
<view class="muted m-t-20 m-b-30">支持jpgpngjpeg格式的图片最多可上传10张</view>
</view>
<view class="apply-form-item">
<view class="label">备注说明</view>
<view class="flex-1" style="background-color: #F8F8F8;">
<u-input v-model="content" type="textarea" placeholder="请描述具体原因,300字以内" :border="false"
:height="160" />
</view>
</view>
<!-- 提交申请 -->
<view style="padding: 30rpx 20rpx 30rpx 0;">
<button type="primary" size="lg" class="br60" @tap="onSubmit">投诉</button>
</view>
<!-- 查阅记录 -->
<router-link to="/bundle/pages/user/complain_recode">
<view class="flex row-center muted">
<u-icon name="order" size="32" />
<view class="m-l-10">查看提交记录</view>
</view>
</router-link>
</view>
</view>
<u-select v-model="showPop" mode="single-column" value-name="id" label-name="name" :list="shopCategory"
@confirm="confirmSelect"></u-select>
</view>
</template>
<script>
import {
complain,
getComplainCategory
} from "@/api/user"
import {
baseURL
} from '@/config/app'
import {
sendSms
} from '@/api/app'
import {
SMSType
} from '@/utils/type'
export default {
data() {
return {
content:'',
//
form: {
cid: '',
clabel: '',
name: '',
image: '',
content: ''
},
codeTips: '',
shopCategory: [],
showPop: false,
action: baseURL + '/api/file/formimage',
fileList: []
}
},
onLoad() {
this.getComplainCategoryFun()
this.goLogin()
},
methods: {
goLogin() {
let {
isLogin
} = this;
if (isLogin) {
return;
}
uni.redirectTo({
url: '/pages/login/login'
});
},
async getComplainCategoryFun() {
const {
code,
data
} = await getComplainCategory()
if (code == 1) {
this.shopCategory = data.lists
}
},
//
async onSubmit() {
const {
form,
fileList
} = this
const submitObj = {
...form,
image: fileList[0],
content:this.content
}
delete submitObj.clabel
const {
data,
code,
msg
} = await complain(submitObj)
if(code == 1) {
this.$toast({
title: msg
})
setTimeout(() => {
this.$Router.replace({
path: '/bundle/pages/user/complain_recode',
query: {
id: data.id
}
})
},1000)
}
},
confirmSelect(e) {
const {
value,
label
} = e[0]
this.form.cid = value
this.form.clabel = label
},
onSuccess(e) {
this.fileList.push(e.data.base_uri)
},
onRemove(index) {
this.fileList.splice(index, 1)
console.log(index)
},
},
}
</script>
<style lang="scss">
.store-settled {
background-color: #FA844C;
min-height: 100vh;
background-repeat: no-repeat;
background-size: 100% auto;
overflow: hidden;
.content {
margin-top: 320rpx;
padding: 0 20rpx 31rpx;
.apply-form {
border-radius: 8px;
padding: 20rpx 0 30rpx 26rpx;
.apply-form-item {
.send-code-btn {
height: 56rpx;
width: 188rpx;
border: 1rpx solid $-color-primary;
}
}
.primary-btn {
width: 100%;
height: 88rpx;
background-color: $-color-primary;
}
}
}
// .pop-categories {
// .reason-item {
// padding: 24rpx 20rpx;
// .reason-desc {
// line-height: 46rpx;
// }
// }
// }
}
</style>

97
bundle/pages/user/complain_recode.vue

@ -0,0 +1,97 @@
<template>
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption"
:up="upOption">
<view class="settled-recode">
<view class="settled-list">
<router-link v-for="(item, index) in list" :key="index" :to="{path: '/bundle/pages/user/complain_result', query: {id: item.id}}">
<view class="settled-item bg-white m-t-20">
<!-- Title -->
<view class="settled-title md bold">{{item.content}}</view>
<view class="settled-info">
<!-- Time -->
<view class="sm muted m-t-26">
提交时间{{item.create_time}}
</view>
<!-- Status -->
<view class="flex row-between m-t-20">
<view class="muted sm" style="align-self: flex-end;">
<text>处理状态</text>
<text :class="{primary: item.is_complate == 1}">{{item.is_complate==1?'已处理':'未处理'}}</text>
</view>
<view class="watch-btn br60 flex row-center" @tap="onShowDetail">查看</view>
</view>
</view>
</view>
</router-link>
</view>
</view>
</mescroll-body>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins";
import {
complainRecord
} from '@/api/user'
export default {
mixins: [MescrollMixin],
data() {
return {
upOption: {
empty: {
icon: '/static/images/order_null.png',
tip: "暂无记录",
}
},
list: []
};
},
methods: {
upCallback(page) {
complainRecord({
page_size: page.size,
page_no: page.num
}).then(({
data
}) => {
if (page.num == 1) this.list = [];
let curPageData = data.lists;
let curPageLen = curPageData.length;
this.list = this.list.concat(curPageData);
let hasNext = !!data.more;
this.mescroll.endSuccess(curPageLen, hasNext);
}).catch(() => {
this.mescroll.endErr()
})
},
}
}
</script>
<style lang="scss">
.settled-recode {
.settled-list {
padding: 20rpx;
.settled-item {
border-radius: 10rpx;
padding: 20rpx 30rpx 30rpx;
.settled-title {
padding: 21rpx 0 25rpx;
border-bottom: $-solid-border;
}
.settled-info {
.watch-btn {
border: $-solid-border;
height: 52rpx;
width: 124rpx;
}
}
}
}
}
</style>

165
bundle/pages/user/complain_result.vue

@ -0,0 +1,165 @@
<template>
<view class="settled-result">
<view class="result-box">
<!-- Header -->
<view class="result-header bg-white flex-col col-center">
<u-image width="165rpx" height="165rpx" class="m-t-42" :src="getStatus.img" />
<view class="m-t-32 lg bold">{{getStatus.text}}</view>
<view>
<view class="m-t-20 muted sm text-center">{{getStatus.desc}}</view>
<view class="flex" v-if="applyDetail.audit_status !=2">
<router-link class="flex-1" to="/pages/index/index" navType="pushTab">
<view class="br60 flex row-center back-btn m-t-60 md">返回首页</view>
</router-link>
</view>
</view>
</view>
<!-- Content -->
<view class="result-content bg-white m-t-20 p-20">
<!-- 主营行业 -->
<view class="apply-form-item flex row-between">
<view><text class="primary m-r-10"></text>投诉类型</view>
<view>{{applyDetail.category}}</view>
</view>
<!-- 图片 -->
<view class="apply-form-item">
<view><text class="primary m-r-10"></text>投诉截图</view>
<view class="license-list flex m-t-10 flex-wrap">
<view v-for="(item,index) in license" class="m-r-14 m-t-20" @tap="previewImage(index)"
:key="index">
<u-image width="152rpx" height="152rpx" :src="item" />
</view>
</view>
</view>
<!-- 投诉内容 -->
<view class="apply-form-item flex row-between">
<view><text class="primary m-r-10"></text>投诉内容</view>
<view>{{applyDetail.content}}</view>
</view>
<!-- 处理结果 -->
<view class="apply-form-item flex row-between">
<view><text class="primary m-r-10"></text>处理结果</view>
<view>{{applyDetail.remark?applyDetail.remark:'--'}}</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
complainDetail
} from '@/api/user'
import {copy} from '@/utils/tools'
export default {
data() {
return {
applyDetail: {},
license: []
}
},
methods: {
async complainDetail() {
const {
data,
code
} = await complainDetail(this.id)
if (code == 1) {
this.applyDetail = data
this.license = [data.image]
}
},
previewImage(current) {
uni.previewImage({
current,
urls: this.license
})
},
onCopy(text) {
copy(text)
}
},
onLoad(options) {
this.id = this.$Route.query.id
this.complainDetail()
},
computed: {
getStatus() {
const {
applyDetail: {
is_complate
}
} = this
switch (is_complate) {
case 0:
return {
img: '/static/images/img_store_submit.png',
text: '已提交等待处理!',
desc: '工作人员将会电话联系您,请注意接听!'
}
case 1:
return {
img: '/static/images/img_store_success.png',
text: '工作人员已处理!',
desc: '请查看处理结果'
}
default:
return {}
}
}
}
}
</script>
<style lang="scss" scoped>
.settled-result {
padding: 20rpx;
.result-box {
.result-header {
padding: 0 75rpx 50rpx;
border-radius: 10rpx;
.btn-copy {
width: 96rpx;
height: 42rpx;
line-height: 42rpx;
border: $-solid-border;
}
}
.back-btn {
height: 88rpx;
border: 1px solid #CCC;
&.primary {
border-color: $-color-primary;
color: $-color-primary;
}
}
.result-content {
border-radius: 10rpx;
.apply-form-item {
padding: 30rpx 0;
&:not(:last-of-type) {
border-bottom: $-solid-border;
}
}
}
}
}
</style>

927
bundle/pages/user/vip.vue

File diff suppressed because one or more lines are too long

100
components/components/explore.vue

@ -0,0 +1,100 @@
<template>
<view class="explore">
<!-- 搜索 -->
<view >
<router-link
:to="{path: '/bundle_b/pages/community_search/community_search'}">
<u-search disabled
placeholder="请输入搜索内容" height="64" focus
></u-search>
</router-link>
</view>
<view class="content">
<tabs :current="current" @change="changeTabs" height="100" >
<tab v-for="(item, index) in tabList" :key="index" :name="item.name">
<lists :cateId="item.id" :typeId="type" :i="index" :index="current"></lists>
</tab>
</tabs>
</view>
</view>
</template>
<script>
import {
getCommunityCate2,
getCommunityArticleLists
} from '@/api/community.js';
import Lists from "./lists.vue"
export default {
components: {
Lists
},
props: {
active: {
type: Number
}
},
data() {
return {
tabList: [{
name: '全部',
id: ''
}],
current: 0.,
type:1,
}
},
watch: {
active() {
if(this.active == 1){
this.initRecommendTopic()
this.mescroll.resetUpScroll()
}
}
},
created() {
this.initRecommendTopic()
},
methods: {
initMescroll(event) {
this.isInit = true; // true
this.mescroll = event;
},
handleCancel() {
this.keyword = '';
},
//
changeTabs(event) {
this.current = event;
},
//
initRecommendTopic() {
getCommunityCate2({'type':this.type}).then(res => {
if( res.code === 1 ) {
this.tabList = [{
name: '全部',
id: ''
}, ...res.data]
} else {
this.$toast({ title: res.msg })
}
})
},
}
}
</script>
<style lang="scss" scoped>
.explore {
// pb
.content {
height: calc(100vh - 92px - var(--window-bottom));
overflow: hidden;
}
}
</style>

413
components/components/follow.vue

@ -0,0 +1,413 @@
<template>
<view class="follow">
<mescroll-uni ref="mescrollRef" top="0" :height="height" @init="initMescroll" @down="downCallback"
@up="upCallback" :down="downOption" :up="upOption">
<block v-for="(item, index) in lists" :key="index">
<view class="content-box">
<!-- 内容头部信息 -->
<router-link :to="'/bundle_b/pages/community_user/community_user?id=' + item.user.id">
<view class="header flex row-between">
<view class="flex">
<!-- 头像 -->
<u-image width="70" height="70" :src="item.user.avatar" borderRadius="50%"></u-image>
<!-- 昵称 -->
<text class="normal bold m-l-16">{{ item.user.nickname }}</text>
</view>
<view>
<text class="muted">{{ item.create_time }}</text>
</view>
</view>
</router-link>
<!-- 内容媒体信息 -->
<view class="swiper-container">
<product-swiper :imgUrls="item.images" :autoplay="false" borderRadius="14"></product-swiper>
</view>
<!-- 提到的宝贝( 商品 ) -->
<view class="goods-box bb flex row-between" @click="handleOpenGoods(item.id)"
v-if="item.goods_data.length">
<text class="nr lighter">查看TA提到的服务({{item.goods_data.length}})</text>
<!-- <text class="tips xs">300+人评价</text> -->
<view class="goods flex">
<block v-for="(goodsItem, goodsIndex) in item.goods_data" :key="goodsItem.id">
<u-image v-if="goodsIndex <= 2" :src="goodsItem.image" width="58" height="58"
class="m-l-6"></u-image>
</block>
<u-icon name="arrow-right" class="m-l-10"></u-icon>
</view>
</view>
<!-- 提到的店铺( 店铺 ) -->
<view class="goods-box bb flex row-between" @click="handleOpenShop(item.id)"
v-if="item.shop_data.length">
<text class="nr lighter">查看TA提到的商家({{item.shop_data.length}})</text>
<!-- <text class="tips xs">300+人评价</text> -->
<view class="goods flex">
<block v-for="(shopItem, shopIndex) in item.shop_data" :key="shopIndex">
<u-image v-if="shopIndex <= 2" :src="shopItem.logo" width="58" height="58"
class="m-l-6"></u-image>
</block>
<u-icon name="arrow-right" class="m-l-10"></u-icon>
</view>
</view>
<!-- 内容文字 -->
<view class="content ">
<view class="text" v-if="item.show">
{{ item.beforeContent }}...
<text class="primary nr m-l-20" @click="handleShowContent(index)">展开</text>
</view>
<view class="text" v-else>
{{ item.content }}
</view>
<view class="tags" v-if="item.topic">
<navigator hover-class="none"
:url="'/bundle_b/pages/community_topic/community_topic?id=' + item.topic.id +'&name=' + item.topic.name">
<text class="sm"># {{ item.topic.name }}</text>
</navigator>
</view>
</view>
<!-- 底部 -->
<view class="footer flex row-between">
<view>
<button open-type="share" @click="handleShare(item)" class="flex-col col--center"
hover-class="none">
<image src="/static/images/icon_forward.png"></image>
</button>
</view>
<view class="flex nr lighter">
<view class="flex likes-box">
<view class="likes" :class="item.is_like==0 ? 'leave':'entry'"
@click="handleCommunityLike(item.is_like, item)">
</view>
<image class="m-l-30"></image>
<text>{{ item.like }}</text>
</view>
<view class=" m-l-40" @click="handleOpenComment(item.id)">
<image src="/static/images/icon_evaluate.png"></image>
<text>{{ item.comment }}</text>
</view>
</view>
</view>
</view>
</block>
</mescroll-uni>
<!-- 提到的商品 -->
<community-goods v-model="showGoodsPopup" v-if="showGoodsPopup" :communityId="communityId"></community-goods>
<!-- 提到的店铺 -->
<community-shop v-model="showShopPopup" :communityId="communityId"></community-shop>
<!-- 评论 -->
<community-comment-popup v-model="showComment" v-if="showComment" :communityId="communityId">
</community-comment-popup>
<!-- #ifdef H5 -->
<u-popup :custom-style="{'background': 'none'}" class="share-tips" v-model="showTips" mode="top">
<view style="overflow: hidden;">
<image src="/static/images/share_arrow.png" class="share-arrow" />
<view class="white" style="text-align: center;margin-top: 280rpx;">
<view class="bold lg">立即分享给好友吧</view>
<view class="sm m-t-10">点击屏幕右上角将本页面分享给好友</view>
</view>
</view>
</u-popup>
<!-- #endif -->
</view>
</template>
<script>
import {
getCommunityFollow,
apiCommunityCommentLike
} from '@/api/community.js';
import {
debounce
} from "@/utils/tools.js"
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import MescrollMoreItemMixin from "@/components/mescroll-uni/mixins/mescroll-more-item.js";
export default {
mixins: [MescrollMixin, MescrollMoreItemMixin],
props: {
active: {
type: Number
}
},
data() {
return {
height: '',
canReset: true,
isLikes: false,
communityId: '',
upOption: {
empty: {
icon: '/static/images/follow_null.png',
tip: '暂未关注哦~', //
fixed: true,
top: "200rpx",
}
},
lists: [],
show: false,
showGoodsPopup: false,
showShopPopup: false,
showTips: false,
showComment: false
}
},
watch: {
active() {
if(this.active == 0){
uni.$emit('hasNew', 0)
this.mescroll.resetUpScroll()
}
}
},
created() {
this.handleCommunityLike = debounce(this.handleCommunityLike, 100)
uni.getSystemInfo({
success: (res) => {
this.height = res.windowHeight - 46 + 'px';
}
});
},
methods: {
initMescroll(event) {
this.isInit = true; // true
this.mescroll = event;
},
//
async upCallback(page) {
const index = this.current;
const pageNum = page.num
const pageSize = page.size
getCommunityFollow({
page_no: pageNum,
page_size: pageSize,
}).then(res => {
//
if (pageNum == 1) this.lists = []
//
const hasNext = !!res.data.more;
res.data.list = this.handleContent(res.data.list)
this.lists = [...this.lists, ...res.data.list]
this.mescroll.endSuccess(res.data.list.length, hasNext);
}).catch((err) => {
this.mescroll.endErr()
})
},
//
handleOpenGoods(id) {
this.communityId = id;
this.showGoodsPopup = true;
},
//
handleOpenShop(id) {
this.communityId = id;
this.showShopPopup = true;
},
//
handleContent(list) {
return list.filter(item => {
if (item.content.indexOf('\n') > -1) {
const arr = item.content.split('\n')
if (arr.length >= 3) {
item.show = true
if (arr[0].length >= 25 || arr[1].length >= 25 || arr[2].length > 20) {
item.beforeContent = item.content.slice(0, arr[0].length + arr[1].length + arr[2].length - 10)
} else {
item.beforeContent = item.content.slice(0, arr[0].length + arr[1].length + arr[
2].length - 10)
}
} else {
if (item.content.length >= 70) {
item.show = true
item.beforeContent = item.content.slice(0, 70)
}
}
} else {
if (item.content.length >= 70) {
item.show = true
item.beforeContent = item.content.slice(0, 70)
}
}
return true
})
},
//
handleShowContent(index) {
this.$set(this.lists[index], 'show', false)
},
//
handleShare(item) {
// #ifdef MP
this.$emit('share', item)
// #endif
// #ifdef H5
this.showTips = true
// #endif
// #ifndef MP
this.$store.commit('setCommunity', {
...item,
url: 'bundle_b/pages/community_detail/community_detail'
})
this.$store.dispatch('communityShare')
// #endif
},
//
handleCommunityLike(status, item) {
switch (status) {
case 0:
this.$set(item, 'like', item.like + 1)
this.$set(item, 'is_like', 1)
break;
case 1:
this.$set(item, 'like', item.like - 1)
this.$set(item, 'is_like', 0)
break;
}
apiCommunityCommentLike({
id: item.id,
status: status ? 0 : 1,
type: 1
}).then(res => {
if (res.code === 1) {
//
uni.$emit('changeItem', {
like: item.like,
is_like: item.is_like,
id: item.id
})
} else {
//
switch (status) {
case 0:
this.$set(item, 'like', item.like - 1)
this.$set(item, 'is_like', 0)
break;
case 1:
this.$set(item, 'like', item.like + 1)
this.$set(item, 'is_like', 1)
break;
}
this.$toast({
title: res.msg
})
}
})
},
//
handleOpenComment(id) {
this.communityId = id;
this.showComment = true;
}
}
}
</script>
<style lang="scss" scoped>
.content-box {
padding-bottom: 20rpx;
background-color: $-color-white;
.bb {
border-bottom: 1px solid #f2f2f2;
}
.header {
font-size: 28rpx;
padding: 20rpx 24rpx;
}
.swiper-container {
padding: 0 20rpx;
}
.goods-box {
padding: 15rpx 24rpx;
.tips {
padding: 0 10rpx;
color: $-color-primary;
border-radius: 20rpx;
border: 1px solid $-color-primary;
}
}
.content {
padding: 24rpx;
padding-bottom: 0;
.text {
white-space: pre-line;
line-height: 48rpx;
font-size: 28rpx;
color: $-color-normal;
}
.tags {
padding-top: 24rpx;
text {
margin-right: 20rpx;
border-radius: 26rpx;
padding: 8rpx 24rpx;
color: $-color-primary;
background: rgba($-color-primary, .1);
}
}
}
.footer {
padding: 0 24rpx;
image {
width: 44rpx;
height: 44rpx;
vertical-align: middle;
margin: 24rpx 6rpx;
}
//
.likes-box {
position: relative;
.likes {
z-index: 99;
left: -36rpx;
width: 120rpx;
height: 120rpx;
margin-right: 6rpx;
position: absolute;
background: url('@/static/images/likes.png') no-repeat;
background-position: left;
background-size: cover;
}
//
.leave {
background-position: left;
}
//
.entry {
background-position: right;
transition: background .6s steps(28);
}
}
}
}
.share-tips .share-arrow {
width: 140rpx;
height: 250rpx;
float: right;
margin: 15rpx 31rpx 0 0;
}
</style>

110
components/components/like-header.vue

@ -0,0 +1,110 @@
<template>
<view class="header flex row-between">
<router-link class="photo" to="/bundle_b/pages/published_works/published_works">
<u-image src="/static/images/icon_photo.png" width="60" height="60" borderRadius="50%"></u-image>
</router-link>
<view class="mainnav flex">
<view class="mainnav--item" :class="{'active': current === 0}" @click="changeNav(0)">
<text>关注</text>
<text v-if="hasNew" class="new"></text>
</view>
<view class="mainnav--item" :class="{'active': current === 1}" @click="changeNav(1)">
<text>服务</text>
</view>
<view class="mainnav--item" :class="{'active': current === 2}" @click="changeNav(2)">
<text>需求</text>
</view>
<view class="mainnav--item" :class="{'active': current === 3}" @click="changeNav(3)">
<text>机构</text>
</view>
<view class="mainnav--item" :class="{'active': current === 4}" @click="changeNav(4)">
<text>专家</text>
</view>
</view>
<view class="user flex row-right">
<router-link to="/bundle_b/pages/community_search/community_search" >
<u-icon v-if="current==0" name="search" size="34" class="m-r-20"></u-icon>
</router-link>
<router-link to="/bundle_b/pages/community_user/community_user">
<u-image :src="userInfo.avatar?userInfo.avatar:'/static/images/portrait_empty.png'" width="60" height="60" borderRadius="50%"></u-image>
</router-link>
</view>
</view>
</template>
<script>
import {
mapGetters
} from "vuex"
export default {
name: 'like-header',
props: {
current: {
type: Number,
default: 1
},
},
data() {
return {
hasNew: false
}
},
created() {
uni.$on('hasNew', item => {
this.hasNew = item
})
},
methods: {
changeNav(index) {
console.log(index)
if(!this.isLogin) return this.$Router.push('/pages/login/login')
this.$emit('change', index);
}
},
computed: {
...mapGetters(['userInfo'])
}
}
</script>
<style lang="scss" scoped>
.header {
padding: 16rpx 24rpx;
background-color: $-color-white;
.photo {
width: 120rpx;
}
.mainnav {
&--item {
width: 120rpx;
font-size: 32rpx;
font-weight: 500;
text-align: center;
color: #BBBBBB;
transition: all .2s linear;
.new {
width: 10rpx;
height: 10rpx;
border-radius: 50%;
display: inline-block;
margin-bottom: 24rpx;
background-color: $-color-primary;
}
}
.active {
color: #000000;
}
}
.user {
width: 120rpx;
}
}
</style>

103
components/components/lists.vue

@ -0,0 +1,103 @@
<template>
<view class="">
<mescroll-uni ref="mescrollRef" top="0" bottom="200rpx" :height="height" @init="mescrollInit"
@down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
<u-waterfall ref="uWaterfall" v-model="lists" :add-time="50">
<template v-slot:left="{leftList}">
<view style="padding:0 9rpx 0 30rpx">
<community-list width="336rpx" type="waterfall" :list="leftList"></community-list>
</view>
</template>
<template v-slot:right="{rightList}">
<view style="padding:0 30rpx 0 9rpx;">
<community-list width="336rpx" type="waterfall" :list="rightList"></community-list>
</view>
</template>
</u-waterfall>
</mescroll-uni>
</view>
</template>
<script>
import {
getCommunityArticleLists
} from '@/api/community.js';
import {
trottle
} from "@/utils/tools.js"
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import MescrollMoreItemMixin from "@/components/mescroll-uni/mixins/mescroll-more-item.js";
export default {
mixins: [MescrollMixin, MescrollMoreItemMixin],
props: {
cateId: {
type: [String, Number]
},
typeId: {
type: [String, Number]
}
},
data() {
return {
height: '',
upOption: {
empty: {
icon: '/static/images/news_null.png',
tip: '暂无任何内容...', //
fixed: true,
top: "0",
}
},
lists: []
}
},
mounted() {
uni.$on('changeItem', (event) => {
const index = this.lists.findIndex(el => el.id == event.id)
if (index == -1) return
this.$refs.uWaterfall.modify(event.id, 'like', event.like)
this.$refs.uWaterfall.modify(event.id, 'is_like', event.is_like)
})
uni.getSystemInfo({
success: (res) => {
this.height = res.windowHeight - 46 + 'px';
}
});
},
methods: {
//
async upCallback(page) {
const pageNum = page.num
const pageSize = page.size
getCommunityArticleLists({
type:this.typeId,
cate_id: this.cateId,
page_no: pageNum,
page_size: pageSize,
}).then(res => {
//
if (pageNum == 1) {
this.$refs.uWaterfall.clear()
this.lists = []
}
//
const hasNext = !!res.data.more;
// vue
// has_new
uni.$emit('hasNew', res.data.has_new)
setTimeout(() => {
this.lists = [...this.lists, ...res.data.list]
}, 0)
this.mescroll.endSuccess(res.data.list.length, hasNext);
})
}
}
}
</script>
<style>
</style>

250
components/components/organ.vue

@ -0,0 +1,250 @@
<template>
<view class="news-list organ">
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
:up="upOption">
<view class="contain">
<view class="banner">
<ad-swipers :pid="30" height="340rpx">
</ad-swipers>
</view>
<!-- 城市 -->
<router-link class="m-l-16 flex row-center" to="/bundle_b/pages/city/city">
<text class="m-r-6">{{ cityInfo.name || '选择' }}</text>
<u-icon name="arrow-down" size="24" color="#FFFFFF"></u-icon>
<!-- <image class="icon-md m-l-30" src="/static/images/icon_news.png">
</image> -->
</router-link>
<tabs :current="active" @change="changeActive" :bar-width="60">
<tab :name="cname" >
</tab>
</tabs>
<view class="main">
<view class="article-list">
<view class="article-item bg-white" v-for="(item, index) in newsList" :key="index" >
<router-link :to="{path: '/pages/community/organ_team_details', query: {id: item.id,type:0}}">
<view class="flex col-top">
<view class="info flex-1">
<view class="title lg line-2 m-b-20">{{ item.name }}</view>
<view class="lighter line-2">
<view>{{ item.intro }}</view>
</view>
</view>
<u-image width="240rpx" height="180rpx" class="img m-l-20" :src="item.image" />
</view>
<view class="flex row-between m-t-20">
<view class="xs muted">区域: <b style="color: red;">{{item.address}}</b></view>
</view>
<view class="flex row-between m-t-20">
<view class="flex">
<image class="icon-sm" src="/static/images/icon_see.png"></image>
<view class="m-l-10 xs muted">{{ item.visit }}人浏览</view>
</view>
</view>
</router-link>
</view>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import {
mapGetters,
mapActions
} from 'vuex'
import {
getOrganLists
} from '@/api/community.js';
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins";
export default {
mixins: [MescrollMixin],
props: {
active: {
type: Number
}
},
data() {
return {
active: 0,
upOption: {
auto: false,
empty: {
icon: '/static/images/news_null.png',
tip: "暂无数据",
}
},
cname : "",
categoryList: [],
newsList: [],
type: -1,
};
},
watch: {
active() {
if(this.active == 3){
this.mescroll.resetUpScroll()
}
},
cityInfo(){
console.log(111)
//
this.downCallback();
}
},
async onShow() {
uni.setNavigationBarTitle({
title: '检测机构'
});
//
await this.downCallback();
},
async onLoad(options) {
this.type = 0;
uni.setNavigationBarTitle({
title: '检测机构'
});
//
await this.downCallback();
},
methods: {
changeActive(e) {
this.active = e;
this.newsList = [] // ,
this.mescroll.resetUpScroll() //
},
async downCallback() {
this.mescroll.resetUpScroll();
},
upCallback(page) {
let {
cityInfo,
isLogin,
type,
active,
categoryList
} = this;
this.cname = this.cityInfo !=null && this.cityInfo.id>0 ? this.cityInfo.name : '全国',
console.log(categoryList,11222)
getOrganLists({
cid: this.cityInfo !=null && this.cityInfo.id>0 ? this.cityInfo.id : '',
page_size:page.size,
page_no:page.num
}).then(({
data
}) => {
if (page.num == 1) this.newsList = [];
let curPageData = data.list;
let curPageLen = curPageData.length;
let hasNext = !!data.more;
this.newsList = this.newsList.concat(curPageData);
this.mescroll.endSuccess(curPageLen, hasNext);
}).catch(() => {
this.mescroll.endErr()
})
},
async getCategoryListFun() {
let {
cityInfo,
isLogin
} = this;
const {
code,
data
} = await getResourceCategoryList({
type: this.type
})
if (code == 1) {
this.categoryList = data
}
let item = {id:0,name:"全国"}
if(cityInfo.id !=null && cityInfo.id!=undefined && cityInfo.id>0){
item = {id:"city_"+cityInfo.id,name:"本地"}
}
this.categoryList.push(item)
if(isLogin){
item = {id:"my_buy",name:"我的购买"}
this.categoryList.push(item)
item = {id:"my_download",name:"我的下载"}
this.categoryList.push(item)
}
},
},
computed: {
...mapGetters(['cityInfo'])
}
};
</script>
<style lang="scss">
.news-list {
.main {
.article-list {
padding-top: 20rpx;
.article-item {
padding: 20rpx;
align-items: flex-start;
&:not(:last-of-type){
border-bottom: $-solid-border;
}
}
}
}
}
page {
padding: 0;
}
.index-bg {
background-image: url('/static/images/index_bg.png');
background-size: 100% auto;
background-repeat: no-repeat;
}
.index {
min-height: calc(100vh - var(--window-bottom));
.u-navbar {
::v-deep .u-search {
padding: 0 30rpx;
}
}
//
.capsule-tips {
width: 584rpx;
color: #FFFFFF;
padding: 12rpx 18rpx;
border-radius: 14rpx;
background: rgba(0, 0, 0, 0.7);
position: relative;
position: absolute;
z-index: 9999;
bottom: -80rpx;
right: -150rpx;
}
.capsule-tips::after {
content: '';
border-bottom: 14rpx solid rgba(0, 0, 0, 0.7);
border-right: 14rpx solid transparent;
border-left: 14rpx solid transparent;
position: absolute;
top: -14rpx;
right: 88rpx;
}
.cate-btn {
padding: 12rpx 16rpx 12rpx 20rpx;
border-radius: 60rpx 0 0 60rpx;
background-color: rgba(256, 256, 256, .4);
}
}
</style>

246
components/components/team.vue

@ -0,0 +1,246 @@
<template>
<view class="news-list team">
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
:up="upOption">
<view class="contain">
<view class="banner">
<ad-swipers :pid="30" height="340rpx">
</ad-swipers>
</view>
<!-- 城市 -->
<router-link class="m-l-16 flex row-center" to="/bundle_b/pages/city/city">
<text class="m-r-6">{{ cityInfo.name || '选择' }}</text>
<u-icon name="arrow-down" size="24" color="#FFFFFF"></u-icon>
<!-- <image class="icon-md m-l-30" src="/static/images/icon_news.png">
</image> -->
</router-link>
<tabs :current="active" @change="changeActive" :bar-width="60">
<tab :name="cname" >
</tab>
</tabs>
<view class="main">
<view class="article-list">
<view class="article-item bg-white" v-for="(item, index) in newsList" :key="index" >
<router-link :to="{path: '/pages/community/organ_team_details', query: {id: item.id,type:1}}">
<view class="flex col-top">
<view class="info flex-1">
<view class="title lg line-2 m-b-20">{{ item.name }}</view>
<view class="lighter line-2">
<view>{{ item.intro }}</view>
</view>
</view>
<u-image width="240rpx" height="180rpx" class="img m-l-20" :src="item.image" />
</view>
<view class="flex row-between m-t-20">
<view class="xs muted">区域: <b style="color: red;">{{item.address}}</b></view>
</view>
<view class="flex row-between m-t-20">
<view class="flex">
<image class="icon-sm" src="/static/images/icon_see.png"></image>
<view class="m-l-10 xs muted">{{ item.visit }}人浏览</view>
</view>
</view>
</router-link>
</view>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import {
mapGetters,
mapActions
} from 'vuex'
import {
getTeamLists
} from '@/api/community.js';
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins";
export default {
mixins: [MescrollMixin],
props: {
active: {
type: Number
}
},
data() {
return {
upOption: {
auto: false,
empty: {
icon: '/static/images/news_null.png',
tip: "暂无数据",
}
},
cname : "",
categoryList: [],
newsList: [],
type: -1,
};
},
watch: {
active() {
if(this.active == 4){
this.mescroll.resetUpScroll()
}
},
cityInfo(){
//
this.downCallback();
}
},
async onShow() {
uni.setNavigationBarTitle({
title: '专家信息'
});
//
await this.downCallback();
},
async onLoad(options) {
uni.setNavigationBarTitle({
title: '专家信息'
});
//
await this.downCallback();
},
methods: {
changeActive(e) {
this.active = e;
this.newsList = [] // ,
this.mescroll.resetUpScroll() //
},
async downCallback() {
this.mescroll.resetUpScroll();
},
upCallback(page) {
let {
cityInfo,
isLogin,
type,
active,
categoryList
} = this;
this.cname = this.cityInfo !=null && this.cityInfo.id>0 ? this.cityInfo.name : '全国',
getTeamLists({
cid: this.cityInfo !=null && this.cityInfo.id>0 ? this.cityInfo.id : '',
page_size:page.size,
page_no:page.num
}).then(({
data
}) => {
if (page.num == 1) this.newsList = [];
let curPageData = data.list;
let curPageLen = curPageData.length;
let hasNext = !!data.more;
this.newsList = this.newsList.concat(curPageData);
this.mescroll.endSuccess(curPageLen, hasNext);
}).catch(() => {
this.mescroll.endErr()
})
},
async getCategoryListFun() {
let {
cityInfo,
isLogin
} = this;
const {
code,
data
} = await getResourceCategoryList({
type: this.type
})
if (code == 1) {
this.categoryList = data
}
let item = {id:0,name:"全国"}
if(cityInfo.id !=null && cityInfo.id!=undefined && cityInfo.id>0){
item = {id:"city_"+cityInfo.id,name:"本地"}
}
this.categoryList.push(item)
if(isLogin){
item = {id:"my_buy",name:"我的购买"}
this.categoryList.push(item)
item = {id:"my_download",name:"我的下载"}
this.categoryList.push(item)
}
},
},
computed: {
...mapGetters(['cityInfo'])
}
};
</script>
<style lang="scss">
.news-list {
.main {
.article-list {
padding-top: 20rpx;
.article-item {
padding: 20rpx;
align-items: flex-start;
&:not(:last-of-type){
border-bottom: $-solid-border;
}
}
}
}
}
page {
padding: 0;
}
.index-bg {
background-image: url('/static/images/index_bg.png');
background-size: 100% auto;
background-repeat: no-repeat;
}
.index {
min-height: calc(100vh - var(--window-bottom));
.u-navbar {
::v-deep .u-search {
padding: 0 30rpx;
}
}
//
.capsule-tips {
width: 584rpx;
color: #FFFFFF;
padding: 12rpx 18rpx;
border-radius: 14rpx;
background: rgba(0, 0, 0, 0.7);
position: relative;
position: absolute;
z-index: 9999;
bottom: -80rpx;
right: -150rpx;
}
.capsule-tips::after {
content: '';
border-bottom: 14rpx solid rgba(0, 0, 0, 0.7);
border-right: 14rpx solid transparent;
border-left: 14rpx solid transparent;
position: absolute;
top: -14rpx;
right: 88rpx;
}
.cate-btn {
padding: 12rpx 16rpx 12rpx 20rpx;
border-radius: 60rpx 0 0 60rpx;
background-color: rgba(256, 256, 256, .4);
}
}
</style>

101
components/components/xuqiu.vue

@ -0,0 +1,101 @@
<template>
<view class="explore">
<!-- 搜索 -->
<view >
<router-link
:to="{path: '/bundle_b/pages/community_search/community_search'}">
<u-search disabled
placeholder="请输入搜索内容" height="64" focus
></u-search>
</router-link>
</view>
<view class="content">
<tabs :current="current" @change="changeTabs" height="100" >
<tab v-for="(item, index) in tabList" :key="index" :name="item.name">
<lists :cateId="item.id" :typeId="type" :i="index" :index="current"></lists>
</tab>
</tabs>
</view>
</view>
</template>
<script>
import {
getCommunityCate2,
getCommunityArticleLists
} from '@/api/community.js';
import Lists from "./lists.vue"
export default {
components: {
Lists
},
props: {
active: {
type: Number
}
},
data() {
return {
tabList: [{
name: '全部',
id: ''
}],
current: 0,
type:0,
}
},
watch: {
active() {
console.log(this.active,12122)
if(this.active == 2){
this.initRecommendTopic()
}
}
},
created() {
this.initRecommendTopic()
console.log(1212222)
},
methods: {
initMescroll(event) {
this.isInit = true; // true
this.mescroll = event;
},
handleCancel() {
this.keyword = '';
},
//
changeTabs(event) {
this.current = event;
},
//
initRecommendTopic() {
getCommunityCate2({'type':this.type}).then(res => {
if( res.code === 1 ) {
this.tabList = [{
name: '全部',
id: ''
}, ...res.data]
} else {
this.$toast({ title: res.msg })
}
})
},
}
}
</script>
<style lang="scss" scoped>
.explore {
// pb
.content {
height: calc(100vh - 92px - var(--window-bottom));
overflow: hidden;
}
}
</style>

109
pages/community/organ_team_details.vue

@ -0,0 +1,109 @@
<template>
<view>
<view class="news-details">
<view class="header">
<view class="title xxl m-b-20">{{ articleDetail.name }}</view>
<product-swiper :imgUrls="swiperList" ></product-swiper>
<view class="flex row-between">
<view class="xs lighter">公司名称{{ articleDetail.company }}</view>
<view class="flex">
<image class="icon-sm" src="/static/images/icon_see.png"></image>
<view class="m-l-10 xs muted">{{ articleDetail.visit }}人浏览</view>
</view>
</view>
<view class="flex row-between">
<view class="xs lighter">地区{{ articleDetail.address }}</view>
</view>
<view class="flex row-between">
<view class="xs lighter">联系方式{{ articleDetail.contact }}</view>
</view>
</view>
<view class="main">
简介{{ articleDetail.intro }}
</view>
<view class="main">
<u-parse :html="article_content" />
</view>
</view>
<loading-view v-if="showLoading"></loading-view>
</view>
</template>
<script>
import { getTeamOrganDetail } from '@/api/community.js';
export default {
data() {
return {
showLoading: true,
articleDetail: {},
article_content: "",
swiperList:[]
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.type = Number(options.type) || '';
this.id = options.id;
if (this.type) {
uni.setNavigationBarTitle({
title: '专家详情'
});
} else {
uni.setNavigationBarTitle({
title: '机构详情'
});
}
this.getArticleDetailFun();
},
methods: {
getArticleDetailFun() {
getTeamOrganDetail({
id: this.id
}).then(res => {
if (res.code == 1) {
this.articleDetail = res.data
this.swiperList = [{id: res.data.id,uri: res.data.image}];
setTimeout(() => {
this.article_content = res.data.content;
}, 200);
setTimeout(() => {
this.showLoading = false
}, 300);
}
});
}
}
};
</script>
<style lang="scss">
page {
background-color: #fff;
}
.news-details .header{
padding: 20rpx 15px;
border-bottom: $-solid-border;
}
.row-between{
padding: 20rpx 14rpx;
}
.news-details .main {
padding: 40rpx 15px;
}
</style>
Loading…
Cancel
Save