线上商城改版
This commit is contained in:
1 parent
b94b5bf911
commit
4a19ae2856
4 files changed
+307
-65
No files matched your search
+1
-1
@@ -102,7 +102,7 @@ const tabbar: TabbarItem[] = [
|
||||
},
|
||||
]
|
||||
|
||||
// 设置tabbar项目
|
||||
// 设置tabbar
|
||||
const setTabbarItem = (index: number, item: TabbarItem, visible: boolean) => {
|
||||
uni.setTabBarItem({
|
||||
index,
|
||||
|
||||
@@ -145,10 +145,11 @@ const doProduct = (v: any) => {
|
||||
:hasAroundGutter="false"
|
||||
backgroundColor="#ffffff00"
|
||||
:crossOrigin="false"
|
||||
:animationDuration="100"
|
||||
:animationDuration="0"
|
||||
:posDuration="0"
|
||||
>
|
||||
<template #default="{ item, url, index }">
|
||||
<div class="card">
|
||||
<view class="card">
|
||||
<LazyImg class="rounded-2" :url="item.picUrl" />
|
||||
<view class="p-x-15rpx p-y-25rpx flex items-center justify-between">
|
||||
<view class="sub-text-28 show-line">{{ item.name }}</view>
|
||||
@@ -162,7 +163,7 @@ const doProduct = (v: any) => {
|
||||
<!-- <view class="second-text-24">{{ hooks.useFormatNum("销量", "", item.salesCount) }}</view> -->
|
||||
<!-- </view> -->
|
||||
</view>
|
||||
</div>
|
||||
</view>
|
||||
</template>
|
||||
</Waterfall>
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "3",
|
||||
},
|
||||
})
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
})
|
||||
onShow(() => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
<tm-tag size="s">{{ v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view v-if="v.phone" class="flex items-center">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/phone.svg" />
|
||||
<view class="second-text-28 ml-1">{{ v.phone }}</view>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view class="second-text-28">{{ v.jobTime == ",," ? "" : "营业时间:" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="v.addressDes" class="second-text-28">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/address.svg" />
|
||||
<text class="ml-1">地址:</text>
|
||||
<text class="m-l-10rpx">{{ v.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
+220
-61
@@ -1,39 +1,3 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "3",
|
||||
},
|
||||
})
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
})
|
||||
onShow(() => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
@@ -49,34 +13,229 @@ const toDetail = async (v: any) => {
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
:auto="false"
|
||||
>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
<tm-tag size="s">{{ v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view v-if="v.phone" class="flex items-center">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/phone.svg" />
|
||||
<view class="second-text-28 ml-1">{{ v.phone }}</view>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view class="second-text-28">{{ v.jobTime == ",," ? "" : "营业时间:" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="v.addressDes" class="second-text-28">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/address.svg" />
|
||||
<text class="ml-1">地址:</text>
|
||||
<text class="m-l-10rpx">{{ v.addressDes }}</text>
|
||||
</view>
|
||||
<template #top>
|
||||
<view class="flex justify-between items-center my-1 z-1000">
|
||||
<tm-text font-size="40" color="#0779FD" class="font-bold">欢迎选购</tm-text>
|
||||
<view class="flex justify-center items-baseline" @tap="changeShop">
|
||||
<tm-icon name="map-pin-2-line" color="#0779FD" />
|
||||
<tm-text font-size="32" color="#0779FD">{{ state.curMerchant.name }}</tm-text>
|
||||
<tm-icon name="arrow-down-s-fill" color="#0779FD" size="40" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<tm-input
|
||||
v-model="state.params.productName"
|
||||
type="text"
|
||||
:height="66"
|
||||
:minHeight="66"
|
||||
:fontSize="28"
|
||||
:showClear="true"
|
||||
:focus="true"
|
||||
placeholder="请输入商品名称"
|
||||
style="border: 2px solid #0779fd; border-radius: 14rpx"
|
||||
:focus-highlight="false"
|
||||
>
|
||||
<template v-slot:rightIcon>
|
||||
<tm-button class="mr-1 py-3" size="xs" @click="searchProduct">搜索</tm-button>
|
||||
</template>
|
||||
</tm-input>
|
||||
<scroll-view scroll-x class="whitespace-nowrap my-2">
|
||||
<tm-tag
|
||||
class="mx-1"
|
||||
size="s"
|
||||
:skin="state.params.categoryId == v.id ? 'normal' : 'outlined'"
|
||||
v-for="(v, i) in state.classifyList"
|
||||
:key="i"
|
||||
@tap="doClassify(v.id)"
|
||||
>
|
||||
{{ v.name }}
|
||||
</tm-tag>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<Waterfall
|
||||
:list="pageHook.list"
|
||||
:gutter="10"
|
||||
:breakpoints="{
|
||||
1800: { rowPerView: 4 },
|
||||
1400: { rowPerView: 3 },
|
||||
975: { rowPerView: 2 },
|
||||
}"
|
||||
:hasAroundGutter="false"
|
||||
backgroundColor="#ffffff00"
|
||||
:crossOrigin="false"
|
||||
:animationCancel="true"
|
||||
>
|
||||
<template #default="{ item, url, index }">
|
||||
<view class="card" @click="toDetail(item)">
|
||||
<LazyImg class="rounded-2" :url="filePath(item.picUrl)" />
|
||||
<view class="p-16rpx flex-col">
|
||||
<view class="sub-text-32 show-line">{{ item.productName }}</view>
|
||||
<view class="flex-row justify-between items-center">
|
||||
<view class="flex items-center">
|
||||
<view class="second-text-32 c-red!">
|
||||
¥{{ parseFloat(item.promotionPrice) != 0 ? hooks.useMoney(item.promotionPrice) : hooks.useMoney(item.retailPrice) }}
|
||||
</view>
|
||||
<view v-if="parseFloat(item.promotionPrice) != 0" class="ml-10rpx second-text-30 line-through">
|
||||
¥{{ hooks.useMoney(item.retailPrice) || 0 }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="second-text-26">已售:{{ item.salesCount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</Waterfall>
|
||||
|
||||
<tm-drawer
|
||||
title="切换超市"
|
||||
:showClose="false"
|
||||
:showFooter="true"
|
||||
size="70%"
|
||||
placement="bottom"
|
||||
v-model:show="state.showDrawer"
|
||||
:duration="100"
|
||||
zIndex="1200"
|
||||
>
|
||||
<tm-radio-group v-model="state.curMerchantRadioId" direction="column">
|
||||
<view
|
||||
v-for="(item, index) in state.merchantList"
|
||||
:key="index"
|
||||
class="w-full flex items-center p-2"
|
||||
:class="[state.curMerchantRadioId == item.id ? 'bg-#e8e8e8' : '']"
|
||||
>
|
||||
<tm-radio class="w-full h-full px-2" :value="item.id">
|
||||
<template v-slot:label="checked">
|
||||
<view class="flex items-center">
|
||||
<image class="w-130rpx h-130rpx" :src="filePath(item.logoPic)" />
|
||||
<view class="ml-2 flex-1 flex-col">
|
||||
<tm-text font-size="30">{{ item.name }}</tm-text>
|
||||
<tm-text font-size="28">地址:{{ item.addressDes }}</tm-text>
|
||||
<tm-text font-size="28">手机:{{ item.phone }}</tm-text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</tm-radio>
|
||||
</view>
|
||||
</tm-radio-group>
|
||||
|
||||
<template #footer>
|
||||
<view class="px-20rpx pt-2 flex justify-between">
|
||||
<tm-button skin="thin" block @click="state.showDrawer = false">取消</tm-button>
|
||||
|
||||
<tm-button block @click="confirmRadioMerchant">确定</tm-button>
|
||||
</view>
|
||||
</template>
|
||||
</tm-drawer>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { ref, reactive } from "vue"
|
||||
import { LazyImg, Waterfall } from "vue-waterfall-plugin-next"
|
||||
import "vue-waterfall-plugin-next/dist/style.css"
|
||||
import { isEmpty } from "radash"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import { merchantApi, shopApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
|
||||
const state = reactive<any>({
|
||||
params: {
|
||||
merchantId: "",
|
||||
categoryId: "",
|
||||
size: 10,
|
||||
productName: "",
|
||||
},
|
||||
merchantList: [],
|
||||
curMerchant: {},
|
||||
classifyList: [],
|
||||
curMerchantRadioId: "",
|
||||
showDrawer: false,
|
||||
})
|
||||
const pageRef = ref<any>(null)
|
||||
|
||||
onLoad(async () => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
|
||||
await getAllMerchant()
|
||||
await getClassify()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
// pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
// 获取所有商户
|
||||
const getAllMerchant = async () => {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
try {
|
||||
const res: any = await merchantApi.page({ current: 1, pagesize: 9999999, type: "3" })
|
||||
if (res.code == 0) {
|
||||
state.merchantList = res.data.records
|
||||
if (!isEmpty(state.merchantList)) {
|
||||
state.curMerchant = state.merchantList[0]
|
||||
return
|
||||
}
|
||||
state.curMerchant = {}
|
||||
}
|
||||
} catch (error) {
|
||||
state.merchantList = []
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取分类
|
||||
const getClassify = async () => {
|
||||
if (state.curMerchant.id) {
|
||||
const { data } = await shopApi.getSupermarketSpuCategory({ merchantId: state.curMerchant.id })
|
||||
state.classifyList = data ?? []
|
||||
if (!isEmpty(state.classifyList)) {
|
||||
state.params.categoryId = state.classifyList[0].id
|
||||
pageRef.value && pageRef.value.reload(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 切换超市
|
||||
const changeShop = () => {
|
||||
state.curMerchantRadioId = state.curMerchant.id || ""
|
||||
state.showDrawer = true
|
||||
}
|
||||
|
||||
// 确定选择超市
|
||||
const confirmRadioMerchant = async () => {
|
||||
state.curMerchant = state.merchantList.find((item: any) => item.id == state.curMerchantRadioId)
|
||||
state.showDrawer = false
|
||||
await getClassify()
|
||||
}
|
||||
|
||||
// 切换分类
|
||||
const doClassify = async (id: string) => {
|
||||
if (state.params.categoryId == id) return
|
||||
state.params.categoryId = id
|
||||
pageRef.value && pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
// 点击搜索
|
||||
const searchProduct = () => {
|
||||
pageRef.value && pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
const pageHook = hooks.usePage(pageRef, shopApi.getSupermarketSpuList, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, { ...state.params, merchantId: state.curMerchant.id })
|
||||
}
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/product-detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in new issue
Block a user