Browse Source

feat: 接口对接;

pull/5/head
Fox-33 6 months ago
parent
commit
53429bb4cf
48 changed files with 615 additions and 861 deletions
  1. +1
    -1
      App.vue
  2. +3
    -2
      api/api.js
  3. +5
    -0
      api/model/activity.js
  4. +34
    -0
      api/model/bind.js
  5. +29
    -0
      api/model/coupon.js
  6. +8
    -0
      api/model/experience.js
  7. +2
    -2
      api/model/login.js
  8. +1
    -1
      api/model/partner.js
  9. +15
    -46
      components/home/pictureLiveView.vue
  10. +1
    -1
      components/home/productView.vue
  11. +9
    -4
      components/partner/posterPopup.vue
  12. +3
    -0
      components/product/productCard.vue
  13. +64
    -16
      pages.json
  14. +10
    -64
      pages/index/category.vue
  15. +10
    -11
      pages/index/center.vue
  16. +34
    -36
      pages/index/growing.vue
  17. +4
    -1
      pages/index/index.vue
  18. +5
    -0
      pages/index/partner.vue
  19. +2
    -4
      pages_order/auth/wxLogin.vue
  20. +20
    -20
      pages_order/auth/wxUserInfo.vue
  21. +3
    -3
      pages_order/comment/commentCard.vue
  22. +29
    -19
      pages_order/comment/commentPopup.vue
  23. +12
    -10
      pages_order/comment/commentRecords.vue
  24. +61
    -26
      pages_order/comment/recordFormPopup.vue
  25. +1
    -0
      pages_order/coupon/couponList/couponCard.vue
  26. +2
    -38
      pages_order/coupon/couponList/index.vue
  27. +3
    -3
      pages_order/coupon/couponSelect/couponCard.vue
  28. +2
    -38
      pages_order/coupon/couponSelect/index.vue
  29. +16
    -0
      pages_order/growing/activity/index.vue
  30. +20
    -18
      pages_order/live/formPopup.vue
  31. +30
    -77
      pages_order/live/index.vue
  32. +21
    -62
      pages_order/live/list.vue
  33. +15
    -7
      pages_order/member/memberApplyCard.vue
  34. +11
    -9
      pages_order/member/memberBind.vue
  35. +1
    -1
      pages_order/member/memberCard.vue
  36. +9
    -54
      pages_order/member/memberList.vue
  37. +3
    -43
      pages_order/member/switch.vue
  38. +28
    -22
      pages_order/order/orderConfirm/infoPopup.vue
  39. +34
    -96
      pages_order/order/orderConfirm/peopleNumberInput.vue
  40. +2
    -3
      pages_order/order/orderConfirm/timeOptionsSelect.vue
  41. +2
    -2
      pages_order/order/orderDetail/index.vue
  42. +4
    -5
      pages_order/order/orderList/index.vue
  43. +3
    -3
      pages_order/partner/apply.vue
  44. +5
    -97
      pages_order/partner/team.vue
  45. +13
    -10
      pages_order/partner/withdraw.vue
  46. +1
    -2
      pages_order/product/productDetail.vue
  47. +1
    -1
      pages_order/traveler/travelerList.vue
  48. +23
    -3
      store/store.js

+ 1
- 1
App.vue View File

@ -3,7 +3,7 @@
onLaunch: function() { onLaunch: function() {
}, },
onShow: function() { onShow: function() {
// this.$store.commit('initConfig')
this.$store.commit('initConfig')
}, },
onHide: function() { onHide: function() {
} }


+ 3
- 2
api/api.js View File

