Branch_csl #1

Merged
root merged 5 commits from Branch_csl into master 2024-09-18 17:11:27 +08:00
161 changed files with 6068 additions and 5145 deletions

View File

@ -184,7 +184,7 @@
"versionCode": 100
},
"mp-weixin": {
"appid": "wx63c280fe3248a3e7",
"appid": "wxa66f2777a5656baf",
"setting": {
"urlCheck": false,
"minified": true,

View File

@ -82,6 +82,15 @@
"title": "自定义页面",
"group": "商城"
}
},
{
"path" : "pages/mulu/mulu",
"style" :
{
"navigationBarTitleText" : "详情",
"enablePullDownRefresh" : true,
"navigationStyle": "default"
}
}
],
"subPackages": [{

View File

@ -1,6 +1,11 @@
<!-- 拼团订单的详情 -->
<template>
<s-layout title="拼团详情" class="detail-wrap" :navbar="state.data && !state.loading ? 'inner': 'normal'" :onShareAppMessage="shareInfo">
<s-layout
title="拼团详情"
class="detail-wrap"
:navbar="state.data && !state.loading ? 'inner' : 'normal'"
:onShareAppMessage="shareInfo"
>
<view v-if="state.loading"></view>
<view v-if="state.data && !state.loading">
<!-- 团长信息 + 活动信息 -->
@ -22,7 +27,7 @@
priceColor="#E1212B"
@tap="
sheep.$router.go('/pages/goods/groupon', {
id: state.data.headRecord.activityId
id: state.data.headRecord.activityId,
})
"
:style="[{ top: Number(statusBarHeight + 108) + 'rpx' }]"
@ -71,7 +76,9 @@
</view>
<view class="countdown-title ss-flex" v-else>
还差
<view class="num">{{ state.data.headRecord.userSize - state.data.headRecord.userCount }}</view>
<view class="num"
>{{ state.data.headRecord.userSize - state.data.headRecord.userCount }}</view
>
拼团成功
<view class="ss-flex countdown-time">
<view class="countdown-h ss-flex ss-row-center">{{ endTime.h }}</view>
@ -109,7 +116,11 @@
</view>
</view>
<!-- 还有几个坑位 -->
<view class="default-avatar ss-m-r-24 ss-m-b-20" v-for="item in state.remainNumber" :key="item">
<view
class="default-avatar ss-m-r-24 ss-m-b-20"
v-for="item in state.remainNumber"
:key="item"
>
<image
:src="sheep.$url.static('/static/img/shop/avatar/unknown.png')"
class="avatar-img"
@ -154,11 +165,7 @@
</view>
<view v-else class="ss-flex ss-row-center">
<view v-if="state.data.orderId">
<button
class="ss-reset-button join-btn"
:disabled="endTime.ms <= 0"
@tap="onShare"
>
<button class="ss-reset-button join-btn" :disabled="endTime.ms <= 0" @tap="onShare">
邀请好友来拼团
</button>
</view>
@ -199,7 +206,7 @@
import { useDurationTime } from '@/sheep/hooks/useGoods';
import { showShareModal } from '@/sheep/hooks/useModal';
import { isEmpty } from 'lodash';
import CombinationApi from "@/sheep/api/promotion/combination";
import CombinationApi from '@/sheep/api/promotion/combination';
const headerBg = sheep.$url.css('/static/img/shop/user/withdraw_bg.png');
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
@ -295,7 +302,9 @@
state.remainNumber = remainNumber > 0 ? remainNumber : 0;
//
const { data: activity } = await CombinationApi.getCombinationActivity(data.headRecord.activityId);
const { data: activity } = await CombinationApi.getCombinationActivity(
data.headRecord.activityId,
);
state.activity = activity;
} else {
state.data = null;
@ -316,8 +325,7 @@
.recharge-box {
position: relative;
margin-bottom: 120rpx;
background: v-bind(headerBg) center/750rpx 100%
no-repeat,
background: v-bind(headerBg) center/750rpx 100% no-repeat,
linear-gradient(115deg, #f44739 0%, #ff6600 100%);
border-radius: 0 0 5% 5%;
height: 100rpx;

View File

@ -68,7 +68,7 @@
import { onLoad, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app';
import sheep from '@/sheep';
import _ from 'lodash';
import {formatOrderColor} from "@/sheep/hooks/useGoods";
import { formatOrderColor } from '@/sheep/hooks/useGoods';
import { resetPagination } from '@/sheep/util';
import CombinationApi from '@/sheep/api/promotion/combination';
@ -121,7 +121,7 @@
if (code !== 0) {
return;
}
state.pagination.list = _.concat(state.pagination.list, data.list)
state.pagination.list = _.concat(state.pagination.list, data.list);
state.pagination.total = data.total;
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
}

View File

@ -118,7 +118,7 @@
const { code, data } = await SpuApi.getSpuPage({
pageNo: state.pagination.pageNo,
pageSize: state.pagination.pageSize,
...params
...params,
});
if (code !== 0) {
return;

View File

@ -8,8 +8,15 @@
></view>
<!-- 时间段轮播图 -->
<view class="header" v-if="activeTimeConfig?.sliderPicUrls?.length > 0">
<swiper indicator-dots="true" autoplay="true" :circular="true" interval="3000" duration="1500"
indicator-color="rgba(255,255,255,0.6)" indicator-active-color="#fff">
<swiper
indicator-dots="true"
autoplay="true"
:circular="true"
interval="3000"
duration="1500"
indicator-color="rgba(255,255,255,0.6)"
indicator-active-color="#fff"
>
<block v-for="(picUrl, index) in activeTimeConfig.sliderPicUrls" :key="index">
<swiper-item class="borRadius14">
<image :src="picUrl" class="slide-image borRadius14" lazy-load />
@ -22,13 +29,24 @@
<!-- 左侧图标 -->
<view class="time-icon">
<!-- TODO 芋艿图片统一维护 -->
<image class="ss-w-100 ss-h-100" src="http://mall.yudao.iocoder.cn/static/images/priceTag.png" />
<image
class="ss-w-100 ss-h-100"
src="http://mall.yudao.iocoder.cn/static/images/priceTag.png"
/>
</view>
<scroll-view class="time-list" :scroll-into-view="activeTimeElId" scroll-x scroll-with-animation>
<view v-for="(config, index) in timeConfigList" :key="index"
<scroll-view
class="time-list"
:scroll-into-view="activeTimeElId"
scroll-x
scroll-with-animation
>
<view
v-for="(config, index) in timeConfigList"
:key="index"
:class="['item', { active: activeTimeIndex === index }]"
:id="`timeItem${index}`"
@tap="handleChangeTimeConfig(index)">
@tap="handleChangeTimeConfig(index)"
>
<!-- 活动起始时间 -->
<view class="time">{{ config.startTime }}</view>
<!-- 活动状态 -->
@ -42,7 +60,10 @@
<!-- 活动倒计时 -->
<view class="content-header ss-flex-col ss-col-center ss-row-center">
<view class="content-header-box ss-flex ss-row-center">
<view class="countdown-box ss-flex" v-if="activeTimeConfig?.status === TimeStatusEnum.STARTED">
<view
class="countdown-box ss-flex"
v-if="activeTimeConfig?.status === TimeStatusEnum.STARTED"
>
<view class="countdown-title ss-m-r-12">距结束</view>
<view class="ss-flex countdown-time">
<view class="ss-flex countdown-h">{{ countDown.h }}</view>
@ -74,12 +95,20 @@
>
<!-- 抢购进度 -->
<template #activity>
<view class="limit">限量 <text class="ss-m-l-5">{{ activity.stock}} {{activity.unitName}}</text></view>
<view class="limit"
>限量
<text class="ss-m-l-5">{{ activity.stock }} {{ activity.unitName }}</text></view
>
<su-progress :percentage="activity.percent" strokeWidth="10" textInside isAnimate />
</template>
<!-- 抢购按钮 -->
<template #cart>
<button :class="['ss-reset-button cart-btn', { disabled: activeTimeConfig.status === TimeStatusEnum.END }]">
<button
:class="[
'ss-reset-button cart-btn',
{ disabled: activeTimeConfig.status === TimeStatusEnum.END },
]"
>
<span v-if="activeTimeConfig?.status === TimeStatusEnum.WAIT_START">未开始</span>
<span v-else-if="activeTimeConfig?.status === TimeStatusEnum.STARTED">马上抢</span>
<span v-else>已结束</span>
@ -104,14 +133,15 @@
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import sheep from '@/sheep';
import { useDurationTime } from '@/sheep/hooks/useGoods';
import SeckillApi from "@/sheep/api/promotion/seckill";
import dayjs from "dayjs";
import {TimeStatusEnum} from "@/sheep/util/const";
import SeckillApi from '@/sheep/api/promotion/seckill';
import dayjs from 'dayjs';
import { TimeStatusEnum } from '@/sheep/util/const';
//
const { safeAreaInsets, safeArea } = sheep.$platform.device;
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
const pageHeight = (safeArea.height + safeAreaInsets.bottom) * 2 + statusBarHeight - sheep.$platform.navbar - 350;
const pageHeight =
(safeArea.height + safeAreaInsets.bottom) * 2 + statusBarHeight - sheep.$platform.navbar - 350;
const headerBg = sheep.$url.css('/static/img/shop/goods/seckill-header.png');
//
@ -124,16 +154,16 @@
//#region
//
const timeConfigList = ref([])
const timeConfigList = ref([]);
//
const getSeckillConfigList = async () => {
const { data } = await SeckillApi.getSeckillConfigList()
const { data } = await SeckillApi.getSeckillConfigList();
const now = dayjs();
const today = now.format('YYYY-MM-DD')
const today = now.format('YYYY-MM-DD');
//
data.forEach((config, index) => {
const startTime = dayjs(`${today} ${config.startTime}`)
const endTime = dayjs(`${today} ${config.endTime}`)
const startTime = dayjs(`${today} ${config.startTime}`);
const endTime = dayjs(`${today} ${config.endTime}`);
if (now.isBefore(startTime)) {
config.status = TimeStatusEnum.WAIT_START;
} else if (now.isAfter(endTime)) {
@ -142,35 +172,35 @@
config.status = TimeStatusEnum.STARTED;
activeTimeIndex.value = index;
}
})
timeConfigList.value = data
});
timeConfigList.value = data;
//
handleChangeTimeConfig(activeTimeIndex.value);
//
scrollToTimeConfig(activeTimeIndex.value)
}
scrollToTimeConfig(activeTimeIndex.value);
};
//
const activeTimeElId = ref('') // ID
const activeTimeElId = ref(''); // ID
const scrollToTimeConfig = (index) => {
nextTick(() => activeTimeElId.value = `timeItem${index}`)
}
nextTick(() => (activeTimeElId.value = `timeItem${index}`));
};
//
const activeTimeIndex = ref(0) //
const activeTimeConfig = computed(() => timeConfigList.value[activeTimeIndex.value]) //
const activeTimeIndex = ref(0); //
const activeTimeConfig = computed(() => timeConfigList.value[activeTimeIndex.value]); //
const handleChangeTimeConfig = (index) => {
activeTimeIndex.value = index
activeTimeIndex.value = index;
//
activityPageParams.pageNo = 1
activityList.value = []
activityPageParams.pageNo = 1;
activityList.value = [];
getActivityList();
}
};
//
const countDown = computed(() => {
const endTime = activeTimeConfig.value?.endTime
const endTime = activeTimeConfig.value?.endTime;
if (endTime) {
return useDurationTime(`${dayjs().format('YYYY-MM-DD')} ${endTime}`);
}
@ -185,17 +215,19 @@
id: 0, // ID
pageNo: 1, //
pageSize: 5, //
})
const activityTotal = ref(0) //
const activityList = ref([]) //
const loadStatus = ref('') //
});
const activityTotal = ref(0); //
const activityList = ref([]); //
const loadStatus = ref(''); //
async function getActivityList() {
loadStatus.value = 'loading';
const { data } = await SeckillApi.getSeckillActivityPage(activityPageParams)
data.list.forEach(activity => {
const { data } = await SeckillApi.getSeckillActivityPage(activityPageParams);
data.list.forEach((activity) => {
//
activity.percent = parseInt(100 * (activity.totalStock - activity.stock) / activity.totalStock);
})
activity.percent = parseInt(
(100 * (activity.totalStock - activity.stock)) / activity.totalStock,
);
});
activityList.value = activityList.value.concat(...data.list);
activityTotal.value = data.total;
@ -205,7 +237,7 @@
//
function loadMore() {
if (loadStatus.value !== 'noMore') {
activityPageParams.pageNo += 1
activityPageParams.pageNo += 1;
getActivityList();
}
}
@ -216,7 +248,7 @@
//
onLoad(async () => {
await getSeckillConfigList()
await getSeckillConfigList();
});
</script>
<style lang="scss" scoped>

View File

@ -10,7 +10,6 @@
</template>
<script setup>
const props = defineProps({
goodsData: {
type: Object,
@ -18,4 +17,3 @@
},
});
</script>

View File

@ -16,9 +16,7 @@
:class="{ 'is-active': toolsMode === 'tools' }"
@tap.stop="onTools('tools')"
></text>
<button v-if="message" class="ss-reset-button send-btn" @tap="sendMessage">
发送
</button>
<button v-if="message" class="ss-reset-button send-btn" @tap="sendMessage"> 发送 </button>
</view>
</template>
@ -46,10 +44,9 @@
},
set(newValue) {
emits(`update:modelValue`, newValue);
}
},
});
//
function onTools(mode) {
emits('onTools', mode);

View File

@ -1,10 +1,21 @@
<template>
<!-- 聊天虚拟列表 -->
<z-paging ref="pagingRef" v-model="messageList" use-chat-record-mode use-virtual-list
cell-height-mode="dynamic" default-page-size="20" :auto-clean-list-when-reload="false"
safe-area-inset-bottom bottom-bg-color="#f8f8f8" :back-to-top-style="backToTopStyle"
:auto-show-back-to-top="showNewMessageTip" @backToTopClick="onBackToTopClick"
@scrolltoupper="onScrollToUpper" @query="queryList">
<z-paging
ref="pagingRef"
v-model="messageList"
use-chat-record-mode
use-virtual-list
cell-height-mode="dynamic"
default-page-size="20"
:auto-clean-list-when-reload="false"
safe-area-inset-bottom
bottom-bg-color="#f8f8f8"
:back-to-top-style="backToTopStyle"
:auto-show-back-to-top="showNewMessageTip"
@backToTopClick="onBackToTopClick"
@scrolltoupper="onScrollToUpper"
@query="queryList"
>
<template #top>
<!-- 撑一下顶部导航 -->
<view style="height: 45px"></view>
@ -14,7 +25,11 @@
<template #cell="{ item, index }">
<view style="transform: scaleY(-1)">
<!-- 消息渲染 -->
<MessageListItem :message="item" :message-index="index" :message-list="messageList"></MessageListItem>
<MessageListItem
:message="item"
:message-index="index"
:message-list="messageList"
></MessageListItem>
</view>
</template>
<!-- 底部聊天输入框 -->
@ -37,13 +52,13 @@
const messageList = ref([]); //
const showNewMessageTip = ref(false); //
const backToTopStyle = reactive({
'width': '100px',
width: '100px',
'background-color': '#fff',
'border-radius': '30px',
'box-shadow': '0 2px 4px rgba(0, 0, 0, 0.1)',
'display': 'flex',
'justifyContent': 'center',
'alignItems': 'center',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}); //
const queryParams = reactive({
pageNo: 1,

View File

@ -4,12 +4,20 @@
<view class="message-item ss-flex-col scroll-item">
<view class="ss-flex ss-row-center ss-col-center">
<!-- 日期 -->
<view v-if="message.contentType !== KeFuMessageContentTypeEnum.SYSTEM && showTime(message, messageIndex)"
class="date-message">
<view
v-if="
message.contentType !== KeFuMessageContentTypeEnum.SYSTEM &&
showTime(message, messageIndex)
"
class="date-message"
>
{{ formatDate(message.createTime) }}
</view>
<!-- 系统消息 -->
<view v-if="message.contentType === KeFuMessageContentTypeEnum.SYSTEM" class="system-message">
<view
v-if="message.contentType === KeFuMessageContentTypeEnum.SYSTEM"
class="system-message"
>
{{ message.content }}
</view>
</view>
@ -37,13 +45,16 @@
></image>
<!-- 内容 -->
<template v-if="message.contentType === KeFuMessageContentTypeEnum.TEXT">
<view class="message-box" :class="{'admin': message.senderType === UserTypeEnum.ADMIN}">
<view class="message-box" :class="{ admin: message.senderType === UserTypeEnum.ADMIN }">
<mp-html :content="replaceEmoji(message.content)" />
</view>
</template>
<template v-if="message.contentType === KeFuMessageContentTypeEnum.IMAGE">
<view class="message-box" :class="{'admin': message.senderType === UserTypeEnum.ADMIN}"
:style="{ width: '200rpx' }">
<view
class="message-box"
:class="{ admin: message.senderType === UserTypeEnum.ADMIN }"
:style="{ width: '200rpx' }"
>
<su-image
class="message-img"
isPreview
@ -80,8 +91,10 @@
<image
v-if="message.senderType === UserTypeEnum.MEMBER"
class="chat-avatar ss-m-l-24"
:src="sheep.$url.cdn(message.senderAvatar) ||
sheep.$url.static('/static/img/shop/chat/default.png')"
:src="
sheep.$url.cdn(message.senderAvatar) ||
sheep.$url.static('/static/img/shop/chat/default.png')
"
mode="aspectFill"
>
</image>
@ -115,7 +128,7 @@
messageList: {
type: Array,
default: () => [],
}
},
});
const getMessageContent = computed(() => (item) => JSON.parse(item.content)); //

