This commit is contained in:
chenhao 2026-06-01 14:42:38 +08:00
parent 1737d73573
commit a2ad18d9bc
20 changed files with 308 additions and 90 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

After

Width:  |  Height:  |  Size: 509 B

BIN
public/img/my_u7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

BIN
public/img/point_banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -1,7 +1,7 @@
<template>
<router-view v-slot="{ Component }">
<keep-alive include="Index,Category">
<component :is="Component" />
<keep-alive include="Index">
<component :is="Component" @updateShare="updateShare" />
</keep-alive>
</router-view>
</template>
@ -43,7 +43,6 @@ export default {
// if (this.$isLogin()) {
// this.getTip();
// }
// updateShare emit
this.updateShare(undefined, undefined, undefined);
}
},

View File

@ -39,6 +39,12 @@
<span>商城</span>
<van-icon class="r" name="arrow"></van-icon>
</div>
<!-- <div @click="navigateAndClose('Social')">
<img src="/img/my_u7.png" alt="">
<span>合作店</span>
<van-icon class="r" name="arrow"></van-icon>
</div> -->
</div>
<button @click="loginout">

View File

@ -27,11 +27,11 @@ const routes = [
meta: { title: '商城', cache: true }
},
{
path: '/PointMall',
name: 'PointMall',
path: '/Social',
name: 'Social',
parentName: 'Index',
component: () => import('./views/Tabbars/PointMall.vue'),
meta: { title: '积分区', cache: true }
component: () => import('./views/Tabbars/Social.vue'),
meta: { title: '合作店', cache: true }
},
{
path: '/My',
@ -51,6 +51,13 @@ const routes = [
noLogin: true,
}
},
{
path: '/PointMall',
name: 'PointMall',
parentName: 'Index',
component: () => import('./views/User/PointMall.vue'),
meta: { title: '积分区', cache: true }
},
{
path: '/Login',
name: 'Login',

View File

@ -5587,3 +5587,46 @@
.paycode-page {
.f5;
}
.social {
.f5;
.top {
padding: 8.88vw 3.33vw;
background-image: linear-gradient(141deg,
#f87b99 14%,
#fb96ae 100%);
.search_box {
.box;
.box-align-center;
height: 9.6vw;
background-color: #ffffff;
border-radius: 4.8vw;
padding: 0 3.73vw;
img {
width: 4.53vw;
height: 4.53vw;
}
input {
border: none;
font-size: 3.47vw;
margin-left: 1.2vw;
}
::placeholder {
color: #999999;
}
}
}
.category_box {
background-color: #f5f5f5;
border-radius: 2.67vw 2.67vw 0vw 0vw;
margin-top: -5vw;
}
}

View File

@ -134,7 +134,20 @@ export default {
_pauseScroll: false,
}
},
watch: {
'$route.fullPath': {
handler(newFullPath, oldFullPath) {
if (newFullPath !== oldFullPath) {
// this.searchKey = ''
// setTimeout(() => {
this.init()
// }, 100);
}
}
}
},
activated() {
this.searchKey = ''
this._scrollRestored = false
this._pauseScroll = false
this.$nextTick(() => {

View File

@ -253,7 +253,9 @@ export default {
this.specCombinations = this.data.specCombinations || [];
const recommend = localStorage.getItem('cellphone') || '';
this.shareLink = `${location.origin}/#/GoodsDetail?id=${this.data.id}${recommend ? '&RecommendCode=' + recommend : ''}`;
this.$emit('updateShare', this.data.name, this.data.description, this.data.img);
setTimeout(() => {
this.$emit('updateShare', this.data.name, this.data.description, this.data.img);
}, 0);
this.initDefaultSku();
});
},
@ -265,17 +267,13 @@ export default {
// skunameskuname
const skuParts = mainSku.skuname.split(',').filter(Boolean);
this.specSelect.forEach((spec) => {
const specIndex = this.specSelect.findIndex(s => s.name === spec.name);
// skuname
if (skuParts[specIndex]) {
const child = spec.children?.find(c => skuParts[specIndex].includes(c.name));
if (child) {
this.selectedSpecs[spec.name] = child.name;
} else if (spec.children?.length > 0) {
this.selectedSpecs[spec.name] = spec.children[0].name;
}
// specskuPart
const matchedChild = spec.children?.find(child =>
skuParts.some(part => part.includes(child.name))
);
if (matchedChild) {
this.selectedSpecs[spec.name] = matchedChild.name;
} else if (spec.children?.length > 0) {
// skuname
this.selectedSpecs[spec.name] = spec.children[0].name;
}
});
@ -293,16 +291,29 @@ export default {
let matchedSku = this.specCombinations.find(combo => {
const skuParts = combo.skuname.split(',').filter(Boolean);
// Every selected spec value must be found in this SKU's parts
return specKeys.every((key) => {
const selectedVal = this.selectedSpecs[key];
const specIndex = this.specSelect.findIndex(s => s.name === key);
return skuParts[specIndex]?.includes(selectedVal);
return skuParts.includes(selectedVal);
});
});
if (matchedSku) {
this.tempSku = { ...matchedSku, Qty: this.tempSku.Qty || 1 };
this.selectedSku = "已选:" + matchedSku.skuname;
} else {
// No exact match found - try to find by individual value
matchedSku = this.specCombinations.find(combo => {
const skuParts = combo.skuname.split(',').filter(Boolean);
return specKeys.every((key) => {
const selectedVal = this.selectedSpecs[key];
return skuParts.some(part => part.includes(selectedVal));
});
});
if (matchedSku) {
this.tempSku = { ...matchedSku, Qty: this.tempSku.Qty || 1 };
this.selectedSku = "已选:" + matchedSku.skuname;
}
}
},
back() {

View File

@ -1,10 +1,10 @@
<template>
<router-view v-slot="{ Component }">
<keep-alive :include="cacheRoutes">
<component :is="Component" />
<component :is="Component" @updateShare="onUpdateShare" />
</keep-alive>
</router-view>
<van-tabbar v-model="DefaultActive" placeholder @change="changeActive" active-color="#841e36" inactive-color="#1b1b1b"
<van-tabbar v-model="DefaultActive" placeholder @change="onTabChange" active-color="#841e36" inactive-color="#1b1b1b"
fixed>
<van-tabbar-item v-for="item in Tabbars" :key="item.Name" :name="item.Name" :badge="getBadge(item)" :dot="item.Dot"
@click="onTabClick(item.Name)">
@ -23,7 +23,7 @@ export default {
data() {
return {
DefaultActive: 'Home',
cacheRoutes: ['Home', 'Gift', 'Mall', 'PointMall'],
cacheRoutes: ['Home', 'Gift', 'Mall', 'Social'],
Tabbars: [
{
Name: 'Home',
@ -44,10 +44,10 @@ export default {
Icon_Inactive: '/img/Mall_Inactive.png',
},
{
Name: 'PointMall',
Label: '积分区',
Icon_Active: '/img/PointMall_Active.png',
Icon_Inactive: '/img/PointMall_Inactive.png',
Name: 'Social',
Label: '合作店',
Icon_Active: '/img/Social_Active.png',
Icon_Inactive: '/img/Social_Inactive.png',
},
{
Name: 'My',
@ -72,31 +72,21 @@ export default {
methods: {
updateActive() {
const routeName = this.$route.name
// if (routeName === 'PointMall') {
// return
// }
if (routeName === 'Social') {
return
}
const tabbar = this.Tabbars.find(item => item.Name === routeName)
if (tabbar) {
this.DefaultActive = tabbar.Name
}
},
changeActive(e) {
if (this.$route.name === e) {
this.DefaultActive = e;
location.replace(`#/${e}`);
location.reload();
window.scrollTo(0, 0)
}
this.DefaultActive = e;
},
getBadge(item) {
return item.Badge || ''
},
onTabClick(name) {
// if (name === 'PointMall') {
// return
// }
if (name === 'Social') {
return
}
if (this.$route.name === name) {
//
// this.$router.replace({ name })
@ -105,6 +95,17 @@ export default {
} else {
this.$router.push({ name })
}
},
onTabChange(name) {
if (name === 'Social') {
this.$showToast('暂未开放')
this.DefaultActive = this.$route.name;
return
}
this.DefaultActive = name
},
onUpdateShare(title, desc, imgUrl) {
this.$emit('updateShare', title, desc, imgUrl)
}
}
}

View File

@ -23,9 +23,35 @@
<van-cell-group inset class="info-group">
<van-field v-model="formData.shopname" label="店铺名称" placeholder="请输入店铺名称" required />
<van-field v-model="formData.cellphone" label="联系电话" placeholder="请输入联系电话" type="tel" required />
<van-field v-model="formData.huili" label="惠利比例" placeholder="请输入惠利比例" type="number">
<van-field v-model="formData.huili" label="惠利比例" type="number" readonly>
<template #extra><span style="color:#666">%</span></template>
</van-field>
<!-- <van-field v-model="formData.cellphone" label="商家分类" type="tel" readonly />
<van-field v-model="formData.address" label="经营地址" placeholder="请联系平台修改" type="text" />
<van-field label="营业时间" readonly is-link @click="onBusinessTimeClick">
<template #input>
<span :style="{ color: formData.starttime && formData.endtime ? '#333' : '#ccc' }"
style="text-align: right;width: 100%;">
{{ formData.starttime && formData.endtime ? formData.starttime + '-' + formData.endtime : '选择营业时间' }}
</span>
</template>
</van-field>
<van-collapse v-model="activeNames" style="border: none;">
<van-collapse-item title="商家介绍" name="1" style="border: none;">
<div class="shop-intro-wrap">
<div class="intro-images">
<div v-for="(img, index) in formData.shopintroimages" :key="index" class="intro-img-item">
<img :src="img" @click="previewImage(img)" />
<van-icon name="cross" class="delete-btn" @click="removeIntroImage(index)" />
</div>
<van-uploader v-if="formData.shopintroimages.length < 9" :after-read="onIntroImageRead"
:max-count="9 - formData.shopintroimages.length" upload-icon="plus" />
</div>
</div>
</van-collapse-item>
</van-collapse> -->
</van-cell-group>
</div>
@ -78,6 +104,16 @@
</van-button>
</div>
</van-form>
<van-popup v-model:show="showStartTimePicker" position="bottom" round>
<van-time-picker v-model="currentTime" title="选择开始时间" @confirm="onStartTimeConfirm"
@cancel="showStartTimePicker = false" />
</van-popup>
<van-popup v-model:show="showEndTimePicker" position="bottom" round>
<van-time-picker v-model="currentTime" title="选择结束时间" @confirm="onEndTimeConfirm"
@cancel="showEndTimePicker = false" />
</van-popup>
</div>
</BasePage>
</template>
@ -90,6 +126,10 @@ export default {
data() {
return {
saving: false,
activeNames: [],
showStartTimePicker: false,
showEndTimePicker: false,
currentTime: ['12', '00'],
formData: {
shopname: '',
shopimg: '',
@ -105,6 +145,9 @@ export default {
bankcardnumber: '',
subbank: '',
bankcellphone: '',
starttime: '',
endtime: '',
shopintroimages: [],
}
}
},
@ -177,6 +220,37 @@ export default {
if (res.status !== 200) throw new Error(res.message)
return res.data
})
},
onStartTimeConfirm({ selectedValues }) {
this.formData.starttime = selectedValues.join(':')
this.showStartTimePicker = false
this.showEndTimePicker = true
},
onEndTimeConfirm({ selectedValues }) {
this.formData.endtime = selectedValues.join(':')
this.showEndTimePicker = false
},
onBusinessTimeClick() {
this.showStartTimePicker = true
},
onIntroImageRead(file) {
const img = file.file
this.uploadFile('/v1/client/DShopsClient/shopintroimg', img).then(url => {
this.formData.shopintroimages.push(this.$file(url))
})
},
removeIntroImage(index) {
this.formData.shopintroimages.splice(index, 1)
},
filter(type, options) {
if (type === 'hour') {
return options.filter(option => option >= 6 && option <= 23)
}
return options
},
onTimeConfirm({ selectedValues }) {
this.formData.businesshours = selectedValues.join(':')
this.showTimePicker = false
}
},
}
@ -275,6 +349,18 @@ export default {
.info-group {
background: #fff;
.intr_input {
&::placeholder {
color: #ccc;
}
}
.van-hairline--top-bottom:after,
.van-hairline-unset--top-bottom:after {
border-width: 0;
}
:deep(.van-cell) {
padding: 0 5.33vw;
height: 12vw;
@ -340,6 +426,51 @@ export default {
font-size: 3.47vw;
}
}
.shop-intro-wrap {
padding: 2vw 0;
.intro-images {
display: flex;
flex-wrap: wrap;
gap: 2vw;
.intro-img-item {
position: relative;
width: 20vw;
height: 20vw;
border-radius: 4px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.delete-btn {
position: absolute;
top: 1vw;
right: 1vw;
width: 5vw;
height: 5vw;
background: rgba(0, 0, 0, 0.5);
border-radius: 50%;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
}
:deep(.van-uploader) {
.van-uploader__upload {
width: 20vw;
height: 20vw;
}
}
}
}
}
.btn-wrap {

View File

@ -13,7 +13,8 @@
<!-- <img class="r" @click="showLeft = true" style="height: 4vw;" src="/img/filter.png" alt="filter"> -->
</div>
</div>
<BaseList cache-key="Business_School" :url="`/v1/client/CBusinessschoolsClient`" :params="params" class="list_item">
<BaseList cache-key="Business_School" :url="`/v1/client/CBusinessschoolsClient`" :params="params"
class="list_item">
<template #default="{ item }">
<div class="school-list" :key="item.id" @click="$navigate(`/School_Detail?id=${item.id}`)">
<div class="img">
@ -93,7 +94,7 @@ export default {
},
mounted() {
this.getList()
this.$emit('updateShare', '泰古润商学院', '学习知识,提升能力', '/img/bs-icon.png');
// this.$emit('updateShare', '', '', '/img/bs-icon.png');
},
methods: {
getList() {

View File

@ -34,9 +34,9 @@ export default {
// console.log(data);
this.articleList = data.data.items;
this.currentColumn.name = data.data.items[0].pidname;
if (this.articleList.length > 0) {
this.$emit('updateShare', this.articleList[0].name, this.articleList[0].description, this.articleList[0].img);
}
// if (this.articleList.length > 0) {
// this.$emit('updateShare', this.articleList[0].name, this.articleList[0].description, this.articleList[0].img);
// }
})
},
data() {

View File

@ -3,9 +3,8 @@
<div class="top">
<div class="search_box">
<img src="/img/search.png" alt="">
<input v-model="searchParams.name" placeholder="请输入关键词搜索"
@search="$navigate('Category?name=' + searchParams.name)">
<button @click="$navigate('Category?name=' + searchParams.name)" :style="btnStyle">搜索</button>
<input v-model="searchname" placeholder="请输入关键词搜索" @search="$navigate('Category?name=' + searchname)">
<button @click="$navigate('Category?name=' + searchname)" :style="btnStyle">搜索</button>
</div>
<div class="banner">
<van-swipe :autoplay="3000" indicator-color="white" @change="onSwipeChange">
@ -42,6 +41,9 @@
</div>
</div>
<img src="/img/point_banner.png" @click="$navigate('PointMall')"
style="width: 100%;margin-top: 2vw;display: block;float: left;" alt="">
<!-- Style1 -->
<!-- <div class="banner_style1" v-if="hotData.length > 0">
Style1

View File

@ -27,7 +27,7 @@
<p>{{ product.mallstatename }}</p>
<b class="r" v-if="product.mallstate !== 5"><span></span>{{ product.saleprice?.toFixed(2)
}}</b>
}}</b>
<b class="r" v-else><span>{{ product.saleprice?.toFixed(2) }}</span>积分</b>
</div>
@ -196,10 +196,11 @@ export default {
const skuname = decodeURIComponent(this.$route.query.skuname || '');
this.$get(`/v1/client/EProsClient/fororder?id=${id}&skuname=${encodeURIComponent(skuname)}`).then(res => {
const data = res.data;
// SKU
// SKU
let sku = null;
if (skuname && data.specCombinations) {
sku = data.specCombinations.find(s => s.skuname === skuname);
const skunameParts = skuname.split(',').sort().join(',');
sku = data.specCombinations.find(s => s.skuname.split(',').sort().join(',') === skunameParts);
}
if (!sku && data.specCombinations?.length) {
sku = data.specCombinations[0];
@ -284,7 +285,8 @@ export default {
county: this.address.county,
address: this.address.ReceiveAddress,
ishuiyuanka: this.checked === '2',
isjifen: this.checked === '1'
isjifen: this.checked === '1',
usermsg: this.remark,
};
this.$post('/v1/client/FOrdersClient', form).then(data => {
this.$showSuccessToast('提交成功');

View File

@ -1,47 +1,49 @@
<template>
<div class="pointmall">
<div class="top">
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item>
<img style="width: 100%;" src="/img/pointmall_bg.jpg" alt="">
</van-swipe-item>
</van-swipe>
<!-- <div class="search">
<BasePage>
<div class="pointmall">
<div class="top">
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item>
<img style="width: 100%;" src="/img/pointmall_bg.jpg" alt="">
</van-swipe-item>
</van-swipe>
<!-- <div class="search">
<img src="/img/search-w.png" alt="">
<input type="text" placeholder="搜索您想要的产品">
</div> -->
</div>
<div class="contaiar">
<div class="tabs">
<van-tabs background="transparent" line-height="0.8vw" line-width="9.33vw" v-model:active="active"
:ellipsis="false" color="#ca2904" title-active-color="#ca2904" title-inactive-color="#4e4e4e">
<van-tab title="全部" name=""></van-tab>
<van-tab v-for="i in tabs" :name="i.id" :title="i.name"></van-tab>
</van-tabs>
<!-- <img @click="showLeft = true" class="filter_img" style="width: 5.4vw;" src="/img/filter.png" alt=""> -->
</div>
<div class="contaiar">
<div class="tabs">
<van-tabs background="transparent" line-height="0.8vw" line-width="9.33vw" v-model:active="active"
:ellipsis="false" color="#ca2904" title-active-color="#ca2904" title-inactive-color="#4e4e4e">
<van-tab title="全部" name=""></van-tab>
<van-tab v-for="i in tabs" :name="i.id" :title="i.name"></van-tab>
</van-tabs>
<!-- <img @click="showLeft = true" class="filter_img" style="width: 5.4vw;" src="/img/filter.png" alt=""> -->
</div>
<BaseList url="/v1/client/EProsClient" class="goods_list" :params="{ mallstate: 5, pid: active }">
<template #default="{ item }">
<div class="goods_item" :key="item.id" @click="toDetail(item.id)">
<img :src="$file(item.img)" alt="">
<div>
<span class="title">{{ item.name }}</span>
<div class="money">
<div>
<b>{{ item.jifen?.toFixed(2) }}</b>积分
<BaseList url="/v1/client/EProsClient" class="goods_list" :params="{ mallstate: 5, pid: active }">
<template #default="{ item }">
<div class="goods_item" :key="item.id" @click="toDetail(item.id)">
<img :src="$file(item.img)" alt="">
<div>
<span class="title">{{ item.name }}</span>
<div class="money">
<div>
<b>{{ item.jifen?.toFixed(2) }}</b>积分
</div>
</div>
</div>
</div>
</div>
</template>
</BaseList>
</template>
</BaseList>
</div>
</div>
</div>
</BasePage>
<van-popup v-model:show="showLeft" position="left" :style="{ width: '30%', height: '100%' }">