@ -5,7 +5,7 @@ import utils from '../utils/utils.js'
let limit = {} let limit = {}
let debounce = {} let debounce = {}
const models = ['login', 'index', 'image', 'activity', 'order', 'comment', 'experience', 'partner', 'info']
const models = ['login', 'index', 'image', 'activity', 'coupon', 'order', 'comment', 'bind', 'experience', 'partner', 'info']
const config = { const config = {
// 示例 // 示例
@ -14,7 +14,8 @@ const config = {
// limit : 1000 // limit : 1000
// }, // },
getConfig : {url : '/config_common/getConfig', method : 'GET', limit : 500},
getConfig : {url : '/config/queryConfigList', method : 'GET', limit : 500},
queryConfigByParamCode : {url : '/config/queryConfigByParamCode', method : 'GET'},
} }


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

@ -1,6 +1,11 @@
// 研学活动相关接口 // 研学活动相关接口
const api = { const api = {
// 系统配置-查询研学活动分类列表
queryCategoryList: {
url: '/config/queryCategoryList',
method: 'GET',
},
// 首页&分类-查询研学活动列表 // 首页&分类-查询研学活动列表
queryActivityList: { queryActivityList: {
url: '/activity/queryActivityList', url: '/activity/queryActivityList',


+ 34
- 0
api/model/bind.js View File

@ -0,0 +1,34 @@
// 成员管理相关接口
const api = {
// 成员管理-查询绑定成员列表
queryBindList: {
url: '/bind/queryBindList',
method: 'GET',
auth: true,
},
// 成员管理-查询绑定人信息
queryBindUser: {
url: '/bind/queryBindUser',
method: 'GET',
auth: true,
},
// 成员管理-绑定申请
addBind: {
url: '/bind/addBind',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
},
// 成员管理-审批绑定申请
updateBind: {
url: '/bind/updateBind',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
},
}
export default api

+ 29
- 0
api/model/coupon.js View File

@ -0,0 +1,29 @@
// 优惠券相关接口
const api = {
// 优惠券-我的优惠券列表
queryCouponList: {
url: '/coupon/queryCouponList',
method: 'GET',
auth: true,
},
// 优惠券-根据id查看优惠券详情
queryCouponById: {
url: '/coupon/queryCouponById',
method: 'GET',
},
// 优惠券-查看可领取的优惠券
queryFetchCouponList: { // todo: check use in where?
url: '/coupon/queryFetchCouponList',
method: 'GET',
auth: true,
},
// 优惠券-领取优惠券
fetchCoupon: { // todo: check use in where?
url: '/coupon/fetchCoupon',
method: 'POST',
auth: true,
},
}
export default api

+ 8
- 0
api/model/experience.js View File

@ -11,6 +11,14 @@ const api = {
url: '/experience/queryExperienceById', url: '/experience/queryExperienceById',
method: 'GET', method: 'GET',
}, },
// 成长档案-新增成长档案
addExperience: {
url: '/experience/addExperience',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
},
} }
export default api export default api

+ 2
- 2
api/model/login.js View File

@ -18,7 +18,7 @@ const api = {
}, },
// 修改个人信息接口 // 修改个人信息接口
updateInfo: { updateInfo: {
url: '/info_common/updateInfo',
url: '/userInfo/updateUser',
method: 'POST', method: 'POST',
auth: true, auth: true,
limit : 500, limit : 500,
@ -26,7 +26,7 @@ const api = {
}, },
// 获取个人信息 // 获取个人信息
getInfo: { getInfo: {
url: '/info_common/getInfo',
url: '/userInfo/queryUser',
method: 'GET', method: 'GET',
auth: true, auth: true,
}, },


+ 1
- 1
api/model/partner.js View File

@ -31,7 +31,7 @@ const api = {
method: 'GET', method: 'GET',
}, },
// 我的团队-获取间推用户列表 // 我的团队-获取间推用户列表
queryDirectList: {
queryIndirectList: {
url: '/partner/queryIndirectList', url: '/partner/queryIndirectList',
method: 'GET', method: 'GET',
}, },


+ 15
- 46
components/home/pictureLiveView.vue View File

@ -27,7 +27,7 @@
<swiper-item v-for="item in list" :key="item.id" style="display: inline-block;"> <swiper-item v-for="item in list" :key="item.id" style="display: inline-block;">
<view class="swiper-item"> <view class="swiper-item">
<view class="swiper-item-content" @click="jumpToLive(item.id)"> <view class="swiper-item-content" @click="jumpToLive(item.id)">
<image class="live-item-bg" :src="item.image" mode="aspectFill"></image>
<image class="live-item-bg" :src="item.url" mode="aspectFill"></image>
<view class="live-item-info"> <view class="live-item-info">
<view class="text-ellipsis live-item-info-title">{{ item.title }}</view> <view class="text-ellipsis live-item-info-title">{{ item.title }}</view>
<view class="live-item-info-time">{{ item.createTime }}</view> <view class="live-item-info-time">{{ item.createTime }}</view>
@ -52,57 +52,26 @@
}, },
methods: { methods: {
async getData() { async getData() {
this.list = [
{
id: '001',
image: '/static/image/temp-15.png',
title: '苕溪露营漂流',
createTime: '2025-04-18',
},
{
id: '002',
image: '/static/image/temp-15.png',
title: '科技奇遇记',
createTime: '2025-04-18',
},
{
id: '003',
image: '/static/image/temp-15.png',
title: '满陇桂雨',
createTime: '2025-04-18',
},
{
id: '004',
image: '/static/image/temp-15.png',
title: '跟着皇帝游江南',
createTime: '2025-04-18',
},
{
id: '005',
image: '/static/image/temp-15.png',
title: '苕溪露营漂流',
createTime: '2025-04-18',
},
{
id: '006',
image: '/static/image/temp-15.png',
title: '科技奇遇记',
createTime: '2025-04-18',
},
]
return
// todo: check
try { try {
this.list = await this.$fetch('queryImageList', { pageNo: 1, pageSize: 8 })
this.list = (await this.$fetch('queryImageList', { pageNo: 1, pageSize: 8 }))?.records?.map(item => {
const { id, image, activityId_dictText, createTime } = item
const images = image?.split?.(',') || []
return {
id,
url: images?.[0],
images,
title: activityId_dictText,
createTime: this.$dayjs(createTime).format('YYYY-MM-DD'),
}
})
} catch (err) { } catch (err) {
} }
}, },
jumpToLive(id) { jumpToLive(id) {
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?id=${id}`)
}, },
showAll() { showAll() {


+ 1
- 1
components/home/productView.vue View File

@ -73,7 +73,7 @@
// todo: fetch // todo: fetch
this.tabs = [ this.tabs = [
{ name: '全部' }, { name: '全部' },
{ id: '1962342791093227522', name: '研学活动一', disabled: true, },
// { id: '1962342791093227522', name: '', disabled: true, },
] ]
}, },
onClickTab(e) { onClickTab(e) {


+ 9
- 4
components/partner/posterPopup.vue View File

@ -21,6 +21,8 @@
<script> <script>
import { mapState } from 'vuex'
export default { export default {
data() { data() {
return { return {
@ -30,6 +32,9 @@
retry: 10, retry: 10,
} }
}, },
computed: {
...mapState(['userInfo', 'configList']),
},
async onLoad() { async onLoad() {
}, },
methods: { methods: {
@ -45,6 +50,7 @@
this.wxCodeImage = 'https://uploadfile.bizhizu.cn/up/e3/64/e0/e364e0f7f6af11f11abdafc22d17b15c.jpg' this.wxCodeImage = 'https://uploadfile.bizhizu.cn/up/e3/64/e0/e364e0f7f6af11f11abdafc22d17b15c.jpg'
return return
try { try {
const path = `pages/index/index?userId=${this.userInfo.id}`
this.wxCodeImage = (await this.$fetch('getInviteCode', { path }))?.url this.wxCodeImage = (await this.$fetch('getInviteCode', { path }))?.url
} catch (err) { } catch (err) {
@ -119,8 +125,7 @@
return new Promise(resolve => { return new Promise(resolve => {
// //
const avatarImage = canvas.createImage() const avatarImage = canvas.createImage()
// todo: fetch
avatarImage.src = 'https://i1.hdslb.com/bfs/archive/c0101b4ce06e6bdda803728408e79c8f8b8d0725.jpg'
avatarImage.src = this.userInfo.headImage
avatarImage.onload = () => { avatarImage.onload = () => {
console.log('avatarImage onload') console.log('avatarImage onload')
@ -253,8 +258,8 @@
ctx.restore(); ctx.restore();
ctx.save() ctx.save()
let text = '战斗世界'
let maxWidth = 220 * Ratio / dpr
let text = this.userInfo.nickName
let maxWidth = 560 * Ratio / dpr
let lineHeight = 17 * Ratio / dpr let lineHeight = 17 * Ratio / dpr
x = 100 * Ratio / dpr x = 100 * Ratio / dpr
y = 474 * Ratio / dpr y = 474 * Ratio / dpr


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

@ -218,11 +218,13 @@
justify-content: flex-start; justify-content: flex-start;
align-items: baseline; align-items: baseline;
column-gap: 12rpx; column-gap: 12rpx;
flex-wrap: wrap;
&-val { &-val {
font-size: 24rpx; font-size: 24rpx;
font-weight: 500; font-weight: 500;
color: #FF4800; color: #FF4800;
white-space: nowrap;
.highlight { .highlight {
font-size: 32rpx; font-size: 32rpx;
@ -249,6 +251,7 @@
color: #FFFFFF; color: #FFFFFF;
background: #00A9FF; background: #00A9FF;
border-radius: 24rpx; border-radius: 24rpx;
white-space: nowrap;
} }
&.small { &.small {


+ 64
- 16
pages.json View File

@ -56,13 +56,19 @@
"path": "auth/loginAndRegisterAndForgetPassword" "path": "auth/loginAndRegisterAndForgetPassword"
}, },
{ {
"path": "product/search"
"path": "product/search",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "product/productDetail" "path": "product/productDetail"
}, },
{ {
"path": "product/collectList"
"path": "product/collectList",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "order/orderConfirm/index" "path": "order/orderConfirm/index"
@ -83,28 +89,49 @@
} }
}, },
{ {
"path": "traveler/travelerList"
"path": "traveler/travelerList",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "coupon/couponSelect/index"
"path": "coupon/couponSelect/index",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "coupon/couponList/index"
"path": "coupon/couponList/index",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "comment/commentRecordsOfProduct"
"path": "comment/commentRecordsOfProduct",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "comment/commentRecords"
"path": "comment/commentRecords",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "growing/activity/search"
"path": "growing/activity/search",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "growing/activity/index" "path": "growing/activity/index"
}, },
{ {
"path": "growing/activity/markList"
"path": "growing/activity/markList",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "growing/activity/applyEmail" "path": "growing/activity/applyEmail"
@ -113,19 +140,34 @@
"path": "growing/achievement/index" "path": "growing/achievement/index"
}, },
{ {
"path": "member/memberList"
"path": "member/memberList",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "member/memberBind"
"path": "member/memberBind",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "member/switch"
"path": "member/switch",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "live/list"
"path": "live/list",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "live/index"
"path": "live/index",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "partner/apply" "path": "partner/apply"
@ -137,13 +179,19 @@
"path": "partner/withdraw" "path": "partner/withdraw"
}, },
{ {
"path": "article/search"
"path": "article/search",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "article/index" "path": "article/index"
}, },
{ {
"path": "message/list"
"path": "message/list",
"style": {
"enablePullDownRefresh": true
}
}, },
{ {
"path": "message/index" "path": "message/index"


+ 10
- 64
pages/index/category.vue View File

@ -204,6 +204,9 @@
} }
}, },
async onLoad({ categoryId }) { async onLoad({ categoryId }) {
if(uni.getStorageSync('token')){
this.$store.commit('getUserInfo')
}
await Promise.allSettled([this.fetchCategoryList(), this.fetchFilters()]) await Promise.allSettled([this.fetchCategoryList(), this.fetchFilters()])
console.log('categoryList', this.categoryList) console.log('categoryList', this.categoryList)
@ -222,6 +225,13 @@
}, },
methods: { methods: {
async fetchCategoryList() { async fetchCategoryList() {
try {
this.categoryList = (await this.$fetch('queryCategoryList', { pageSize: 1000 }))?.records?.map(item => ({ id: item.id, name: item.title, children: [] }))
} catch(err) {
this.categoryList = []
}
return
this.categoryList = [ this.categoryList = [
{ {
"key": "1962345168240185345", "key": "1962345168240185345",
@ -363,12 +373,6 @@
} }
}) })
return
try {
this.categoryList = (await this.$fetch('getCategoryList', { pageSize: 1000 }))?.records?.map(item => ({ id: item.id, name: item.name, children: [] }))
} catch(err) {
this.categoryList = []
}
}, },
async fetchFilters() { async fetchFilters() {
@ -499,69 +503,11 @@
// todo: fetch // todo: fetch
}, },
async queryProductList(categoryId) { async queryProductList(categoryId) {
try { try {
return (await this.$fetch('queryActivityList', { ...this.queryParams, categoryId }))?.records || [] return (await this.$fetch('queryActivityList', { ...this.queryParams, categoryId }))?.records || []
} catch (err) { } catch (err) {
return [] return []
} }
return [
{
id: '001',
image: '/static/image/temp-20.png',
title: '新疆天山行7/9日丨醉美伊犁&吐鲁番双套餐',
tagList: ['国内游','7-9天','12岁+'],
priceDiscount: 688.99,
priceOrigin: 1200,
applyNum: 4168,
},
{
id: '002',
image: '/static/image/temp-20.png',
title: '坝上双草原6日|乌兰布统+锡林郭勒+长城',
tagList: ['国内游','7-9天','12岁+'],
priceDiscount: 688.99,
priceOrigin: 1200,
applyNum: 4168,
},
{
id: '003',
image: '/static/image/temp-20.png',
title: '牛湖线探秘 | 清远牛湖线徒步,探秘天坑与大草原',
tagList: ['国内游','7-9天','12岁+'],
priceDiscount: 688.99,
priceOrigin: 1200,
applyNum: 4168,
},
{
id: '004',
image: '/static/image/temp-20.png',
title: '低海拔藏区草原,汉藏文化大穿越',
tagList: ['国内游','7-9天','12岁+'],
priceDiscount: 688.99,
priceOrigin: 1200,
applyNum: 4168,
},
{
id: '005',
image: '/static/image/temp-20.png',
title: '新丝路到敦煌7日 | 甘青轻松穿越,沙漠+草原',
tagList: ['国内游','7-9天','12岁+'],
priceDiscount: 688.99,
priceOrigin: 1200,
applyNum: 4168,
},
{
id: '006',
image: '/static/image/temp-20.png',
title: '呼伦贝尔6/8日|经典or环线双套餐可选',
tagList: ['国内游','7-9天','12岁+'],
priceDiscount: 688.99,
priceOrigin: 1200,
applyNum: 4168,
},
]
}, },
async initList() { async initList() {
console.log('queryParams', this.queryParams) console.log('queryParams', this.queryParams)


+ 10
- 11
pages/index/center.vue View File

@ -9,18 +9,18 @@
<view class="flex user"> <view class="flex user">
<!-- 用户信息 --> <!-- 用户信息 -->
<template v-if="isLogin"> <template v-if="isLogin">
<view class="user-avatar">
<!-- todo: check key -->
<image class="user-avatar-img" src="@/pages_order/static/temp-30.png" mode="scaleToFill"></image>
<view class="user-avatar" v-if="userInfo.headImage">
<image class="user-avatar-img" :src="userInfo.headImage" mode="scaleToFill"></image>
</view>
<view class="user-avatar is-default" v-else>
<image class="user-avatar-img" src="@/pages_order/static/center/avatar-default.png" mode="scaleToFill"></image>
</view> </view>
<view class="user-info"> <view class="user-info">
<!-- todo: check key -->
<view class="flex user-info-name"> <view class="flex user-info-name">
<view class="highligt">战斗世界</view>
<view class="light">ID5625354</view>
<view class="highligt" v-if="userInfo.nickName">{{ userInfo.nickName || '' }}</view>
<view class="light">{{ `ID:${userInfo.id}` }}</view>
</view> </view>
<!-- todo: check key -->
<view class="user-info-desc">手机号19989674531</view>
<view class="user-info-desc" v-if="userInfo.phone">{{ `手机号${userInfo.phone}` }}</view>
</view> </view>
</template> </template>
<template v-else> <template v-else>
@ -129,8 +129,6 @@
computed: { computed: {
...mapState(['userInfo', 'configList']), ...mapState(['userInfo', 'configList']),
isLogin() { isLogin() {
// todo: delete
return true
return this.userInfo && this.userInfo.id return this.userInfo && this.userInfo.id
} }
}, },
@ -239,7 +237,8 @@
&-name { &-name {
justify-content: flex-start; justify-content: flex-start;
column-gap: 16rpx;
flex-wrap: wrap;
gap: 16rpx;
font-family: PingFang SC; font-family: PingFang SC;
color: #FFFFFF; color: #FFFFFF;


+ 34
- 36
pages/index/growing.vue View File

@ -60,48 +60,46 @@
return { return {
keyword: '', keyword: '',
isFocusSearch: false, isFocusSearch: false,
// todo
mixinsListApi: '',
queryParams: {
pageNo: 1,
pageSize: 10,
userId: '',
},
} }
}, },
computed: { computed: {
...mapState(['memberInfo']), ...mapState(['memberInfo']),
mixinsListApi() {
return this.queryParams.userId ? 'queryExperienceList' : ''
},
},
onLoad() {
if(uni.getStorageSync('token')){
this.$store.commit('getUserInfo')
}
},
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()
}, },
methods: { methods: {
// todo: delete
getData() {
this.list = [
{
id: '001',
name: '新疆天山行7/9日丨醉美伊犁&吐鲁番双套餐',
image: [
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
],
createTime: '2025-07-12',
},
{
id: '002',
name: '仙踪新昌·韩妃江古道|邂逅“江南小桂林”',
image: [
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
],
createTime: '2025-06-18',
},
{
id: '003',
name: '山水石窟·大佛寺|江南佛窟造像,新昌山水轻徒',
image: [
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
],
createTime: '2025-06-15',
},
]
getDataThen(records) {
this.list = records.map(item => {
const { id, name, image, createTime } = item
return {
id,
// todo: check key
name,
image: image?.split?.(',') || [],
createTime
}
})
}, },
search() { search() {
console.log('search', this.keyword) console.log('search', this.keyword)


+ 4
- 1
pages/index/index.vue View File

@ -103,6 +103,9 @@
} }
}, },
onLoad() { onLoad() {
if(uni.getStorageSync('token')){
this.$store.commit('getUserInfo')
}
}, },
computed: { computed: {
searchStyle() { searchStyle() {
@ -155,7 +158,7 @@
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
padding: 100rpx 32rpx calc(120rpx + env(safe-area-inset-bottom) + 100rpx) 32rpx;
padding: 100rpx 32rpx calc(120rpx + env(safe-area-inset-bottom) + 32rpx) 32rpx;
box-sizing: border-box; box-sizing: border-box;
} }


+ 5
- 0
pages/index/partner.vue View File

@ -112,6 +112,11 @@
mixinsListApi: '', mixinsListApi: '',
} }
}, },
onLoad() {
if(uni.getStorageSync('token')){
this.$store.commit('getUserInfo')
}
},
onShow() { onShow() {
// todo: refresh is partner? // todo: refresh is partner?
}, },


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

@ -3,10 +3,8 @@
<view class="flex flex-column content"> <view class="flex flex-column content">
<!-- todo: check key -->
<image class="logo" src="@/pages_order/static/temp-29.png" mode="widthFix"></image>
<!-- todo: check key -->
<view class="name">鸿宇研学生</view>
<image class="logo" :src="configList.config_logo" mode="widthFix"></image>
<view class="name">{{ configList.app_name }}</view>
<button class="btn btn-login flex" @click="wxLogin" > </button> <button class="btn btn-login flex" @click="wxLogin" > </button>


+ 20
- 20
pages_order/auth/wxUserInfo.vue View File

@ -15,14 +15,14 @@
errorType="toast" errorType="toast"
> >
<view class="form-item"> <view class="form-item">
<uv-form-item prop="name" :customStyle="formItemStyle">
<uv-form-item prop="nickName" :customStyle="formItemStyle">
<view class="form-item-label">昵称</view> <view class="form-item-label">昵称</view>
<view class="form-item-content input"> <view class="form-item-content input">
<input <input
type="nickname" type="nickname"
placeholder="请输入" placeholder="请输入"
placeholderStyle="color: #C6C6C6; font-size: 32rpx; font-weight: 400;" placeholderStyle="color: #C6C6C6; font-size: 32rpx; font-weight: 400;"
v-model="form.name"
v-model="form.nickName"
/> />
</view> </view>
</uv-form-item> </uv-form-item>
@ -45,12 +45,12 @@
</uv-form-item> </uv-form-item>
</view> </view>
<view class="form-item"> <view class="form-item">
<uv-form-item prop="phone" :customStyle="formItemStyle">
<uv-form-item prop="headImage" :customStyle="formItemStyle">
<view class="form-item-label">头像</view> <view class="form-item-label">头像</view>
<view class="form-item-content input"> <view class="form-item-content input">
<button class="btn btn-avatar" :plain="true" :hairline="false" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> <button class="btn btn-avatar" :plain="true" :hairline="false" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<view v-if="form.avatar" class="avatar">
<image class="img" :src="form.avatar" mode="aspectFill"></image>
<view v-if="form.headImage" class="avatar">
<image class="img" :src="form.headImage" mode="aspectFill"></image>
<view class="flex mask"> <view class="flex mask">
<image class="icon" src="@/pages_order/static/icon-change.png" mode="widthFix" /> <image class="icon" src="@/pages_order/static/icon-change.png" mode="widthFix" />
</view> </view>
@ -93,12 +93,12 @@
data() { data() {
return { return {
form: { form: {
name: null,
nickName: null,
phone: null, phone: null,
avatar: null,
headImage: null,
}, },
rules: { rules: {
'name': {
'nickName': {
type: 'string', type: 'string',
required: true, required: true,
message: '请输入昵称', message: '请输入昵称',
@ -108,9 +108,9 @@
required: true, required: true,
message: '请输入手机号', message: '请输入手机号',
}, },
'avatar': {
type: 'array',
required: true,
'headImage': {
type: 'string',
required: false,
message: '请选择头像', message: '请选择头像',
}, },
}, },
@ -123,15 +123,15 @@
onLoad(arg) { onLoad(arg) {
this.mode = arg.mode this.mode = arg.mode
this.form.name = this.userInfo.name || ''
this.form.nickName = this.userInfo.nickName || ''
this.form.phone = this.userInfo.phone || '' this.form.phone = this.userInfo.phone || ''
this.form.avatar = this.userInfo.avatar || ''
this.form.headImage = this.userInfo.headImage || ''
}, },
methods: { methods: {
onChooseAvatar(res) { onChooseAvatar(res) {
this.$Oss.ossUpload(res.target.avatarUrl) this.$Oss.ossUpload(res.target.avatarUrl)
.then(url => { .then(url => {
this.form.avatar = url
this.form.headImage = url
}) })
}, },
getPhone(e){ getPhone(e){
@ -141,7 +141,8 @@
if(res.code == 200){ if(res.code == 200){
if(res.success){ if(res.success){
this.form.phone = res.result
const result = JSON.parse(res.result)
this.form.phone = result.phone_info.phoneNumber
}else{ }else{
uni.showModal({ uni.showModal({
title: res.message title: res.message
@ -155,18 +156,17 @@
await this.$refs.form.validate() await this.$refs.form.validate()
const { const {
name,
nickName,
phone, phone,
avatar,
headImage,
} = this.form } = this.form
const params = { const params = {
name,
nickName,
phone, phone,
avatar,
headImage,
} }
// todo: check 415 Unsupported Media Type
const res = await this.$fetch('updateInfo', params, false) const res = await this.$fetch('updateInfo', params, false)
if (res.code == 200) { if (res.code == 200) {


+ 3
- 3
pages_order/comment/commentCard.vue View File

@ -24,15 +24,15 @@
<view class="section score"> <view class="section score">
<view class="flex score-item"> <view class="flex score-item">
<view class="score-item-label">行程</view> <view class="score-item-label">行程</view>
<formRate :value="data.tripNum" :readonly="true"></formRate>
<formRate :value="data.processScore" :readonly="true"></formRate>
</view> </view>
<view class="flex score-item"> <view class="flex score-item">
<view class="score-item-label">景点</view> <view class="score-item-label">景点</view>
<formRate :value="data.spotNum" :readonly="true"></formRate>
<formRate :value="data.spotScore" :readonly="true"></formRate>
</view> </view>
<view class="flex score-item"> <view class="flex score-item">
<view class="score-item-label">导师</view> <view class="score-item-label">导师</view>
<formRate :value="data.mentorNum" :readonly="true"></formRate>
<formRate :value="data.teacherScore" :readonly="true"></formRate>
</view> </view>
</view> </view>
<view class="section operate"> <view class="section operate">


+ 29
- 19
pages_order/comment/commentPopup.vue View File

@ -18,31 +18,31 @@
</view> </view>
<view class="section"> <view class="section">
<view class="form-item"> <view class="form-item">
<uv-form-item prop="tripNum" :customStyle="formItemStyle">
<uv-form-item prop="processScore" :customStyle="formItemStyle">
<view class="flex row"> <view class="flex row">
<view class="form-item-label">行程</view> <view class="form-item-label">行程</view>
<view class="form-item-content"> <view class="form-item-content">
<formRate v-model="form.tripNum"></formRate>
<formRate v-model="form.processScore"></formRate>
</view> </view>
</view> </view>
</uv-form-item> </uv-form-item>
</view> </view>
<view class="form-item"> <view class="form-item">
<uv-form-item prop="spotNum" :customStyle="formItemStyle">
<uv-form-item prop="spotScore" :customStyle="formItemStyle">
<view class="flex row"> <view class="flex row">
<view class="form-item-label">景点</view> <view class="form-item-label">景点</view>
<view class="form-item-content"> <view class="form-item-content">
<formRate v-model="form.spotNum"></formRate>
<formRate v-model="form.spotScore"></formRate>
</view> </view>
</view> </view>
</uv-form-item> </uv-form-item>
</view> </view>
<view class="form-item"> <view class="form-item">
<uv-form-item prop="mentorNum" :customStyle="formItemStyle">
<uv-form-item prop="teacherScore" :customStyle="formItemStyle">
<view class="flex row"> <view class="flex row">
<view class="form-item-label">导师</view> <view class="form-item-label">导师</view>
<view class="form-item-content"> <view class="form-item-content">
<formRate v-model="form.mentorNum"></formRate>
<formRate v-model="form.teacherScore"></formRate>
</view> </view>
</view> </view>
</uv-form-item> </uv-form-item>
@ -89,23 +89,23 @@
// todo: fetch // todo: fetch
detail: {}, detail: {},
form: { form: {
tripNum: null,
spotNum: null,
mentorNum: null,
processScore: null,
spotScore: null,
teacherScore: null,
content: null, content: null,
}, },
rules: { rules: {
'tripNum': {
'processScore': {
type: 'number', type: 'number',
required: true, required: true,
message: '请为行程打分', message: '请为行程打分',
}, },
'spotNum': {
'spotScore': {
type: 'number', type: 'number',
required: true, required: true,
message: '请为景点打分', message: '请为景点打分',
}, },
'mentorNum': {
'teacherScore': {
type: 'number', type: 'number',
required: true, required: true,
message: '请为导师打分', message: '请为导师打分',
@ -124,15 +124,17 @@
async getData() { async getData() {
// todo: fetch order product // todo: fetch order product
}, },
async open(id) {
async open(id, detail) {
this.id = id this.id = id
await this.getData()
this.detail = detail
// todo: fetch order product
// await this.getData()
this.form = { this.form = {
tripNum: null,
spotNum: null,
mentorNum: null,
processScore: null,
spotScore: null,
teacherScore: null,
content: null, content: null,
} }
@ -152,13 +154,21 @@
await this.$refs.form.validate() await this.$refs.form.validate()
const { const {
processScore,
spotScore,
teacherScore,
content,
} = this.form } = this.form
const params = { const params = {
orderId: this.id,
processScore,
spotScore,
teacherScore,
content,
} }
// todo: fetch
// await this.$fetch('updateAddress', params)
await this.$fetch('addComment', params)
uni.showToast({ uni.showToast({
icon: 'success', icon: 'success',


+ 12
- 10
pages_order/comment/commentRecords.vue View File

@ -37,21 +37,23 @@
data() { data() {
return { return {
// todo // todo
mixinsListApi: '',
// mixinsListApi: '',
list: [],
total: 0,
} }
}, },
onShow() {
console.log('onShow')
},
onLoad(arg) {
console.log('onLoad')
const { productId } = arg
this.queryParams.productId = productId
onLoad() {
this.getData() this.getData()
}, },
methods: { methods: {
async getData() {
try {
this.list = await this.$fetch('queryMyCommentList')
this.total = this.list.length
} catch (err) {
}
},
}, },
} }
</script> </script>


+ 61
- 26
pages_order/comment/recordFormPopup.vue View File

@ -10,18 +10,17 @@
<uv-form <uv-form
ref="form" ref="form"
:model="form" :model="form"
:rules="rules"
errorType="toast" errorType="toast"
> >
<view class="form-item"> <view class="form-item">
<uv-form-item prop="project" :customStyle="formItemStyle">
<uv-form-item prop="activityId" :customStyle="formItemStyle">
<view class="form-item-label"> <view class="form-item-label">
<image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image> <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>
关联项目 关联项目
</view> </view>
<view class="form-item-content"> <view class="form-item-content">
<view class="flex row" @click="openRelatePojectPicker"> <view class="flex row" @click="openRelatePojectPicker">
<view v-if="form.project" class="text">{{ projectDesc }}</view>
<view v-if="form.activityId" class="text">{{ projectDesc }}</view>
<view v-else class="text placeholder">请选择关联项目</view> <view v-else class="text placeholder">请选择关联项目</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon> <uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view> </view>
@ -30,31 +29,31 @@
</uv-form-item> </uv-form-item>
</view> </view>
<view class="form-item"> <view class="form-item">
<uv-form-item prop="tripNum" :customStyle="formItemStyle">
<uv-form-item prop="processScore" :customStyle="formItemStyle">
<view class="flex row"> <view class="flex row">
<view class="form-item-label">行程</view> <view class="form-item-label">行程</view>
<view class="form-item-content"> <view class="form-item-content">
<formRate v-model="form.tripNum"></formRate>
<formRate v-model="form.processScore"></formRate>
</view> </view>
</view> </view>
</uv-form-item> </uv-form-item>
</view> </view>
<view class="form-item"> <view class="form-item">
<uv-form-item prop="spotNum" :customStyle="formItemStyle">
<uv-form-item prop="spotScore" :customStyle="formItemStyle">
<view class="flex row"> <view class="flex row">
<view class="form-item-label">景点</view> <view class="form-item-label">景点</view>
<view class="form-item-content"> <view class="form-item-content">
<formRate v-model="form.spotNum"></formRate>
<formRate v-model="form.spotScore"></formRate>
</view> </view>
</view> </view>
</uv-form-item> </uv-form-item>
</view> </view>
<view class="form-item"> <view class="form-item">
<uv-form-item prop="mentorNum" :customStyle="formItemStyle">
<uv-form-item prop="teacherScore" :customStyle="formItemStyle">
<view class="flex row"> <view class="flex row">
<view class="form-item-label">导师</view> <view class="form-item-label">导师</view>
<view class="form-item-content"> <view class="form-item-content">
<formRate v-model="form.mentorNum"></formRate>
<formRate v-model="form.teacherScore"></formRate>
</view> </view>
</view> </view>
</uv-form-item> </uv-form-item>
@ -89,6 +88,8 @@
</template> </template>
<script> <script>
import { mapState } from 'vuex'
import reloateProjectPopup from '@/pages_order/components/reloateProjectPopup.vue' import reloateProjectPopup from '@/pages_order/components/reloateProjectPopup.vue'
import formTextarea from '@/pages_order/components/formTextarea.vue' import formTextarea from '@/pages_order/components/formTextarea.vue'
import formUpload from '@/pages_order/components/formUpload.vue' import formUpload from '@/pages_order/components/formUpload.vue'
@ -105,24 +106,22 @@
return { return {
isShow: false, isShow: false,
form: { form: {
project: null,
tripNum: null,
spotNum: null,
mentorNum: null,
activityId: null,
processScore: null,
spotScore: null,
teacherScore: null,
images: [], images: [],
texts: [], texts: [],
}, },
rules: {
// todo
},
projects: [], projects: [],
questions: [], questions: [],
} }
}, },
computed: { computed: {
...mapState(['userInfo']),
projectDesc() { projectDesc() {
const { project } = this.form
const target = this.projects?.find?.(item => item.id === project)
const { activityId } = this.form
const target = this.projects?.find?.(item => item.id === activityId)
return target?.name || '' return target?.name || ''
}, },
@ -176,6 +175,26 @@
}, },
] ]
}, },
setRules() {
const rules = {
'activityId': {
type: 'string',
required: true,
message: '请选择关联项目',
},
}
// todo: check
this.questions.forEach((item, index) => {
rules[`texts[${index}]`] = {
type: 'string',
required: true,
message: `请回答“${item.label}`,
}
})
this.$refs.form.setRules(this.rules)
},
async open() { async open() {
await this.getData() await this.getData()
@ -183,10 +202,10 @@
const texts = this.questions.map(() => '') const texts = this.questions.map(() => '')
this.form = { this.form = {
project: null,
tripNum: null,
spotNum: null,
mentorNum: null,
activityId: null,
processScore: null,
spotScore: null,
teacherScore: null,
images: [], images: [],
texts, texts,
} }
@ -198,25 +217,41 @@
}, },
onPopupChange(e) { onPopupChange(e) {
this.isShow = e.show this.isShow = e.show
// todo: need settimeout?
this.setRules()
}, },
openRelatePojectPicker() { openRelatePojectPicker() {
this.$refs.reloateProjectPopup.open(this.form.project?.id || null)
this.$refs.reloateProjectPopup.open(this.form.activityId?.id || null)
}, },
onRelateProjectChange(id) { onRelateProjectChange(id) {
this.form.project = id
this.form.activityId = id
}, },
async onPublish() { async onPublish() {
try { try {
await this.$refs.form.validate() await this.$refs.form.validate()
const { const {
activityId,
processScore,
spotScore,
teacherScore,
images,
texts,
} = this.form } = this.form
const params = { const params = {
// todo: check
userId: this.userInfo.id,
activityId,
processScore,
spotScore,
teacherScore,
image: images.join(','),
content: texts.join('\r\n') // todo: check
} }
// todo: fetch
// await this.$fetch('updateAddress', params)
await this.$fetch('addExperience', params)
uni.showToast({ uni.showToast({
icon: 'success', icon: 'success',


+ 1
- 0
pages_order/coupon/couponList/couponCard.vue View File

@ -88,6 +88,7 @@
font-size: 30rpx; font-size: 30rpx;
font-weight: 500; font-weight: 500;
line-height: 1.4; line-height: 1.4;
color: #FFFFFF;
background: linear-gradient(to right, #21FEEC, #019AF9); background: linear-gradient(to right, #21FEEC, #019AF9);
border: 2rpx solid #00A9FF; border: 2rpx solid #00A9FF;
border-radius: 28rpx; border-radius: 28rpx;


+ 2
- 38
pages_order/coupon/couponList/index.vue View File

@ -28,52 +28,16 @@
}, },
data() { data() {
return { return {
// todo: check key
mixinsListApi: '',
mixinsListApi: 'queryCouponList',
queryParams: { queryParams: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
status: 0,
}, },
selectedId: null, selectedId: null,
} }
}, },
methods: { methods: {
// todo: delete
getData() {
this.list = [
{
id: '001',
label: '专属福利】20元红包',
price: 20,
validTime: '2026-04-28',
},
{
id: '002',
label: '专属福利】400元红包',
price: 400,
validTime: '2026-04-28',
},
{
id: '003',
label: '专属福利】400元红包',
price: 400,
validTime: '2026-04-28',
},
{
id: '004',
label: '专属福利】400元红包',
price: 400,
validTime: '2026-04-28',
},
{
id: '005',
label: '专属福利】400元红包',
price: 400,
validTime: '2026-04-28',
},
]
},
onSelect(id) { onSelect(id) {
console.log('onSelect', id) console.log('onSelect', id)
this.selectedId = id this.selectedId = id


+ 3
- 3
pages_order/coupon/couponSelect/couponCard.vue View File

@ -4,11 +4,11 @@
<uv-radio :name="data.id"></uv-radio> <uv-radio :name="data.id"></uv-radio>
</view> </view>
<view class="flex price"> <view class="flex price">
¥<view class="highlight">{{ data.price }}</view>
¥<view class="highlight">{{ data.discountAmount }}</view>
</view> </view>
<view class="flex flex-column info"> <view class="flex flex-column info">
<view class="title">{{ data.label }}</view>
<view class="desc">{{ `有效期至 ${data.validTime}` }}</view>
<view class="title">{{ data.title }}</view>
<view class="desc">{{ `有效期至 ${data.validDate}` }}</view>
</view> </view>
</view> </view>
</template> </template>


+ 2
- 38
pages_order/coupon/couponSelect/index.vue View File

@ -38,11 +38,11 @@
}, },
data() { data() {
return { return {
// todo: check key
mixinsListApi: '',
mixinsListApi: 'queryCouponList',
queryParams: { queryParams: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
status: 0,
}, },
selectedId: null, selectedId: null,
} }
@ -67,42 +67,6 @@
this.$store.commit('setCouponInfo', target) this.$store.commit('setCouponInfo', target)
}, },
methods: { methods: {
// todo: delete
getData() {
this.list = [
{
id: '001',
label: '专属福利】20元红包',
price: 20,
validTime: '2026-04-28',
},
{
id: '002',
label: '专属福利】400元红包',
price: 400,
validTime: '2026-04-28',
},
{
id: '003',
label: '专属福利】400元红包',
price: 400,
validTime: '2026-04-28',
},
{
id: '004',
label: '专属福利】400元红包',
price: 400,
validTime: '2026-04-28',
},
{
id: '005',
label: '专属福利】400元红包',
price: 400,
validTime: '2026-04-28',
},
]
},
}, },
} }
</script> </script>


+ 16
- 0
pages_order/growing/activity/index.vue View File

@ -112,6 +112,22 @@
}, },
methods: { methods: {
async getData() { async getData() {
try {
const result = await this.$fetch('queryExperienceById', { recordId: this.id })
const { image, thoughts } = result
this.detail = {
highlights: image?.split?.(',') || [],
// todo: check key
thoughts,
// todo: check key about ""
}
} catch (err) {
}
return
// todo // todo
this.detail = { this.detail = {


+ 20
- 18
pages_order/live/formPopup.vue View File

@ -14,14 +14,14 @@
errorType="toast" errorType="toast"
> >
<view class="form-item"> <view class="form-item">
<uv-form-item prop="project" :customStyle="formItemStyle">
<uv-form-item prop="activityId" :customStyle="formItemStyle">
<view class="form-item-label"> <view class="form-item-label">
<image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image> <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>
关联项目 关联项目
</view> </view>
<view class="form-item-content"> <view class="form-item-content">
<view class="flex row" @click="openRelatePojectPicker"> <view class="flex row" @click="openRelatePojectPicker">
<view v-if="form.project" class="text">{{ projectDesc }}</view>
<view v-if="form.activityId" class="text">{{ projectDesc }}</view>
<view v-else class="text placeholder">请选择关联项目</view> <view v-else class="text placeholder">请选择关联项目</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon> <uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view> </view>
@ -75,14 +75,14 @@
data() { data() {
return { return {
form: { form: {
project: null,
activityId: null,
area: null, area: null,
latitude: null, latitude: null,
longitude: null, longitude: null,
images: [], images: [],
}, },
rules: { rules: {
'project': {
'activityId': {
type: 'string', type: 'string',
required: true, required: true,
message: '请选择关联项目', message: '请选择关联项目',
@ -104,8 +104,8 @@
}, },
computed: { computed: {
projectDesc() { projectDesc() {
const { project } = this.form
const target = this.projects?.find?.(item => item.id === project)
const { activityId } = this.form
const target = this.projects?.find?.(item => item.id === activityId)
return target?.name || '' return target?.name || ''
}, },
@ -160,18 +160,15 @@
] ]
}, },
async open(id) { async open(id) {
// todo: auto bind project by id?
// todo: auto bind activityId by id?
await this.getData() await this.getData()
const texts = this.questions.map(() => '')
this.form = { this.form = {
project: null,
tripNum: null,
spotNum: null,
mentorNum: null,
activityId: null,
area: null,
latitude: null,
longitude: null,
images: [], images: [],
texts,
} }
this.$refs.popup.open() this.$refs.popup.open()
@ -180,10 +177,10 @@
this.$refs.popup.close() this.$refs.popup.close()
}, },
openRelatePojectPicker() { openRelatePojectPicker() {
this.$refs.reloateProjectPopup.open(this.form.project?.id || null)
this.$refs.reloateProjectPopup.open(this.form.activityId?.id || null)
}, },
onRelateProjectChange(id) { onRelateProjectChange(id) {
this.form.project = id
this.form.activityId = id
}, },
// //
selectAddr() { selectAddr() {
@ -212,13 +209,18 @@
await this.$refs.form.validate() await this.$refs.form.validate()
const { const {
activityId,
area,
images,
} = this.form } = this.form
const params = { const params = {
activityId,
address: area,
image: images.join(',')
} }
// todo: fetch
// await this.$fetch('updateAddress', params)
await this.$fetch('addImage', params)
uni.showToast({ uni.showToast({
icon: 'success', icon: 'success',


+ 30
- 77
pages_order/live/index.vue View File

@ -1,14 +1,14 @@
<template> <template>
<view class="page__view highlight"> <view class="page__view highlight">
<navbar :title="detail.title" leftClick @leftClick="$utils.navigateBack" />
<navbar :title="liveInfo.title" leftClick @leftClick="$utils.navigateBack" />
<view class="header"> <view class="header">
<image class="cover-img" :src="detail.image" mode="widthFix"></image>
<image class="cover-img" :src="liveInfo.url" mode="widthFix"></image>
<view class="flex" style="padding: 40rpx 40rpx 0 40rpx;"> <view class="flex" style="padding: 40rpx 40rpx 0 40rpx;">
<view class="flex flex-column"> <view class="flex flex-column">
<view class="title">{{ detail.title }}</view>
<view class="tag">{{ detail.createTime }}</view>
<view class="title">{{ liveInfo.title }}</view>
<view class="tag">{{ liveInfo.createTime }}</view>
</view> </view>
<view v-if="isManager" class="flex operate"> <view v-if="isManager" class="flex operate">
<view class="btn btn-add" @click="onAdd">新增记录</view> <view class="btn btn-add" @click="onAdd">新增记录</view>
@ -25,7 +25,7 @@
</view> </view>
<view class="info"> <view class="info">
<view class="flex title"> <view class="flex title">
<view>{{ item.name }}</view>
<view>{{ item.createBy }}</view>
<image class="icon" src="@/static/image/icon-location.png" mode="widthFix"></image> <image class="icon" src="@/static/image/icon-location.png" mode="widthFix"></image>
<view class="address text-ellipsis">{{ item.address }}</view> <view class="address text-ellipsis">{{ item.address }}</view>
</view> </view>
@ -34,7 +34,7 @@
</view> </view>
<view class="section-content record"> <view class="section-content record">
<view class="record-item" v-for="(image, imgIdx) in item.images" :key="imgIdx"> <view class="record-item" v-for="(image, imgIdx) in item.images" :key="imgIdx">
<image class="img" :src="image" mode="scaleToFill"></image>
<image class="img" :src="image" mode="aspectFill"></image>
</view> </view>
</view> </view>
</view> </view>
@ -47,6 +47,8 @@
</template> </template>
<script> <script>
import { mapState } from 'vuex'
import mixinsList from '@/mixins/list.js' import mixinsList from '@/mixins/list.js'
import SYStackedCarousel from '@/uni_modules/SY-StackedCarousel/components/SY-StackedCarousel/SY-StackedCarousel.vue' import SYStackedCarousel from '@/uni_modules/SY-StackedCarousel/components/SY-StackedCarousel/SY-StackedCarousel.vue'
@ -60,93 +62,44 @@
}, },
data() { data() {
return { return {
id: null,
detail: {},
bannerList: [],
current: 0, current: 0,
queryParams: { queryParams: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
id: '',
imageId: '',
}, },
// todo
mixinsListApi: '',
mixinsListApi: 'queryImageContentList',
// todo: fetch // todo: fetch
isManager: false,
isManager: true,
} }
}, },
computed: { computed: {
swiperCurrent() {
return this.bannerList[this.current]
},
...mapState(['liveInfo']),
}, },
onLoad(arg) { onLoad(arg) {
const { id } = arg const { id } = arg
this.id = id
this.fetchDetail()
this.queryParams.id = id
this.queryParams.imageId = id
this.getData() this.getData()
}, },
methods: { methods: {
async fetchDetail() {
// todo: fetch
this.detail = {
id: '001',
image: '/static/image/temp-20.png',
title: '趣玩新加坡',
createTime: '2025-04-18',
}
},
// todo: delete
getData() {
this.list = [
{
id: '001',
avatar: '/pages_order/static/temp-30.png',
name: '战斗世界',
address: '241 Orchard Road, Singapore 238863',
createTime: '2023-04-18 12:00:00',
images: [
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
]
},
{
id: '001',
avatar: '/pages_order/static/temp-30.png',
name: '战斗世界',
address: '10 Bayfront Avenue, Singapore 018956',
createTime: '2023-04-18 12:00:00',
images: [
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
]
},
]
},
clickHandler(item, index) {
console.log("item: ", item);
console.log("index: ", index);
this.current = index
},
changeHandler(index) {
console.log("当前触发change事件,返回索引: ", index);
getCoverImage(image) {
return image?.split?.(',')?.[0]
},
getDataThen(records) {
this.list = records.map(item => {
const { id, avatar, createBy, address, image, createTime } = item
return {
id,
// todo: check key
avatar: avatar || '/pages_order/static/center/avatar-default.png',
createBy,
address,
images: image?.split?.(',') || [],
createTime,
}
})
}, },
onAdd() { onAdd() {
this.$refs.formPopup.open() this.$refs.formPopup.open()


+ 21
- 62
pages_order/live/list.vue View File

@ -6,7 +6,7 @@
<view class="swiper"> <view class="swiper">
<SYStackedCarousel <SYStackedCarousel
height="536rpx" height="536rpx"
:images="bannerList"
:images="list"
:current="current" :current="current"
:autoplay="true" :autoplay="true"
horizontalMargin="25" horizontalMargin="25"
@ -42,7 +42,7 @@
</view> </view>
<view class="section-content record"> <view class="section-content record">
<view class="record-item" v-for="(image, imgIdx) in item.images" :key="imgIdx"> <view class="record-item" v-for="(image, imgIdx) in item.images" :key="imgIdx">
<image class="img" :src="image" mode="scaleToFill"></image>
<image class="img" :src="image" mode="aspectFill"></image>
</view> </view>
</view> </view>
</view> </view>
@ -70,79 +70,37 @@
}, },
data() { data() {
return { return {
bannerList: [],
current: 0, current: 0,
queryParams: {
pageNo: 1,
pageSize: 10,
id: '',
},
// todo
mixinsListApi: '',
mixinsListApi: 'queryImageList',
// todo: fetch // todo: fetch
isManager: true, isManager: true,
} }
}, },
computed: { computed: {
swiperCurrent() { swiperCurrent() {
return this.bannerList[this.current]
return this.list[this.current]
}, },
}, },
onLoad() {
this.fetchBanner()
async onLoad() {
this.getData()
}, },
methods: { methods: {
async fetchBanner() {
this.bannerList = [
{
url: '/static/image/temp-20.png',
title: '趣玩新加坡',
createTime: '2025-04-18',
},
{
url: '/static/image/temp-20.png',
title: '坝上双草原',
createTime: '2025-04-18',
},
{
url: '/static/image/temp-20.png',
title: '牛湖线',
createTime: '2025-04-18',
},
]
},
// todo: delete
getData() {
this.list = [
{
id: '001',
title: '桂林深度游',
images: [
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
]
},
{
id: '002',
title: '西双版纳雨林10+体验',
images: [
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
'/pages_order/static/temp-38.png',
]
},
]
getDataThen(records) {
this.list = records.map(item => {
const { id, image, activityId_dictText, createTime } = item
const images = image?.split?.(',') || []
return {
id,
url: images?.[0],
images,
title: activityId_dictText,
createTime: this.$dayjs(createTime).format('YYYY-MM-DD'),
}
})
}, },
clickHandler(item, index) { clickHandler(item, index) {
console.log("item: ", item);
console.log("index: ", index);
this.current = index this.current = index
}, },
changeHandler(index) { changeHandler(index) {
@ -155,6 +113,7 @@
this.$refs.formPopup.open() this.$refs.formPopup.open()
}, },
showAll(id) { showAll(id) {
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?id=${id}`)
}, },
}, },