View File

@ -1,6 +1,5 @@
<template>
<view class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20"
:key="orderData.id">
<view class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20" :key="orderData.id">
<view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20">
<view class="order-no">订单号{{ orderData.no }}</view>
<view class="order-state ss-font-26" :class="formatOrderColor(orderData)">
@ -18,10 +17,10 @@
</view>
<view class="pay-box ss-m-t-30 ss-flex ss-row-right ss-p-r-20">
<view class="ss-flex ss-col-center">
<view class="discounts-title pay-color"> {{ orderData.productCount }} 件商品,总金额:</view>
<view class="discounts-money pay-color">
{{ fen2yuan(orderData.payPrice) }}
</view>
<view class="discounts-title pay-color"
> {{ orderData.productCount }} 件商品,总金额:</view
>
<view class="discounts-money pay-color"> {{ fen2yuan(orderData.payPrice) }} </view>
</view>
</view>
</view>
@ -48,7 +47,8 @@
font-weight: 500;
}
.order-state {}
.order-state {
}
}
.pay-box {
.discounts-title {

View File

@ -1,8 +1,5 @@
<template>
<su-popup
:show="showTools"
@close="handleClose"
>
<su-popup :show="showTools" @close="handleClose">
<view class="ss-modal-box ss-flex-col">
<slot></slot>
<view class="content ss-flex ss-flex-1">
@ -20,7 +17,8 @@
<swiper-item v-for="emoji in emojiPage" :key="emoji">
<view class="ss-flex ss-flex-wrap">
<image
v-for="item in emoji" :key="item"
v-for="item in emoji"
:key="item"
class="emoji-img"
:src="sheep.$url.cdn(`/static/img/chat/emoji/${item.file}`)"
@tap="onEmoji(item)"

View File

@ -1,17 +1,35 @@
<template>
<s-layout class="chat-wrap" :title="!isReconnecting ? '连接客服成功' : '会话重连中'" navbar="inner">
<s-layout
class="chat-wrap"
:title="!isReconnecting ? '连接客服成功' : '会话重连中'"
navbar="inner"
>
<!-- 覆盖头部导航栏背景颜色 -->
<div class="page-bg" :style="{ height: sys_navBar + 'px' }"></div>
<!-- 聊天区域 -->
<MessageList ref="messageListRef">
<template #bottom>
<message-input v-model="chat.msg" @on-tools="onTools" @send-message="onSendMessage"></message-input>
<message-input
v-model="chat.msg"
@on-tools="onTools"
@send-message="onSendMessage"
></message-input>
</template>
</MessageList>
<!-- 聊天工具 -->
<tools-popup :show-tools="chat.showTools" :tools-mode="chat.toolsMode" @close="handleToolsClose"
@on-emoji="onEmoji" @image-select="onSelect" @on-show-select="onShowSelect">
<message-input v-model="chat.msg" @on-tools="onTools" @send-message="onSendMessage"></message-input>
<tools-popup
:show-tools="chat.showTools"
:tools-mode="chat.toolsMode"
@close="handleToolsClose"
@on-emoji="onEmoji"
@image-select="onSelect"
@on-show-select="onShowSelect"
>
<message-input
v-model="chat.msg"
@on-tools="onTools"
@send-message="onSendMessage"
></message-input>
</tools-popup>
<!-- 商品订单选择 -->
<SelectPopup
@ -30,7 +48,10 @@
import ToolsPopup from '@/pages/chat/components/toolsPopup.vue';
import MessageInput from '@/pages/chat/components/messageInput.vue';
import SelectPopup from '@/pages/chat/components/select-popup.vue';
import { KeFuMessageContentTypeEnum, WebSocketMessageTypeConstants } from '@/pages/chat/util/constants';
import {
KeFuMessageContentTypeEnum,
WebSocketMessageTypeConstants,
} from '@/pages/chat/util/constants';
import FileApi from '@/sheep/api/infra/file';
import KeFuApi from '@/sheep/api/promotion/kefu';
import { useWebSocket } from '@/sheep/hooks/useWebSocket';
@ -134,8 +155,7 @@
//======================= end =======================
const { options } = useWebSocket({
//
onConnected: async () => {
},
onConnected: async () => {},
//
onMessage: async (data) => {
const type = data.type;
@ -160,7 +180,6 @@
<style scoped lang="scss">
.chat-wrap {
.page-bg {
width: 100%;
position: absolute;

View File

@ -15,5 +15,5 @@ export const UserTypeEnum = {
// Promotion 的 WebSocket 消息类型枚举类
export const WebSocketMessageTypeConstants = {
KEFU_MESSAGE_TYPE: 'kefu_message_type', // 客服消息类型
KEFU_MESSAGE_ADMIN_READ: 'kefu_message_read_status_change' // 客服消息管理员已读
}
KEFU_MESSAGE_ADMIN_READ: 'kefu_message_read_status_change', // 客服消息管理员已读
};

File diff suppressed because one or more lines are too long

View File

@ -63,7 +63,7 @@
onMounted(async () => {
let { code, data } = await BrokerageApi.getBrokerageUserSummary();
if (code === 0) {
state.summary = data || {}
state.summary = data || {};
}
});
</script>

View File

@ -45,7 +45,8 @@
type: Boolean,
default: false,
},
methods: { //
methods: {
//
type: Array,
default: [],
},
@ -89,7 +90,7 @@
}
//
emits('update:modelValue', {
type: state.currentValue
type: state.currentValue,
});
//
emits('close');

View File

@ -25,7 +25,6 @@
const state = reactive({
showMoney: false,
});
</script>
<style lang="scss" scoped>

View File

@ -8,14 +8,26 @@
<text class="cicon-forward" />
</view>
</view>
<scroll-view scroll-y="true" @scrolltolower="loadmore" class="scroll-box log-scroll"
scroll-with-animation="true">
<scroll-view
scroll-y="true"
@scrolltolower="loadmore"
class="scroll-box log-scroll"
scroll-with-animation="true"
>
<view v-if="state.pagination.list">
<view class="log-item-box ss-flex ss-row-between" v-for="item in state.pagination.list" :key="item.id">
<view
class="log-item-box ss-flex ss-row-between"
v-for="item in state.pagination.list"
:key="item.id"
>
<view class="log-item-wrap">
<view class="log-item ss-flex ss-ellipsis-1 ss-col-center">
<view class="ss-flex ss-col-center">
<image class="log-img" :src="sheep.$url.static('/static/img/shop/avatar/notice.png')" mode="aspectFill" />
<image
class="log-img"
:src="sheep.$url.static('/static/img/shop/avatar/notice.png')"
mode="aspectFill"
/>
</view>
<view class="log-text ss-ellipsis-1">
{{ item.title }} {{ fen2yuan(item.price) }}
@ -27,8 +39,12 @@
</view>
<!-- 加载更多 -->
<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" color="#333333"
@tap="loadmore" />
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
color="#333333"
@tap="loadmore"
/>
</scroll-view>
</view>
</template>
@ -55,7 +71,7 @@
state.loadStatus = 'loading';
const { code, data } = await BrokerageApi.getBrokerageRecordPage({
pageNo: state.pagination.pageNo,
pageSize: state.pagination.pageSize
pageSize: state.pagination.pageSize,
});
if (code !== 0) {
return;

View File

@ -9,9 +9,17 @@
</view>
</view>
<view class="menu-list ss-flex ss-flex-wrap">
<view v-for="(item, index) in state.menuList" :key="index" class="item-box ss-flex-col ss-col-center"
@tap="sheep.$router.go(item.path)">
<image class="menu-icon ss-m-b-10" :src="sheep.$url.static(item.img)" mode="aspectFill"></image>
<view
v-for="(item, index) in state.menuList"
:key="index"
class="item-box ss-flex-col ss-col-center"
@tap="sheep.$router.go(item.path)"
>
<image
class="menu-icon ss-m-b-10"
:src="sheep.$url.static(item.img)"
mode="aspectFill"
></image>
<view>{{ item.title }}</view>
</view>
</view>
@ -23,7 +31,8 @@
import { reactive } from 'vue';
const state = reactive({
menuList: [{
menuList: [
{
img: '/static/img/shop/commission/commission_icon1.png',
title: '我的团队',
path: '/pages/commission/team',
@ -65,7 +74,7 @@
// img: '/static/img/shop/commission/commission_icon7.png',
title: '佣金排行',
path: '/pages/commission/commission-ranking',
}
},
],
});
</script>

View File

@ -14,12 +14,18 @@
>
<template #rightBottom>
<view class="ss-flex ss-row-between">
<view class="commission-num" v-if="item.brokerageMinPrice === undefined">预计佣金计算中</view>
<view class="commission-num" v-else-if="item.brokerageMinPrice === item.brokerageMaxPrice">
<view class="commission-num" v-if="item.brokerageMinPrice === undefined"
>预计佣金计算中</view
>
<view
class="commission-num"
v-else-if="item.brokerageMinPrice === item.brokerageMaxPrice"
>
预计佣金{{ fen2yuan(item.brokerageMinPrice) }}
</view>
<view class="commission-num" v-else>
预计佣金{{ fen2yuan(item.brokerageMinPrice) }} ~ {{ fen2yuan(item.brokerageMaxPrice) }}
预计佣金{{ fen2yuan(item.brokerageMinPrice) }} ~
{{ fen2yuan(item.brokerageMaxPrice) }}
</view>
<button
class="ss-reset-button share-btn ui-BG-Main-Gradient"

View File

@ -1,6 +1,12 @@
<!-- 分销中心 -->
<template>
<s-layout navbar="inner" class="index-wrap" title="分销中心" :bgStyle="bgStyle" :onShareAppMessage="shareInfo">
<s-layout
navbar="inner"
class="index-wrap"
title="分销中心"
:bgStyle="bgStyle"
:onShareAppMessage="shareInfo"
>
<!-- 分销商信息 -->
<commission-info />
<!-- 账户信息 -->
@ -25,13 +31,16 @@
import sheep from '@/sheep';
const shareInfo = computed(() => {
return sheep.$platform.share.getShareInfo({
return sheep.$platform.share.getShareInfo(
{
params: {
page: '6',
},
}, {
},
{
type: 'user',
});
},
);
});
const bgStyle = {

View File

@ -41,10 +41,7 @@
<view class="no-box ss-flex ss-col-center ss-row-between">
<text class="order-code">订单编号{{ item.bizId }}</text>
<text class="order-state">
{{
item.status === 0 ? '待结算'
: item.status === 1 ? '已结算' : '已取消'
}}
{{ item.status === 0 ? '待结算' : item.status === 1 ? '已结算' : '已取消' }}
( 佣金 {{ fen2yuan(item.price) }} )
</text>
</view>

File diff suppressed because one or more lines are too long

View File

@ -6,14 +6,22 @@
<view class="card-box ui-BG-Main ui-Shadow-Main">
<view class="card-head ss-flex ss-col-center">
<view class="card-title ss-m-r-10">当前佣金</view>
<view @tap="state.showMoney = !state.showMoney" class="ss-eye-icon"
:class="state.showMoney ? 'cicon-eye' : 'cicon-eye-off'" />
<view
@tap="state.showMoney = !state.showMoney"
class="ss-eye-icon"
:class="state.showMoney ? 'cicon-eye' : 'cicon-eye-off'"
/>
</view>
<view class="ss-flex ss-row-between ss-col-center ss-m-t-30">
<view class="money-num">{{ state.showMoney ? fen2yuan(state.summary.withdrawPrice || 0) : '*****' }}</view>
<view class="money-num">{{
state.showMoney ? fen2yuan(state.summary.withdrawPrice || 0) : '*****'
}}</view>
<view class="ss-flex">
<view class="ss-m-r-20">
<button class="ss-reset-button withdraw-btn" @tap="sheep.$router.go('/pages/commission/withdraw')">
<button
class="ss-reset-button withdraw-btn"
@tap="sheep.$router.go('/pages/commission/withdraw')"
>
提现
</button>
</view>
@ -43,7 +51,12 @@
<su-sticky>
<!-- 统计 -->
<view class="filter-box ss-p-x-30 ss-flex ss-col-center ss-row-between">
<uni-datetime-picker v-model="state.date" type="daterange" @change="onChangeTime" :end="state.today">
<uni-datetime-picker
v-model="state.date"
type="daterange"
@change="onChangeTime"
:end="state.today"
>
<button class="ss-reset-button date-btn">
<text>{{ dateFilterText }}</text>
<text class="cicon-drop-down ss-seldate-icon" />
@ -56,21 +69,44 @@
<!-- <view>总支出{{ (-state.pagination.expense).toFixed(2) }}</view> -->
</view>
</view>
<su-tabs :list="tabMaps" @change="onChangeTab" :scrollable="false" :current="state.currentTab" />
<su-tabs
:list="tabMaps"
@change="onChangeTab"
:scrollable="false"
:current="state.currentTab"
/>
</su-sticky>
<s-empty v-if="state.pagination.total === 0" icon="/static/data-empty.png" text="暂无数据"></s-empty>
<s-empty
v-if="state.pagination.total === 0"
icon="/static/data-empty.png"
text="暂无数据"
></s-empty>
<!-- 转余额弹框 -->
<su-popup :show="state.showModal" type="bottom" round="20" @close="state.showModal = false" showClose>
<su-popup
:show="state.showModal"
type="bottom"
round="20"
@close="state.showModal = false"
showClose
>
<view class="ss-p-x-20 ss-p-y-30">
<view class="model-title ss-m-b-30 ss-m-l-20">转余额</view>
<view class="model-subtitle ss-m-b-100 ss-m-l-20">将您的佣金转到余额中继续消费</view>
<view class="input-box ss-flex ss-col-center border-bottom ss-m-b-70 ss-m-x-20">
<view class="unit"></view>
<uni-easyinput :inputBorder="false" class="ss-flex-1 ss-p-l-10" v-model="state.price" type="number"
placeholder="请输入金额" />
<uni-easyinput
:inputBorder="false"
class="ss-flex-1 ss-p-l-10"
v-model="state.price"
type="number"
placeholder="请输入金额"
/>
</view>
<button class="ss-reset-button model-btn ui-BG-Main-Gradient ui-Shadow-Main" @tap="onConfirm">
<button
class="ss-reset-button model-btn ui-BG-Main-Gradient ui-Shadow-Main"
@tap="onConfirm"
>
确定
</button>
</view>
@ -78,7 +114,11 @@
<!-- 钱包记录 -->
<view v-if="state.pagination.total > 0">
<view class="wallet-list ss-flex border-bottom" v-for="item in state.pagination.list" :key="item.id">
<view
class="wallet-list ss-flex border-bottom"
v-for="item in state.pagination.list"
:key="item.id"
>
<view class="list-content">
<view class="title-box ss-flex ss-row-between ss-m-b-20">
<text class="title ss-line-1">{{ item.title }}</text>
@ -87,15 +127,21 @@
<text v-else class="minus">{{ fen2yuan(item.price) }}</text>
</view>
</view>
<text class="time">{{ sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</text>
<text class="time">{{
sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss')
}}</text>
</view>
</view>
</view>
<!-- <u-gap></u-gap> -->
<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多',
}" />
}"
/>
</s-layout>
</template>
@ -130,14 +176,15 @@
showModal: false,
});
const tabMaps = [{
const tabMaps = [
{
name: '分佣',
value: '1', // BrokerageRecordBizTypeEnum.ORDER
},
{
name: '提现',
value: '2', // BrokerageRecordBizTypeEnum.WITHDRAW
}
},
];
const dateFilterText = computed(() => {
@ -199,10 +246,10 @@
state.showModal = false;
await getAgentInfo();
onChangeTab({
index: 1
index: 1,
});
}
}
},
});
}
@ -217,7 +264,8 @@
onLoad(async (options) => {
state.today = dayjs().format('YYYY-MM-DD');
state.date = [state.today, state.today];
if (options.type === 2) { // tab
if (options.type === 2) {
// tab
state.currentTab = 1;
}
getLogList();

View File

@ -15,7 +15,10 @@
<view class="num-title">可提现金额</view>
<view class="wallet-num">{{ fen2yuan(state.brokerageInfo.brokeragePrice) }}</view>
</view>
<button class="ss-reset-button log-btn" @tap="sheep.$router.go('/pages/commission/wallet', { type: 2 })">
<button
class="ss-reset-button log-btn"
@tap="sheep.$router.go('/pages/commission/wallet', { type: 2 })"
>
提现记录
</button>
</view>
@ -215,12 +218,12 @@
confirmText: '查看记录',
success: (res) => {
if (res.confirm) {
sheep.$router.go('/pages/commission/wallet', { type: 2 })
sheep.$router.go('/pages/commission/wallet', { type: 2 });
return;
}
getBrokerageUser();
state.accountInfo = {};
}
},
});
};
@ -247,8 +250,8 @@
onBeforeMount(() => {
getWithdrawRules();
getBrokerageUser()
})
getBrokerageUser();
});
</script>
<style lang="scss" scoped>

View File

@ -16,13 +16,16 @@
<view class="title ss-m-t-50 ss-m-b-20 ss-m-x-20">{{ state.coupon.name }}</view>
<view class="subtitle ss-m-b-50">
{{ fen2yuan(state.coupon.usePrice) }}
{{ state.coupon.discountType === 1
{{
state.coupon.discountType === 1
? '减 ' + fen2yuan(state.coupon.discountPrice) + ' 元'
: '打 ' + state.coupon.discountPercent / 10.0 + ' 折' }}
: '打 ' + state.coupon.discountPercent / 10.0 + ' 折'
}}
</view>
<button
class="ss-reset-button ss-m-b-30"
:class="state.coupon.canTake || state.coupon.status === 1
:class="
state.coupon.canTake || state.coupon.status === 1
? 'use-btn' // 使
: 'disable-btn'
"
@ -31,7 +34,13 @@
>
<text v-if="state.id > 0">{{ state.coupon.canTake ? '立即领取' : '已领取' }}</text>
<text v-else>
{{ state.coupon.status === 1 ? '立即使用' : state.coupon.status === 2 ? '已使用' : '已过期' }}
{{
state.coupon.status === 1
? '立即使用'
: state.coupon.status === 2
? '已使用'
: '已过期'
}}
</text>
</button>
<view class="time ss-m-y-30" v-if="state.coupon.validityType === 2">
@ -176,7 +185,7 @@
const { code, data } = await SpuApi.getSpuPage({
categoryId: state.categoryId,
pageNo: state.pagination.pageNo,
pageSize: state.pagination.pageSize
pageSize: state.pagination.pageSize,
});
if (code !== 0) {
return;
@ -197,7 +206,9 @@
//
async function getCategoryList() {
const { data, code } = await CategoryApi.getCategoryListByIds(state.coupon.productScopeValues.join(','));
const { data, code } = await CategoryApi.getCategoryListByIds(
state.coupon.productScopeValues.join(','),
);
if (code !== 0) {
return;
}
@ -225,7 +236,9 @@
//
async function getCouponContent() {
const { code, data } = state.id > 0 ? await CouponApi.getCouponTemplate(state.id)
const { code, data } =
state.id > 0
? await CouponApi.getCouponTemplate(state.id)
: await CouponApi.getCoupon(state.couponId);
if (code !== 0) {
return;

View File

@ -56,9 +56,14 @@
</view>
</template>
<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多',
}" @tap="loadMore" />
}"
@tap="loadMore"
/>
</s-layout>
</template>
@ -78,7 +83,7 @@
list: [],
total: 0,
pageNo: 1,
pageSize: 5
pageSize: 5,
},
loadStatus: '',
});
@ -106,7 +111,7 @@
function onTabsChange(e) {
state.currentTab = e.index;
state.type = e.value;
resetPagination(state.pagination)
resetPagination(state.pagination);
if (state.currentTab === 0) {
getData();
} else {
@ -135,7 +140,7 @@
const { data, code } = await CouponApi.getCouponPage({
pageNo: state.pagination.pageNo,
pageSize: state.pagination.pageSize,
status: state.type
status: state.type,
});
if (code !== 0) {
return;

View File

@ -27,13 +27,23 @@
</view>
<!-- 评价 -->
<view class="area-box">
<uni-easyinput :inputBorder="false" type="textarea" maxlength="120" autoHeight
<uni-easyinput
:inputBorder="false"
type="textarea"
maxlength="120"
autoHeight
v-model="state.commentList[index].content"
placeholder="宝贝满足你的期待吗?说说你的使用心得,分享给想买的他们吧~" />
placeholder="宝贝满足你的期待吗?说说你的使用心得,分享给想买的他们吧~"
/>
<!-- TODO 芋艿文件上传 -->
<view class="img-box">
<s-uploader v-model:url="state.commentList[index].images" fileMediatype="image"
limit="9" mode="grid" :imageStyles="{ width: '168rpx', height: '168rpx' }" />
<s-uploader
v-model:url="state.commentList[index].images"
fileMediatype="image"
limit="9"
mode="grid"
:imageStyles="{ width: '168rpx', height: '168rpx' }"
/>
</view>
</view>
</view>
@ -61,7 +71,7 @@
const state = reactive({
orderInfo: {},
commentList: [],
id: null
id: null,
});
async function onSubmit() {
@ -76,14 +86,14 @@
onLoad(async (options) => {
if (!options.id) {
sheep.$helper.toast(`缺少订单信息,请检查`);
return
return;
}
state.id = options.id;
const { code, data } = await OrderApi.getOrder(state.id);
if (code !== 0) {
sheep.$helper.toast('无待评价订单');
return
return;
}
//
data.items.forEach((item) => {
@ -93,7 +103,7 @@
descriptionScores: 5,
benefitScores: 5,
content: '',
picUrls: []
picUrls: [],
});
});
state.orderInfo = data;

View File

@ -42,14 +42,13 @@
type: Array,
default() {
return [];
}
}
},
},
});
function onActivity(activity) {
const type = activity.type;
const typePath = type === 1 ? 'seckill' :
type === 2 ? 'TODO 拼团' : 'groupon';
const typePath = type === 1 ? 'seckill' : type === 2 ? 'TODO 拼团' : 'groupon';
sheep.$router.go(`/pages/goods/${typePath}`, {
id: activity.id,
});

View File

@ -15,15 +15,15 @@
},
},
sku: {
type: Object
}
type: Object,
},
});
const value = computed(() => {
if (!props.sku?.id) {
return '请选择商品规格';
}
let str = '';
props.sku.properties.forEach(property => {
props.sku.properties.forEach((property) => {
str += property.propertyName + ':' + property.valueName + ' ';
});
return str;

View File

@ -98,7 +98,8 @@
function getCommentCardNode() {
return new Promise((res, rej) => {
uni.createSelectorQuery()
uni
.createSelectorQuery()
.select('.detail-comment-selector')
.boundingClientRect((data) => {
if (data) {

View File

@ -119,7 +119,7 @@
if (props.modelValue.favorite) {
const { code } = await FavoriteApi.deleteFavorite(props.modelValue.id);
if (code !== 0) {
return
return;
}
sheep.$helper.toast('取消收藏');
props.modelValue.favorite = false;
@ -127,7 +127,7 @@
} else {
const { code } = await FavoriteApi.createFavorite(props.modelValue.id);
if (code !== 0) {
return
return;
}
sheep.$helper.toast('收藏成功');
props.modelValue.favorite = true;

View File

@ -37,7 +37,7 @@
import { onMounted, reactive } from 'vue';
import sheep from '@/sheep';
import { useDurationTime } from '@/sheep/hooks/useGoods';
import CombinationApi from "@/sheep/api/promotion/combination";
import CombinationApi from '@/sheep/api/promotion/combination';
const props = defineProps({
modelValue: {

View File

@ -7,7 +7,11 @@
<detailSkeleton v-if="state.skeletonLoading" />
<!-- 下架/售罄提醒 -->
<s-empty
v-else-if="state.goodsInfo === null || state.activity.status !== 0 || state.activity.endTime < new Date().getTime()"
v-else-if="
state.goodsInfo === null ||
state.activity.status !== 0 ||
state.activity.endTime < new Date().getTime()
"
text="活动不存在或已结束"
icon="/static/soldout-empty.png"
showAction
@ -47,10 +51,7 @@
</view>
</view>
<view class="ss-flex ss-row-between">
<view
class="origin-price ss-flex ss-col-center"
v-if="state.goodsInfo.price"
>
<view class="origin-price ss-flex ss-col-center" v-if="state.goodsInfo.price">
单买价
<view class="origin-price-text">
{{ fen2yuan(state.goodsInfo.price) }}
@ -123,7 +124,9 @@
"
:disabled="state.goodsInfo.stock === 0 || state.activity.status !== 0"
>
<view class="btn-price">{{ fen2yuan(state.activity.price || state.goodsInfo.price) }}</view>
<view class="btn-price">{{
fen2yuan(state.activity.price || state.goodsInfo.price)
}}</view>
<view v-if="state.activity.startTime > new Date().getTime()">未开始</view>
<view v-else-if="state.activity.endTime <= new Date().getTime()">已结束</view>
<view v-else>
@ -150,14 +153,12 @@
import detailContentCard from './components/detail/detail-content-card.vue';
import grouponCardList from './components/groupon/groupon-card-list.vue';
import { useDurationTime, formatGoodsSwiper, fen2yuan } from '@/sheep/hooks/useGoods';
import CombinationApi from "@/sheep/api/promotion/combination";
import SpuApi from "@/sheep/api/product/spu";
import CombinationApi from '@/sheep/api/promotion/combination';
import SpuApi from '@/sheep/api/product/spu';
const headerBg = sheep.$url.css('/static/img/shop/goods/groupon-bg.png');
const btnBg = sheep.$url.css('/static/img/shop/goods/groupon-btn.png');
const disabledBtnBg = sheep.$url.css(
'/static/img/shop/goods/activity-btn-disabled.png',
);
const disabledBtnBg = sheep.$url.css('/static/img/shop/goods/activity-btn-disabled.png');
const grouponBg = sheep.$url.css('/static/img/shop/goods/groupon-tip-bg.png');
onPageScroll(() => {});
@ -261,7 +262,7 @@
//
const { data: spu } = await SpuApi.getSpuDetail(activity.spuId);
state.goodsId = spu.id;
activity.products.forEach(product => {
activity.products.forEach((product) => {
spu.price = Math.min(spu.price, product.combinationPrice); // SPU
});
//
@ -475,8 +476,7 @@
}
.groupon-box {
background: v-bind(grouponBg)
no-repeat;
background: v-bind(grouponBg) no-repeat;
background-size: 100% 100%;
}

View File

@ -7,13 +7,26 @@
<!-- 骨架屏 -->
<detailSkeleton v-if="state.skeletonLoading" />
<!-- 下架/售罄提醒 -->
<s-empty v-else-if="state.goodsInfo === null" text="商品不存在或已下架" icon="/static/soldout-empty.png" showAction
actionText="再逛逛" actionUrl="/pages/goods/list" />
<s-empty
v-else-if="state.goodsInfo === null"
text="商品不存在或已下架"
icon="/static/soldout-empty.png"
showAction
actionText="再逛逛"
actionUrl="/pages/goods/list"
/>
<block v-else>
<view class="detail-swiper-selector">
<!-- 商品轮播图 -->
<su-swiper class="ss-m-b-14" isPreview :list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)"
otStyle="tag" imageMode="widthFix" dotCur="bg-mask-40" :seizeHeight="750" />
<su-swiper
class="ss-m-b-14"
isPreview
:list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)"
otStyle="tag"
imageMode="widthFix"
dotCur="bg-mask-40"
:seizeHeight="750"
/>
<!-- 价格+标题 -->
<view class="title-card detail-card ss-p-y-40 ss-p-x-20">
@ -34,16 +47,23 @@
<!-- 满减送/限时折扣活动的提示 -->
<div class="tag-content">
<view class="tag-box ss-flex">
<view class="tag ss-m-r-10" v-for="promos in state.activityInfo"
:key="promos.id" @tap="onActivity">
<view
class="tag ss-m-r-10"
v-for="promos in state.activityInfo"
:key="promos.id"
@tap="onActivity"
>
{{ promos.name }}
</view>
</view>
</div>
<!-- 优惠劵 -->
<view class="get-coupon-box ss-flex ss-col-center ss-m-l-20" @tap="state.showModel = true"
v-if="state.couponInfo.length">
<view
class="get-coupon-box ss-flex ss-col-center ss-m-l-20"
@tap="state.showModel = true"
v-if="state.couponInfo.length"
>
<view class="discounts-title ss-m-r-8">领券</view>
<text class="cicon-forward"></text>
</view>
@ -54,30 +74,51 @@
<!-- 功能卡片 -->
<view class="detail-cell-card detail-card ss-flex-col">
<detail-cell-sku v-model="state.selectedSku.goods_sku_text" :sku="state.selectedSku"
@tap="state.showSelectSku = true" />
<detail-cell-sku
v-model="state.selectedSku.goods_sku_text"
:sku="state.selectedSku"
@tap="state.showSelectSku = true"
/>
</view>
<!-- 规格与数量弹框 -->
<s-select-sku :goodsInfo="state.goodsInfo" :show="state.showSelectSku" @addCart="onAddCart"
@buy="onBuy" @change="onSkuChange" @close="state.showSelectSku = false" />
<s-select-sku
:goodsInfo="state.goodsInfo"
:show="state.showSelectSku"
@addCart="onAddCart"
@buy="onBuy"
@change="onSkuChange"
@close="state.showSelectSku = false"
/>
</view>
<!-- 评价 -->
<detail-comment-card class="detail-comment-selector" :goodsId="state.goodsId" />
<!-- 详情 -->
<detail-content-card class="detail-content-selector" :content="state.goodsInfo.description" />
<detail-content-card
class="detail-content-selector"
:content="state.goodsInfo.description"
/>
<!-- 活动跳转拼团/秒杀/砍价活动 -->
<detail-activity-tip v-if="state.activityList.length > 0" :activity-list="state.activityList" />
<detail-activity-tip
v-if="state.activityList.length > 0"
:activity-list="state.activityList"
/>
<!-- 详情 tabbar -->
<detail-tabbar v-model="state.goodsInfo">
<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-if="state.goodsInfo.stock > 0">
<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="state.showSelectSku = true">
<button
class="ss-reset-button add-btn ui-Shadow-Main"
@tap="state.showSelectSku = true"
>
加入购物车
</button>
<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="state.showSelectSku = true">
<button
class="ss-reset-button buy-btn ui-Shadow-Main"
@tap="state.showSelectSku = true"
>
立即购买
</button>
</view>
@ -87,12 +128,19 @@
</detail-tabbar>
<!-- 优惠劵弹窗 -->
<s-coupon-get v-model="state.couponInfo" :show="state.showModel" @close="state.showModel = false"
@get="onGet" />
<s-coupon-get
v-model="state.couponInfo"
:show="state.showModel"
@close="state.showModel = false"
@get="onGet"
/>
<!-- 满减送/限时折扣活动弹窗 -->
<s-activity-pop v-model="state.activityInfo" :show="state.showActivityModel"
@close="state.showActivityModel = false" />
<s-activity-pop
v-model="state.activityInfo"
:show="state.showActivityModel"
@close="state.showActivityModel = false"
/>
</block>
</s-layout>
</view>
@ -154,10 +202,12 @@
}
sheep.$router.go('/pages/order/confirm', {
data: JSON.stringify({
items: [{
items: [
{
skuId: e.id,
count: e.goods_num
}],
count: e.goods_num,
},
],
// TODO 2
deliveryType: 1,
pointStatus: false,
@ -187,7 +237,8 @@
// TODO
const shareInfo = computed(() => {
if (isEmpty(state.goodsInfo)) return {};
return sheep.$platform.share.getShareInfo({
return sheep.$platform.share.getShareInfo(
{
title: state.goodsInfo.name,
image: sheep.$url.cdn(state.goodsInfo.picUrl),
desc: state.goodsInfo.introduction,
@ -195,13 +246,15 @@
page: '2',
query: state.goodsInfo.id,
},
}, {
},
{
type: 'goods', //
title: state.goodsInfo.name, //
image: sheep.$url.cdn(state.goodsInfo.picUrl), //
price: fen2yuan(state.goodsInfo.price), //
original_price: fen2yuan(state.goodsInfo.marketPrice), //
});
},
);
});
async function getCoupon() {
@ -248,15 +301,18 @@
if (res.code !== 0) {
return;
}
res.data.forEach(activity => {
if ([1, 2, 3].includes(activity.type)) { // //
res.data.forEach((activity) => {
if ([1, 2, 3].includes(activity.type)) {
// //
state.activityList.push(activity);
} else if (activity.type === 5) { //
} else if (activity.type === 5) {
//
state.activityInfo.push(activity);
} else { // TODO
} else {
// TODO
console.log('待实现!优先级不高');
}
})
});
});
});
</script>

View File

@ -1,12 +1,22 @@
<template>
<s-layout navbar="normal" :leftWidth="0" :rightWidth="0" tools="search" :defaultSearch="state.keyword"
@search="onSearch">
<s-layout
navbar="normal"
:leftWidth="0"
:rightWidth="0"
tools="search"
:defaultSearch="state.keyword"
@search="onSearch"
>
<!-- 筛选 -->
<su-sticky bgColor="#fff">
<view class="ss-flex">
<view class="ss-flex-1">
<su-tabs :list="state.tabList" :scrollable="false" @change="onTabsChange"
:current="state.currentTab" />
<su-tabs
:list="state.tabList"
:scrollable="false"
@change="onTabsChange"
:current="state.currentTab"
/>
</view>
<view class="list-icon" @tap="state.iconStatus = !state.iconStatus">
<text v-if="state.iconStatus" class="sicon-goods-list" />
@ -16,12 +26,23 @@
</su-sticky>
<!-- 弹窗 -->
<su-popup :show="state.showFilter" type="top" round="10" :space="sys_navBar + 38" backgroundColor="#F6F6F6"
:zIndex="10" @close="state.showFilter = false">
<su-popup
:show="state.showFilter"
type="top"
round="10"
:space="sys_navBar + 38"
backgroundColor="#F6F6F6"
:zIndex="10"
@close="state.showFilter = false"
>
<view class="filter-list-box">
<view class="filter-item" v-for="(item, index) in state.tabList[state.currentTab].list"
:key="item.value" :class="[{ 'filter-item-active': index === state.curFilter }]"
@tap="onFilterItem(index)">
<view
class="filter-item"
v-for="(item, index) in state.tabList[state.currentTab].list"
:key="item.value"
:class="[{ 'filter-item-active': index === state.curFilter }]"
@tap="onFilterItem(index)"
>
{{ item.label }}
</view>
</view>
@ -29,7 +50,11 @@
<!-- 情况一单列布局 -->
<view v-if="state.iconStatus && state.pagination.total > 0" class="goods-list ss-m-t-20">
<view class="ss-p-l-20 ss-p-r-20 ss-m-b-20" v-for="item in state.pagination.list" :key="item.id">
<view
class="ss-p-l-20 ss-p-r-20 ss-m-b-20"
v-for="item in state.pagination.list"
:key="item.id"
>
<s-goods-column
class=""
size="lg"
@ -41,8 +66,10 @@
</view>
</view>
<!-- 情况二双列布局 -->
<view v-if="!state.iconStatus && state.pagination.total > 0"
class="ss-flex ss-flex-wrap ss-p-x-20 ss-m-t-20 ss-col-top">
<view
v-if="!state.iconStatus && state.pagination.total > 0"
class="ss-flex ss-flex-wrap ss-p-x-20 ss-m-t-20 ss-col-top"
>
<view class="goods-list-box">
<view class="left-list" v-for="item in state.leftGoodsList" :key="item.id">
<s-goods-column
@ -78,9 +105,14 @@
</view>
</view>
</view>
<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多',
}" @tap="loadMore" />
}"
@tap="loadMore"
/>
<s-empty v-if="state.pagination.total === 0" icon="/static/soldout-empty.png" text="暂无商品" />
</s-layout>
</template>
@ -111,10 +143,12 @@
iconStatus: false, // true - false -
keyword: '',
categoryId: 0,
tabList: [{
tabList: [
{
name: '综合推荐',
list: [{
label: '综合推荐'
list: [
{
label: '综合推荐',
},
{
label: '价格升序',
@ -131,12 +165,12 @@
{
name: '销量',
sort: 'salesCount',
order: false
order: false,
},
{
name: '新品优先',
value: 'createTime',
order: false
order: false,
},
],
loadStatus: '',
@ -211,8 +245,10 @@
const onFilterItem = (val) => {
//
// tabList[0] list
if (state.currentSort === state.tabList[0].list[val].sort
&& state.currentOrder === state.tabList[0].list[val].order) {
if (
state.currentSort === state.tabList[0].list[val].sort &&
state.currentOrder === state.tabList[0].list[val].order
) {
state.showFilter = false;
return;
}
@ -226,7 +262,7 @@
// +
emptyList();
getList();
}
};
async function getList() {
state.loadStatus = 'loading';
@ -241,7 +277,7 @@
if (code !== 0) {
return;
}
state.pagination.list = _.concat(state.pagination.list, data.list)
state.pagination.list = _.concat(state.pagination.list, data.list);
state.pagination.total = data.total;
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
mountMasonry();

View File

@ -69,10 +69,7 @@
<!-- 功能卡片 -->
<view class="detail-cell-card detail-card ss-flex-col">
<detail-cell-sku
:sku="state.selectedSku"
@tap="state.showSelectSku = true"
/>
<detail-cell-sku :sku="state.selectedSku" @tap="state.showSelectSku = true" />
</view>
<!-- 规格与数量弹框 -->
<s-select-seckill-sku
@ -107,7 +104,9 @@
<button v-else class="ss-reset-button origin-price-btn ss-flex-col">
<view
class="no-original"
:class="state.goodsInfo.stock === 0 || timeStatusEnum !== TimeStatusEnum.STARTED ? '' : ''"
:class="
state.goodsInfo.stock === 0 || timeStatusEnum !== TimeStatusEnum.STARTED ? '' : ''
"
>
秒杀价
</view>
@ -148,15 +147,13 @@
import detailCommentCard from './components/detail/detail-comment-card.vue';
import detailContentCard from './components/detail/detail-content-card.vue';
import detailProgress from './components/detail/detail-progress.vue';
import SeckillApi from "@/sheep/api/promotion/seckill";
import SpuApi from "@/sheep/api/product/spu";
import {getTimeStatusEnum, TimeStatusEnum} from "@/sheep/util/const";
import SeckillApi from '@/sheep/api/promotion/seckill';
import SpuApi from '@/sheep/api/product/spu';
import { getTimeStatusEnum, TimeStatusEnum } from '@/sheep/util/const';
const headerBg = sheep.$url.css('/static/img/shop/goods/seckill-bg.png');
const btnBg = sheep.$url.css('/static/img/shop/goods/seckill-btn.png');
const disabledBtnBg = sheep.$url.css(
'/static/img/shop/goods/activity-btn-disabled.png',
);
const disabledBtnBg = sheep.$url.css('/static/img/shop/goods/activity-btn-disabled.png');
const seckillBg = sheep.$url.css('/static/img/shop/goods/seckill-tip-bg.png');
const grouponBg = sheep.$url.css('/static/img/shop/goods/groupon-tip-bg.png');
@ -221,36 +218,40 @@
);
});
const activity = ref()
const timeStatusEnum = ref('')
const activity = ref();
const timeStatusEnum = ref('');
//
const getActivity = async (id) => {
const { data } = await SeckillApi.getSeckillActivity(id)
activity.value = data
timeStatusEnum.value = getTimeStatusEnum(activity.startTime, activity.endTime)
const { data } = await SeckillApi.getSeckillActivity(id);
activity.value = data;
timeStatusEnum.value = getTimeStatusEnum(activity.startTime, activity.endTime);
//
await getSpu(data.spuId)
}
await getSpu(data.spuId);
};
const getSpu = async (id) => {
const { data } = await SpuApi.getSpuDetail(id)
const { data } = await SpuApi.getSpuDetail(id);
//
data.activity_type = 'seckill'
state.goodsInfo = data
data.activity_type = 'seckill';
state.goodsInfo = data;
//
state.goodsSwiper = formatGoodsSwiper(state.goodsInfo.sliderPicUrls);
//
state.goodsInfo.price = min([state.goodsInfo.price, ...activity.value.products.map(spu => spu.seckillPrice)])
state.goodsInfo.price = min([
state.goodsInfo.price,
...activity.value.products.map((spu) => spu.seckillPrice),
]);
// 使
data.skus.forEach(sku => {
const product = activity.value.products.find(product => product.skuId === sku.id);
data.skus.forEach((sku) => {
const product = activity.value.products.find((product) => product.skuId === sku.id);
if (product) {
sku.price = product.seckillPrice;
sku.stock = Math.min(sku.stock, product.stock);
} else { //
} else {
//
sku.stock = 0;
}
//
@ -264,7 +265,7 @@
});
state.skeletonLoading = false;
}
};
onLoad((options) => {
//
@ -274,7 +275,7 @@
}
//
getActivity(options.id)
getActivity(options.id);
});
</script>

View File

@ -1,6 +1,10 @@
<template>
<s-layout title="购物车" tabbar="/pages/index/cart" :bgStyle="{ color: '#fff' }">
<s-empty v-if="state.list.length === 0" text="购物车空空如也,快去逛逛吧~" icon="/static/cart-empty.png" />
<s-empty
v-if="state.list.length === 0"
text="购物车空空如也,快去逛逛吧~"
icon="/static/cart-empty.png"
/>
<!-- 头部 -->
<view class="cart-box ss-flex ss-flex-col ss-row-between" v-if="state.list.length">
@ -24,15 +28,35 @@
<view class="goods-box ss-r-10 ss-m-b-14" v-for="item in state.list" :key="item.id">
<view class="ss-flex ss-col-center">
<label class="check-box ss-flex ss-col-center ss-p-l-10" @tap="onSelectSingle(item.id)">
<radio :checked="state.selectedIds.includes(item.id)" color="var(--ui-BG-Main)"
style="transform: scale(0.8)" @tap.stop="onSelectSingle(item.id)" />
<radio
:checked="state.selectedIds.includes(item.id)"
color="var(--ui-BG-Main)"
style="transform: scale(0.8)"
@tap.stop="onSelectSingle(item.id)"
/>
</label>
<s-goods-item :title="item.spu.name" :img="item.spu.picUrl || item.goods.image"
<s-goods-item
:title="item.spu.name"
:img="item.spu.picUrl || item.goods.image"
:price="item.sku.price"
:skuText="item.sku.properties.length>1? item.sku.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.sku.properties[0].valueName"
priceColor="#FF3000" :titleWidth="400">
:skuText="
item.sku.properties.length > 1
? item.sku.properties.reduce(
(items2, items) => items2.valueName + ' ' + items.valueName,
)
: item.sku.properties[0].valueName
"
priceColor="#FF3000"
:titleWidth="400"
>
<template v-if="!state.editMode" v-slot:tool>
<su-number-box :min="0" :max="item.sku.stock" :step="1" v-model="item.count" @change="onNumberChange($event, item)" />
<su-number-box
:min="0"
:max="item.sku.stock"
:step="1"
v-model="item.count"
@change="onNumberChange($event, item)"
/>
</template>
</s-goods-item>
</view>
@ -43,8 +67,12 @@
<view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom">
<view class="footer-left ss-flex ss-col-center">
<label class="check-box ss-flex ss-col-center ss-p-r-30" @tap="onSelectAll">
<radio :checked="state.isAllSelected" color="var(--ui-BG-Main)"
style="transform: scale(0.8)" @tap.stop="onSelectAll" />
<radio
:checked="state.isAllSelected"
color="var(--ui-BG-Main)"
style="transform: scale(0.8)"
@tap.stop="onSelectAll"
/>
<view class="ss-m-l-8"> 全选 </view>
</label>
<text>合计</text>
@ -53,12 +81,18 @@
</view>
</view>
<view class="footer-right">
<button v-if="state.editMode" class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
@tap="onDelete">
<button
v-if="state.editMode"
class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
@tap="onDelete"
>
删除
</button>
<button v-else class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
@tap="onConfirm">
<button
v-else
class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
@tap="onConfirm"
>
去结算
{{ state.selectedIds?.length ? `(${state.selectedIds.length})` : '' }}
</button>
@ -98,7 +132,7 @@
//
function onConfirm() {
let items = []
let items = [];
let goods_list = [];
state.selectedList = state.list.filter((item) => state.selectedIds.includes(item.id));
state.selectedList.map((item) => {
@ -107,7 +141,7 @@
skuId: item.sku.id,
count: item.count,
cartId: item.id,
})
});
goods_list.push({
// goods_id: item.goods_id,
goods_id: item.spu.id,

View File

@ -1,9 +1,19 @@
<!-- 首页支持店铺装修 -->
<template>
<view v-if="template">
<s-layout title="首页" navbar="custom" tabbar="/pages/index/index" :bgStyle="template.page"
:navbarStyle="template.navigationBar" onShareAppMessage>
<s-block v-for="(item, index) in template.components" :key="index" :styles="item.property.style">
<s-layout
title="首页"
navbar="custom"
tabbar="/pages/index/index"
:bgStyle="template.page"
:navbarStyle="template.navigationBar"
onShareAppMessage
>
<s-block
v-for="(item, index) in template.components"
:key="index"
:styles="item.property.style"
>
<s-block-item :type="item.id" :data="item.property" :styles="item.property.style" />
</s-block>
</s-layout>
@ -11,14 +21,8 @@
</template>
<script setup>
import {
computed
} from 'vue';
import {
onLoad,
onPageScroll,
onPullDownRefresh
} from '@dcloudio/uni-app';
import { computed } from 'vue';
import { onLoad, onPageScroll, onPullDownRefresh } from '@dcloudio/uni-app';
import sheep from '@/sheep';
import $share from '@/sheep/platform/share';
// tabBar
@ -47,13 +51,12 @@
// })
// }())
onLoad((options) => {
// #ifdef MP
//
if (options.scene) {
const sceneParams = decodeURIComponent(options.scene).split('=');
console.log("sceneParams=>",sceneParams);
console.log('sceneParams=>', sceneParams);
options[sceneParams[0]] = sceneParams[1];
}
// #endif

View File

@ -17,9 +17,11 @@
const event = options.event;
const code = options.code;
const state = options.state;
if (event === 'login') { //
if (event === 'login') {
//
const res = await sheep.$platform.useProvider().login(code, state);
} else if (event === 'bind') { //
} else if (event === 'bind') {
//
sheep.$platform.useProvider().bind(code, state);
}

View File

@ -26,7 +26,7 @@
page: {},
});
onLoad(async (options) => {
let id = options.id
let id = options.id;
// #ifdef MP
//

View File

@ -8,7 +8,11 @@
:navbarStyle="template.navigationBar"
onShareAppMessage
>
<s-block v-for="(item, index) in template.components" :key="index" :styles="item.property.style">
<s-block
v-for="(item, index) in template.components"
:key="index"
:styles="item.property.style"
>
<s-block-item :type="item.id" :data="item.property" :styles="item.property.style" />
</s-block>
</s-layout>

View File

@ -0,0 +1,52 @@
<!-- 商品详情描述卡片 -->
<template>
<view class="detail-content-card bg-white ss-m-x-20 ss-p-t-20">
<view class="card-header ss-flex ss-col-center ss-m-b-30 ss-m-l-20">
<view class="line"></view>
<view class="title ss-m-l-20 ss-m-r-20">详情</view>
</view>
<view class="card-content">
<mp-html :content="content" />
</view>
</view>
</template>
<script setup>
import sheep from '@/sheep';
const { safeAreaInsets } = sheep.$platform.device;
const props = defineProps({
content: {
type: String,
default: '',
},
});
</script>
<style lang="scss" scoped>
.detail-content-card {
.card-header {
.line {
width: 6rpx;
height: 30rpx;
background: linear-gradient(180deg, var(--ui-BG-Main) 0%, var(--ui-BG-Main-gradient) 100%);
border-radius: 3rpx;
}
.title {
font-size: 30rpx;
font-weight: bold;
}
.des {
font-size: 24rpx;
color: $dark-9;
}
.more-btn {
font-size: 24rpx;
color: var(--ui-BG-Main);
}
}
}
</style>

43
pages/mulu/mulu.vue Normal file
View File

@ -0,0 +1,43 @@
<template>
<view>
<view class="ccclass">
<detail-content-card
class="detail-content-selector"
:content="state.model.content"
/>
</view>
</view>
</template>
<script setup>
import { onLoad, onPageScroll } from '@dcloudio/uni-app';
import { ref, reactive, unref, createApp } from 'vue';
import AddressApi from '../../sheep/api/member/address';
import detailContentCard from './detail-content-card.vue';
const state = reactive({
model: [],
});
const ff = async (id) => {
let { code, data } = await AddressApi.textListDetail(id);
state.model = data;
}
onLoad( (options) => {
if (!options.id) {
return;
}
ff(options.id);
} )
</script>
<style scoped lang="scss">
.ccclass {
width: 100%;
background-color: white;
}
::v-deep .title, ::v-deep .card-header{
display: none;
}
</style>

View File

@ -98,11 +98,7 @@
</view>
<view class="modal-content content_box">
<radio-group @change="onChange">
<label
class="radio ss-flex ss-col-center"
v-for="item in state.reasonList"
:key="item"
>
<label class="radio ss-flex ss-col-center" v-for="item in state.reasonList" :key="item">
<view class="ss-flex-1 ss-p-20">{{ item }}</view>
<radio
:value="item"
@ -152,7 +148,7 @@
],
reasonList: [], //
showModal: false, //
currentValue: '' //
currentValue: '', //
});
const formData = reactive({
way: '',

View File

@ -3,24 +3,38 @@
<s-layout title="售后详情" :navbar="!isEmpty(state.info) && state.loading ? 'inner' : 'normal'">
<view class="content_box" v-if="!isEmpty(state.info) && state.loading">
<!-- 步骤条 -->
<view class="steps-box ss-flex" :style="[
<view
class="steps-box ss-flex"
:style="[
{
marginTop: '-' + Number(statusBarHeight + 88) + 'rpx',
paddingTop: Number(statusBarHeight + 88) + 'rpx',
},
]">
]"
>
<view class="ss-flex">
<view class="steps-item" v-for="(item, index) in state.list" :key="index">
<view class="ss-flex">
<text class="sicon-circleclose"
v-if="state.list.length - 1 === index && [61, 62, 63].includes(state.info.status)" />
<text class="sicon-circlecheck" v-else
:class="state.active >= index ? 'activity-color' : 'info-color'" />
<text
class="sicon-circleclose"
v-if="state.list.length - 1 === index && [61, 62, 63].includes(state.info.status)"
/>
<text
class="sicon-circlecheck"
v-else
:class="state.active >= index ? 'activity-color' : 'info-color'"
/>
<view v-if="state.list.length - 1 !== index" class="line"
:class="state.active >= index ? 'activity-bg' : 'info-bg'" />
<view
v-if="state.list.length - 1 !== index"
class="line"
:class="state.active >= index ? 'activity-bg' : 'info-bg'"
/>
</view>
<view class="steps-item-title" :class="state.active >= index ? 'activity-color' : 'info-color'">
<view
class="steps-item-title"
:class="state.active >= index ? 'activity-color' : 'info-color'"
>
{{ item.title }}
</view>
</view>
@ -28,8 +42,10 @@
</view>
<!-- 服务状态 -->
<view class="status-box ss-flex ss-col-center ss-row-between ss-m-x-20"
@tap="sheep.$router.go('/pages/order/aftersale/log', { id: state.id })">
<view
class="status-box ss-flex ss-col-center ss-row-between ss-m-x-20"
@tap="sheep.$router.go('/pages/order/aftersale/log', { id: state.id })"
>
<view class="">
<view class="status-text">
{{ formatAfterSaleStatusDescription(state.info) }}
@ -86,18 +102,31 @@
</view>
<!-- 操作区 -->
<s-empty v-if="isEmpty(state.info) && state.loading" icon="/static/order-empty.png" text="暂无该订单售后详情" />
<s-empty
v-if="isEmpty(state.info) && state.loading"
icon="/static/order-empty.png"
text="暂无该订单售后详情"
/>
<su-fixed bottom placeholder bg="bg-white" v-if="!isEmpty(state.info)">
<view class="foot_box">
<button class="ss-reset-button btn" v-if="state.info.buttons?.includes('cancel')"
@tap="onApply(state.info.id)">
<button
class="ss-reset-button btn"
v-if="state.info.buttons?.includes('cancel')"
@tap="onApply(state.info.id)"
>
取消申请
</button>
<button class="ss-reset-button btn" v-if="state.info.buttons?.includes('delivery')"
@tap="sheep.$router.go('/pages/order/aftersale/return-delivery', { id: state.info.id })">
<button
class="ss-reset-button btn"
v-if="state.info.buttons?.includes('delivery')"
@tap="sheep.$router.go('/pages/order/aftersale/return-delivery', { id: state.info.id })"
>
填写退货
</button>
<button class="ss-reset-button contcat-btn btn" @tap="sheep.$router.go('/pages/chat/index')">
<button
class="ss-reset-button contcat-btn btn"
@tap="sheep.$router.go('/pages/chat/index')"
>
联系客服
</button>
</view>
@ -110,7 +139,11 @@
import { onLoad } from '@dcloudio/uni-app';
import { reactive } from 'vue';
import { isEmpty } from 'lodash';
import { fen2yuan, formatAfterSaleStatusDescription, handleAfterSaleButtons } from '@/sheep/hooks/useGoods';
import {
fen2yuan,
formatAfterSaleStatusDescription,
handleAfterSaleButtons,
} from '@/sheep/hooks/useGoods';
import AfterSaleApi from '@/sheep/api/trade/afterSale';
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
@ -120,13 +153,17 @@
info: {}, //
loading: false,
active: 0, // list
list: [{
list: [
{
title: '提交申请',
}, {
},
{
title: '处理中',
}, {
title: '完成'
}], //
},
{
title: '完成',
},
], //
});
function onApply(id) {
@ -175,7 +212,7 @@
onLoad((options) => {
if (!options.id) {
sheep.$helper.toast(`缺少订单信息,请检查`);
return
return;
}
state.id = options.id;
getDetail(options.id);

View File

@ -3,13 +3,22 @@
<s-layout title="售后列表">
<!-- tab -->
<su-sticky bgColor="#fff">
<su-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab" />
<su-tabs
:list="tabMaps"
:scrollable="false"
@change="onTabsChange"
:current="state.currentTab"
/>
</su-sticky>
<s-empty v-if="state.pagination.total === 0" icon="/static/data-empty.png" text="暂无数据" />
<!-- 列表 -->
<view v-if="state.pagination.total > 0">
<view class="list-box ss-m-y-20" v-for="order in state.pagination.list" :key="order.id"
@tap="sheep.$router.go('/pages/order/aftersale/detail', { id: order.id })">
<view
class="list-box ss-m-y-20"
v-for="order in state.pagination.list"
:key="order.id"
@tap="sheep.$router.go('/pages/order/aftersale/detail', { id: order.id })"
>
<view class="order-head ss-flex ss-col-center ss-row-between">
<text class="no">服务单号{{ order.no }}</text>
<text class="state">{{ formatAfterSaleStatus(order) }}</text>
@ -30,15 +39,24 @@
<view class="tool-btn-box ss-flex ss-col-center ss-row-right ss-p-r-20">
<!-- TODO 功能缺失填写退货信息 -->
<view>
<button class="ss-reset-button tool-btn" @tap.stop="onApply(order.id)"
v-if="order?.buttons.includes('cancel')">取消申请</button>
<button
class="ss-reset-button tool-btn"
@tap.stop="onApply(order.id)"
v-if="order?.buttons.includes('cancel')"
>取消申请</button
>
</view>
</view>
</view>
</view>
<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多',
}" @tap="loadMore" />
}"
@tap="loadMore"
/>
</s-layout>
</template>
@ -47,7 +65,11 @@
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import { reactive } from 'vue';
import _ from 'lodash';
import { formatAfterSaleStatus, formatAfterSaleStatusDescription, handleAfterSaleButtons } from '@/sheep/hooks/useGoods';
import {
formatAfterSaleStatus,
formatAfterSaleStatusDescription,
handleAfterSaleButtons,
} from '@/sheep/hooks/useGoods';
import AfterSaleApi from '@/sheep/api/trade/afterSale';
import { resetPagination } from '@/sheep/util';
@ -58,13 +80,14 @@
list: [],
total: 0,
pageNo: 1,
pageSize: 10
pageSize: 10,
},
loadStatus: '',
});
// TODO
const tabMaps = [{
const tabMaps = [
{
name: '全部',
value: 'all',
},
@ -104,7 +127,7 @@
if (code !== 0) {
return;
}
data.list.forEach(order => handleAfterSaleButtons(order));
data.list.forEach((order) => handleAfterSaleButtons(order));
state.pagination.list = _.concat(state.pagination.list, data.list);
state.pagination.total = data.total;
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
@ -137,7 +160,7 @@
//
function loadMore() {
if (state.loadStatus === 'noMore') {
return
return;
}
state.pagination.pageNo++;
getOrderList();

View File

@ -1,29 +1,28 @@
<template>
<s-layout title="退货物流">
<view>
<form @submit="subRefund" report-submit='true'>
<view class='apply-return'>
<view class='list borRadius14'>
<view class='item acea-row row-between-wrapper' style="display: flex;align-items: center;">
<form @submit="subRefund" report-submit="true">
<view class="apply-return">
<view class="list borRadius14">
<view class="item acea-row row-between-wrapper" style="display: flex; align-items: center">
<view>物流公司</view>
<view v-if="state.expresses.length>0" style="flex:1">
<picker mode='selector' class='num' @change="bindPickerChange" :value="state.expressIndex"
:range="state.expresses" range-key="name">
<view class="picker acea-row row-between-wrapper" style="display: flex;justify-content: space-between;">
<view class='reason'>{{ state.expresses[state.expressIndex].name }}</view>
<text class='iconfont _icon-forward' />
<view v-if="state.expresses.length > 0" style="flex: 1;">
<picker mode="selector" class="num" @change="bindPickerChange"
:value="state.expressIndex" :range="state.expresses" range-key="name">
<view class="picker acea-row row-between-wrapper"
style="display: flex; justify-content: space-between;">
<view class="reason">{{ state.expresses[state.expressIndex].name }}</view>
<text class="iconfont _icon-forward"></text>
</view>
</picker>
</view>
</view>
<view class='item textarea acea-row row-between' style="display: flex;align-items: center;">
<view class="item textarea acea-row row-between" style="display: flex; align-items: center">
<view>物流单号</view>
<input placeholder='请填写物流单号' class='num' name="logisticsNo"
placeholder-class='placeholder' />
<input placeholder="请填写物流单号" class="num" name="logisticsNo" placeholder-class="placeholder" />
</view>
<button class='returnBnt bg-color ss-reset-button ui-BG-Main-Gradient sub-btn'
form-type="submit"
style="background: linear-gradient(90deg,var(--ui-BG-Main),var(--ui-BG-Main-gradient))!important">提交</button>
<button class="returnBnt bg-color ss-reset-button ui-BG-Main-Gradient sub-btn" form-type="submit" style="background: linear-gradient( 90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient) ) !important; ">
提交</button>
</view>
</view>
</form>
@ -32,8 +31,12 @@
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { reactive } from 'vue';
import {
onLoad
} from '@dcloudio/uni-app';
import {
reactive
} from 'vue';
import sheep from '@/sheep';
import AfterSaleApi from '@/sheep/api/trade/afterSale';
import DeliveryApi from '@/sheep/api/trade/delivery';
@ -42,7 +45,7 @@
id: 0, //
expressIndex: 0, // expresses
expresses: [], //
})
});
function bindPickerChange(e) {
state.expressIndex = e.detail.value;
@ -54,34 +57,41 @@
logisticsId: state.expresses[state.expressIndex].id,
logisticsNo: e.detail.value.logisticsNo,
};
const { code } = await AfterSaleApi.deliveryAfterSale(data);
const {
code
} = await AfterSaleApi.deliveryAfterSale(data);
if (code !== 0) {
return;
}
uni.showToast({
title: '填写退货成功',
});
sheep.$router.go('/pages/order/aftersale/detail', { id: state.id });
sheep.$router.go('/pages/order/aftersale/detail', {
id: state.id
});
}
//
async function getExpressList() {
const { code, data } = await DeliveryApi.getDeliveryExpressList();
const {
code,
data
} = await DeliveryApi.getDeliveryExpressList();
if (code !== 0) {
return;
}
state.expresses = data;
}
onLoad(options => {
onLoad((options) => {
if (!options.id) {
sheep.$helper.toast(`缺少订单信息,请检查`);
return
return;
}
state.id = options.id;
//
getExpressList();
})
});
</script>
<style lang="scss" scoped>
.apply-return {

View File

@ -221,7 +221,7 @@
pointStatus: false, // TODO
combinationActivityId: state.orderPayload.combinationActivityId,
combinationHeadId: state.orderPayload.combinationHeadId,
seckillActivityId: state.orderPayload.seckillActivityId
seckillActivityId: state.orderPayload.seckillActivityId,
});
if (code !== 0) {
return;
@ -247,7 +247,7 @@
pointStatus: false, // TODO
combinationActivityId: state.orderPayload.combinationActivityId,
combinationHeadId: state.orderPayload.combinationHeadId,
seckillActivityId: state.orderPayload.seckillActivityId
seckillActivityId: state.orderPayload.seckillActivityId,
});
if (code !== 0) {
return;

View File

@ -371,7 +371,7 @@
//
function onComment(id) {
sheep.$router.go('/pages/goods/comment/add', {
id
id,
});
}

View File

@ -78,7 +78,7 @@
}
async function getOrderDetail(id) {
const { data } = await OrderApi.getOrder(id)
const { data } = await OrderApi.getOrder(id);
state.info = data;
}

View File

@ -2,12 +2,21 @@
<template>
<s-layout title="我的订单">
<su-sticky bgColor="#fff">
<su-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab" />
<su-tabs
:list="tabMaps"
:scrollable="false"
@change="onTabsChange"
:current="state.currentTab"
/>
</su-sticky>
<s-empty v-if="state.pagination.total === 0" icon="/static/order-empty.png" text="暂无订单" />
<view v-if="state.pagination.total > 0">
<view class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20" v-for="order in state.pagination.list"
:key="order.id" @tap="onOrderDetail(order.id)">
<view
class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20"
v-for="order in state.pagination.list"
:key="order.id"
@tap="onOrderDetail(order.id)"
>
<view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20">
<view class="order-no">订单号{{ order.no }}</view>
<view class="order-state ss-font-26" :class="formatOrderColor(order)">
@ -25,45 +34,71 @@
</view>
<view class="pay-box ss-m-t-30 ss-flex ss-row-right ss-p-r-20">
<view class="ss-flex ss-col-center">
<view class="discounts-title pay-color"> {{ order.productCount }} 件商品,总金额:</view>
<view class="discounts-money pay-color">
{{ fen2yuan(order.payPrice) }}
<view class="discounts-title pay-color"
> {{ order.productCount }} 件商品,总金额:</view
>
<view class="discounts-money pay-color"> {{ fen2yuan(order.payPrice) }} </view>
</view>
</view>
</view>
<view class="order-card-footer ss-flex ss-col-center ss-p-x-20"
:class="order.buttons.length > 3 ? 'ss-row-between' : 'ss-row-right'">
<view
class="order-card-footer ss-flex ss-col-center ss-p-x-20"
:class="order.buttons.length > 3 ? 'ss-row-between' : 'ss-row-right'"
>
<view class="ss-flex ss-col-center">
<button v-if="order.buttons.includes('combination')" class="tool-btn ss-reset-button"
@tap.stop="onOrderGroupon(order)">
<button
v-if="order.buttons.includes('combination')"
class="tool-btn ss-reset-button"
@tap.stop="onOrderGroupon(order)"
>
拼团详情
</button>
<button v-if="order.buttons.length === 0" class="tool-btn ss-reset-button"
@tap.stop="onOrderDetail(order.id)">
<button
v-if="order.buttons.length === 0"
class="tool-btn ss-reset-button"
@tap.stop="onOrderDetail(order.id)"
>
查看详情
</button>
<button v-if="order.buttons.includes('confirm')" class="tool-btn ss-reset-button"
@tap.stop="onConfirm(order)">
<button
v-if="order.buttons.includes('confirm')"
class="tool-btn ss-reset-button"
@tap.stop="onConfirm(order)"
>
确认收货
</button>
<button v-if="order.buttons.includes('express')" class="tool-btn ss-reset-button"
@tap.stop="onExpress(order.id)">
<button
v-if="order.buttons.includes('express')"
class="tool-btn ss-reset-button"
@tap.stop="onExpress(order.id)"
>
查看物流
</button>
<button v-if="order.buttons.includes('cancel')" class="tool-btn ss-reset-button"
@tap.stop="onCancel(order.id)">
<button
v-if="order.buttons.includes('cancel')"
class="tool-btn ss-reset-button"
@tap.stop="onCancel(order.id)"
>
取消订单
</button>
<button v-if="order.buttons.includes('comment')" class="tool-btn ss-reset-button"
@tap.stop="onComment(order.id)">
<button
v-if="order.buttons.includes('comment')"
class="tool-btn ss-reset-button"
@tap.stop="onComment(order.id)"
>
评价
</button>
<button v-if="order.buttons.includes('delete')" class="delete-btn ss-reset-button"
@tap.stop="onDelete(order.id)">
<button
v-if="order.buttons.includes('delete')"
class="delete-btn ss-reset-button"
@tap.stop="onDelete(order.id)"
>
删除订单
</button>
<button v-if="order.buttons.includes('pay')" class="tool-btn ss-reset-button ui-BG-Main-Gradient"
@tap.stop="onPay(order.payOrderId)">
<button
v-if="order.buttons.includes('pay')"
class="tool-btn ss-reset-button ui-BG-Main-Gradient"
@tap.stop="onPay(order.payOrderId)"
>
继续支付
</button>
</view>
@ -72,9 +107,14 @@
</view>
<!-- 加载更多 -->
<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多',
}" @tap="loadMore" />
}"
@tap="loadMore"
/>
</s-layout>
</template>
@ -83,13 +123,13 @@
import { onLoad, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app';
import {
fen2yuan,
formatOrderColor, formatOrderStatus, handleOrderButtons,
formatOrderColor,
formatOrderStatus,
handleOrderButtons,
} from '@/sheep/hooks/useGoods';
import sheep from '@/sheep';
import _ from 'lodash';
import {
isEmpty
} from 'lodash';
import { isEmpty } from 'lodash';
import OrderApi from '@/sheep/api/trade/order';
import { resetPagination } from '@/sheep/util';
@ -102,11 +142,12 @@
pageNo: 1,
pageSize: 5,
},
loadStatus: ''
loadStatus: '',
});
const tabMaps = [{
name: '全部'
const tabMaps = [
{
name: '全部',
},
{
name: '待付款',
@ -275,13 +316,13 @@
pageNo: state.pagination.pageNo,
pageSize: state.pagination.pageSize,
status: tabMaps[state.currentTab].value,
commentStatus: tabMaps[state.currentTab].value === 30 ? false : null
commentStatus: tabMaps[state.currentTab].value === 30 ? false : null,
});
if (code !== 0) {
return;
}
data.list.forEach(order => handleOrderButtons(order));
state.pagination.list = _.concat(state.pagination.list, data.list)
data.list.forEach((order) => handleOrderButtons(order));
state.pagination.list = _.concat(state.pagination.list, data.list);
state.pagination.total = data.total;
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
}
@ -296,7 +337,7 @@
//
function loadMore() {
if (state.loadStatus === 'noMore') {
return
return;
}
state.pagination.pageNo++;
getOrderList();
@ -380,7 +421,8 @@
font-weight: 500;
}
.order-state {}
.order-state {
}
}
.pay-box {

View File

@ -135,12 +135,13 @@
// payOrder.status => payStatus
function checkPayStatus() {
if (state.orderInfo.status === 10
|| state.orderInfo.status === 20 ) { //
if (state.orderInfo.status === 10 || state.orderInfo.status === 20) {
//
state.payStatus = 2;
return;
}
if (state.orderInfo.status === 30) { //
if (state.orderInfo.status === 30) {
//
state.payStatus = -1;
return;
}
@ -169,17 +170,19 @@
//
async function setPayMethods() {
const { data, code } = await PayChannelApi.getEnableChannelCodeList(state.orderInfo.appId)
const { data, code } = await PayChannelApi.getEnableChannelCodeList(state.orderInfo.appId);
if (code !== 0) {
return
return;
}
state.payMethods = getPayMethods(data)
state.payMethods = getPayMethods(data);
}
onLoad((options) => {
if (sheep.$platform.name === 'WechatOfficialAccount'
&& sheep.$platform.os === 'ios'
&& !sheep.$platform.landingPage.includes('pages/pay/index')) {
if (
sheep.$platform.name === 'WechatOfficialAccount' &&
sheep.$platform.os === 'ios' &&
!sheep.$platform.landingPage.includes('pages/pay/index')
) {
location.reload();
return;
}
@ -208,7 +211,6 @@
position: relative;
padding: 60rpx 20rpx 40rpx;
.money-text {
color: $red;
font-size: 46rpx;

View File

@ -30,7 +30,9 @@
</view>
<view class="time-box item ss-flex ss-col-center ss-row-between">
<text class="item-title">充值时间</text>
<view class="time"> {{ sheep.$helper.timeFormat(item.payTime, 'yyyy-mm-dd hh:MM:ss') }}</view>
<view class="time">
{{ sheep.$helper.timeFormat(item.payTime, 'yyyy-mm-dd hh:MM:ss') }}</view
>
</view>
</view>
</view>

View File

@ -1,12 +1,15 @@
<!-- 充值界面 -->
<template>
<s-layout title="充值" class="withdraw-wrap" navbar="inner">
<view class="wallet-num-box ss-flex ss-col-center ss-row-between" :style="[
<view
class="wallet-num-box ss-flex ss-col-center ss-row-between"
:style="[
{
marginTop: '-' + Number(statusBarHeight + 88) + 'rpx',
paddingTop: Number(statusBarHeight + 108) + 'rpx',
},
]">
]"
>
<view class="">
<view class="num-title">当前余额</view>
<view class="wallet-num">{{ fen2yuan(userWallet.balance) }}</view>
@ -20,20 +23,31 @@
<view class="input-label ss-m-b-50">充值金额</view>
<view class="input-box ss-flex border-bottom ss-p-b-20">
<view class="unit"></view>
<uni-easyinput v-model="state.recharge_money" type="digit" placeholder="请输入充值金额"
:inputBorder="false" />
<uni-easyinput
v-model="state.recharge_money"
type="digit"
placeholder="请输入充值金额"
:inputBorder="false"
/>
</view>
<view class="face-value-box ss-flex ss-flex-wrap ss-m-y-40">
<button class="ss-reset-button face-value-btn" v-for="item in state.packageList" :key="item.money"
<button
class="ss-reset-button face-value-btn"
v-for="item in state.packageList"
:key="item.money"
:class="[{ 'btn-active': state.recharge_money === fen2yuan(item.payPrice) }]"
@tap="onCard(item.payPrice)">
@tap="onCard(item.payPrice)"
>
<text class="face-value-title">{{ fen2yuan(item.payPrice) }}</text>
<view v-if="item.bonusPrice" class="face-value-tag">
{{ fen2yuan(item.bonusPrice) }}
</view>
</button>
</view>
<button class="ss-reset-button save-btn ui-BG-Main-Gradient ss-m-t-60 ui-Shadow-Main" @tap="onConfirm">
<button
class="ss-reset-button save-btn ui-BG-Main-Gradient ss-m-t-60 ui-Shadow-Main"
@tap="onConfirm"
>
确认充值
</button>
</view>
@ -74,8 +88,9 @@
//
async function onConfirm() {
const { code, data } = await PayWalletApi.createWalletRecharge({
packageId: state.packageList.find((item) => fen2yuan(item.payPrice) === state.recharge_money)?.id,
payPrice: state.recharge_money * 100
packageId: state.packageList.find((item) => fen2yuan(item.payPrice) === state.recharge_money)
?.id,
payPrice: state.recharge_money * 100,
});
if (code !== 0) {
return;
@ -85,7 +100,7 @@
// #endif
sheep.$router.go('/pages/pay/index', {
id: data.payOrderId,
orderType: 'recharge'
orderType: 'recharge',
});
}

View File

@ -53,7 +53,7 @@
if (true) {
sheep.$router.go('/pages/public/richtext', {
title: '常见问题',
})
});
return;
}
getFaqList();

View File

@ -41,7 +41,6 @@
}
getRichTextContent(options.id, options.title);
});
</script>
<style lang="scss" scoped>

View File

@ -35,7 +35,7 @@
class="list-border"
@tap="
sheep.$router.go('/pages/public/richtext', {
title: '关于我们'
title: '关于我们',
})
"
/>
@ -59,7 +59,7 @@
class="tcp-text"
@tap="
sheep.$router.go('/pages/public/richtext', {
title: '用户协议'
title: '用户协议',
})
"
>
@ -70,7 +70,7 @@
class="tcp-text"
@tap="
sheep.$router.go('/pages/public/richtext', {
title: '隐私协议'
title: '隐私协议',
})
"
>

View File

@ -1,34 +1,70 @@
<!-- 收货地址的新增/编辑 -->
<template>
<s-layout :title="state.model.id ? '编辑地址' : '新增地址'">
<uni-forms ref="addressFormRef" v-model="state.model" :rules="rules" validateTrigger="bind"
labelWidth="160" labelAlign="left" border :labelStyle="{ fontWeight: 'bold' }">
<uni-forms
ref="addressFormRef"
v-model="state.model"
:rules="rules"
validateTrigger="bind"
labelWidth="160"
labelAlign="left"
border
:labelStyle="{ fontWeight: 'bold' }"
>
<view class="bg-white form-box ss-p-x-30">
<uni-forms-item name="name" label="收货人" class="form-item">
<uni-easyinput v-model="state.model.name" placeholder="请填写收货人姓名" :inputBorder="false"
placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal" />
<uni-easyinput
v-model="state.model.name"
placeholder="请填写收货人姓名"
:inputBorder="false"
placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
/>
</uni-forms-item>
<uni-forms-item name="mobile" label="手机号" class="form-item">
<uni-easyinput v-model="state.model.mobile" type="number" placeholder="请输入手机号" :inputBorder="false"
placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal">
<uni-easyinput
v-model="state.model.mobile"
type="number"
placeholder="请输入手机号"
:inputBorder="false"
placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item name="areaName" label="省市区" @tap="state.showRegion = true" class="form-item">
<uni-easyinput v-model="state.model.areaName" disabled :inputBorder="false"
<uni-forms-item
name="areaName"
label="省市区"
@tap="state.showRegion = true"
class="form-item"
>
<uni-easyinput
v-model="state.model.areaName"
disabled
:inputBorder="false"
:styles="{ disableColor: '#fff', color: '#333' }"
placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
placeholder="请选择省市区">
placeholder="请选择省市区"
>
<template v-slot:right>
<uni-icons type="right" />
</template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item name="detailAddress" label="详细地址" :formItemStyle="{ alignItems: 'flex-start' }"
:labelStyle="{ lineHeight: '5em' }" class="textarea-item">
<uni-easyinput :inputBorder="false" type="textarea" v-model="state.model.detailAddress"
<uni-forms-item
name="detailAddress"
label="详细地址"
:formItemStyle="{ alignItems: 'flex-start' }"
:labelStyle="{ lineHeight: '5em' }"
class="textarea-item"
>
<uni-easyinput
:inputBorder="false"
type="textarea"
v-model="state.model.detailAddress"
placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
placeholder="请输入详细地址" clearable />
placeholder="请输入详细地址"
clearable
/>
</uni-forms-item>
</view>
<view class="ss-m-y-20 bg-white ss-p-x-30 ss-flex ss-row-between ss-col-center default-box">
@ -48,7 +84,11 @@
</su-fixed>
<!-- 省市区弹窗 -->
<su-region-picker :show="state.showRegion" @cancel="state.showRegion = false" @confirm="onRegionConfirm" />
<su-region-picker
:show="state.showRegion"
@cancel="state.showRegion = false"
@confirm="onRegionConfirm"
/>
</s-layout>
</template>
@ -85,22 +125,26 @@
},
mobile,
detailAddress: {
rules: [{
rules: [
{
required: true,
errorMessage: '请输入详细地址',
}]
},
],
},
areaName: {
rules: [{
rules: [
{
required: true,
errorMessage: '请选择您的位置'
}]
errorMessage: '请选择您的位置',
},
],
},
};
//
const onRegionConfirm = (e) => {
state.model.areaName = `${e.province_name} ${e.city_name} ${e.district_name}`
state.model.areaName = `${e.province_name} ${e.city_name} ${e.district_name}`;
state.model.areaId = e.district_id;
state.showRegion = false;
};
@ -130,9 +174,11 @@
//
const formData = {
...state.model
}
const {code } = state.model.id > 0 ? await AddressApi.updateAddress(formData)
...state.model,
};
const { code } =
state.model.id > 0
? await AddressApi.updateAddress(formData)
: await AddressApi.createAddress(formData);
if (code === 0) {
sheep.$router.back();
@ -171,7 +217,7 @@
if (options.data) {
let data = JSON.parse(options.data);
const areaData = uni.getStorageSync('areaData');
const findAreaByName = (areas, name) => areas.find(item => item.name === name);
const findAreaByName = (areas, name) => areas.find((item) => item.name === name);
let provinceObj = findAreaByName(areaData, data.province_name);
let cityObj = provinceObj ? findAreaByName(provinceObj.children, data.city_name) : undefined;
@ -181,7 +227,9 @@
state.model = {
...state.model,
areaId,
areaName: [data.province_name, data.city_name, data.district_name].filter(Boolean).join(" "),
areaName: [data.province_name, data.city_name, data.district_name]
.filter(Boolean)
.join(' '),
defaultStatus: false,
detailAddress: data.address,
mobile: data.mobile,

View File

@ -2,26 +2,39 @@
<template>
<s-layout title="收货地址" :bgStyle="{ color: '#FFF' }">
<view v-if="state.list.length">
<s-address-item hasBorderBottom v-for="item in state.list" :key="item.id" :item="item"
@tap="onSelect(item)" />
<s-address-item
hasBorderBottom
v-for="item in state.list"
:key="item.id"
:item="item"
@tap="onSelect(item)"
/>
</view>
<su-fixed bottom placeholder>
<view class="footer-box ss-flex ss-row-between ss-p-20">
<!-- 微信小程序和微信H5 -->
<button v-if="['WechatMiniProgram', 'WechatOfficialAccount'].includes(sheep.$platform.name)"
<button
v-if="['WechatMiniProgram', 'WechatOfficialAccount'].includes(sheep.$platform.name)"
@tap="importWechatAddress"
class="border ss-reset-button sync-wxaddress ss-m-20 ss-flex ss-row-center ss-col-center">
class="border ss-reset-button sync-wxaddress ss-m-20 ss-flex ss-row-center ss-col-center"
>
<text class="cicon-weixin ss-p-r-10" style="color: #09bb07; font-size: 40rpx"></text>
导入微信地址
</button>
<button class="add-btn ss-reset-button ui-Shadow-Main"
@tap="sheep.$router.go('/pages/user/address/edit')">
<button
class="add-btn ss-reset-button ui-Shadow-Main"
@tap="sheep.$router.go('/pages/user/address/edit')"
>
新增收货地址
</button>
</view>
</su-fixed>
<s-empty v-if="state.list.length === 0 && !state.loading" text="暂无收货地址" icon="/static/data-empty.png" />
<s-empty
v-if="state.list.length === 0 && !state.loading"
text="暂无收货地址"
icon="/static/data-empty.png"
/>
</s-layout>
</template>

View File

@ -5,7 +5,8 @@
<!-- 头部 -->
<view class="cart-header ss-flex ss-col-center ss-row-between ss-p-x-30">
<view class="header-left ss-flex ss-col-center ss-font-26">
<text class="goods-number ui-TC-Main ss-flex">{{ state.pagination.total }}</text> 件商品
<text class="goods-number ui-TC-Main ss-flex">{{ state.pagination.total }}</text> 件商品
</view>
<view class="header-right">
<button
@ -77,7 +78,8 @@
<view class="footer-right">
<button
class="ss-reset-button ui-BG-Main-Gradient pay-btn ss-font-28 ui-Shadow-Main"
@tap="onCancel">
@tap="onCancel"
>
取消收藏
</button>
</view>
@ -129,7 +131,7 @@
if (code !== 0) {
return;
}
state.pagination.list = _.concat(state.pagination.list, data.list)
state.pagination.list = _.concat(state.pagination.list, data.list);
state.pagination.total = data.total;
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
}
@ -174,7 +176,7 @@
//
function loadMore() {
if (state.loadStatus === 'noMore') {
return
return;
}
state.pagination.pageNo++;
getData();

View File

@ -81,11 +81,13 @@
</view>
<view class="footer-right ss-flex">
<button
:class="['ss-reset-button pay-btn ss-font-28 ',
:class="[
'ss-reset-button pay-btn ss-font-28 ',
{
'ui-BG-Main-Gradient': state.selectedSpuIdList.length > 0,
'ui-Shadow-Main': state.selectedSpuIdList.length > 0
}]"
'ui-Shadow-Main': state.selectedSpuIdList.length > 0,
},
]"
@tap="onDelete"
>
删除足迹
@ -121,8 +123,8 @@
import { reactive } from 'vue';
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import _ from 'lodash';
import SpuHistoryApi from "@/sheep/api/product/history";
import {cloneDeep} from "@/sheep/helper/utils";
import SpuHistoryApi from '@/sheep/api/product/history';
import { cloneDeep } from '@/sheep/helper/utils';
const sys_navBar = sheep.$platform.navbar;
const pagination = {

View File

@ -26,7 +26,8 @@
<button
class="ss-reset-button avatar-action-btn"
open-type="chooseAvatar"
@chooseavatar="onChooseAvatar">
@chooseavatar="onChooseAvatar"
>
修改
</button>
<!-- #endif -->
@ -154,10 +155,7 @@
</view>
<view class="ss-flex ss-col-center">
<view class="info ss-flex ss-col-center" v-if="state.thirdInfo">
<image
class="avatar ss-m-r-20"
:src="sheep.$url.cdn(state.thirdInfo.avatar)"
/>
<image class="avatar ss-m-r-20" :src="sheep.$url.cdn(state.thirdInfo.avatar)" />
<text class="name">{{ state.thirdInfo.nickname }}</text>
</view>
<view class="bind-box ss-m-l-20">
@ -198,14 +196,15 @@
const placeholderStyle = 'color:#BBBBBB;font-size:28rpx;line-height:normal';
const sexRadioMap = [{
const sexRadioMap = [
{
name: '男',
value: '1',
},
{
name: '女',
value: '2',
}
},
];
const userInfo = computed(() => sheep.$store('user').userInfo);

View File

@ -13,7 +13,9 @@
/>
</view>
<view class="ss-flex ss-row-between ss-col-center ss-m-t-64">
<view class="money-num">{{ state.showMoney ? fen2yuan(userWallet.balance) : '*****' }}</view>
<view class="money-num">{{
state.showMoney ? fen2yuan(userWallet.balance) : '*****'
}}</view>
<button class="ss-reset-button topup-btn" @tap="sheep.$router.go('/pages/pay/recharge')">
充值
</button>
@ -24,7 +26,12 @@
<su-sticky>
<!-- 统计 -->
<view class="filter-box ss-p-x-30 ss-flex ss-col-center ss-row-between">
<uni-datetime-picker v-model="state.data" type="daterange" @change="onChangeTime" :end="state.today">
<uni-datetime-picker
v-model="state.data"
type="daterange"
@change="onChangeTime"
:end="state.today"
>
<button class="ss-reset-button date-btn">
<text>{{ dateFilterText }}</text>
<text class="cicon-drop-down ss-seldate-icon"></text>
@ -98,7 +105,7 @@
list: [],
total: 0,
pageNo: 1,
pageSize: 8
pageSize: 8,
},
summary: {
totalIncome: 0,
@ -155,7 +162,7 @@
//
async function getSummary() {
const { data, code } = await PayWalletApi.getWalletTransactionSummary({
'createTime': [state.date[0] + ' 00:00:00', state.date[1] + ' 23:59:59'],
createTime: [state.date[0] + ' 00:00:00', state.date[1] + ' 23:59:59'],
});
if (code !== 0) {
return;
@ -226,8 +233,7 @@
position: absolute;
top: 0;
left: 0;
background: v-bind(headerBg)
no-repeat;
background: v-bind(headerBg) no-repeat;
pointer-events: none;
}

View File

@ -24,7 +24,12 @@
<su-sticky :customNavHeight="sys_navBar">
<!-- 统计 -->
<view class="filter-box ss-p-x-30 ss-flex ss-col-center ss-row-between">
<uni-datetime-picker v-model="state.date" type="daterange" @change="onChangeTime" :end="state.today">
<uni-datetime-picker
v-model="state.date"
type="daterange"
@change="onChangeTime"
:end="state.today"
>
<button class="ss-reset-button date-btn">
<text>{{ dateFilterText }}</text>
<text class="cicon-drop-down ss-seldate-icon"></text>

View File

@ -5,7 +5,7 @@ const AddressApi = {
getAddressList: () => {
return request({
url: '/member/address/list',
method: 'GET'
method: 'GET',
});
},
// 创建用户收件地址
@ -16,7 +16,7 @@ const AddressApi = {
data,
custom: {
showSuccess: true,
successMsg: '保存成功'
successMsg: '保存成功',
},
});
},
@ -28,7 +28,7 @@ const AddressApi = {
data,
custom: {
showSuccess: true,
successMsg: '更新成功'
successMsg: '更新成功',
},
});
},
@ -37,7 +37,7 @@ const AddressApi = {
return request({
url: '/member/address/get',
method: 'GET',
params: { id }
params: { id },
});
},
// 删除用户收件地址
@ -45,7 +45,24 @@ const AddressApi = {
return request({
url: '/member/address/delete',
method: 'DELETE',
params: { id }
params: { id },
});
},
// 文章列表
textList: (id) => {
return request({
url: '/promotion/article/list',
method: 'GET',
params: { id },
});
},
// 文章列表详情
textListDetail: (id) => {
return request({
url: '/promotion/article/get',
method: 'GET',
params: { id },
});
},
};

View File

@ -56,7 +56,7 @@ const AuthUtil = {
url: '/member/auth/refresh-token',
method: 'POST',
params: {
refreshToken
refreshToken,
},
custom: {
loading: false, // 不用加载中
@ -103,7 +103,7 @@ const AuthUtil = {
data: {
phoneCode,
loginCode,
state
state,
},
custom: {
showSuccess: true,
@ -118,13 +118,13 @@ const AuthUtil = {
url: '/member/auth/create-weixin-jsapi-signature',
method: 'POST',
params: {
url
url,
},
custom: {
showError: false,
showLoading: false,
},
})
});
},
//
};

View File

@ -4,7 +4,7 @@ const PointApi = {
// 获得用户积分记录分页
getPointRecordPage: (params) => {
if (params.addStatus === undefined) {
delete params.addStatus
delete params.addStatus;
}
const queryString = Object.keys(params)
.map((key) => encodeURIComponent(key) + '=' + params[key])
@ -13,7 +13,7 @@ const PointApi = {
url: `/member/point/record/page?${queryString}`,
method: 'GET',
});
}
},
};
export default PointApi;

