Browse Source

feat: 接口对接;

pull/8/head
Fox-33 1 month ago
parent
commit
b8ea8620f0
51 changed files with 603 additions and 423 deletions
  1. +2
    -2
      api/api.js
  2. +2
    -2
      api/fetch.js
  3. +3
    -5
      api/http.js
  4. +2
    -0
      api/model/image.js
  5. +5
    -0
      api/model/partner.js
  6. +116
    -0
      components/base/servicePopup.vue
  7. +1
    -1
      components/growing/recordsView.vue
  8. +9
    -13
      components/growing/userCard.vue
  9. +5
    -5
      components/home/pictureLiveView.vue
  10. +0
    -5
      components/product/productCard.vue
  11. +2
    -1
      pages.json
  12. +0
    -4
      pages/index/category.vue
  13. +22
    -2
      pages/index/center.vue
  14. +18
    -18
      pages/index/growing.vue
  15. +30
    -10
      pages/index/partner.vue
  16. +2
    -2
      pages_order/auth/agreementConfirmPopup.vue
  17. +4
    -0
      pages_order/auth/roleChoose.vue
  18. +2
    -4
      pages_order/auth/wxLogin.vue
  19. +12
    -2
      pages_order/center/orderCard.vue
  20. +0
    -2
      pages_order/comment/commentCard.vue
  21. +0
    -12
      pages_order/comment/recordFormPopup.vue
  22. +5
    -0
      pages_order/components/formInput.vue
  23. +46
    -14
      pages_order/growing/achievement/index.vue
  24. +1
    -1
      pages_order/growing/achievement/recordsView.vue
  25. +6
    -4
      pages_order/growing/activity/index.vue
  26. +16
    -77
      pages_order/growing/activity/markList.vue
  27. +17
    -14
      pages_order/growing/activity/markPopup.vue
  28. +2
    -3
      pages_order/growing/activity/search.vue
  29. +8
    -88
      pages_order/live/formPopup.vue
  30. +29
    -10
      pages_order/live/index.vue
  31. +28
    -22
      pages_order/live/list.vue
  32. +2
    -2
      pages_order/member/memberApplyCard.vue
  33. +14
    -17
      pages_order/member/memberBind.vue
  34. +7
    -7
      pages_order/member/memberCard.vue
  35. +46
    -16
      pages_order/member/switch.vue
  36. +1
    -1
      pages_order/message/card.vue
  37. +1
    -1
      pages_order/message/index.vue
  38. +0
    -1
      pages_order/order/components/productCard.vue
  39. +4
    -9
      pages_order/order/orderConfirm/index.vue
  40. +5
    -2
      pages_order/order/orderDetail/index.vue
  41. +6
    -3
      pages_order/order/orderList/index.vue
  42. +4
    -9
      pages_order/order/orderPay/index.vue
  43. +37
    -8
      pages_order/partner/apply.vue
  44. +29
    -2
      pages_order/partner/withdraw.vue
  45. +1
    -1
      pages_order/product/collectList.vue
  46. +1
    -2
      pages_order/product/productDetail.vue
  47. +27
    -4
      pages_order/product/search.vue
  48. +0
    -1
      pages_order/traveler/travelerCard.vue
  49. +5
    -2
      pages_order/traveler/travelerList.vue
  50. +8
    -11
      pages_order/traveler/travelerPopup.vue
  51. +10
    -1
      store/store.js

+ 2
- 2
api/api.js View File