+ 15
- 7
pages_order/member/memberApplyCard.vue View File

@ -7,7 +7,7 @@
</view> </view>
<view class="row"> <view class="row">
<view class="row-label">申请人ID</view> <view class="row-label">申请人ID</view>
<view class="row-content">{{ data.userId }}</view>
<view class="row-content">{{ data.bindId }}</view>
</view> </view>
<view class="row"> <view class="row">
<view class="row-label">申请时间</view> <view class="row-label">申请时间</view>
@ -44,13 +44,21 @@
} }
}, },
methods: { methods: {
onReject() {
// todo: fetch reject
this.$emit('submitted')
async fetchUpdate(status) {
try {
await this.$fetch('updateBind', { id: this.data.id, status }) // (status)0- 1- 2-
return true
} catch (err) {
return false
}
},
async onReject() {
const succ = await this.fetchUpdate(2)
succ && this.$emit('submitted')
}, },
onConfirm() {
// todo: fetch confirm
this.$emit('submitted')
async onConfirm() {
const succ = await this.fetchUpdate(1)
succ && this.$emit('submitted')
}, },
}, },
} }


+ 11
- 9
pages_order/member/memberBind.vue View File

@ -16,7 +16,7 @@
errorType="toast" errorType="toast"
> >
<view class="form-item"> <view class="form-item">
<uv-form-item prop="id" :customStyle="formItemStyle">
<uv-form-item prop="bindId" :customStyle="formItemStyle">
<view class="form-item-label">绑定人ID</view> <view class="form-item-label">绑定人ID</view>
<view class="form-item-content"> <view class="form-item-content">
<view class="flex search"> <view class="flex search">
@ -37,7 +37,7 @@
<view class="form-item" v-for="item in list" :key="item.id"> <view class="form-item" v-for="item in list" :key="item.id">
<view <view
:class="['flex', 'list-item', item.id === form.id ? 'is-active' : '']" :class="['flex', 'list-item', item.id === form.id ? 'is-active' : '']"
@click="onSelect"
@click="onSelect(item.id)"
> >
<view class="avatar"> <view class="avatar">
<image class="img" :src="item.avatar" mode="scaleToFill"></image> <image class="img" :src="item.avatar" mode="scaleToFill"></image>
@ -55,7 +55,7 @@
</view> </view>
<view class="bottom"> <view class="bottom">
<button class="btn" @click="onSubmit">提现</button>
<button class="btn" @click="onSubmit">申请</button>
</view> </view>
</view> </view>
@ -82,10 +82,10 @@
// todo // todo
mixinsListApi: '', mixinsListApi: '',
form: { form: {
id: null,
bindId: null,
}, },
rules: { rules: {
'id': {
'bindId': {
type: 'string', type: 'string',
required: true, required: true,
message: '请选择绑定人', message: '请选择绑定人',
@ -99,21 +99,23 @@
this.queryParams.title = this.keyword this.queryParams.title = this.keyword
this.getData() this.getData()
}, },
onSelect(id) {
this.form.id = id
onSelect(bindId) {
this.form.bindId = bindId
}, },
async onSubmit() { async onSubmit() {
try { try {
await this.$refs.form.validate() await this.$refs.form.validate()
const { const {
bindId,
} = this.form } = this.form
const params = { const params = {
bindId,
userId: this.userInfo.id,
} }
// todo: fetch
// await this.$fetch('updateAddress', params)
await this.$fetch('addBind', params)
uni.showToast({ uni.showToast({
icon: 'success', icon: 'success',


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

@ -11,7 +11,7 @@
</view> </view>
<view class="row"> <view class="row">
<view class="row-label">申请人ID</view> <view class="row-label">申请人ID</view>
<view class="row-content">{{ data.userId }}</view>
<view class="row-content">{{ data.bindId }}</view>
</view> </view>
</view> </view>
</view> </view>


+ 9
- 54
pages_order/member/memberList.vue View File

@ -8,7 +8,7 @@
<view class="tabs"> <view class="tabs">
<uv-tabs <uv-tabs
:list="tabs" :list="tabs"
:current="current"
:current="queryParams.status"
:scrollable="false" :scrollable="false"
lineColor="#00A9FF" lineColor="#00A9FF"
lineWidth="48rpx" lineWidth="48rpx"
@ -32,7 +32,7 @@
</view> </view>
<view class="list"> <view class="list">
<template v-if="current == 0">
<template v-if="queryParams.status == 0">
<view class="list-item" v-for="item in list" :key="item.id"> <view class="list-item" v-for="item in list" :key="item.id">
<memberApplyCard :data="item" @submitted="getData"></memberApplyCard> <memberApplyCard :data="item" @submitted="getData"></memberApplyCard>
</view> </view>
@ -68,9 +68,12 @@
{ name: '绑定申请' }, { name: '绑定申请' },
{ name: '已绑定' }, { name: '已绑定' },
], ],
// todo
mixinsListApi: '',
current: 0,
queryParams: {
pageNo: 1,
pageSize: 10,
status: 0, // (status)0- 1- 2-
},
mixinsListApi: 'queryBindList',
} }
}, },
onShow() { onShow() {
@ -80,57 +83,9 @@
this.clickTabs({ index: arg.index || 0 }) this.clickTabs({ index: arg.index || 0 })
}, },
methods: { methods: {
// todo: delete
getData() {
this.list = [
{
id: '001',
name: '周小艺',
userId: '15558661691',
type: 0,
createTime: '2025-04-28 08:14',
},
{
id: '002',
name: '周小艺',
userId: '15558661691',
type: 0,
createTime: '2025-04-28 08:14',
},
{
id: '003',
name: '周小艺',
userId: '15558661691',
type: 1,
createTime: '2025-04-28 08:14',
},
{
id: '004',
name: '周小艺',
userId: '15558661691',
type: 0,
createTime: '2025-04-28 08:14',
},
{
id: '005',
name: '周小艺',
userId: '15558661691',
type: 0,
createTime: '2025-04-28 08:14',
},
]
},
//tab //tab
clickTabs({ index }) { clickTabs({ index }) {
console.log('clickTabs')
this.current = index
if (index == 0) {
delete this.queryParams.status
} else {
this.queryParams.status = index - 1
}
this.queryParams.status = index
this.getData() this.getData()
}, },
}, },


+ 3
- 43
pages_order/member/switch.vue View File

@ -11,7 +11,6 @@
size="36rpx" size="36rpx"
iconSize="36rpx" iconSize="36rpx"
activeColor="#00A9FF" activeColor="#00A9FF"
@change="onRadioChange"
> >
<view class="list-item" v-for="item in list" :key="item.id"> <view class="list-item" v-for="item in list" :key="item.id">
<memberCard <memberCard
@ -40,12 +39,12 @@
}, },
data() { data() {
return { return {
// todo: check key
mixinsListApi: '',
queryParams: { queryParams: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
status: 1, // (status)0- 1- 2-
}, },
mixinsListApi: 'queryBindList',
selectedId: null, selectedId: null,
} }
}, },
@ -54,7 +53,7 @@
}, },
onLoad(arg) { onLoad(arg) {
if (this.memberInfo?.id) { if (this.memberInfo?.id) {
this.memberInfo = this.memberInfo.id
this.selectedId = this.memberInfo.id
} }
this.getData() this.getData()
@ -69,49 +68,10 @@
this.$store.commit('setMemberInfo', target) this.$store.commit('setMemberInfo', target)
}, },
methods: { methods: {
// todo: delete
getData() {
this.list = [
{
id: '001',
name: '周小艺',
userId: '15558661691',
type: 0,
},
{
id: '002',
name: '周小艺',
userId: '15558661691',
type: 0,
},
{
id: '003',
name: '周小艺',
userId: '15558661691',
type: 1,
},
{
id: '004',
name: '周小艺',
userId: '15558661691',
type: 0,
},
{
id: '005',
name: '周小艺',
userId: '15558661691',
type: 0,
},
]
},
onSelect(id) { onSelect(id) {
console.log('onSelect', id) console.log('onSelect', id)
this.selectedId = id this.selectedId = id
}, },
onRadioChange(e) {
console.log('onRadioChange', e)
},
}, },
} }
</script> </script>