View File

@ -7,7 +7,7 @@ const SocialApi = {
url: '/member/social-user/get',
method: 'GET',
params: {
type
type,
},
custom: {
showLoading: false,
@ -22,7 +22,7 @@ const SocialApi = {
data: {
type,
code,
state
state,
},
custom: {
custom: {
@ -40,7 +40,7 @@ const SocialApi = {
method: 'DELETE',
data: {
type,
openid
openid,
},
custom: {
showLoading: false,

View File

@ -21,7 +21,7 @@ const UserApi = {
custom: {
auth: true,
showSuccess: true,
successMsg: '更新成功'
successMsg: '更新成功',
},
});
},
@ -34,7 +34,7 @@ const UserApi = {
custom: {
loadingMsg: '验证中',
showSuccess: true,
successMsg: '修改成功'
successMsg: '修改成功',
},
});
},
@ -44,12 +44,12 @@ const UserApi = {
url: '/member/user/update-mobile-by-weixin',
method: 'PUT',
data: {
code
code,
},
custom: {
showSuccess: true,
loadingMsg: '获取中',
successMsg: '修改成功'
successMsg: '修改成功',
},
});
},
@ -62,7 +62,7 @@ const UserApi = {
custom: {
loadingMsg: '验证中',
showSuccess: true,
successMsg: '修改成功'
successMsg: '修改成功',
},
});
},
@ -75,11 +75,10 @@ const UserApi = {
custom: {
loadingMsg: '验证中',
showSuccess: true,
successMsg: '修改成功'
}
successMsg: '修改成功',
},
});
},
};
export default UserApi;