@ -25,7 +25,7 @@ const config = {
}
export function api(key, data, callback, loadingTitle) {
export function api(key, data, callback, loadingTitle, disabledToast) {
let req = config[key]
if (!req) {
@ -85,7 +85,7 @@ export function api(key, data, callback, loadingTitle) {
}
return http.http(req.url, data, callback, req.method,
loadingTitle || req.showLoading, loadingTitle || req.loadingTitle)
loadingTitle || req.showLoading, loadingTitle || req.loadingTitle, disabledToast)
}


+ 2
- 2
api/fetch.js View File

@ -1,6 +1,6 @@
import api from './api.js'
const fetch = (key, data = {}, transform = true, loadingTitle) => {
const fetch = (key, data = {}, transform = true, loadingTitle, disabledToast = false) => {
return new Promise((resolve, reject) => {
const callback = (res) => {
@ -15,7 +15,7 @@ const fetch = (key, data = {}, transform = true, loadingTitle) => {
}
}
api(key, data, callback, loadingTitle)
api(key, data, callback, loadingTitle, disabledToast)
})
}


+ 3
- 5
api/http.js View File

@ -3,7 +3,7 @@ import Vue from 'vue'
import utils from '../utils/utils.js'
import store from '../store/store.js'
function http(uri, data, callback, method = 'GET', showLoading, title) {
function http(uri, data, callback, method = 'GET', showLoading, title, disabledToast) {
if(showLoading){
uni.showLoading({
@ -35,12 +35,10 @@ function http(uri, data, callback, method = 'GET', showLoading, title) {
if(res.statusCode == 401 ||
res.data.message == '操作失败,token非法无效!' ||
res.data.message == '操作失败,用户不存在!'){
store.commit('logout')
console.error('登录过期');
store.commit('clearUserInfo')
utils.toLogin()
}
if(res.statusCode == 200 && res.data.code != 200
} else if(!disabledToast && res.statusCode == 200 && res.data.code != 200
&& res.data.code != 902){
uni.showToast({
mask: true,


+ 2
- 0
api/model/image.js View File

@ -25,6 +25,8 @@ const api = {
queryMarkmeList: {
url: '/image/queryMarkmeList',
method: 'GET',
limit : 500,
showLoading : true,
},
}

+ 5
- 0
api/model/partner.js View File

@ -9,6 +9,11 @@ const api = {
limit : 500,
showLoading : true,
},
// 合伙人-查询合伙人信息
queryPartner: {
url: '/partner/queryPartner',
method: 'GET',
},
// 合伙人-邀请二维码
getInviteCode: {
url: '/partner/getInviteCode',


+ 116
- 0
components/base/servicePopup.vue View File

@ -0,0 +1,116 @@
<template>
<view>
<uv-popup ref="popup" mode="bottom" bgColor="none"
:zIndex="1000000"
>
<view class="popup__view">
<view class="flex header">
<view class="title">申请售后</view>
<button class="btn" @click="close">关闭</button>
</view>
<view class="flex content">
<view>{{ phone }}</view>
<button plain class="flex btn" @click="onCall">
<image class="btn-icon" src="@/pages_order/static/order/icon-phone.png" mode="widthFix"></image>
</button>
</view>
</view>
</uv-popup>
</view>
</template>
<script>
export default {
data() {
return {
phone: null,
}
},
methods: {
open() {
this.phone = this.configList.after_sale_service_hotline
this.$refs.popup.open()
},
close() {
this.$refs.popup.close()
},
onCall() {
uni.makePhoneCall({
phoneNumber: this.phone,
success() {
console.log('安卓拨打成功');
},
fail() {
console.log('安卓拨打失败');
}
})
},
},
}
</script>
<style lang="scss" scoped>
.popup__view {
width: 100vw;
display: flex;
flex-direction: column;
box-sizing: border-box;
font-family: PingFang SC;
font-weight: 400;
line-height: 1.4;
background: #FFFFFF;
border-top-left-radius: 32rpx;
border-top-right-radius: 32rpx;
}
.header {
position: relative;
width: 100%;
padding: 24rpx 0;
box-sizing: border-box;
border-bottom: 2rpx solid #EEEEEE;
.title {
font-family: PingFang SC;
font-weight: 500;
font-size: 34rpx;
line-height: 1.4;
color: #181818;
}
.btn {
font-family: PingFang SC;
font-weight: 500;
font-size: 32rpx;
line-height: 1.4;
color: #8B8B8B;
position: absolute;
top: 26rpx;
left: 40rpx;
}
}
.content {
padding: 84rpx;
column-gap: 12rpx;
font-size: 36rpx;
color: #181818;
.btn {
border: none;
width: 72rpx;
height: 72rpx;
background: #F6F6F6;
border-radius: 50%;
overflow: hidden;
&-icon {
width: 40rpx;
height: auto;
}
}
}
</style>

+ 1
- 1
components/growing/recordsView.vue View File

@ -17,7 +17,7 @@
<view class="content" @click="onClickActivity(record.id)">
<view class="desc">{{ record.name }}</view>
<view class="image">
<view class="image-item" v-for="(image, imgIdx) in record.image" :key="imgIdx">
<view class="image-item" v-for="(image, imgIdx) in record.images" :key="imgIdx">
<image class="img" :src="image" mode="aspectFill"></image>
</view>
</view>


+ 9
- 13
components/growing/userCard.vue View File

@ -16,13 +16,13 @@
<view class="card-content">
<view class="flex info">
<view class="avatar">
<image class="img" :src="memberInfo.headImage" mode="scaleToFill"></image>
<view :class="['tag', `tag-${memberInfo.role}`]">{{ memberInfo.roleDesc || '' }}</view>
<image class="img" :src="info.headImage" mode="scaleToFill"></image>
<view :class="['tag', `tag-${info.role}`]">{{ info.roleDesc || '' }}</view>
</view>
<view class="flex summary">
<view class="flex flex-column summary-item name">
<view class="summary-item-content">{{ memberInfo.nickName }}</view>
<view class="summary-item-label">{{ `ID:${memberInfo.id}` }}</view>
<view class="summary-item-content">{{ info.nickName || '' }}</view>
<view class="summary-item-label">{{ `ID:${info.id}` }}</view>
</view>
<view class="flex flex-column summary-item" @click="jumpToAchievement">
<view class="summary-item-content">{{ medalCount }}</view>
@ -34,7 +34,7 @@
</view>
</view>
</view>
<view class="flex medal">
<view class="flex medal" @click="jumpToAchievement">
<image class="medal-item" v-for="item in medalList" :key="item.id" :src="item.medal.icon1" mode="widthFix"></image>
</view>
</view>
@ -69,16 +69,12 @@
},
computed: {
...mapState(['memberInfo']),
...mapState(['userInfo', 'memberInfo']),
info() {
return this.memberInfo || this.userInfo
},
},
methods: {
async getData() {
try {
await this.$fetch('queryMedalList', { pageNo: 1, pageSize: 1000, isLight: '1', })
} catch (err) {
}
},
onAdd() {
this.$emit('addRecord')
},


+ 5
- 5
components/home/pictureLiveView.vue View File

@ -7,7 +7,6 @@
<image class="img" src="@/static/image/icon-arrow-right.png" mode="widthFix"></image>
</button>
</view>
<!-- todo: auto scroll -->
<!-- <view class="live-content">
<view class="live-item" v-for="item in list" :key="item.id">
<image class="live-item-bg" :src="item.image" mode="aspectFill"></image>
@ -26,7 +25,7 @@
>
<swiper-item v-for="item in list" :key="item.id" style="display: inline-block;">
<view class="swiper-item">
<view class="swiper-item-content" @click="jumpToLive(item.id)">
<view class="swiper-item-content" @click="jumpToLive(item.id, item.activityId)">
<image class="live-item-bg" :src="item.url" mode="aspectFill"></image>
<view class="live-item-info">
<view class="text-ellipsis live-item-info-title">{{ item.title }}</view>
@ -54,12 +53,13 @@
async getData() {
try {
this.list = (await this.$fetch('queryImageList', { pageNo: 1, pageSize: 8 }))?.records?.map(item => {
const { id, image, activityId_dictText, createTime } = item
const { id, image, activityId, activityId_dictText, createTime } = item
const images = image?.split?.(',') || []
return {
id,
activityId,
url: images?.[0],
images,
title: activityId_dictText,
@ -70,9 +70,9 @@
}
},
jumpToLive(id) {
jumpToLive(id, activityId) {
this.$store.commit('setLiveInfo', this.list.find(item => item.id === id))
this.$utils.navigateTo(`/pages_order/live/index?id=${id}`)
this.$utils.navigateTo(`/pages_order/live/index?imageId=${id}&activityId=${activityId}`)
},
showAll() {
this.$utils.navigateTo(`/pages_order/live/list`)


+ 0
- 5
components/product/productCard.vue View File

@ -64,14 +64,9 @@
},
computed: {
tagDesc() {
// todo: check key
const { tagList } = this.data
return tagList?.length ? tagList.split('、').join('·') : ''
return
const { categoryId_dictText, timeId_dictText, ageId_dictText } = this.data
return [categoryId_dictText, timeId_dictText, ageId_dictText].filter(val => val).join('·')
},
priceInt() {
return Math.floor(this.data.priceDiscount)


+ 2
- 1
pages.json View File

@ -24,7 +24,8 @@
{
"path": "pages/index/partner",
"style": {
"navigationBarTitleText": ""
"navigationBarTitleText": "",
"enablePullDownRefresh": true
}
},
{


+ 0
- 4
pages/index/category.vue View File

@ -387,10 +387,6 @@
change(e) {
this.current = e
},
search(){
// todo: set filter
this.initList()
},
onClickFilter(key, val) {
if (val) {
this.queryParams[key] = val


+ 22
- 2
pages/index/center.vue View File

@ -76,7 +76,11 @@
<image class="icon" :src="item.icon" mode="scaleToFill"></image>
<view>{{ item.label }}</view>
</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="24rpx"></uv-icon>
<view class="flex right">
<!-- 开营通知 -->
<view class="flex sup" v-if="item.id === '006' && userCenterData.noticeNum">{{ userCenterData.noticeNum }}</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="24rpx"></uv-icon>
</view>
</view>
</view>
</view>
@ -126,7 +130,7 @@
}
},
computed: {
...mapState(['userInfo', 'configList']),
...mapState(['userInfo', 'userCenterData', 'configList']),
isLogin() {
return this.userInfo && this.userInfo.id
}
@ -292,6 +296,22 @@
height: 40rpx;
}
}
.right {
column-gap: 8rpx;
}
.sup {
min-width: 32rpx;
height: 32rpx;
font-family: PingFang SC;
font-weight: 500;
font-size: 24rpx;
line-height: 1.3;
color: #FFFFFF;
background: #F53F3F;
border-radius: 32rpx;
}
}
}


+ 18
- 18
pages/index/growing.vue View File

@ -20,11 +20,11 @@
</uv-search>
</view>
<view class="archives">
<view class="archives" v-if="userInfo.id">
<userCard :medalList="medalList" :medalCount="medalCount" :experienceCount="total" @switchMember="jumpToChooseMember" @addRecord="onAdd"></userCard>
</view>
<view class="list" v-if="memberInfo">
<view class="list" v-if="userInfo.id">
<recordsView :list="list"></recordsView>
</view>
<view class="flex" v-else>
@ -63,18 +63,17 @@
queryParams: {
pageNo: 1,
pageSize: 10,
// userId: '',
bindUserId: '',
},
mixinsListApi: '',
medalList: [],
medalCount: 0,
}
},
computed: {
...mapState(['memberInfo']),
mixinsListApi() {
return 'queryExperienceList'
// todo
return this.queryParams.userId ? 'queryExperienceList' : ''
...mapState(['userInfo', 'memberInfo']),
bindUserId() {
return this.memberInfo?.id || this.userInfo.id
},
},
onLoad() {
@ -83,26 +82,27 @@
}
},
onShow() {
// todo: set queryParams.userId by memberInfo
if (!this.memberInfo && this.userInfo.id) {
this.$store.commit('setMemberInfo', this.userInfo)
}
// this.queryParams.userId = this.memberInfo.id
// this.getData()
console.log('bindUserId', this.bindUserId)
this.queryParams.bindUserId = this.bindUserId
this.mixinsListApi = this.queryParams.bindUserId ? 'queryExperienceList' : ''
if(uni.getStorageSync('token')){
this.fetchMedalList()
this.getData()
}
},
onHide() {
this.mixinsListApi = ''
},
methods: {
getDataThen(records) {
this.list = records.map(item => {
const { id, activityTitle, activityId_dictText, image, createTime } = item
const { id, activityTitle, activityId_dictText, imageList, createTime } = item
return {
id,
name: activityTitle || activityId_dictText || '',
image: image?.split?.(',') || [],
images: imageList?.split?.(',') || [],
createTime
}
})
@ -116,7 +116,7 @@
},
async fetchMedalList() {
try {
const result = await this.$fetch('queryMedalList', { pageNo: 1, pageSize: 1000, isLight: '1', })
const result = await this.$fetch('queryMedalList', { pageNo: 1, pageSize: 1000, isLight: '1', bindUserId: this.bindUserId })
const { records, total } = result
this.medalList = records


+ 30
- 10
pages/index/partner.vue View File

@ -16,7 +16,7 @@
</view>
<view class="card">
<view class="flex user">
<view class="flex user" v-if="userInfo.id">
<view class="avatar">
<image class="img" :src="userInfo.headImage" mode="scaleToFill"></image>
<view :class="['tag', `tag-${userInfo.role}`]">{{ userInfo.roleDesc || '' }}</view>
@ -65,12 +65,11 @@
</button>
</view>
<!-- todo: check -->
<button class="btn-apply" @click="onApplyPartner">
<image class="bg" src="@/pages_order/static/partner/apply.png" mode="widthFix"></image>
</button>
<view class="list" v-if="isPartner && list.length">
<view class="list" v-if="list.length">
<view class="flex list-item" v-for="item in list" :key="item.id">
<view class="flex col info">
<view class="avatar">
@ -108,13 +107,18 @@
data() {
return {
advantages: ['收益高', '品类全', '到账快', '城市多'],
// todo: fetch
isPartner: true,
mixinsListApi: 'queryCommissionList',
partnerInfo: {},
mixinsListApi: '',
}
},
computed: {
...mapState(['userCenterData']),
isPartner() {
// status0- 1- 2-
const { status } = this.partnerInfo
return status == '1'
},
},
onLoad() {
if(uni.getStorageSync('token')){
@ -123,13 +127,29 @@
}
},
onShow() {
// todo: refresh is partner?
if(uni.getStorageSync('token')){
this.fetchPartner()
this.mixinsListApi = 'queryCommissionList'
console.log('onShow getData')
this.getData()
}
},
//
async onPullDownRefresh() {
await this.fetchPartner()
uni.stopPullDownRefresh()
},
methods: {
async fetchPartner() {
try {
const result = await this.$fetch('queryPartner')
this.partnerInfo = result || {}
} catch (err) {
}
},
onApplyPartner() {
// todo: check
return
this.$utils.navigateTo(`/pages_order/partner/apply`)
this.$utils.navigateTo(`/pages_order/partner/apply?readonly=${this.isPartner ? 1 : 0}`)
},
jumpToTeam() {
this.$utils.navigateTo(`/pages_order/partner/team`)


+ 2
- 2
pages_order/auth/agreementConfirmPopup.vue View File

@ -7,9 +7,9 @@
</view>
<view class="content">
在你使用 鸿宇研学生服务之前请仔细阅读
<text class="highlight" @click="$refs.modal.open('user_ys', '用户服务协议')">用户服务协议</text>
<text class="highlight" @click="$refs.modal.open('service_agreement', '用户服务协议')">用户服务协议</text>
<text class="highlight" @click="$refs.modal.open('user_bh', '隐私政策')">隐私政策</text>
<text class="highlight" @click="$refs.modal.open('privacy_policy', '隐私政策')">隐私政策</text>
如你同意该指引请点击同意开始使用本小程序
</view>
<view class="footer">


+ 4
- 0
pages_order/auth/roleChoose.vue View File

@ -48,6 +48,10 @@
},
async onConfirm() {
try {
const params = {
role: this.role
}
await this.$fetch('updateInfo', params, false)
uni.showToast({


+ 2
- 4
pages_order/auth/wxLogin.vue View File

@ -24,11 +24,9 @@
</uv-checkbox-group>
<view class="desc">
我已阅读并同意
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('user_ys', '服务协议')">服务协议</text>
<text class="highlight" @click="$refs.modal.open('service_agreement', '服务协议')">服务协议</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('user_bh', '隐私政策')">隐私政策</text>
<text class="highlight" @click="$refs.modal.open('privacy_policy', '隐私政策')">隐私政策</text>
</view>
</view>


+ 12
- 2
pages_order/center/orderCard.vue View File

@ -7,13 +7,20 @@
</view>
<view class="label">{{ item.label }}</view>
</view>
<servicePopup ref="servicePopup"></servicePopup>
</view>
</template>
<script>
import { mapState } from 'vuex'
import servicePopup from '@/components/base/servicePopup.vue'
export default {
components: {
servicePopup,
},
data() {
return {
}
@ -26,14 +33,17 @@
{ id: '001', label: '待支付', value: this.userCenterData.orderStatus0 || 0, index: 1, icon: '/pages_order/static/center/order-1.png' },
{ id: '002', label: '已支付', value: this.userCenterData.orderStatus1 || 0, index: 2, icon: '/pages_order/static/center/order-2.png' },
{ id: '003', label: '已完成', value: this.userCenterData.orderStatus2 || 0, index: 3, icon: '/pages_order/static/center/order-3.png' },
// todo: check
{ id: '004', label: '售后', value: 0, index: 0, icon: '/pages_order/static/center/order-4.png' },
{ id: '004', label: '售后', index: 4, value: 0, icon: '/pages_order/static/center/order-4.png' },
{ id: '005', label: '全部', index: 0, icon: '/pages_order/static/center/order-5.png' },
]
}
},
methods: {
jumpToOrderList(index) {
if (index === 4) { //
this.$refs.servicePopup.open()
return
}
this.$utils.navigateTo(`/pages_order/order/orderList/index?index=${index}`)
}
},


+ 0
- 2
pages_order/comment/commentCard.vue View File

@ -1,10 +1,8 @@
<template>
<view class="card">
<!-- todo: delete -->
<view class="flex header">
<view class="flex left">
<view class="avatar">
<!-- todo: check key -->
<image class="avatar-img" :src="data.user.headImage" mode="scaleToFill"></image>
</view>
<view class="info">


+ 0
- 12
pages_order/comment/recordFormPopup.vue View File

@ -162,15 +162,6 @@
},
}
// todo: check
// this.configList.experienceQuestionList.forEach((item, index) => {
// rules[`texts[${index}]`] = {
// type: 'string',
// required: true,
// message: `${item.question}`,
// }
// })
this.$refs.form.setRules(rules)
},
async open() {
@ -227,9 +218,6 @@
// todo: check
userId: this.userInfo.id,
experienceId,
// processScore,
// spotScore,
// teacherScore,
image: images.join(','),
content: texts.join('\r\n')
}


+ 5
- 0
pages_order/components/formInput.vue View File

@ -15,6 +15,7 @@
transform: 'translateX(-4px)'
}"
:fontSize="fontSize"
:disabled="disabled"
></uv-input>
</template>
@ -41,6 +42,10 @@
type: String,
default: '32rpx'
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {


+ 46
- 14
pages_order/growing/achievement/index.vue View File

@ -25,6 +25,7 @@
</template>
<script>
import { mapState } from 'vuex'
import mixinsList from '@/mixins/list.js'
import recordsView from './recordsView.vue'
@ -40,36 +41,67 @@
mixinsListApi: 'queryMedalList',
}
},
computed: {
...mapState(['userInfo', 'memberInfo']),
},
onLoad({ search }) {
if (search) {
this.keyword = search
this.queryParams.title = search
}
this.queryParams.bindUserId = this.memberInfo?.id || this.userInfo.id
this.getData()
},
methods: {
getDataThen(records) {
this.list = records.map(item => {
const { id, activityId_dictText, medalId, medal, createTime, isLight: _isLight } = item
const list = records.reduce((arr, item) => {
const { id, activityId, activityId_dictText, medalId, medal, lightDate, createTime, isLight: _isLight } = item
const { title, icon1, icon2 } = medal
const isLight = _isLight == '1'
return {
id,
name: activityId_dictText,
children: [
{
medalId,
icon: isLight ? icon1 : icon2,
label: title,
createTime,
isLight,
},
]
const obj = {
medalId,
icon: isLight ? icon1 : icon2,
label: title,
createTime: lightDate || createTime,
isLight,
}
let index = arr.findIndex(activity => activity.id === activityId)
if (index === -1) {
arr.push({
id: activityId,
name: activityId_dictText,
createTime,
children: [obj]
})
} else {
arr[index].children.push(obj)
}
return arr
}, [])
list.sort((a, b) => new Date(b.createTime).getTime() - new Date(a.createTime).getTime())
list.forEach(item => {
item.children.sort((a, b) => {
if ((a.isLight && b.isLight) || (!a.isLight && !b.isLight)) {
return new Date(a.createTime).getTime() - new Date(b.createTime).getTime()
}
if (a.isLight) {
return -1
}
return 1
})
})
this.list = list
},
},
}


+ 1
- 1
pages_order/growing/achievement/recordsView.vue View File

@ -19,7 +19,7 @@
<view class="flex flex-column list-item" v-for="(child, cIdx) in record.children" :key="cIdx" @click="onLightMedal(child.medalId)">
<image class="list-item-icon" :src="child.icon" mode="aspectFill"></image>
<view class="list-item-title">{{ child.label }}</view>
<view class="list-item-desc">{{ $dayjs(child.createTime).format('YYYY-MM-DD') }}</view>
<view class="list-item-desc" v-if="child.createTime">{{ $dayjs(child.createTime).format('YYYY-MM-DD') }}</view>
</view>
</view>
</view>


+ 6
- 4
pages_order/growing/activity/index.vue View File

@ -48,7 +48,7 @@
</view>
<view class="section-content highlights">
<view class="highlights-item" v-for="(image, idx) in detail.highlights" :key="idx">
<image class="img" :src="image" mode="scaleToFill" @click="previewImage(detail.highlights, idx)"></image>
<image class="img" :src="image" mode="aspectFill" @click="previewImage(detail.highlights, idx)"></image>
</view>
</view>
</view>
@ -141,9 +141,10 @@
try {
const result = await this.$fetch('queryExperienceById', { recordId: this.id })
const { imageContentList, experienceList } = result
const { activityId, imageContentList, experienceList } = result
this.detail = {
activityId,
highlights: imageContentList.reduce((arr, item) => {
return arr.concat(item.image?.split?.(',') || [])
}, []),
@ -171,7 +172,7 @@
this.$utils.navigateTo(`/pages_order/growing/activity/applyEmail?id=${this.id}`)
},
onMark() {
this.$refs.markPopup.open(this.id)
this.$refs.markPopup.open(this.detail.activityId)
},
onAdd() {
this.$refs.recordFormPopup.open()
@ -263,13 +264,14 @@
&-item {
min-width: 0;
height: 304rpx;
border: 2rpx solid #CDCDCD;
border-radius: 12rpx;
overflow: hidden;
.img {
width: 100%;
height: 304rpx;
height: 100%;
}
}
}


+ 16
- 77
pages_order/growing/activity/markList.vue View File

@ -3,20 +3,9 @@
<navbar title="标记有我" leftClick @leftClick="$utils.navigateBack" />
<view class="main">
<view class="section" v-for="item in list" :key="item.id">
<view class="section-header">
<view class="flex title">{{ item.title }}</view>
<button class="flex btn btn-all" @click="jumpToGrowing(item.id)">
<view>查看成长档案</view>
<image class="icon" src="@/static/image/icon-arrow-right.png" mode="widthFix"></image>
</button>
</view>
<view class="section-content record">
<view class="record-item" v-for="(image, imgIdx) in item.images" :key="imgIdx">
<image class="img" :src="image" mode="scaleToFill"></image>
</view>
</view>
<view class="record">
<view class="record-item" v-for="(image, imgIdx) in markmeList" :key="imgIdx">
<image class="img" :src="image" mode="aspectFill" @click="previewImage(markmeList, imgIdx)"></image>
</view>
</view>
@ -24,20 +13,22 @@
</template>
<script>
import mixinsList from '@/mixins/list.js'
import { mapState } from 'vuex'
export default {
mixins: [mixinsList],
data() {
return {
// todo
mixinsListApi: '',
}
},
computed: {
...mapState(['markmeList']),
},
methods: {
jumpToGrowing(id) {
// todo
this.$utils.navigateTo(`/pages/index/growing`)
previewImage(arr, index) {
uni.previewImage({
urls: arr,
current: arr[index], //
});
},
},
}
@ -45,68 +36,16 @@
<style lang="scss" scoped>
.swiper {
margin-top: 40rpx;
.title {
margin-top: 12rpx;
font-size: 28rpx;
font-weight: 600;
color: #252545;
}
.tag {
margin-top: 4rpx;
padding: 2rpx 8rpx;
font-size: 24rpx;
color: #00A9FF;
background: #E0F5FF;
border-radius: 8rpx;
}
}
.main {
padding: 0 40rpx;
}
.section {
margin-top: 64rpx;
&-header {
font-size: 36rpx;
font-weight: 500;
color: #191919;
.title {
flex: 1;
justify-content: flex-start;
column-gap: 8rpx;
}
.btn-all {
column-gap: 4rpx;
font-size: 24rpx;
line-height: 1.4;
color: #8B8B8B;
.icon {
width: 32rpx;
height: auto;
}
}
}
&-content {
margin-top: 24rpx;
}
}
.record {
width: 100%;
padding: 40rpx;
box-sizing: border-box;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16rpx;
&-item {
height: 300rpx;
border: 2rpx solid #CDCDCD;
border-radius: 12rpx;
overflow: hidden;


+ 17
- 14
pages_order/growing/activity/markPopup.vue View File

@ -20,7 +20,7 @@
上传本人照片
</view>
<view class="form-item-content">
<button class="flex btn">
<button class="flex btn btn-avatar" @clickan class="s">="onUpload">
<view v-if="form.imagePath" class="avatar">
<image class="img" :src="form.imagePath" mode="aspectFill"></image>
<view class="flex mask">
@ -49,7 +49,7 @@
export default {
data() {
return {
id: null,
activityId: null,
form: {
imagePath: null,
},
@ -64,8 +64,8 @@
}
},
methods: {
open(id) {
this.id = id
open(activityId) {
this.activityId = activityId
this.$refs.popup.open();
},
close() {
@ -94,22 +94,27 @@
} = this.form
const params = {
activityId: this.activityId,
imagePath,
}
// todo: check
await this.$fetch('queryMarkmeList', params)
const result = await this.$fetch('queryMarkmeList', params)
uni.showToast({
icon: 'success',
title: '提交成功',
title: '标记成功',
});
this.$emit('submitted')
this.$emit('submitted', result)
this.close()
this.$store.commit('setMarkmeList', result)
this.$utils.navigateTo(`/pages_order/growing/activity/markList`)
uni.navigateTo({
url: '/pages_order/growing/activity/markList',
success: () => {
this.close()
}
})
} catch (err) {
console.log('onSave err', err)
@ -243,9 +248,7 @@
}
.btn-avatar {
display: inline-block;
width: auto;
border: none;
display: inline-flex;
}
.avatar {
@ -276,7 +279,7 @@
}
&.is-empty {
background: #F3F2F7;
background: #F7F8FA;
.icon {
width: 61rpx;


+ 2
- 3
pages_order/growing/activity/search.vue View File

@ -58,7 +58,6 @@
pageNo: 1,
pageSize: 10,
activityTitle: '',
// sort: 'comprehensive',
},
mixinsListApi: 'queryExperienceList',
}
@ -106,12 +105,12 @@
},
getDataThen(records) {
this.list = records.map(item => {
const { id, activityTitle, activityId_dictText, image, createTime } = item
const { id, activityTitle, activityId_dictText, imageList, createTime } = item
return {
id,
name: activityTitle || activityId_dictText || '',
image: image?.split?.(',') || [],
images: imageList?.split?.(',') || [],
createTime
}
})


+ 8
- 88
pages_order/live/formPopup.vue View File

@ -13,22 +13,6 @@
:rules="rules"
errorType="toast"
>
<view class="form-item">
<uv-form-item prop="activityId" :customStyle="formItemStyle">
<view class="form-item-label">
<image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>
关联项目
</view>
<view class="form-item-content">
<view class="flex row" @click="openRelatePojectPicker">
<view v-if="form.activityId" class="text">{{ projectDesc }}</view>
<view v-else class="text placeholder">请选择关联项目</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view>
<reloateProjectPopup ref="reloateProjectPopup" :options="projects" @confirm="onRelateProjectChange"></reloateProjectPopup>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="area" :customStyle="formItemStyle">
<view class="form-item-label">选择地址</view>
@ -74,19 +58,15 @@
},
data() {
return {
imageId: null,
activityId: null,
form: {
activityId: null,
area: null,
latitude: null,
longitude: null,
images: [],
},
rules: {
'activityId': {
type: 'string',
required: true,
message: '请选择关联项目',
},
'area': {
type: 'string',
required: true,
@ -103,68 +83,14 @@
}
},
computed: {
projectDesc() {
const { activityId } = this.form
const target = this.projects?.find?.(item => item.id === activityId)
return target?.name || ''
},
},
methods: {
getData() {
// todo
this.projects = [
{
id: '001',
name: '亲子•坝上双草原6日 |乌兰布统+锡林郭勒+长城',
},
{
id: '002',
name: '青青草原•云中岭 |5-10公里AB线强度可选',
},
{
id: '003',
name: '新疆天山行7/9日丨醉美伊犁&吐鲁番双套餐',
},
{
id: '004',
name: '九色甘南|人间净土6日/7日深度游',
},
{
id: '005',
name: '北疆全景12日| 入疆首推!阿勒泰+伊犁+吐鲁番',
},
{
id: '006',
name: '塞上江南•神奇宁夏5日|穿越大漠与历史对话',
},
{
id: '007',
name: '尊享•天山环线9日| 伊犁全景+独库,头等舱大巴',
},
]
async open(imageId, activityId) {
this.questions = [
{
id: '001',
label: '这次研学之旅,整体给你留下了怎样的印象?用几个词或几句话简单概括一下',
},
{
id: '002',
label: '在整个行程中,你最喜欢的部分是哪里?为什么?',
},
{
id: '003',
label: '你觉得这次研学的行程安排是否合理?有没有哪些地方让你觉得特别满意或需要改进的?',
},
]
},
async open(id) {
// todo: auto bind activityId by id?
await this.getData()
this.imageId = imageId
this.activityId = activityId
this.form = {
activityId: null,
area: null,
latitude: null,
longitude: null,
@ -175,12 +101,6 @@
},
close() {
this.$refs.popup.close()
},
openRelatePojectPicker() {
this.$refs.reloateProjectPopup.open(this.form.activityId?.id || null)
},
onRelateProjectChange(id) {
this.form.activityId = id
},
//
selectAddr() {
@ -209,18 +129,18 @@
await this.$refs.form.validate()
const {
activityId,
area,
images,
} = this.form
const params = {
activityId,
imageId: this.imageId,
activityId: this.activityId,
address: area,
image: images.join(',')
}
await this.$fetch('addImage', params)
await this.$fetch('addImageContent', params)
uni.showToast({
icon: 'success',


+ 29
- 10
pages_order/live/index.vue View File

@ -11,6 +11,7 @@
<view class="tag">{{ liveInfo.createTime }}</view>
</view>
<view v-if="isManager" class="flex operate">
<view class="btn btn-add" @click="onMark">标记有我</view>
<view class="btn btn-add" @click="onAdd">新增记录</view>
</view>
</view>
@ -21,11 +22,11 @@
<view class="section" v-for="item in list" :key="item.id">
<view class="flex section-header">
<view class="avatar">
<image class="avatar-img" :src="item.avatar" mode="scaleToFill"></image>
<image class="avatar-img" :src="item.user.headImage" mode="scaleToFill"></image>
</view>
<view class="info">
<view class="flex title">
<view>{{ item.createBy }}</view>
<view>{{ item.user.nickName }}</view>
<image class="icon" src="@/static/image/icon-location.png" mode="widthFix"></image>
<view class="address text-ellipsis">{{ item.address }}</view>
</view>
@ -34,7 +35,7 @@
</view>
<view class="section-content record">
<view class="record-item" v-for="(image, imgIdx) in item.images" :key="imgIdx">
<image class="img" :src="image" mode="aspectFill"></image>
<image class="img" :src="image" mode="aspectFill" @click="previewImage(item.images, imgIdx)"></image>
</view>
</view>
</view>
@ -43,6 +44,8 @@
<formPopup ref="formPopup" @submitted="getData"></formPopup>
<markPopup ref="markPopup"></markPopup>
</view>
</template>
@ -53,16 +56,19 @@
import SYStackedCarousel from '@/uni_modules/SY-StackedCarousel/components/SY-StackedCarousel/SY-StackedCarousel.vue'
import formPopup from './formPopup.vue'
import markPopup from '@/pages_order/growing/activity/markPopup.vue'
export default {
mixins: [mixinsList],
components: {
SYStackedCarousel,
formPopup,
markPopup,
},
data() {
return {
current: 0,
activityId: '',
queryParams: {
pageNo: 1,
pageSize: 10,
@ -77,9 +83,10 @@
...mapState(['liveInfo']),
},
onLoad(arg) {
const { id } = arg
const { imageId, activityId } = arg
this.queryParams.imageId = id
this.queryParams.imageId = imageId
this.activityId = activityId
this.getData()
},
methods: {
@ -88,21 +95,32 @@
},
getDataThen(records) {
this.list = records.map(item => {
const { id, avatar, createBy, address, image, createTime } = item
const { id, user, address, image, createTime } = item
return {
id,
// todo: check key
avatar: avatar || '/pages_order/static/center/avatar-default.png',
createBy,
user,
address,
images: image?.split?.(',') || [],
createTime,
}
})
},
setData(e) {
console.log('setData', e)
this.mixinsListApi = ''
},
onAdd() {
this.$refs.formPopup.open()
this.$refs.formPopup.open(this.queryParams.imageId, this.activityId)
},
onMark() {
this.$refs.markPopup.open(this.activityId)
},
previewImage(arr, index) {
uni.previewImage({
urls: arr,
current: arr[index], //
});
},
},
}
@ -138,6 +156,7 @@
.operate {
flex: 1;
justify-content: flex-end;
column-gap: 16rpx;
.btn-add {
padding: 6rpx 22rpx;


+ 28
- 22
pages_order/live/list.vue View File

@ -7,7 +7,6 @@
<SYStackedCarousel
height="536rpx"
:images="list"
:current="current"
:autoplay="true"
horizontalMargin="25"
baseOpacity="0.5"
@ -26,30 +25,30 @@
<view class="main">
<view class="flex header">
<view>图片直播</view>
<view class="btn btn-mark" @click="onMark">标记有我</view>
<!-- <view class="btn btn-mark" @click="onMark">标记有我</view> -->
</view>
<view class="section" v-for="item in list" :key="item.id">
<view class="flex section-header">
<view class="flex title">
<view>{{ item.title }}</view>
<view v-if="isManager" class="btn btn-add" @click="onAdd(item.id)">新增记录</view>
<!-- <view v-if="isManager" class="btn btn-add" @click="onAdd(item.id)">新增记录</view> -->
</view>
<button class="flex btn btn-all" @click="showAll(item.id)">
<button class="flex btn btn-all" @click="showAll(item.id, item.activityId)">
<view>查看全部</view>
<image class="icon" src="@/static/image/icon-arrow-right.png" mode="widthFix"></image>
</button>
</view>
<view class="section-content record">
<view class="record-item" v-for="(image, imgIdx) in item.images" :key="imgIdx">
<image class="img" :src="image" mode="aspectFill"></image>
<image class="img" :src="image" mode="aspectFill" @click="previewImage(item.images, imgIdx)"></image>
</view>
</view>
</view>
</view>
<markPopup ref="markPopup"></markPopup>
<formPopup ref="formPopup" @submitted="getData"></formPopup>
<!-- <markPopup ref="markPopup"></markPopup> -->
<!-- <formPopup ref="formPopup" @submitted="getData"></formPopup> -->
</view>
</template>
@ -58,22 +57,22 @@
import mixinsList from '@/mixins/list.js'
import SYStackedCarousel from '@/uni_modules/SY-StackedCarousel/components/SY-StackedCarousel/SY-StackedCarousel.vue'
import markPopup from '@/pages_order/growing/activity/markPopup.vue'
import formPopup from './formPopup.vue'
// import markPopup from '@/pages_order/growing/activity/markPopup.vue'
// import formPopup from './formPopup.vue'
export default {
mixins: [mixinsList],
components: {
SYStackedCarousel,
markPopup,
formPopup,
// markPopup,
// formPopup,
},
data() {
return {
current: 0,
mixinsListApi: 'queryImageList',
// todo: fetch
isManager: true,
// isManager: true,
}
},
computed: {
@ -87,12 +86,13 @@
methods: {
getDataThen(records) {
this.list = records.map(item => {
const { id, image, activityId_dictText, createTime } = item
const { id, image, activityId, activityId_dictText, createTime } = item
const images = image?.split?.(',') || []
return {
id,
activityId,
url: images?.[0],
images,
title: activityId_dictText,
@ -104,17 +104,23 @@
this.current = index
},
changeHandler(index) {
console.log("当前触发change事件,返回索引: ", index);
},
onMark() {
this.$refs.markPopup.open(this.id)
},
onAdd() {
this.$refs.formPopup.open()
this.current = index
},
showAll(id) {
// onMark() {
// this.$refs.markPopup.open(this.id)
// },
// onAdd() {
// this.$refs.formPopup.open()
// },
showAll(id, activityId) {
this.$store.commit('setLiveInfo', this.list.find(item => item.id === id))
this.$utils.navigateTo(`/pages_order/live/index?id=${id}`)
this.$utils.navigateTo(`/pages_order/live/index?imageId=${id}&activityId=${activityId}`)
},
previewImage(arr, index) {
uni.previewImage({
urls: arr,
current: arr[index], //
});
},
},
}


+ 2
- 2
pages_order/member/memberApplyCard.vue View File

@ -3,11 +3,11 @@
<view class="title">绑定申请</view>
<view class="row">
<view class="row-label">绑定人</view>
<view class="row-content">{{ data.name }}</view>
<view class="row-content">{{ data.user.nickName }}</view>
</view>
<view class="row">
<view class="row-label">申请人ID</view>
<view class="row-content">{{ data.bindId }}</view>
<view class="row-content">{{ data.user.id }}</view>
</view>
<view class="row">
<view class="row-label">申请时间</view>


+ 14
- 17
pages_order/member/memberBind.vue View File

@ -36,14 +36,14 @@
</view>
<view class="form-item" v-for="item in list" :key="item.id">
<view
:class="['flex', 'list-item', item.id === form.id ? 'is-active' : '']"
:class="['flex', 'list-item', item.id === form.bindId ? 'is-active' : '']"
@click="onSelect(item.id)"
>
<view class="avatar">
<image class="img" :src="item.avatar" mode="scaleToFill"></image>
<image class="img" :src="item.headImage" mode="scaleToFill"></image>
</view>
<view>
<view class="title">{{ item.name }}</view>
<view class="title">{{ item.nickName }}</view>
<view class="desc">{{ `ID:${item.id}` }}</view>
</view>
</view>
@ -62,25 +62,16 @@
</template>
<script>
import mixinsList from '@/mixins/list.js'
import formInput from '@/pages_order/components/formInput.vue'
export default {
mixins: [mixinsList],
components: {
formInput,
},
data() {
return {
keyword: '',
queryParams: {
pageNo: 1,
pageSize: 1000,
title: '',
},
// todo
mixinsListApi: '',
list: [],
form: {
bindId: null,
},
@ -95,9 +86,15 @@
}
},
methods: {
search() {
this.queryParams.title = this.keyword
this.getData()
async search() {
try {
const result = await this.$fetch('queryBindUser', { bindUserId: this.keyword })
this.list = [result]
this.form.bindId = result.id
} catch (err) {
}
},
onSelect(bindId) {
this.form.bindId = bindId
@ -112,7 +109,7 @@
const params = {
bindId,
userId: this.userInfo.id,
// userId: this.userInfo.id,
}
await this.$fetch('addBind', params)


+ 7
- 7
pages_order/member/memberCard.vue View File

@ -1,17 +1,17 @@
<template>
<view class="flex card">
<view class="radio" v-if="showRadio">
<uv-radio :name="data.id"></uv-radio>
<uv-radio :name="data.user.id"></uv-radio>
</view>
<view class="info">
<view class="title">{{ typeDesc }}</view>
<view class="row">
<view class="row-label">绑定人</view>
<view class="row-content">{{ data.name }}</view>
<view class="row-content">{{ data.user.nickName }}</view>
</view>
<view class="row">
<view class="row-label">申请人ID</view>
<view class="row-content">{{ data.bindId }}</view>
<view class="row-content">{{ data.user.id }}</view>
</view>
</view>
</view>
@ -19,8 +19,8 @@
<script>
const TYPE_AND_DESC_MAPPING = {
0: '学生',
1: '家长',
0: '家长',
1: '学生',
}
export default {
@ -46,9 +46,9 @@
},
computed: {
typeDesc() {
const { type } = this.data
const { user } = this.data
return TYPE_AND_DESC_MAPPING[type] || ''
return TYPE_AND_DESC_MAPPING[user?.role] || ''
},
},
methods: {


+ 46
- 16
pages_order/member/switch.vue View File

@ -21,6 +21,10 @@
</uv-radio-group>
</view>
<view class="bottom">
<button class="btn" @click="onConfirm">确定切换</button>
</view>
</view>
</template>
@ -49,28 +53,25 @@
}
},
computed: {
...mapState(['memberInfo']),
...mapState(['userInfo', 'memberInfo']),
},
onLoad(arg) {
if (this.memberInfo?.id) {
this.selectedId = this.memberInfo.id
}
this.selectedId = this.memberInfo?.id || this.userInfo?.id
this.getData()
},
onUnload() {
if (!this.selectedId) {
this.$store.commit('setMemberInfo', null)
return
}
const target = this.list.find(item => item.id === this.selectedId)
this.$store.commit('setMemberInfo', target)
},
methods: {
onSelect(id) {
console.log('onSelect', id)
this.selectedId = id
getDataThen(records) {
this.list = [{
...this.userInfo,
user: this.userInfo,
}].concat(records)
},
onConfirm() {
const target = this.list.find(item => item.user.id === this.selectedId)?.user
this.$store.commit('setMemberInfo', target)
this.$utils.navigateBack()
},
},
}
@ -86,6 +87,7 @@
.list {
padding: 32rpx 40rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 198rpx);
&-item {
@ -96,4 +98,32 @@
}
}
.bottom {
position: fixed;
left: 0;
bottom: 0;
width: 100vw;
// height: 200rpx;
padding: 32rpx 40rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 32rpx);
background: #FFFFFF;
box-sizing: border-box;
.btn {
width: 100%;
padding: 14rpx 0;
box-sizing: border-box;
font-family: PingFang SC;
font-weight: 500;
font-size: 36rpx;
line-height: 1.4;
color: #FFFFFF;
background: linear-gradient(to right, #21FEEC, #019AF9);
border: 2rpx solid #00A9FF;
border-radius: 41rpx;
}
}
</style>

+ 1
- 1
pages_order/message/card.vue View File

@ -2,7 +2,7 @@
<view class="card">
<view class="card-header">
<view class="title">{{ data.title }}</view>
<view class="desc">{{ data.createTime }}</view>
<view class="desc">{{ data.noticeDate }}</view>
</view>
<view class="card-content">
<uv-parse :content="data.content"></uv-parse>


+ 1
- 1
pages_order/message/index.vue View File

@ -6,7 +6,7 @@
<view class="card">
<view class="card-header">
<view class="title">{{ detail.title }}</view>
<view class="desc">{{ detail.createTime }}</view>
<view class="desc">{{ detail.noticeDate }}</view>
</view>
<view class="card-content">
<uv-parse :content="detail.content"></uv-parse>


+ 0
- 1
pages_order/order/components/productCard.vue View File

@ -46,7 +46,6 @@
return this.data?.product || {}
},
tagList() {
// todo: check key
const { tagDetails } = this.product || {}
return tagDetails?.length ? tagDetails.split('、') : []


+ 4
- 9
pages_order/order/orderConfirm/index.vue View File

@ -108,14 +108,10 @@
</uv-checkbox-group>
<view class="desc">
我已阅读并同意
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_agreement', '退订政策')">退订政策</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_privacy', '合同范本')">合同范本</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_privacy', '预订须知')">预订须知</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_privacy', '安全提示')">安全提示</text>
<text class="highlight" @click="$refs.modal.open('unsubscribe_policy', '退订政策')">退订政策</text>
<text class="highlight" @click="$refs.modal.open('model_contract', '合同范本')">合同范本</text>
<text class="highlight" @click="$refs.modal.open('booking_instructions', '预订须知')">预订须知</text>
<text class="highlight" @click="$refs.modal.open('safety_reminder', '安全提示')">安全提示</text>
</view>
</view>
<view class="flex bar">
@ -296,7 +292,6 @@
try {
await this.$refs.form.validate()
// todo: fetch create order and save wx pay data
const {
product,
time,


+ 5
- 2
pages_order/order/orderDetail/index.vue View File

@ -11,7 +11,6 @@
<view class="notice">
<view class="notice-header">下单须知</view>
<view class="notice-content">
<!-- todo: check key -->
<uv-parse :content="configList['order_instructions']"></uv-parse>
</view>
</view>
@ -42,6 +41,8 @@
<commentPopup ref="commentPopup" @submitted="getData"></commentPopup>
<servicePopup ref="servicePopup"></servicePopup>
</view>
</template>
@ -52,6 +53,7 @@
import orderInfoView from '@/pages_order/order/components/orderInfoView.vue'
import contactMentorPopup from '@/pages_order/order/components/contactMentorPopup.vue'
import commentPopup from '@/pages_order/comment/commentPopup.vue'
import servicePopup from '@/components/base/servicePopup.vue'
export default {
components: {
@ -59,6 +61,7 @@
orderInfoView,
contactMentorPopup,
commentPopup,
servicePopup,
},
data() {
return {
@ -122,7 +125,7 @@
this.$refs.commentPopup.open(this.id, this.detail)
},
onApplyService() {
// todo
this.$refs.servicePopup.open()
},
onContactMentor() {
this.$refs.contactMentorPopup.open(this.detail.teacherPhone)


+ 6
- 3
pages_order/order/orderList/index.vue View File

@ -48,6 +48,8 @@
<commentPopup ref="commentPopup" @submitted="getData"></commentPopup>
<servicePopup ref="servicePopup"></servicePopup>
</view>
</template>
@ -58,6 +60,7 @@
import orderCard from './orderCard.vue'
import contactMentorPopup from '@/pages_order/order/components/contactMentorPopup.vue'
import commentPopup from '@/pages_order/comment/commentPopup.vue'
import servicePopup from '@/components/base/servicePopup.vue'
export default {
mixins: [mixinsList],
@ -65,6 +68,7 @@
orderCard,
contactMentorPopup,
commentPopup,
servicePopup,
},
data() {
return {
@ -102,9 +106,8 @@
onComment(id, detail) {
this.$refs.commentPopup.open(id, detail)
},
onApplyService(obj) {
// todo
// this.$refs.serviceSelectPopup.open(obj)
onApplyService() {
this.$refs.servicePopup.open()
},
onContactMentor(teacherPhone) {
this.$refs.contactMentorPopup.open(teacherPhone)


+ 4
- 9
pages_order/order/orderPay/index.vue View File

@ -29,7 +29,6 @@
<view class="notice">
<view class="notice-header">下单须知</view>
<view class="notice-content">
<!-- todo: check key -->
<uv-parse :content="configList['order_instructions']"></uv-parse>
</view>
</view>
@ -51,14 +50,10 @@
</uv-checkbox-group>
<view class="desc">
我已阅读并同意
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_agreement', '退订政策')">退订政策</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_privacy', '合同范本')">合同范本</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_privacy', '预订须知')">预订须知</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_privacy', '安全提示')">安全提示</text>
<text class="highlight" @click="$refs.modal.open('unsubscribe_policy', '退订政策')">退订政策</text>
<text class="highlight" @click="$refs.modal.open('model_contract', '合同范本')">合同范本</text>
<text class="highlight" @click="$refs.modal.open('booking_instructions', '预订须知')">预订须知</text>
<text class="highlight" @click="$refs.modal.open('safety_reminder', '安全提示')">安全提示</text>
</view>
</view>
<view class="flex bar">


+ 37
- 8
pages_order/partner/apply.vue View File

@ -31,7 +31,7 @@
姓名
</view>
<view class="form-item-content">
<formInput v-model="form.name"></formInput>
<formInput v-model="form.name" :disabled="readonly"></formInput>
</view>
</uv-form-item>
</view>
@ -42,24 +42,24 @@
电话
</view>
<view class="form-item-content">
<formInput v-model="form.phone"></formInput>
<formInput v-model="form.phone" :disabled="readonly"></formInput>
</view>
</uv-form-item>
</view>
<view class="form-item">
<!-- <view class="form-item">
<uv-form-item prop="inviteId" :customStyle="formItemStyle">
<view class="form-item-label">推荐人</view>
<view class="form-item-content">
<formInput v-model="form.inviteId"></formInput>
</view>
</uv-form-item>
</view>
</view> -->
</uv-form>
</view>
</view>
</view>
<view class="bottom">
<view class="bottom" v-if="!readonly">
<view class="flex btn" @click="onSubmit">提交</view>
</view>
</view>
@ -78,7 +78,7 @@
form: {
name: null,
phone: null,
inviteId: null,
// inviteId: null,
},
rules: {
'name': {
@ -93,21 +93,50 @@
},
},
formItemStyle: { padding: 0 },
readonly: false,
}
},
onLoad(arg) {
const { readonly } = arg
this.readonly = Boolean(parseInt(readonly))
console.log('readonly', readonly, parseInt(readonly), this.readonly)
this.fetchPartner()
},
methods: {
async fetchPartner() {
try {
const result = await this.$fetch('queryPartner')
const {
name,
phone,
} = result || {}
this.form = {
name: name || null,
phone: phone || null,
}
} catch (err) {
}
},
async onSubmit() {
try {
await this.$refs.form.validate()
const {
name,
phone,
} = this.form
const params = {
name,
phone,
}
// todo: fetch
// await this.$fetch('updateAddress', params)
await this.$fetch('applyPartner', params)
uni.showToast({
icon: 'success',


+ 29
- 2
pages_order/partner/withdraw.vue View File

@ -5,6 +5,11 @@
<navbar title="提现" leftClick @leftClick="$utils.navigateBack" color="#191919" bgColor="#FFFFFF" />
<view class="main">
<view class="flex card row">
<view class="row-label">余额</view>
<view class="row-content">{{ `¥${userCenterData.balance}` }}</view>
</view>
<view class="card">
<view class="card-header">微信提现</view>
@ -37,8 +42,7 @@
<view class="notice">
请仔细检查并确认相关信息因用户个人疏忽导致的充值错误需由用户自行承担
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('user_ys', '提现须知')">提现须知</text>
<text class="highlight" @click="$refs.modal.open('withdrawal_instructions', '提现须知')">提现须知</text>
</view>
<agreementModal ref="modal"></agreementModal>
@ -53,6 +57,8 @@
</template>
<script>
import { mapState } from 'vuex'
import formInput from '@/pages_order/components/formInput.vue'
import agreementModal from '@/pages_order/components/agreementModal.vue'
@ -82,6 +88,9 @@
formItemStyle: { padding: 0 },
}
},
computed: {
...mapState(['userCenterData']),
},
methods: {
async onSubmit() {
try {
@ -205,6 +214,24 @@
}
}
.row {
justify-content: flex-start;
column-gap: 16rpx;
font-family: PingFang SC;
font-weight: 400;
font-size: 36rpx;
line-height: 1.4;
color: #181818;
&-label {
font-weight: 500;
}
&-content {
}
}
.form {
padding: 8rpx 0 0 0;


+ 1
- 1
pages_order/product/collectList.vue View File

@ -6,7 +6,7 @@
<view class="list">
<view class="list-item" v-for="item in list" :key="item.id">
<productCard :data="item.activity" :isCollected="true" @collect="getData"></productCard>
<productCard :data="item.activity" @collect="getData"></productCard>
</view>
</view>
</view>


+ 1
- 2
pages_order/product/productDetail.vue View File

@ -147,7 +147,6 @@
return Array.isArray(image) ? image : image.split(',')
},
tagList() {
// todo: check key
const { tagDetails } = this.detail || {}
return tagDetails?.length ? tagDetails.split('、') : []
@ -207,7 +206,7 @@
pageSize: 2,
activityId,
}
this.commentList = (await this.$fetch('queryCommentList', queryParams))?.records
this.commentList = (await this.$fetch('queryCommentList', queryParams, true, null, true))?.records
} catch (err) {
console.log('fetchComment', err)
}


+ 27
- 4
pages_order/product/search.vue View File

@ -24,7 +24,7 @@
</view>
<view class="main">
<sortBar v-model="queryParams.sort" @change="onSortChange"></sortBar>
<sortBar v-model="sort" @change="onSortChange"></sortBar>
<view v-if="list.length" class="content">
<view v-for="item in list" :key="item.id">
@ -59,12 +59,11 @@
title: '搜索结果',
keyword: '',
isFocusSearch: false,
sort: 'comprehensive',
queryParams: {
pageNo: 1,
pageSize: 10,
title: '',
// todo
sort: 'comprehensive',
},
mixinsListApi: 'queryActivityList',
}
@ -98,9 +97,33 @@
},
onSortChange(sort) {
console.log('onSortChange', sort)
// todo set sort
this.getData()
},
beforeGetData() {
console.log('beforeGetData')
let params = {}
switch(this.sort) {
// (saleOrder)0- 1-
case 'sale-desc': // -
params.saleOrder = '0'
break
case 'sale-asc': // -
params.saleOrder = '1'
break
// (priceOrder)0- 1-
case 'price-desc': // -
params.priceOrder = '0'
break
case 'price-asc': // -
params.priceOrder = '1'
break
default:
break
}
return params
},
},
}
</script>


+ 0
- 1
pages_order/traveler/travelerCard.vue View File

@ -115,7 +115,6 @@
title: '确认删除?',
success : e => {
if(e.confirm){
// todo
this.$emit('delete')
}
}


+ 5
- 2
pages_order/traveler/travelerList.vue View File

@ -65,8 +65,6 @@
this.list = records.map(item => {
return {
...item,
// todo: transform periodId to type and type desc
type: 0, // 0- 1- 2-
isDefault: item.isDefault == '1' ? true : false
}
})
@ -86,6 +84,11 @@
}
},
async onDelete(id) {
uni.showToast({
icon: 'none',
title: '该功能待对接接口',
});
return
uni.showToast({
icon: 'loading',


+ 8
- 11
pages_order/traveler/travelerPopup.vue View File

@ -43,11 +43,11 @@
</view>
<view class="form-item-content">
<uv-radio-group v-model="form.periodId"
iconColor="#00A9FF"
iconSize="36rpx"
size="36rpx"
labelColor="#181818"
labelSize="26rpx"
activeColor="#00A9FF"
>
<uv-radio
v-for="item in configList.periodList"
@ -68,11 +68,11 @@
</view>
<view class="form-item-content">
<uv-radio-group v-model="form.sex"
iconColor="#00A9FF"
iconSize="36rpx"
size="36rpx"
labelColor="#181818"
labelSize="26rpx"
activeColor="#00A9FF"
>
<uv-radio
v-for="(item, index) in sexOptions"
@ -177,11 +177,9 @@
</view>
<view class="desc">
我已阅读并同意
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_agreement', '服务协议')">服务协议</text>
<text class="highlight" @click="$refs.modal.open('service_agreement', '服务协议')">服务协议</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_privacy', '隐私政策')">隐私政策</text>
<text class="highlight" @click="$refs.modal.open('privacy_policy', '隐私政策')">隐私政策</text>
</view>
</view>
<view class="bar">
@ -212,8 +210,8 @@
form: {
name: null,
cerNo: null,
periodId: 0,
sex: 0,
periodId: null,
sex: null,
phone: null,
wechat: null,
school: null,
@ -328,9 +326,8 @@
this.form = {
name: '',
cerNo: '',
// todo: fetch default
periodId: 0,
sex: 0,
periodId: this.configList?.periodList?.[0]?.id || null,
sex: this.sexOptions?.[0]?.value,
phone: '',
wechat: '',
school: '',


+ 10
- 1
store/store.js View File

@ -18,6 +18,7 @@ const store = new Vuex.Store({
couponInfo: null,
memberInfo: null,
liveInfo: null,
markmeList: [],
},
getters: {
// 角色 true为水洗店 false为酒店 : 身份判断如果不需要,可以删除
@ -143,6 +144,11 @@ const store = new Vuex.Store({
}
})
},
clearUserInfo(state) {
state.userInfo = {}
state.role = false
uni.removeStorageSync('token')
},
setTravelerList(state, data) {
state.travelerList = data
},
@ -153,12 +159,15 @@ const store = new Vuex.Store({
state.couponInfo = data
},
setMemberInfo(state, data) {
console.log('memberInfo', data)
state.memberInfo = data
},
setLiveInfo(state, data) {
console.log('liveInfo', data)
state.liveInfo = data
},
setMarkmeList(state, data) {
state.markmeList = data
},
},
actions: {
async collect(state, activityId) {


Loading…
Cancel
Save