+ 28
- 22
pages_order/order/orderConfirm/infoPopup.vue View File

@ -19,28 +19,24 @@
<image class="img" src="@/static/image/icon-arrow-right.png" mode="widthFix"></image> <image class="img" src="@/static/image/icon-arrow-right.png" mode="widthFix"></image>
</button> </button>
</view> </view>
<timeCalendarSelect ref="timeCalendarSelect" v-model="form.time" :options="data.timeOptions"></timeCalendarSelect>
<timeCalendarSelect ref="timeCalendarSelect" v-model="form.time" :options="data.dateList"></timeCalendarSelect>
<view class="flex section-content"> <view class="flex section-content">
<timeOptionsSelect style="width: calc(100vw - 40rpx*2);" <timeOptionsSelect style="width: calc(100vw - 40rpx*2);"
v-model="form.time" v-model="form.time"
:options="data.timeOptions"
:options="data.dateList"
></timeOptionsSelect> ></timeOptionsSelect>
</view> </view>
</uv-form-item> </uv-form-item>
</view> </view>
<view class="section"> <view class="section">
<uv-form-item prop="adults" :customStyle="formItemStyle">
<uv-form-item prop="prices" :customStyle="formItemStyle">
<view class="flex section-header"> <view class="flex section-header">
<view>选择人数</view> <view>选择人数</view>
</view> </view>
<view class="flex section-content"> <view class="flex section-content">
<peopleNumberInput style="width: calc(100vw - 40rpx*2);" <peopleNumberInput style="width: calc(100vw - 40rpx*2);"
:adults.sync="form.adults"
:teenager.sync="form.teenager"
:child.sync="form.child"
:adultsPrice="selectTimeObj.adultsPrice"
:teenagerPrice="selectTimeObj.teenagerPrice"
:childPrice="selectTimeObj.childPrice"
v-model="form.prices"
:options="priceList"
></peopleNumberInput> ></peopleNumberInput>
</view> </view>
</uv-form-item> </uv-form-item>
@ -77,6 +73,12 @@
import timeCalendarSelect from '@/pages_order/order/orderConfirm/timeCalendarSelect.vue' import timeCalendarSelect from '@/pages_order/order/orderConfirm/timeCalendarSelect.vue'
import peopleNumberInput from '@/pages_order/order/orderConfirm/peopleNumberInput.vue' import peopleNumberInput from '@/pages_order/order/orderConfirm/peopleNumberInput.vue'
const TYPE_INDEX_MAPPING = {
'成人': 0,
'青少年': 1,
'儿童': 2,
}
export default { export default {
components: { components: {
timeOptionsSelect, timeOptionsSelect,
@ -96,25 +98,29 @@
options: [], options: [],
form: { form: {
time: null, time: null,
adults: 0,
teenager: 0,
child: 0,
prices: [],
members: [], members: [],
}, },
formItemStyle: { padding: 0 }, formItemStyle: { padding: 0 },
} }
}, },
computed : { computed : {
...mapState(['configList', 'travelerList']),
selectTimeObj() {
...mapState(['configList', 'userInfo', 'travelerList']),
priceList() {
const { time: id } = this.form const { time: id } = this.form
const { timeOptions } = this.data
const { dateList } = this.data
let priceList = dateList?.[0]?.priceList || []
if (id) { if (id) {
return timeOptions?.find?.(option => option.id === id) || {}
priceList = dateList?.find?.(option => option.id === id)?.priceList || []
} }
return timeOptions?.[0] || {}
priceList.sort((a, b) => {
return TYPE_INDEX_MAPPING[a.period_dictText] - TYPE_INDEX_MAPPING[b.period_dictText]
})
return priceList
}, },
}, },
watch: { watch: {
@ -144,13 +150,12 @@
required: true, required: true,
message: '请选择团期', message: '请选择团期',
}, },
'adults': {
type: 'number',
required: true,
'prices': {
type: 'array',
message: '请选择人数', message: '请选择人数',
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
if (adults || teenager || child) {
if (value.some(num => num > 0)) {
return true return true
} }
@ -169,7 +174,8 @@
}, },
async getDefaultMembers() { async getDefaultMembers() {
try { try {
return (await this.$fetch('queryTouristList', { isDefault: '1' })).records
// todo: check params
return (await this.$fetch('queryTouristList', { pageNo: 1, pageSize: 1000, userId: this.userInfo.id, isDefault: '1' })).records
} catch (err) { } catch (err) {
return [] return []
} }


+ 34
- 96
pages_order/order/orderConfirm/peopleNumberInput.vue View File

@ -1,69 +1,19 @@
<template> <template>
<view class="input__view" :style="style"> <view class="input__view" :style="style">
<view class="flex row">
<view class="flex row" v-for="(item, index) in options" :key="item.id">
<view class="flex row-label"> <view class="flex row-label">
<view class="title">成人</view>
<view class="desc">(18周岁以上)</view>
<view class="title">{{ item.period_dictText }}</view>
<!-- todo: check key -->
<view class="desc" v-if="getTypeDesc(item.period_dictText)">{{ `(${getTypeDesc(item.period_dictText)})` }}</view>
<view class="flex price"> <view class="flex price">
<text>¥</text> <text>¥</text>
<text class="highlight">{{ adultsPrice }}</text>
<text class="highlight">{{ item.price }}</text>
</view> </view>
</view> </view>
<view class="row-content"> <view class="row-content">
<uv-number-box <uv-number-box
v-model="adultsNum"
:min="0"
:integer="true"
:inputWidth="68"
bgColor="transparent"
:iconStyle="{
background: '#F7F8FA',
fontSize: '13px',
lineHeight: 1,
padding: '12px',
borderRadius: '50%',
}"
></uv-number-box>
</view>
</view>
<view class="flex row">
<view class="flex row-label">
<view class="title">青少年</view>
<view class="desc">(14周岁以上)</view>
<view class="flex price">
<text>¥</text>
<text class="highlight">{{ teenagerPrice }}</text>
</view>
</view>
<view class="row-content">
<uv-number-box
v-model="teenagerNum"
:min="0"
:integer="true"
:inputWidth="68"
bgColor="transparent"
:iconStyle="{
background: '#F7F8FA',
fontSize: '13px',
lineHeight: 1,
padding: '12px',
borderRadius: '50%',
}"
></uv-number-box>
</view>
</view>
<view class="flex row">
<view class="flex row-label">
<view class="title">儿童</view>
<view class="desc">(14周岁以下)</view>
<view class="flex price">
<text>¥</text>
<text class="highlight">{{ childPrice }}</text>
</view>
</view>
<view class="row-content">
<uv-number-box
v-model="childNum"
:value="value[index]"
@input="onInput(index, $event)"
:min="0" :min="0"
:integer="true" :integer="true"
:inputWidth="68" :inputWidth="68"
@ -82,31 +32,25 @@
</template> </template>
<script> <script>
const TYPE_DESC = {
'成人': '(18周岁以上)',
'青少年': '(14周岁以上)',
'儿童': '(14周岁以下)',
}
export default { export default {
props: { props: {
adults: {
type: Number,
default: 0,
},
teenager: {
type: Number,
default: 0,
},
child: {
type: Number,
default: 0,
},
adultsPrice: {
type: Number,
default: 0,
},
teenagerPrice: {
type: Number,
default: 0,
value: {
type: Array,
default() {
return []
}
}, },
childPrice: {
type: Number,
default: 0,
options: {
type: Array,
default() {
return []
}
}, },
style: { style: {
type: String, type: String,
@ -114,29 +58,23 @@
}, },
}, },
computed: { computed: {
adultsNum: {
prices: {
set(val) { set(val) {
this.$emit('update:adults', val)
this.$emit('input', val)
}, },
get() { get() {
return this.adults
return this.value
} }
}, },
teenagerNum: {
set(val) {
this.$emit('update:teenager', val)
},
get() {
return this.teenager
}
},
methods: {
onInput(index, value) {
let prices = [...this.prices]
prices[index] = value
this.prices = prices
}, },
childNum: {
set(val) {
this.$emit('update:child', val)
},
get() {
return this.child
}
getTypeDesc(type) {
return TYPE_DESC[type]
}, },
}, },
} }