View File

@ -10,12 +10,12 @@ export default {
method: 'GET',
params: {
ids: ids.join(','),
}
},
}),
getMpLink: () =>
request({
url: 'app/mplive/getMpLink',
method: 'GET'
method: 'GET',
}),
},
};

View File

@ -6,7 +6,7 @@ const PayChannelApi = {
return request({
url: '/pay/channel/get-enable-code-list',
method: 'GET',
params: { appId }
params: { appId },
});
},
};

View File

@ -6,7 +6,7 @@ const PayOrderApi = {
return request({
url: '/pay/order/get',
method: 'GET',
params: { id }
params: { id },
});
},
// 提交支付订单
@ -14,9 +14,9 @@ const PayOrderApi = {
return request({
url: '/pay/order/submit',
method: 'POST',
data
data,
});
}
},
};
export default PayOrderApi;

View File

@ -31,7 +31,7 @@ const SpuHistoryApi = {
method: 'GET',
data,
custom: {
showLoading: false
showLoading: false,
},
});
},

View File

@ -6,7 +6,7 @@ export default {
return request({
url: '/promotion/article/get',
method: 'GET',
params: { id, title }
params: { id, title },
});
}
}
},
};

View File

@ -47,9 +47,9 @@ const CombinationApi = {
// 获得我的拼团记录分页
getCombinationRecordPage: (params) => {
return request({
url: "/promotion/combination-record/page",
url: '/promotion/combination-record/page',
method: 'GET',
params
params,
});
},

View File

@ -95,7 +95,7 @@ const CouponApi = {
showLoading: false, // 避免影响 settlementOrder 结算的结果
},
});
}
},
};
export default CouponApi;

