完成京东购物新增

This commit is contained in:
tangxinyue 2026-04-08 18:32:10 +08:00
parent a2dc82ab4b
commit 8c3298af2a
8 changed files with 1015 additions and 326 deletions

View File

@ -7,7 +7,7 @@ export default {
},
onLaunch: function (options) {
console.log=()=>{}
// console.log=()=>{}
// === wgt ===
console.log('=== App Launch 开始 ===')
console.log('启动参数:', JSON.stringify(options))

View File

@ -8,12 +8,15 @@
<!-- 输入层 -->
<template v-if="type !== 'textarea'">
<input class="auto-input" :type="type" :value="modelValue" :placeholder="placeholder" :placeholder-style="placeholderStyle"
:style="[inputStyle, { width: inputWidth }]" @input="onInput" :maxlength="maxlength" />
:style="[inputStyle, { width: finalInputWidth }]" @input="onInput" :maxlength="maxlength" :focus="isFocus" @blur="onBlur" />
</template>
<template v-else>
<textarea class="auto-textarea" :value="modelValue" :placeholder="placeholder" :placeholder-style="placeholderStyle"
:style="[inputStyle]" @input="onInput" :maxlength="maxlength" auto-height />
:style="[inputStyle]" @input="onInput" :maxlength="maxlength" auto-height :focus="isFocus" @blur="onBlur" />
</template>
<!-- 编辑图标 -->
<image v-if="showEdit" class="edit-icon" src="/static/image/common/edit.png" @click="handleFocusIcon"></image>
</view>
</template>
@ -60,12 +63,28 @@ const props = defineProps({
extraWidth: {
type: Number,
default: 10 //
},
showEdit: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['update:modelValue', 'change']);
const instance = getCurrentInstance();
const inputWidth = ref(props.minWidth);
//
const finalInputWidth = computed(() => {
// textarea 使
if (props.type === 'textarea') return '100%';
// class
const classStr = instance.proxy.$attrs.class || '';
if (classStr.includes('flex-1') || classStr.includes('w100')) {
return '100%';
}
return inputWidth.value;
});
const isFocus = ref(false);
const inputStyle = computed(() => ({
fontSize: props.fontSize,
@ -74,11 +93,29 @@ const inputStyle = computed(() => ({
fontFamily: 'inherit'
}));
/**
* 点击图标触发聚焦
*/
const handleFocusIcon = () => {
isFocus.value = false;
nextTick(() => {
isFocus.value = true;
});
};
/**
* 失去焦点处理
*/
const onBlur = () => {
isFocus.value = false;
};
/**
* 核心逻辑测量隐藏文本的物理宽度
*/
const updateWidth = () => {
if (props.type === 'textarea') return;
//
nextTick(() => {
const query = uni.createSelectorQuery().in(instance.proxy);
query.select('.measure-text').boundingClientRect(data => {
@ -114,11 +151,23 @@ onMounted(() => {
<style lang="less" scoped>
.auto-width-input-container {
position: relative;
display: inline-block;
display: inline-flex; //
align-items: center;
vertical-align: middle;
max-width: 100%;
flex-wrap: nowrap;
// flex-1 width: 100% flex
&.flex-1, &.w100 {
display: flex !important;
width: 100% !important;
}
&.is-textarea {
display: flex !important;
width: 100%;
align-items: flex-start;
flex-direction: row !important;
}
.measure-text {
@ -131,18 +180,34 @@ onMounted(() => {
min-width: v-bind('props.minWidth');
padding: 0;
margin: 0;
text-align: inherit; //
height: 1.4em; //
text-align: inherit;
height: 1.4em;
line-height: 1.4em;
flex-shrink: 0;
// input
& {
flex: 1;
}
}
.auto-textarea {
width: 100%;
flex: 1 !important;
width: 0 !important;
min-width: 0;
min-height: 1.4em;
padding: 0;
margin: 0;
line-height: 1.4em;
display: block;
}
.edit-icon {
width: 28rpx;
height: 28rpx;
margin-left: 8rpx;
flex-shrink: 0;
margin-top: 4rpx;
}
}
</style>

View File

@ -14,7 +14,7 @@
<view v-if="item.status === '等待付款'" class="status-warning">
<image style="width: 116rpx;height: 30rpx;" src="/static/image/shopping/jingdong/dengdaifukuan.png">
</image>
<text class="status-desc" v-if="item.statusDesc">{{ item.statusDesc }}</text>
<text class="status-desc" v-if="item.statusDesc">{{ formatStatusDesc(item.statusDesc) }}</text>
</view>
<text v-else class="status-text"
:class="{ red: item.statusColor === 'red' || item.status === '正在出库' || item.status === '商家备餐中' || item.status === '骑手到店取餐中' || item.status === '骑手已到店' }">{{
@ -87,8 +87,7 @@
<view class="product-price-box">
<view class="price-wrap wx-font-regular">
<text class="price-symbol"></text>
<text class="price-num">{{ item.price || (item.products && item.products[0] &&
item.products[0].price) }}</text>
<text class="price-num">{{ safeFormatPrice(item) }}</text>
</view>
<text class="product-count"
v-if="item.count || (item.products && item.products[0] && item.products[0].count)">{{
@ -162,6 +161,21 @@ const onLongPress = (e) => {
emit('longpress', { event: e, item: props.item });
};
const formatStatusDesc = (desc) => {
if (!desc || !desc.includes(' : ')) return desc;
const parts = desc.split(' : ');
if (parts.length >= 2) {
return `${parts[0]}${parts[1]}`;
}
return desc;
};
const safeFormatPrice = (item) => {
const val = item.price || (item.products && item.products[0] && item.products[0].price);
const num = Number(val);
return isNaN(num) ? '0.00' : num.toFixed(2);
};
const getButtons = (shopType, status, item) => {
const buttons = [];
if (status == '等待付款') {

View File

@ -27,7 +27,7 @@ export function createApp() {
const systemInfo = uni.getStorageSync('systemInfo') || {}
app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android'
app.config.globalProperties.$systemInfo = systemInfo
uni.setStorageSync('version', '1.0.4.sp2')
uni.setStorageSync('version', '1.0.4.sp3')
app.config.globalProperties.$version = uni.getStorageSync('version')
app.use(globalMethods);
return {

View File

@ -275,16 +275,16 @@ const otherList = [{
name: "通话",
path: "/pages/common/call-and-message-entry/call-and-message-entry?type=call"
},
// {
// icon: "/static/image/index/qita/gouwu.png",
// name: "购物",
// path: "/pages/shopping/index"
// },
{
icon: "/static/image/index/qita/ranking.png",
name: "从夯倒拉排名",
path: "/pages/other/ranking/ranking"
},
{
icon: "/static/image/index/qita/gouwu.png",
name: "购物",
path: "/pages/shopping/index"
},
]
const data = reactive({

View File

@ -1,9 +1,10 @@
<template>
<view>
<nav-bar :title="navTitle" bgColor="#F2F3F7" isRightButton @right-click="confirmOrder"></nav-bar>
<view class="tab-box">
<view class="tab" :class="{ active: item.key == activeTab }" v-for="item in shoppingType" :key="item.key"
@click="switchTab(item)">
<NavBar :title="navTitle" bgColor="#F2F3F7" isRightButton @right-click="onConfirm"></NavBar>
<view class="page-container">
<view class="tab-box" v-if="!isEditMode">
<view class="tab" :class="{ active: item.key == activeTab }" v-for="item in shoppingType"
:key="item.key" @click="switchTab(item)">
<text>{{ item.label }}</text>
</view>
</view>
@ -13,7 +14,8 @@
<view class="tip-box">
<picker mode="multiSelector" :range="timeRange" :value="timeValue" @change="handleTimeChange">
<text>还剩
<text style="color: #DD223F;font-weight: 500; margin-left: 10rpx;">{{ order.statusDesc }}</text>
<text style="color: #DD223F;font-weight: 500; margin-left: 10rpx;">{{ order.statusDesc
}}</text>
<image class="edit-icon" src="/static/image/common/edit.png"></image>
订单自动取消
</text>
@ -22,49 +24,76 @@
<view class="address-info">
<view class="flex-1">
<view>
<image class="location" src="/static/image/shopping/jingdong/detail/location.png"></image>
<image class="location" src="/static/image/shopping/jingdong/detail/location.png">
</image>
<view class="name-box animate-scale">
<auto-width-input v-model="order.consignee" fontSize="30rpx" fontWeight="500"
placeholder="姓名" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
placeholder="姓名" show-edit />
</view>
<view class="number-box animate-scale">
<auto-width-input v-model="order.phone" fontSize="26rpx" placeholder="电话" color="#8C8C8C" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
<auto-width-input v-model="order.phone" fontSize="26rpx" placeholder="电话"
color="#8C8C8C" show-edit />
</view>
</view>
<view class="address-box animate-scale">
<auto-width-input v-model="order.fullAddress" type="textarea" fontSize="26rpx" placeholder="地址"
color="#8C8C8C" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
<auto-width-input v-model="order.fullAddress" type="textarea" fontSize="26rpx"
placeholder="地址" color="#8C8C8C" show-edit />
</view>
</view>
<view class="edit-btn">
<!-- <view class="edit-btn">
<text>修改</text>
</view>
</view> -->
</view>
</template>
<!-- 正在出库 -->
<template v-if="activeTab == 'zhengzaichuku'">
<view class="time-box" @click="onClickTrackingTime">
<text style="color: #87868E;">出库时间
<text style="color: #1A1A1A;font-weight: 500; margin-left: 10rpx;">{{
order.trackingTime }}</text>
<image class="edit-icon" src="/static/image/common/edit.png"></image>
</text>
</view>
<view class="outbound-info">
<image class="outbound-icon" src="/static/image/shopping/jingdong/detail/xiadan.png" mode="aspectFit">
<image class="outbound-icon shrink-0" src="/static/image/shopping/jingdong/detail/xiadan.png"
mode="aspectFit">
</image>
<view class="outbound-info-content">
<view class="title-info">
<view>
<text>已下单 </text>
<text>预计明天 09:00-15:00送达</text>
<view class="flex flex-1">
<text style="margin-right: 8rpx;" class="shrink-0">已下单 </text>
<view class="flex-1 animate-scale flex-align-center">
<auto-width-input v-model="order.trackingDesc" fontSize="30rpx" fontWeight="500"
placeholder="预计送达时间" color="#1A1A1A" type="text" show-edit />
</view>
</view>
<uni-icons type="right" size="10" color="#1A1A1A"></uni-icons>
</view>
<text class="desc">快递运输 · 温馨提示您的订单预计3月11日09:00- 15:53送达</text>
<view class="animate-scale desc flex-align-center">
<auto-width-input class="desc" v-model="order.trackingDesc2" fontSize="26rpx"
placeholder="运输信息" color="#8C8C8C" type="textarea" show-edit />
<!-- <text >{{ order.trackingDesc2 }}</text> -->
</view>
<view class="address-box">
<view class="top">
<text class="address">华哈哈哈哈哈哈哈哈哈2栋 22-1</text>
<view class="edit-btn">修改</view>
<!-- <text class="address">华哈哈哈哈哈哈哈哈哈2栋 22-1</text> -->
<view class="address flex-1 animate-scale flex-align-center">
<auto-width-input v-model="order.fullAddress" type="textarea" fontWeight="500"
fontSize="30rpx" placeholder="收货地址" color="#1A1A1A" show-edit />
</view>
<view class="edit-btn" style="margin-left: 16rpx;">修改</view>
</view>
<view class="flex" style="margin-top: 8rpx;">
<view class="phone animate-scale flex-align-center" style="margin-right: 8rpx;">
<auto-width-input v-model="order.consignee" type="text" fontSize="26rpx"
placeholder="收货人" color="#8C8C8C" show-edit />
</view>
<view class="phone animate-scale flex-align-center">
<auto-width-input v-model="order.phone" type="text" fontSize="26rpx"
placeholder="电话" color="#8C8C8C" show-edit />
</view>
</view>
<view class="phone">肖战123****1234</view>
</view>
</view>
</view>
@ -90,7 +119,8 @@
<view class="order-status-box">
<view class="status-main">
<image class="status-icon" src="/static/image/shopping/jingdong/detail/xiadan.png" mode="aspectFit">
<image class="status-icon" src="/static/image/shopping/jingdong/detail/xiadan.png"
mode="aspectFit">
</image>
<view class="status-content">
<view class="title-row">
@ -104,9 +134,21 @@
</view>
<view class="bottom-box">
<view class="dot"></view>
<view>
<text class="desc">华哈哈哈哈哈哈哈哈哈2栋 22-1</text>
<view class="name">肖战123****1234</view>
<view class="flex-1">
<view class="address flex-1 animate-scale flex-align-center w100">
<auto-width-input class="auto-width" v-model="order.fullAddress" type="textarea"
fontWeight="500" fontSize="30rpx" placeholder="收货地址" color="#1A1A1A" show-edit />
</view>
<view class="flex" style="margin-top: 8rpx;">
<view class="phone animate-scale flex-align-center" style="margin-right: 8rpx;">
<auto-width-input v-model="order.consignee" type="text" fontSize="26rpx"
placeholder="收货人" color="#8C8C8C" show-edit />
</view>
<view class="phone animate-scale flex-align-center">
<auto-width-input v-model="order.phone" type="text" fontSize="26rpx"
placeholder="电话" color="#8C8C8C" show-edit />
</view>
</view>
</view>
</view>
</view>
@ -114,6 +156,13 @@
<!-- 签收 -->
<template v-if="activeTab == 'yiqianshou'">
<view class="time-box" @click="onClickTrackingTime">
<text style="color: #87868E;">签收时间
<text style="color: #1A1A1A;font-weight: 500; margin-left: 10rpx;">{{
order.trackingTime }}</text>
<image class="edit-icon" src="/static/image/common/edit.png"></image>
</text>
</view>
<view class="order-status-box">
<view class="status-main">
<image class="status-icon" src="/static/image/shopping/jingdong/detail/qianshou.png"
@ -126,16 +175,26 @@
</view>
</view>
</view>
<view class="progress-box" style="height: 192rpx;">
<text class="text">快递运输 · 温馨提示您的订单预计3月11日09:00- 15:53送达</text>
<view class="upload-box">
<view class="info-box">
<view class="image-box">
<view class="progress-box" style="min-height: 192rpx;">
<view class="animate-scale desc flex-align-center shrink-0">
<auto-width-input class="desc" v-model="order.trackingDesc2" fontSize="26rpx"
placeholder="运输信息" color="#8C8C8C" type="textarea" show-edit />
</view>
<text class="name">肖战</text>
<view class="upload-box flex1 w100">
<view class="info-box flex-1 w100">
<view class="image-box shrink-0">
<view style="background-color: #EEEEEE;" class="w100 h100 flex-center">
<image style="width: 30rpx;height: 30rpx;" src="/static/image/common/add.png">
</image>
</view>
<view class="btn-box">
</view>
<view class="phone animate-scale flex-align-center flex-1"
style="margin-right: 8rpx;width: 100px;">
<auto-width-input class="auto-input" v-model="order.courier" type="text"
fontSize="26rpx" placeholder="快递员" color="#8C8C8C" show-edit />
</view>
</view>
<view class="btn-box shrink-0">
<view class="btn grey">联系Ta</view>
<view class="btn red">打赏Ta</view>
</view>
@ -144,23 +203,54 @@
</view>
<view class="bottom-box">
<view class="dot"></view>
<view>
<text class="desc">华哈哈哈哈哈哈哈哈哈2栋 22-1</text>
<view class="name">肖战123****1234</view>
<view class="flex-1">
<view class="address flex-1 animate-scale flex-align-center w100">
<auto-width-input class="auto-width" v-model="order.fullAddress" type="textarea"
fontWeight="500" fontSize="30rpx" placeholder="收货地址" color="#1A1A1A" show-edit />
</view>
<view class="flex" style="margin-top: 8rpx;">
<view class="phone animate-scale flex-align-center" style="margin-right: 8rpx;">
<auto-width-input v-model="order.consignee" type="text" fontSize="26rpx"
placeholder="收货人" color="#8C8C8C" show-edit />
</view>
<view class="phone animate-scale flex-align-center">
<auto-width-input v-model="order.phone" type="text" fontSize="26rpx"
placeholder="电话" color="#8C8C8C" show-edit />
</view>
</view>
</view>
</view>
</view>
</template>
<!-- 商品类型 (自营,京东,其它)-->
<view class="time-box" style="margin-top: 16rpx;">
<view style="color: #87868E;" class="flex-justify-between flex-align-center">
<text>商店类型</text>
<picker class="flex-1" style="display: flex;justify-content: flex-end;" :range="shopTypeOptions"
:value="shopTypeIndex" @change="onShopTypeChange">
<view class="flex-align-center">
<text style="color: #1A1A1A; margin-right: 8rpx;">{{ shopTypeOptions[shopTypeIndex]
}}</text>
<uni-icons type="right" size="14" color="#87868E"></uni-icons>
</view>
</picker>
</view>
</view>
<!-- 商品卡片 -->
<view class="product-card">
<view class="title-box">
<view class="left-box">
<image class="img" src="/static/image/shopping/jingdong/detail/ziyin.png"></image>
<image v-if="order.shopType == 'self'" class="img"
src="/static/image/shopping/jingdong/detail/ziyin.png">
</image>
<image v-if="order.shopType == 'jd'" style="width: 32rpx;height: 32rpx;margin-right: 12rpx;"
src="/static/image/shopping/jingdong/JD.png">
</image>
<view class="title flex animate-scale">
<auto-width-input v-model="order.products[0].name" fontSize="26rpx" fontWeight="700"
placeholder="请输入店铺名称" color="#1A1A1A" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
<auto-width-input v-model="order.shopName" fontSize="26rpx" fontWeight="700"
placeholder="请输入店铺名称" color="#1A1A1A" show-edit />
</view>
</view>
<uni-icons class="right-icon" size="14" color="#1A1A1A" type="right"></uni-icons>
@ -176,29 +266,31 @@
<view class="info-box">
<view class="name flex animate-scale">
<auto-width-input class="name" v-model="order.products[0].title" fontSize="26rpx"
fontWeight="700" placeholder="商品标题名称" color="#1A1A1A" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
fontWeight="700" placeholder="商品标题名称" color="#1A1A1A" show-edit type="textarea" />
</view>
<view class="flex flex-align-center animate-scale">
<auto-width-input class="desc" v-model="order.products[0].desc" type="textarea" fontSize="22rpx"
placeholder="商品描述" color="#87868E" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
<auto-width-input class="desc" v-model="order.products[0].desc" type="textarea"
fontSize="22rpx" placeholder="商品描述" color="#87868E" show-edit />
</view>
<view class="flex flex-align-center animate-scale">
<auto-width-input class="desc" v-model="order.products[0].service" type="textarea"
fontSize="22rpx" placeholder="请输入服务" color="#A96F24" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
fontSize="22rpx" placeholder="请输入服务" color="#A96F24" show-edit />
</view>
<view class="flex flex-align-center animate-scale wx-font-medium"
style="align-items: baseline;margin-top: 10rpx;">
<text style="font-size: 28rpx;font-weight: 500;"></text>
<auto-width-input class="flex-1 wx-font-medium" v-model="order.products[0].price"
type="number" fontSize="36rpx" placeholder="请输入商品价格" color="#1A1A1A" fontWeight="500"
show-edit />
</view>
</view>
<view class="price-box">
<!-- <view class="price-box">
<view class="price wx-font-medium flex-align-center animate-scale"><text
style="font-size: 36rpx;">{{ order.totalPrice }}</text>
<!-- <auto-width-input style="min-width: 20px;" class="price" v-model="order.products[0].price"
type="number" fontSize="36rpx" placeholder="价格" color="#1A1A1A" fontWeight="500" />
<image class="edit-icon" style="margin-left: 0;" src="/static/image/common/edit.png"></image> -->
</view>
style="font-size: 36rpx;">{{
order.totalPrice }}</text>
</view>
</view> -->
</view>
<view v-if="activeTab == 'dengdaifukuan' || activeTab == 'yiquxiao'" class="btn-box flex"
style="margin-top: 60rpx;">
@ -232,44 +324,230 @@
<text>商品总价</text>
<view class="wx-font-medium flex flex-align-center"><text
style="font-size: 32rpx;font-weight: 500;"></text>
<auto-width-input class="wx-font-medium" v-model="order.totalPrice" fontSize="32rpx"
placeholder="商品总价" color="#1A1A1A" fontWeight="500" type="number" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
<text style="font-size: 32rpx;font-weight: 500;">{{ order.products[0].price }}</text>
<!-- <auto-width-input class="wx-font-medium" v-model="order.products[0].price" fontSize="32rpx"
placeholder="商品总价" color="#1A1A1A" fontWeight="500" type="number" show-edit /> -->
</view>
</view>
<view class="item flex-justify-between">
<text class="label">运费</text>
<view class="wx-font-medium flex flex-align-center">
<auto-width-input class="wx-font-medium" v-model="order.carriage" fontSize="32rpx" placeholder="运费"
color="#1A1A1A" fontWeight="500" type="number" />
<image class="edit-icon" src="/static/image/common/edit.png"></image>
<auto-width-input class="wx-font-medium" v-model="order.carriage" fontSize="32rpx"
placeholder="运费" color="#1A1A1A" fontWeight="500" type="number" show-edit />
</view>
</view>
<view class="price">需付款 <text class="number wx-font-medium">{{ (Number(order.totalPrice) +
Number(order.carriage))
}}</text></view>
<view class="price">需付款 <text class="number wx-font-medium">
{{ (Number(order.products[0].price) + Number(order.carriage)) ?
(Number(order.products[0].price)
+ Number(order.carriage)) :
0 }}</text></view>
</view>
<!-- 订单信息 -->
<view class="order-info-box">
<view class="title flex-justify-between">
<text>订单信息</text>
</view>
<view v-if="activeTab != 'dengdaifukuan' && activeTab != 'yiquxiao'" class="item flex-justify-between">
<text class="label shrink-0">实付款</text>
<view class="flex-1 flex-align-center"
style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;">
<view class="wx-font-medium flex flex-align-center">
<view class="flex" style="align-items: baseline;color: #FF4444;">
<text>共减</text>
<auto-width-input class="wx-font-medium" v-model="order.totalPrice" fontSize="32rpx"
placeholder="优惠价格" color="#F10F1A" fontWeight="500" type="number" show-edit />
</view>
</view>
<view class="wx-font-medium flex flex-align-center">
<view class="flex" style="align-items: baseline;color: #1A1A1A;">
<text>合计</text>
<auto-width-input class="wx-font-medium" v-model="order.totalPrice" fontSize="36rpx"
placeholder="合计总价" color="#1A1A1A" fontWeight="500" type="number" show-edit />
</view>
</view>
</view>
</view>
<view class="order-info">
<view class="item flex-justify-between" v-for="item in order.orderInfo"
@click="onClickItemInfo(item)">
<text class="label shrink-0">{{ item.label }}</text>
<view class="flex-1 flex-align-center"
style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;">
<auto-width-input class="value" v-model="item.value" fontSize="26rpx" color="#1A1A1A"
:type="item.type ? item.type : 'text'" show-edit />
</view>
</view>
</view>
<view class="delivery-info">
<view class="item flex-justify-between" v-for="item in order.sendType"
@click="onClickItemInfo(item)">
<text class="label shrink-0">{{ item.label }}</text>
<view class="flex-1 flex-align-center"
style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;">
<auto-width-input class="value" v-model="item.value" fontSize="26rpx" color="#1A1A1A"
:type="item.type ? item.type : 'text'" show-edit />
</view>
</view>
</view>
</view>
</view>
</view>
<uni-popup ref="timepopup" type="bottom">
<!-- 时间选择器 -->
<view v-if="selectItemInfo.type == 'time'" class="timeBox">
<view class="titleBox">
<view class="title" @click="closeTimePicker">
取消
</view>
<view class="btn" @click="settmes">
确定
</view>
</view>
<DateTimePicker :defaultDate="datePickerData.selectDate" :minDate="datePickerData.startDate"
:maxDate="datePickerData.endDate" :mode="4" @onChange="onChangeStartDate" />
</view>
<!-- 时间段选择器 -->
<view v-if="selectItemInfo.type == 'timeRange'" class="timeBox">
<view class="titleBox">
<view class="title" @click="closeTimePicker">
取消
</view>
<view class="btn" @click="settmes">
确定
</view>
</view>
<view class="picker-container">
<picker-view class="range-picker-view" :value="timeRangePickerData.rangeSelect"
@change="onTimeRangeChange">
<picker-view-column>
<view class="picker-item" v-for="(item, index) in timeRangePickerData.rangeCols[0]"
:key="index">
{{ item }}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item, index) in timeRangePickerData.rangeCols[1]"
:key="index">
{{ item }}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item, index) in timeRangePickerData.rangeCols[2]"
:key="index">
{{ item }}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item, index) in timeRangePickerData.rangeCols[3]"
:key="index">
{{ item }}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item, index) in timeRangePickerData.rangeCols[4]"
:key="index">
{{ item }}
</view>
</picker-view-column>
</picker-view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { onLoad } from "@dcloudio/uni-app";
import { ref, computed } from "vue";
import { ref, computed, onMounted, nextTick } from "vue";
import NavBar from "@/components/nav-bar/nav-bar.vue";
import { shoppingType, shoppingClassfiy } from "../json/order.json";
import AutoWidthInput from "@/components/common/auto-width-input.vue";
import DateTimePicker from '@/components/dengrq-datetime-picker/dateTimePicker/index.vue';
import { stringUtil } from '@/utils/common.js';
const activeTab = ref("dengdaifukuan");
const navTitle = ref("新增订单");
const isEditMode = ref(false);
const currentId = ref('');
const navTitle = computed(() => isEditMode.value ? "修改订单" : "新增订单");
const shopTypeOptions = ['自营商店', '京东商店', '其它'];
const shopTypeValues = ['self', 'jd', 'none'];
const shopTypeIndex = computed(() => {
const idx = shopTypeValues.indexOf(order.value.shopType);
return idx > -1 ? idx : 2; //
});
const statusBarHeight = ref(0);
const timepopup = ref();
const selectItemInfo = ref({
type: '',
value: '',
label: '',
id: ''
});
const datePickerData = ref({
selectDate: "",
startDate: "",
endDate: "",
});
//
const timeRangePickerData = ref({
rangeCols: [[], [], [], [], []], // , , , ,
rangeSelect: [0, 5, 14, 9, 22] // 2026, 06, 15, 09:00, 22:00 ()
});
//
const initTimeRangeColumns = () => {
const years = [];
const now = new Date();
const currentYear = now.getFullYear();
for (let i = currentYear - 5; i <= currentYear + 5; i++) {
years.push(i + '年');
}
const months = [];
for (let i = 1; i <= 12; i++) {
months.push(i.toString().padStart(2, '0') + '月');
}
const days = [];
for (let i = 1; i <= 31; i++) {
days.push(i.toString().padStart(2, '0') + '日');
}
const hours = [];
for (let i = 0; i < 24; i++) {
hours.push(i.toString().padStart(2, '0') + ':00');
}
timeRangePickerData.value.rangeCols = [years, months, days, hours, hours];
// (2026-06-15 )
const yearIdx = years.indexOf('2026年') !== -1 ? years.indexOf('2026年') : 5;
timeRangePickerData.value.rangeSelect = [yearIdx, 5, 14, 9, 22];
};
onMounted(() => {
const info = uni.getSystemInfoSync();
statusBarHeight.value = info.statusBarHeight || 0;
initTimeRangeColumns();
});
const order = ref(shoppingClassfiy[activeTab.value]);
//
if (order.value) {
order.value.consignee = order.value.consignee || "肖战";
order.value.phone = order.value.phone || "152633221112";
order.value.fullAddress = order.value.fullAddress || "上海市浦东新区世纪大道123号";
order.value.consignee = order.value.consignee;
order.value.phone = order.value.phone;
order.value.fullAddress = order.value.fullAddress;
}
//
@ -303,6 +581,26 @@ const handleTimeChange = (e) => {
};
onLoad((options) => {
console.log('页面参数接收:', options);
const editFlag = String(options.isEdit) === 'true' || options.isEdit === true;
if (editFlag && options.id) {
// 1.
isEditMode.value = true;
currentId.value = String(options.id);
// 2.
const list = uni.getStorageSync('jingdongShopping') || [];
const editData = list.find(item => String(item.id) === String(options.id));
if (editData) {
order.value = JSON.parse(JSON.stringify(editData));
if (editData.activeTab) {
activeTab.value = editData.activeTab;
}
console.log('编辑模式已激活,数据已回填:', activeTab.value);
}
}
});
/**
@ -319,6 +617,97 @@ const chooseImage = () => {
});
}
/**
* 点击列表项触发
*/
const onClickItemInfo = (item) => {
if (item.type == 'time') {
datePickerData.value.selectDate = item.value;
datePickerData.value.endDate = formatTime(new Date());
selectItemInfo.value = item;
timepopup.value.open();
} else if (item.type == 'timeRange') {
selectItemInfo.value = item;
timepopup.value.open();
} else {
//
item.focus = false;
nextTick(() => {
item.focus = true;
});
}
}
/**
* 时间选择器变化
*/
const onChangeStartDate = (e) => {
datePickerData.value.selectDate = e;
}
/**
* 点击出库时间
*/
const onClickTrackingTime = () => {
selectItemInfo.value = {
type: 'time',
isTrackingTime: true
};
datePickerData.value.selectDate = order.value.trackingTime || formatTime(new Date());
datePickerData.value.endDate = "2099-12-31 23:59:59";
timepopup.value.open();
}
/**
* 确认时间选择
*/
const settmes = () => {
if (selectItemInfo.value.type == 'time') {
if (selectItemInfo.value.isTrackingTime) {
order.value.trackingTime = datePickerData.value.selectDate;
} else {
selectItemInfo.value.value = datePickerData.value.selectDate;
}
} else if (selectItemInfo.value.type == 'timeRange') {
const cols = timeRangePickerData.value.rangeCols;
const sel = timeRangePickerData.value.rangeSelect;
const y = cols[0][sel[0]].replace('年', '');
const m = cols[1][sel[1]].replace('月', '');
const d = cols[2][sel[2]].replace('日', '');
const startStr = cols[3][sel[3]];
const endStr = cols[4][sel[4]];
selectItemInfo.value.value = `${y}-${m}-${d},${startStr}-${endStr}`;
}
timepopup.value.close();
}
/**
* 时间段选择器变化
*/
const onTimeRangeChange = (e) => {
timeRangePickerData.value.rangeSelect = e.detail.value;
}
/**
* 关闭时间选择器
*/
const closeTimePicker = () => {
timepopup.value.close();
}
/**
* 格式化时间
*/
const formatTime = (date) => {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
const second = date.getSeconds();
return `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')} ${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:${second.toString().padStart(2, '0')}`;
}
/**
* 切换tab
* @param item
@ -327,15 +716,94 @@ const switchTab = (item) => {
activeTab.value = item.key;
order.value = shoppingClassfiy[activeTab.value];
if (order.value) {
order.value.consignee = order.value.consignee || "肖战";
order.value.phone = order.value.phone || "152633221112";
order.value.fullAddress = order.value.fullAddress || "上海市浦东新区世纪大道123号";
order.value.consignee = order.value.consignee;
order.value.phone = order.value.phone;
order.value.fullAddress = order.value.fullAddress;
}
}
async function onConfirm() {
let list = uni.getStorageSync('jingdongShopping') || [];
if (!Array.isArray(list)) {
list = [];
}
order.value.activeTab = activeTab.value;
//
const product = order.value.products[0];
if (product && product.image && (product.image.includes('tmp') || product.image.includes('blob'))) {
try {
const res = await new Promise((resolve, reject) => {
uni.saveFile({
tempFilePath: product.image,
success: resolve,
fail: reject
});
});
product.image = res.savedFilePath;
console.log('图片持久化成功:', product.image);
} catch (err) {
console.error('图片保存失败:', err);
}
}
if (isEditMode.value) {
// ID ()
const index = list.findIndex(item => String(item.id) === String(currentId.value));
if (index > -1) {
list[index] = JSON.parse(JSON.stringify(order.value));
} else {
//
list.push(JSON.parse(JSON.stringify(order.value)));
}
} else {
// UUID
order.value.id = stringUtil.uuid();
list.push(JSON.parse(JSON.stringify(order.value)));
}
uni.setStorageSync('jingdongShopping', list);
uni.showToast({
title: isEditMode.value ? '修改成功' : '保存成功',
icon: 'success'
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
const onShopTypeChange = (e) => {
const idx = e.detail.value;
order.value.shopType = shopTypeValues[idx];
}
</script>
<style lang="less" scoped>
/* 右上角点击蒙层position:fixed透明覆盖导航栏右侧按钮区域 */
.right-btn-mask {
position: fixed;
top: 0;
right: 0;
width: 80px;
/* height 由 :style 动态绑定 = statusBarHeight + 44px */
z-index: 10000;
background: transparent;
}
.tab-box {
// // position: -webkit-sticky;
// position: sticky;
// /* #ifdef H5 */
// top: 44px;
// /* H5 */
// /* #endif */
// /* #ifndef H5 */
// top: 88rpx;
// /* #endif */
// z-index: 9;
background-color: #F2F3F7;
padding: 22rpx 24rpx;
display: flex;
justify-content: space-between;
@ -635,7 +1103,8 @@ const switchTab = (item) => {
padding-left: 40rpx;
font-size: 26rpx;
color: #8C8C8C;
height: 62rpx;
padding-bottom: 18rpx;
// height: 62rpx;
.text {
@ -653,6 +1122,7 @@ const switchTab = (item) => {
border-radius: 8rpx;
padding: 6rpx;
.info-box {
display: flex;
align-items: center;
@ -829,7 +1299,6 @@ const switchTab = (item) => {
.info-box {
flex: 1;
margin-right: 44rpx;
overflow: hidden;
.name {
@ -934,9 +1403,9 @@ const switchTab = (item) => {
margin: 16rpx;
.title {
font-size: 32rpx;
font-size: 30rpx;
color: #1A1A1A;
line-height: 32rpx;
line-height: 30rpx;
font-weight: 700;
}
@ -973,10 +1442,94 @@ const switchTab = (item) => {
}
}
}
.order-info-box {
margin: 16rpx;
background-color: #FFFFFF;
border-radius: 24rpx;
padding: 28rpx 22rpx;
.title {
font-size: 30rpx;
color: #1A1A1A;
line-height: 30rpx;
font-weight: 700;
}
.order-info {
padding-bottom: 34rpx;
border-bottom: 1rpx solid #F2F2F2;
}
.item {
display: flex;
justify-content: space-between;
margin-top: 36rpx;
.label {
font-size: 26rpx;
color: #87868E;
line-height: 26rpx;
}
.value {
font-size: 26rpx;
color: #1A1A1A;
line-height: 26rpx;
text-align: right;
}
}
}
.timeBox {
background-color: #fff;
padding: 10px;
border-radius: 24rpx 24rpx 0 0;
.titleBox {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding: 0 10px;
.title {
font-size: 28rpx;
color: #999;
}
.btn {
font-size: 28rpx;
color: #1676FE;
font-weight: 500;
}
}
.range-picker-view {
width: 100%;
height: 400rpx;
background-color: #fff;
}
.picker-item {
line-height: 40px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-size: 24rpx;
color: #333;
}
}
</style>
<style>
/* 直接在页面导入公共样式 */
@import '/common/main.css';
@import "@/common/specify-style.less";
.page-container {
padding-bottom: 100rpx;
}
.edit-icon {
width: 28rpx;
@ -984,4 +1537,16 @@ const switchTab = (item) => {
margin-left: 0;
flex-shrink: 0;
}
.auto-input {
overflow-x: auto;
}
.time-box {
text-align: left;
margin: 8rpx 20rpx;
padding: 16rpx;
background-color: #ffffff;
border-radius: 24rpx;
}
</style>

View File

@ -1,32 +1,33 @@
{
"shoppingClassfiy": {
"dengdaifukuan": {
"id": 8562245551,
"id": "",
"shopType": "self",
"shopName": "安野屋 (AARYE) 京联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦",
"shopName": "",
"status": "等待付款",
"statusDesc": "18 : 25 : 46",
"consignee": "肖战",
"phone": "152633221112",
"fullAddress": "上海市浦东新区世纪大道123号",
"totalPrice": "69.00",
"carriage": "0.00",
"statusDesc": "",
"consignee": "",
"phone": "",
"fullAddress": "",
"totalPrice": "",
"carriage": "",
"products": [
{
"image": "",
"name": "哈哈哈哈哈",
"title": "安野屋AARYE红红火火恍恍惚惚哈哈哈哈哈好",
"desc": "联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦",
"service": "无理由退货政策",
"price": "69.00",
"count": "1"
"name": "",
"title": "",
"desc": "",
"service": "",
"price": "",
"count": ""
}
],
"orderInfo": [
{
"label": "订单编号",
"key": "orderNumber",
"value": "8562245551"
"value": "",
"type": "number"
},
{
"label": "交易快照",
@ -46,7 +47,8 @@
{
"label": "下单时间",
"key": "orderTime",
"value": "2022-01-01 12:00:00"
"value": "",
"type": "time"
}
],
"sendType": [
@ -58,42 +60,48 @@
{
"label": "期望配送时间",
"key": "expectedDeliveryTime",
"value": "大王 122555662221555"
"value": " ",
"type": "timeRange"
},
{
"label": "收货方式",
"key": "shippingMethod",
"value": "送货上门"
"value": ""
}
],
"promoType": "text",
"promoHighlight": "白条支付券0.5元优惠券"
},
"zhengzaichuku": {
"id": 5504455,
"shopType": "none",
"shopName": "甜小南旗舰店",
"id": "",
"shopType": "self",
"shopName": "",
"status": "正在出库",
"trackingTitle": "仓库处理中",
"trackingDesc": "预计 3月12日24:00 前发货3月15日 24:00 前送达",
"trackingTime": "2026-03-10 15:14:30",
"trackingDesc": "",
"trackingDesc2": "",
"trackingTime": "",
"consignee": "",
"phone": "",
"fullAddress": "",
"totalPrice": "",
"carriage": "",
"products": [
{
"image": "/static/image/shopping/jingdong/product1.png",
"title": "安野哈哈哈哈哈哈哈哈哈哈哈哈好好",
"desc": "联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦",
"tags": [
"无理由退货政策"
],
"price": "69.00",
"count": 1
"image": "",
"title": "",
"desc": "",
"service": "",
"price": "",
"count": ""
}
],
"orderInfo": [
{
"label": "订单编号",
"key": "orderNumber",
"value": "8562245551"
"value": "",
"type": "number"
},
{
"label": "交易快照",
@ -108,12 +116,13 @@
{
"label": "支付时间",
"key": "paymentTime",
"value": "2022-01-01 12:00:00"
"value": "",
"type": "time"
},
{
"label": "下单时间",
"key": "orderTime",
"value": "2022-01-01 12:00:00"
"value": ""
}
],
"sendType": [
@ -125,17 +134,18 @@
{
"label": "收货信息",
"key": "userInfo",
"value": "大王 122555662221555"
"value": ""
},
{
"label": "收货地址",
"key": "address",
"value": "哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
"value": ""
},
{
"label": "期望配送时间",
"key": "expectedDeliveryTime",
"value": "大王 122555662221555"
"value": "",
"type": "timeRange"
},
{
"label": "收货方式",
@ -147,31 +157,32 @@
"promoText": "告别凑单, 享免运优惠"
},
"yiqianshou": {
"id": 585552,
"id": "",
"shopType": "self",
"shopName": "甜小南旗舰店",
"shopName": "",
"status": "完成",
"statusColor": "gray",
"trackingTitle": "已签收",
"courier": "",
"trackingDesc": "您的订单已签收,可对快递员的服务进行评价或打赏哦~",
"trackingTime": "2026-03-10 15: 14: 30",
"trackingDesc2": "",
"trackingTime": "",
"products": [
{
"image": "/static/image/shopping/jingdong/product1.png",
"title": "安野哈哈哈哈哈哈哈哈哈哈哈哈好好",
"desc": "联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦",
"tags": [
"无理由退货政策"
],
"price": "69.00",
"count": 1
"image": "",
"title": "",
"desc": "",
"service": "",
"price": "",
"count": ""
}
],
"orderInfo": [
{
"label": "订单编号",
"key": "orderNumber",
"value": "8562245551"
"value": "",
"type": "number"
},
{
"label": "交易快照",
@ -186,12 +197,12 @@
{
"label": "支付时间",
"key": "paymentTime",
"value": "2022-01-01 12:00:00"
"value": ""
},
{
"label": "下单时间",
"key": "orderTime",
"value": "2022-01-01 12:00:00"
"value": ""
}
],
"sendType": [
@ -203,7 +214,8 @@
{
"label": "期望配送时间",
"key": "expectedDeliveryTime",
"value": "大王 122555662221555"
"value": "",
"type": "timeRange"
},
{
"label": "收货方式",
@ -216,28 +228,27 @@
"hasMore": true
},
"wancheng": {
"id": 4545451,
"id": "",
"shopType": "jd",
"shopName": "甜小南旗舰店",
"shopName": "",
"status": "完成",
"statusColor": "gray",
"products": [
{
"image": "/static/image/shopping/jingdong/product1.png",
"title": "安野哈哈哈哈哈哈哈哈哈哈哈哈好好",
"desc": "联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦",
"tags": [
"无理由退货政策"
],
"price": "69.00",
"count": 1
"image": "",
"title": "",
"desc": "",
"service": "",
"price": "",
"count": ""
}
],
"orderInfo": [
{
"label": "订单编号",
"key": "orderNumber",
"value": "8562245551"
"value": "",
"type": "number"
},
{
"label": "交易快照",
@ -252,12 +263,13 @@
{
"label": "支付时间",
"key": "paymentTime",
"value": "2022-01-01 12:00:00"
"value": "",
"type": "time"
},
{
"label": "下单时间",
"key": "orderTime",
"value": "2022-01-01 12:00:00"
"value": ""
}
],
"sendType": [
@ -269,39 +281,38 @@
{
"label": "收货信息",
"key": "userInfo",
"value": "大王 122555662221555"
"value": ""
},
{
"label": "收货地址",
"key": "address",
"value": "哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"
"value": ""
}
],
"hasMore": true
},
"yiquxiao": {
"id": 1236524,
"id": "",
"shopType": "self",
"shopName": "甜小南旗舰店",
"shopName": "",
"status": "已取消",
"statusColor": "gray",
"products": [
{
"image": "/static/image/shopping/jingdong/product1.png",
"title": "安野哈哈哈哈哈哈哈哈哈哈哈哈好好",
"desc": "联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦",
"tags": [
"无理由退货政策"
],
"price": "1669.00",
"count": 1
"image": "",
"title": "",
"desc": "",
"service": "",
"price": "",
"count": ""
}
],
"orderInfo": [
{
"label": "订单编号",
"key": "orderNumber",
"value": "8562245551"
"value": "",
"type": "number"
},
{
"label": "交易快照",
@ -321,7 +332,7 @@
{
"label": "下单时间",
"key": "orderTime",
"value": "2022-01-01 12:00:00"
"value": ""
}
],
"sendType": [
@ -333,7 +344,8 @@
{
"label": "期望配送时间",
"key": "expectedDeliveryTime",
"value": "大王 122555662221555"
"value": "",
"type": "timeRange"
},
{
"label": "收货方式",

View File

@ -78,6 +78,7 @@
<script setup>
import { ref, computed, onMounted, getCurrentInstance } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import ShoppingCard from '@/components/shopping/jingdong/shopping-card.vue';
import { util } from '@/utils/common.js';
@ -87,12 +88,20 @@ const actionMenuState = ref({ x: 0, y: 0, item: null });
//
const buttonGroup = [
{
name: "新增购物",
name: "新增购物订单",
click: () => {
uni.navigateTo({
url: '/pages/shopping/jingdong/add-order/add-order'
});
}
}, {
name: "新增秒送订单",
click: () => {
uni.showToast({
title: '开发中,敬请期待',
icon: 'none'
});
}
},
]
/**
@ -138,7 +147,7 @@ const editOrder = () => {
if (!item) return;
showActionMenu.value = false;
uni.navigateTo({
url: '/pages/shopping/jingdong/add-order/add-order?id=' + item.id + '&type=' + item.shopType
url: '/pages/shopping/jingdong/add-order/add-order?id=' + item.id + '&type=' + item.shopType + '&isEdit=true'
});
};
@ -163,12 +172,29 @@ const handleCardClick = (item) => {
*/
const handleDeleteOrder = () => {
const itemToDel = actionMenuState.value.item;
// 1.
const productImage = itemToDel?.products?.[0]?.image;
if (productImage && (productImage.includes('_doc/') || productImage.includes('_downloads/') || productImage.includes('store_'))) {
uni.removeSavedFile({
filePath: productImage,
success: () => console.log('图片文件删除成功:', productImage),
fail: (err) => console.error('图片文件删除失败:', err)
});
}
// 2.
const realIndex = mockOrderList.value.findIndex(item => item === itemToDel);
if (realIndex > -1) {
mockOrderList.value.splice(realIndex, 1);
//
uni.setStorageSync('jingdongShopping', mockOrderList.value);
}
showActionMenu.value = false;
uni.showToast({ title: '已删除', icon: 'none' });
uni.showToast({
title: '已删除',
icon: 'none'
});
};
const contentPaddingTop = ref('0px');
@ -196,6 +222,13 @@ onMounted(() => {
}, 100);
});
onShow(() => {
const cachedData = uni.getStorageSync('jingdongShopping');
if (cachedData && Array.isArray(cachedData)) {
mockOrderList.value = cachedData;
}
});
const currentTab = ref(0);
const tabList = ref([
{ name: '全部' },