+ 2
- 3
pages_order/order/orderConfirm/timeOptionsSelect.vue View File

@ -8,9 +8,9 @@
> >
<view class="option-item-content"> <view class="option-item-content">
<view class="flex time"> <view class="flex time">
<view class="time-val">{{ item.startDate }}</view>
<view class="time-val">{{ $dayjs(item.startDate).format('MM/DD') }}</view>
<view class="time-split">-</view> <view class="time-split">-</view>
<view class="time-val">{{ item.endDate }}</view>
<view class="time-val">{{ $dayjs(item.endDate).format('MM/DD') }}</view>
</view> </view>
<view class="flex price"> <view class="flex price">
<view class="price-val"> <view class="price-val">
@ -126,7 +126,6 @@
.price { .price {
margin-top: 4rpx; margin-top: 4rpx;
justify-content: flex-start;
align-items: baseline; align-items: baseline;
column-gap: 8rpx; column-gap: 8rpx;
white-space: nowrap; white-space: nowrap;


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

@ -239,8 +239,8 @@
uni.stopPullDownRefresh() uni.stopPullDownRefresh()
}, },
onComment(id) {
this.$refs.commentPopup.open(id)
onComment() {
this.$refs.commentPopup.open(this.id, this.detail)
}, },
onApplyService() { onApplyService() {
// todo // todo


+ 4
- 5
pages_order/order/orderList/index.vue View File

@ -35,7 +35,7 @@
<view class="card" v-for="item in list" :key="item.id"> <view class="card" v-for="item in list" :key="item.id">
<orderCard <orderCard
:data="item" :data="item"
@comment="onComment(item.id)"
@comment="onComment(item.id, item)"
@applyService="onApplyService" @applyService="onApplyService"
@contatcMentor="onContactMentor" @contatcMentor="onContactMentor"
@statusChange="getData" @statusChange="getData"
@ -76,8 +76,7 @@
{ name: '待收货' }, { name: '待收货' },
{ name: '待评价' }, { name: '待评价' },
], ],
// todo
mixinsListApi: '',
mixinsListApi: 'queryOrderList',
current: 0, current: 0,
} }
}, },
@ -100,8 +99,8 @@
} }
this.getData() this.getData()
}, },
onComment(id) {
this.$refs.commentPopup.open(id)
onComment(id, detail) {
this.$refs.commentPopup.open(id, detail)
}, },
onApplyService(obj) { onApplyService(obj) {
// todo // todo


+ 3
- 3
pages_order/partner/apply.vue View File

@ -47,10 +47,10 @@
</uv-form-item> </uv-form-item>
</view> </view>
<view class="form-item"> <view class="form-item">
<uv-form-item prop="recommend" :customStyle="formItemStyle">
<uv-form-item prop="inviteId" :customStyle="formItemStyle">
<view class="form-item-label">推荐人</view> <view class="form-item-label">推荐人</view>
<view class="form-item-content"> <view class="form-item-content">
<formInput v-model="form.recommend"></formInput>
<formInput v-model="form.inviteId"></formInput>
</view> </view>
</uv-form-item> </uv-form-item>
</view> </view>
@ -78,7 +78,7 @@
form: { form: {
name: null, name: null,
phone: null, phone: null,
recommend: null,
inviteId: null,
}, },
rules: { rules: {
'name': { 'name': {


+ 5
- 97
pages_order/partner/team.vue View File

@ -57,11 +57,14 @@
{ name: '直推用户列表' }, { name: '直推用户列表' },
{ name: '间推用户列表' }, { name: '间推用户列表' },
], ],
// todo
mixinsListApi: '',
current: 0, current: 0,
} }
}, },
computed: {
mixinsListApi() {
return this.current == 0 ? 'queryDirectList' : 'queryIndirectList'
}
},
onShow() { onShow() {
console.log('onShow') console.log('onShow')
}, },
@ -69,105 +72,10 @@
this.clickTabs({ index: arg.index || 0 }) this.clickTabs({ index: arg.index || 0 })
}, },
methods: { methods: {
// todo: delete
getData() {
this.list = [
{
id: '001',
avatar: '/pages_order/static/temp-30.png',
name: '李世海',
price: 10,
createTime: '2025-07-15',
},
{
id: '002',
avatar: '/pages_order/static/temp-30.png',
name: '周静',
price: 10,
createTime: '2025-07-15',
},
{
id: '003',
avatar: '/pages_order/static/temp-30.png',
name: '周海',
price: 10,
createTime: '2025-07-15',
},
{
id: '004',
avatar: '/pages_order/static/temp-30.png',
name: '冯启彬',
price: 10,
createTime: '2025-07-15',
},
{
id: '005',
avatar: '/pages_order/static/temp-30.png',
name: '李娉',
price: 10,
createTime: '2025-07-15',
},
{
id: '006',
avatar: '/pages_order/static/temp-30.png',
name: '李书萍',
price: 10,
createTime: '2025-07-15',
},
{
id: '007',
avatar: '/pages_order/static/temp-30.png',
name: '李世海',
price: 10,
createTime: '2025-07-15',
},
{
id: '008',
avatar: '/pages_order/static/temp-30.png',
name: '周静',
price: 10,
createTime: '2025-07-15',
},
{
id: '009',
avatar: '/pages_order/static/temp-30.png',
name: '周海',
price: 10,
createTime: '2025-07-15',
},
{
id: '010',
avatar: '/pages_order/static/temp-30.png',
name: '冯启彬',
price: 10,
createTime: '2025-07-15',
},
{
id: '011',
avatar: '/pages_order/static/temp-30.png',
name: '李娉',
price: 10,
createTime: '2025-07-15',
},
{
id: '012',
avatar: '/pages_order/static/temp-30.png',
name: '李书萍',
price: 10,
createTime: '2025-07-15',
},
]
},
//tab //tab
clickTabs({ index }) { clickTabs({ index }) {
console.log('clickTabs') console.log('clickTabs')
this.current = index this.current = index
if (index == 0) {
delete this.queryParams.status
} else {
this.queryParams.status = index - 1
}
this.getData() this.getData()
}, },
}, },