View File

@ -16,7 +16,7 @@ const DiyApi = {
url: '/promotion/diy-template/get',
method: 'GET',
params: {
id
id,
},
custom: {
showError: false,
@ -29,8 +29,8 @@ const DiyApi = {
url: '/promotion/diy-page/get',
method: 'GET',
params: {
id
}
id,
},
});
},
};

View File

@ -8,7 +8,7 @@ const RewardActivityApi = {
method: 'GET',
params: { id },
});
}
},
};
export default RewardActivityApi;

View File

@ -1,4 +1,4 @@
import request from "@/sheep/request";
import request from '@/sheep/request';
const SeckillApi = {
// 获得秒杀时间段列表
@ -25,9 +25,9 @@ const SeckillApi = {
return request({
url: 'promotion/seckill-activity/get-detail',
method: 'GET',
params: { id }
params: { id },
});
}
}
},
};
export default SeckillApi;

View File

@ -5,7 +5,7 @@ const AreaApi = {
getAreaTree: () => {
return request({
url: '/system/area/tree',
method: 'GET'
method: 'GET',
});
},
};

View File

@ -57,7 +57,7 @@ const AfterSaleApi = {
method: 'PUT',
data,
});
}
},
};
export default AfterSaleApi;

View File

@ -6,14 +6,14 @@ const BrokerageApi = {
return request({
url: '/trade/brokerage-user/bind',
method: 'PUT',
data
data,
});
},
// 获得个人分销信息
getBrokerageUser: () => {
return request({
url: '/trade/brokerage-user/get',
method: 'GET'
method: 'GET',
});
},
// 获得个人分销统计
@ -24,12 +24,12 @@ const BrokerageApi = {
});
},
// 获得分销记录分页
getBrokerageRecordPage: params => {
getBrokerageRecordPage: (params) => {
if (params.status === undefined) {
delete params.status
delete params.status;
}
const queryString = Object.keys(params)
.map(key => encodeURIComponent(key) + '=' + params[key])
.map((key) => encodeURIComponent(key) + '=' + params[key])
.join('&');
return request({
url: `/trade/brokerage-record/page?${queryString}`,
@ -37,7 +37,7 @@ const BrokerageApi = {
});
},
// 创建分销提现
createBrokerageWithdraw: data => {
createBrokerageWithdraw: (data) => {
return request({
url: '/trade/brokerage-withdraw/create',
method: 'POST',
@ -45,15 +45,15 @@ const BrokerageApi = {
});
},
// 获得商品的分销金额
getProductBrokeragePrice: spuId => {
getProductBrokeragePrice: (spuId) => {
return request({
url: '/trade/brokerage-record/get-product-brokerage-price',
method: 'GET',
params: { spuId }
params: { spuId },
});
},
// 获得分销用户排行(基于佣金)
getRankByPrice: params => {
getRankByPrice: (params) => {
const queryString = `times=${params.times[0]}&times=${params.times[1]}`;
return request({
url: `/trade/brokerage-user/get-rank-by-price?${queryString}`,
@ -61,9 +61,9 @@ const BrokerageApi = {
});
},
// 获得分销用户排行分页(基于佣金)
getBrokerageUserChildSummaryPageByPrice: params => {
getBrokerageUserChildSummaryPageByPrice: (params) => {
const queryString = Object.keys(params)
.map(key => encodeURIComponent(key) + '=' + params[key])
.map((key) => encodeURIComponent(key) + '=' + params[key])
.join('&');
return request({
url: `/trade/brokerage-user/rank-page-by-price?${queryString}`,
@ -71,9 +71,9 @@ const BrokerageApi = {
});
},
// 获得分销用户排行分页(基于用户量)
getBrokerageUserRankPageByUserCount: params => {
getBrokerageUserRankPageByUserCount: (params) => {
const queryString = Object.keys(params)
.map(key => encodeURIComponent(key) + '=' + params[key])
.map((key) => encodeURIComponent(key) + '=' + params[key])
.join('&');
return request({
url: `/trade/brokerage-user/rank-page-by-user-count?${queryString}`,
@ -81,13 +81,13 @@ const BrokerageApi = {
});
},
// 获得下级分销统计分页
getBrokerageUserChildSummaryPage: params => {
getBrokerageUserChildSummaryPage: (params) => {
return request({
url: '/trade/brokerage-user/child-summary-page',
method: 'GET',
params,
})
}
}
});
},
};
export default BrokerageApi
export default BrokerageApi;

View File

@ -9,21 +9,21 @@ const CartApi = {
custom: {
showSuccess: true,
successMsg: '已添加到购物车~',
}
},
});
},
updateCartCount: (data) => {
return request({
url: '/trade/cart/update-count',
method: 'PUT',
data: data
data: data,
});
},
updateCartSelected: (data) => {
return request({
url: '/trade/cart/update-selected',
method: 'PUT',
data: data
data: data,
});
},
deleteCart: (ids) => {
@ -31,8 +31,8 @@ const CartApi = {
url: '/trade/cart/delete',
method: 'DELETE',
params: {
ids
}
ids,
},
});
},
getCartList: () => {

View File

@ -7,7 +7,7 @@ const DeliveryApi = {
url: `/trade/delivery/express/list`,
method: 'get',
});
}
},
};
export default DeliveryApi;

View File

@ -43,7 +43,7 @@
const emits = defineEmits(['close']);
const state = reactive({
activityInfo: computed(() => props.modelValue),
activityMap: {}
activityMap: {},
});
watch(
@ -51,13 +51,13 @@
() => {
//
if (props.show) {
state.activityInfo?.forEach(activity => {
RewardActivityApi.getRewardActivity(activity.id).then(res => {
state.activityInfo?.forEach((activity) => {
RewardActivityApi.getRewardActivity(activity.id).then((res) => {
if (res.code !== 0) {
return;
}
state.activityMap[activity.id] = res.data;
})
});
});
}
},

View File

@ -18,9 +18,7 @@
<view class="address-text">
{{ props.item.detailAddress }}
</view>
<view class="person-text">
{{ props.item.name }} {{ props.item.mobile }}
</view>
<view class="person-text"> {{ props.item.name }} {{ props.item.mobile }} </view>
</view>
<view v-else>
<view class="address-text ss-m-b-10">请选择收货地址</view>

View File

@ -89,7 +89,7 @@
//
if (!props.agreeStatus) {
emits('onConfirm', true)
emits('onConfirm', true);
sheep.$helper.toast('请勾选同意');
return;
}

View File

@ -53,9 +53,7 @@
</uni-forms-item>
</uni-forms>
<button class="ss-reset-button type-btn" @tap="closeAuthModal">
取消修改
</button>
<button class="ss-reset-button type-btn" @tap="closeAuthModal"> 取消修改 </button>
</view>
</template>

View File

@ -110,7 +110,7 @@
return;
}
//
showAuthModal('accountLogin')
showAuthModal('accountLogin');
};
</script>

View File

@ -102,7 +102,7 @@
return;
}
if (!props.agreeStatus) {
emits('onConfirm', true)
emits('onConfirm', true);
sheep.$helper.toast('请勾选同意');
return;
}