+ 13
- 10
pages_order/partner/withdraw.vue View File

@ -16,18 +16,18 @@
errorType="toast" errorType="toast"
> >
<view class="form-item"> <view class="form-item">
<uv-form-item prop="name" :customStyle="formItemStyle">
<uv-form-item prop="userName" :customStyle="formItemStyle">
<view class="form-item-label">真实姓名</view> <view class="form-item-label">真实姓名</view>
<view class="form-item-content"> <view class="form-item-content">
<formInput v-model="form.name"></formInput>
<formInput v-model="form.userName"></formInput>
</view> </view>
</uv-form-item> </uv-form-item>
</view> </view>
<view class="form-item"> <view class="form-item">
<uv-form-item prop="amount" :customStyle="formItemStyle">
<uv-form-item prop="transferAmount" :customStyle="formItemStyle">
<view class="form-item-label">提现金额</view> <view class="form-item-label">提现金额</view>
<view class="form-item-content"> <view class="form-item-content">
<formInput v-model="form.amount"></formInput>
<formInput v-model="form.transferAmount"></formInput>
</view> </view>
</uv-form-item> </uv-form-item>
</view> </view>
@ -64,16 +64,16 @@
data() { data() {
return { return {
form: { form: {
name: null,
amount: null,
userName: null,
transferAmount: null,
}, },
rules: { rules: {
'name': {
'userName': {
type: 'string', type: 'string',
required: true, required: true,
message: '请输入真实姓名', message: '请输入真实姓名',
}, },
'amount': {
'transferAmount': {
type: 'string', type: 'string',
required: true, required: true,
message: '请输入提现金额', message: '请输入提现金额',
@ -88,13 +88,16 @@
await this.$refs.form.validate() await this.$refs.form.validate()
const { const {
userName,
transferAmount,
} = this.form } = this.form
const params = { const params = {
userName,
transferAmount,
} }
// todo: fetch
// await this.$fetch('updateAddress', params)
await this.$fetch('cashout', params)
uni.showToast({ uni.showToast({
icon: 'success', icon: 'success',


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

@ -44,8 +44,7 @@
<view class="card"> <view class="card">
<view class="card-header">选择团期</view> <view class="card-header">选择团期</view>
<view class="card-content"> <view class="card-content">
<!-- todo: check key -->
<timeOptionsSelect v-model="selectTime" :options="detail.timeOptions"></timeOptionsSelect>
<timeOptionsSelect v-model="selectTime" :options="detail.dateList"></timeOptionsSelect>
</view> </view>
</view> </view>


+ 1
- 1
pages_order/traveler/travelerList.vue View File

@ -50,7 +50,7 @@
}, },
onLoad(arg) { onLoad(arg) {
const { selectIds } = arg const { selectIds } = arg
this.selectedIdList = selectIds?.split?.(',') || []
this.selectedIdList = selectIds?.split?.(',')?.filter(val => val) || []
this.getData() this.getData()
}, },


+ 23
- 3
store/store.js View File

@ -16,6 +16,7 @@ const store = new Vuex.Store({
orderInfo: null, orderInfo: null,
couponInfo: null, couponInfo: null,
memberInfo: null, memberInfo: null,
liveInfo: null,
}, },
getters: { getters: {
// 角色 true为水洗店 false为酒店 : 身份判断如果不需要,可以删除 // 角色 true为水洗店 false为酒店 : 身份判断如果不需要,可以删除
@ -25,7 +26,24 @@ const store = new Vuex.Store({
}, },
mutations: { mutations: {
// 初始化配置 // 初始化配置
initConfig(state){
async initConfig(state) {
const records = (await fetch('getConfig'))?.records
const configList = {
...state.configList,
}
records.forEach(n => {
configList[n.paramCode] = n.paramImage || n.paramText || n.paramTextarea;
});
state.configList = configList
// todo: fetch
// fetch('queryConfigByParamCode', { paramCode: 'studytour_period' })
uni.$emit('initConfig', state.configList)
return
api('getConfig', res => { api('getConfig', res => {
const configList = { const configList = {
...state.configList, ...state.configList,
@ -86,8 +104,6 @@ const store = new Vuex.Store({
}, },
// 获取用户个人信息 // 获取用户个人信息
getUserInfo(state){ getUserInfo(state){
// todo delete
return
api('getInfo', res => { api('getInfo', res => {
if(res.code == 200){ if(res.code == 200){
state.userInfo = res.result state.userInfo = res.result
@ -122,6 +138,10 @@ const store = new Vuex.Store({
setMemberInfo(state, data) { setMemberInfo(state, data) {
state.memberInfo = data state.memberInfo = data
}, },
setLiveInfo(state, data) {
console.log('liveInfo', data)
state.liveInfo = data
},
}, },
actions: { actions: {
async collect(state, activityId) { async collect(state, activityId) {


Loading…
Cancel
Save