View File

@ -10,7 +10,11 @@
/>
<!-- 2. 短信登录 smsLogin -->
<sms-login v-if="authType === 'smsLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
<sms-login
v-if="authType === 'smsLogin'"
:agreeStatus="state.protocol"
@onConfirm="onConfirm"
/>
<!-- 3. 忘记密码 resetPassword-->
<reset-password v-if="authType === 'resetPassword'" />
@ -32,7 +36,11 @@
<!-- 7.1 微信小程序的快捷登录 -->
<view v-if="sheep.$platform.name === 'WechatMiniProgram'" class="ss-flex register-box">
<view class="register-title">还没有账号?</view>
<button class="ss-reset-button login-btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
<button
class="ss-reset-button login-btn"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
>
快捷登录
</button>
<view class="circle" />
@ -81,13 +89,9 @@
/>
<view class="agreement-text ss-flex ss-col-center ss-m-l-8">
我已阅读并遵守
<view class="tcp-text" @tap.stop="onProtocol('用户协议')">
用户协议
</view>
<view class="tcp-text" @tap.stop="onProtocol('用户协议')"> 用户协议 </view>
<view class="agreement-text"></view>
<view class="tcp-text" @tap.stop="onProtocol('隐私协议')">
隐私协议
</view>
<view class="tcp-text" @tap.stop="onProtocol('隐私协议')"> 隐私协议 </view>
</view>
</label>
</view>

View File

@ -44,7 +44,24 @@
<!-- 营销组件优惠券 -->
<s-coupon-block v-if="type === 'CouponCard'" :data="data" :styles="styles" />
<!-- 营销组件文章 -->
<s-richtext-block v-if="type === 'PromotionArticle'" :data="data" :styles="styles" />
<!-- <s-richtext-block v-if="type === 'PromotionArticle'" :data="data" :styles="styles" /> -->
<view class="floxt" v-if="type === 'PromotionArticle'" >
<view class="addClass" v-for="(item, index) in state.model" @click="path(item.id)">
<view class="image">
<image
:src="item.picUrl"
alt="" />
</view>
<view class="text">
<view class="top">
{{item.title}}
</view>
<view class="bottom">
{{ sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}
</view>
</view>
</view>
</view>
<!-- 用户组件用户卡片 -->
<s-user-card v-if="type === 'UserCard'" />
@ -58,6 +75,19 @@
</template>
<script setup>
import sheep from '@/sheep';
import { ref, reactive, unref } from 'vue';
import AddressApi from '@/sheep/api/member/address';
const state = reactive({
model: [],
});
const ff = async (id) => {
let { code, data } = await AddressApi.textList();
state.model = data;
}
ff();
/**
* 装修组件 - 组件集
*/
@ -75,7 +105,54 @@
default () {},
},
});
function onSearch() {}
function path(id) {
// $u.route({url:'/pages/goods/index',params:{id:'14'}})
uni.navigateTo({
url: `/pages/mulu/mulu?id=${id}`
});
}
</script>
<style></style>
<style scoped lang="scss">
.floxt {
width: 100%;
.addClass {
background:white;
display: flex;
justify-content: space-between;
width: 100%;
margin:20rpx 0;
// padding: 40rpx;
// padding-right: 0;
// height: 200rpx;
.image {
width: 250rpx;
height: 156rpx;
margin-right: 18rpx;
padding:20rpx 20rpx;
image{
width: 100%;
height: 100%;
}
}
.text {
display: flex;
width: 100%;
// text-align: center;
padding:20rpx 20rpx;
flex:1;
flex-direction: column;
justify-content: space-between;
.bottom{
color: #999;
font-size: 12px;
}
}
}
}
</style>

View File

@ -21,8 +21,7 @@
const elBackground = computed(() => {
if (props.styles) {
if (props.styles.bgType === 'color')
return { background: props.styles.bgColor };
if (props.styles.bgType === 'color') return { background: props.styles.bgColor };
if (props.styles.bgType === 'img')
return {
background: `url(${sheep.$url.cdn(

View File

@ -1,76 +1,106 @@
<template>
<view class="time" :style="justifyLeft">
<text class="" v-if="tipText">{{ tipText }}</text>
<text class="styleAll p6" v-if="isDay === true"
:style="{background:bgColor.bgColor,color:bgColor.Color}">{{ day }}{{bgColor.isDay?'天':''}}</text>
<text class="timeTxt" v-if="dayText"
:style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ dayText }}</text>
<text class="styleAll" :class='isCol?"timeCol":""'
:style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ hour }}</text>
<text class="timeTxt" v-if="hourText" :class='isCol?"whit":""'
:style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ hourText }}</text>
<text class="styleAll" :class='isCol?"timeCol":""'
:style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ minute }}</text>
<text class="timeTxt" v-if="minuteText" :class='isCol?"whit":""'
:style="{width:bgColor.timeTxtwidth,color:bgColor.bgColor}">{{ minuteText }}</text>
<text class="styleAll" :class='isCol?"timeCol":""'
:style="{background:bgColor.bgColor,color:bgColor.Color,width:bgColor.width}">{{ second }}</text>
<text
class="styleAll p6"
v-if="isDay === true"
:style="{ background: bgColor.bgColor, color: bgColor.Color }"
>{{ day }}{{ bgColor.isDay ? '天' : '' }}</text
>
<text
class="timeTxt"
v-if="dayText"
:style="{ width: bgColor.timeTxtwidth, color: bgColor.bgColor }"
>{{ dayText }}</text
>
<text
class="styleAll"
:class="isCol ? 'timeCol' : ''"
:style="{ background: bgColor.bgColor, color: bgColor.Color, width: bgColor.width }"
>{{ hour }}</text
>
<text
class="timeTxt"
v-if="hourText"
:class="isCol ? 'whit' : ''"
:style="{ width: bgColor.timeTxtwidth, color: bgColor.bgColor }"
>{{ hourText }}</text
>
<text
class="styleAll"
:class="isCol ? 'timeCol' : ''"
:style="{ background: bgColor.bgColor, color: bgColor.Color, width: bgColor.width }"
>{{ minute }}</text
>
<text
class="timeTxt"
v-if="minuteText"
:class="isCol ? 'whit' : ''"
:style="{ width: bgColor.timeTxtwidth, color: bgColor.bgColor }"
>{{ minuteText }}</text
>
<text
class="styleAll"
:class="isCol ? 'timeCol' : ''"
:style="{ background: bgColor.bgColor, color: bgColor.Color, width: bgColor.width }"
>{{ second }}</text
>
<text class="timeTxt" v-if="secondText">{{ secondText }}</text>
</view>
</template>
<script>
export default {
name: "countDown",
name: 'countDown',
props: {
justifyLeft: {
type: String,
default: ""
default: '',
},
//
tipText: {
type: String,
default: "倒计时"
default: '倒计时',
},
dayText: {
type: String,
default: "天"
default: '天',
},
hourText: {
type: String,
default: "时"
default: '时',
},
minuteText: {
type: String,
default: "分"
default: '分',
},
secondText: {
type: String,
default: "秒"
default: '秒',
},
datatime: {
type: Number,
default: 0
default: 0,
},
isDay: {
type: Boolean,
default: true
default: true,
},
isCol: {
type: Boolean,
default: false
default: false,
},
bgColor: {
type: Object,
default: null
}
default: null,
},
},
data: function () {
return {
day: "00",
hour: "00",
minute: "00",
second: "00"
day: '00',
hour: '00',
minute: '00',
second: '00',
};
},
created: function () {
@ -97,29 +127,25 @@
}
hour = Math.floor(intDiff / (60 * 60)) - day * 24;
minute = Math.floor(intDiff / 60) - day * 24 * 60 - hour * 60;
second =
Math.floor(intDiff) -
day * 24 * 60 * 60 -
hour * 60 * 60 -
minute * 60;
if (hour <= 9) hour = "0" + hour;
if (minute <= 9) minute = "0" + minute;
if (second <= 9) second = "0" + second;
second = Math.floor(intDiff) - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60;
if (hour <= 9) hour = '0' + hour;
if (minute <= 9) minute = '0' + minute;
if (second <= 9) second = '0' + second;
that.day = day;
that.hour = hour;
that.minute = minute;
that.second = second;
} else {
that.day = "00";
that.hour = "00";
that.minute = "00";
that.second = "00";
that.day = '00';
that.hour = '00';
that.minute = '00';
that.second = '00';
}
}
runTime();
setInterval(runTime, 1000);
}
}
},
},
};
</script>
@ -168,6 +194,6 @@
border-radius: 6px;
background: #fff;
font-size: 24rpx; */
color: #E93323;
color: #e93323;
}
</style>

View File

@ -47,8 +47,8 @@
import sheep from '@/sheep';
import CouponApi from '@/sheep/api/promotion/coupon';
import { ref, onMounted } from 'vue';
import { CouponTemplateValidityTypeEnum, PromotionDiscountTypeEnum } from "@/sheep/util/const";
import { floatToFixed2, formatDate } from "@/sheep/util";
import { CouponTemplateValidityTypeEnum, PromotionDiscountTypeEnum } from '@/sheep/util/const';
import { floatToFixed2, formatDate } from '@/sheep/util';
const props = defineProps({
data: {
@ -61,7 +61,7 @@
},
});
const { columns, button } = props.data;
const SIZE_LIST = ['lg', 'md', 'xs']
const SIZE_LIST = ['lg', 'md', 'xs'];
const couponBg = {
background: `url(${sheep.$url.cdn(props.data.bgImg)}) no-repeat top center / 100% 100%`,
};
@ -73,35 +73,35 @@
//
const formatCouponDiscountType = (coupon) => {
if (coupon.discountType === PromotionDiscountTypeEnum.PRICE.type) {
return 'reduce'
return 'reduce';
}
if (coupon.discountType === PromotionDiscountTypeEnum.PERCENT.type) {
return 'percent'
}
return `未知【${coupon.discountType}`
return 'percent';
}
return `未知【${coupon.discountType}`;
};
//
const formatCouponDiscountValue = (coupon) => {
if (coupon.discountType === PromotionDiscountTypeEnum.PRICE.type) {
return floatToFixed2(coupon.discountPrice)
return floatToFixed2(coupon.discountPrice);
}
if (coupon.discountType === PromotionDiscountTypeEnum.PERCENT.type) {
return coupon.discountPercent
}
return `未知【${coupon.discountType}`
return coupon.discountPercent;
}
return `未知【${coupon.discountType}`;
};
//
const formatValidityType = (row) => {
if (row.validityType === CouponTemplateValidityTypeEnum.DATE.type) {
return `${formatDate(row.validStartTime)}${formatDate(row.validEndTime)}`
return `${formatDate(row.validStartTime)}${formatDate(row.validEndTime)}`;
}
if (row.validityType === CouponTemplateValidityTypeEnum.TERM.type) {
return `领取后第 ${row.fixedStartTerm} - ${row.fixedEndTerm} 天内可用`
}
return '未知【' + row.validityType + '】'
return `领取后第 ${row.fixedStartTerm} - ${row.fixedEndTerm} 天内可用`;
}
return '未知【' + row.validityType + '】';
};
const couponList = ref([]);
//
@ -112,16 +112,16 @@
title: msg,
icon: 'none',
});
return
return;
}
await getCouponTemplateList()
await getCouponTemplateList();
}
const getCouponTemplateList = async () => {
const { data } = await CouponApi.getCouponTemplateListByIds(props.data.couponIds.join(','));
couponList.value = data;
}
};
onMounted(() => {
getCouponTemplateList()
getCouponTemplateList();
});
</script>

View File

@ -1,9 +1,13 @@
<!-- 装修用户组件用户卡券 -->
<template>
<view class="ss-coupon-menu-wrap ss-flex ss-col-center">
<view class="menu-item ss-flex-col ss-row-center ss-col-center" v-for="item in props.list" :key="item.title"
<view
class="menu-item ss-flex-col ss-row-center ss-col-center"
v-for="item in props.list"
:key="item.title"
@tap="sheep.$router.go(item.path, { type: item.type })"
:class="item.type === 'all' ? 'menu-wallet' : 'ss-flex-1'">
:class="item.type === 'all' ? 'menu-wallet' : 'ss-flex-1'"
>
<image class="item-icon" :src="sheep.$url.static(item.icon)" mode="aspectFit"></image>
<view class="menu-title ss-m-t-28">{{ item.title }}</view>
</view>
@ -21,7 +25,8 @@
list: {
type: Array,
default() {
return [{
return [
{
title: '已领取',
value: '0',
icon: '/static/img/shop/order/nouse_coupon.png',

View File

@ -52,7 +52,7 @@
const emits = defineEmits(['get', 'close']);
const state = reactive({
couponInfo: computed(() => props.modelValue)
couponInfo: computed(() => props.modelValue),
});
//

View File

@ -42,18 +42,11 @@
>
有效期领取后 {{ data.fixedEndTerm }} 天内可用
</view>
<view
class="sellby-text"
:class=" isDisable ? 'disabled-color' : 'subtitle-color'"
v-else
>
<view class="sellby-text" :class="isDisable ? 'disabled-color' : 'subtitle-color'" v-else>
有效期: {{ sheep.$helper.timeFormat(data.validStartTime, 'yyyy-mm-dd') }}
{{ sheep.$helper.timeFormat(data.validEndTime, 'yyyy-mm-dd') }}
</view>
<view
class="value-enough"
:class="isDisable ? 'disabled-color' : 'subtitle-color'"
>
<view class="value-enough" :class="isDisable ? 'disabled-color' : 'subtitle-color'">
{{ fen2yuan(data.usePrice) }} 可用
</view>
</view>

Some files were not shown because too many files have changed in this diff Show More