新增:余额支付、微信支付、下单确认功能
This commit is contained in:
@@ -8,3 +8,5 @@ export const BaseUrl = API_BASE_URL;
|
||||
export const Version = 'v3.0.8';
|
||||
// 版权信息
|
||||
export const Copyright = 'WebSoft Inc.';
|
||||
|
||||
// java -jar CertificateDownloader.jar -k 0kF5OlPr482EZwtn9zGufUcqa7ovgxRL -m 1723321338 -f ./apiclient_key.pem -s 2B933F7C35014A1C363642623E4A62364B34C4EB -o ./
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
export const ENV_CONFIG = {
|
||||
// 开发环境
|
||||
development: {
|
||||
API_BASE_URL: 'https://cms-api.websoft.top/api',
|
||||
API_BASE_URL: 'https://cms-api.s209.websoft.top/api',
|
||||
APP_NAME: '时里院子市集',
|
||||
DEBUG: 'true',
|
||||
},
|
||||
// 生产环境
|
||||
production: {
|
||||
API_BASE_URL: 'https://cms-api.websoft.top/api',
|
||||
API_BASE_URL: 'https://cms-api.s209.websoft.top/api',
|
||||
APP_NAME: '时里院子市集',
|
||||
DEBUG: 'false',
|
||||
},
|
||||
|
||||
@@ -42,6 +42,8 @@ export interface ShopOrder {
|
||||
phone?: string;
|
||||
// 手机号码(脱敏)
|
||||
mobile?: string;
|
||||
// 关联收货地址
|
||||
addressId?: number;
|
||||
// 收货地址
|
||||
address?: string;
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Image} from '@nutui/nutui-react-taro'
|
||||
import {Share} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import Taro, {useShareAppMessage, useShareTimeline} from "@tarojs/taro";
|
||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||
import {pageShopGoods} from "@/api/shop/shopGoods";
|
||||
import './BestSellers.scss'
|
||||
@@ -9,6 +9,7 @@ import './BestSellers.scss'
|
||||
|
||||
const BestSellers = () => {
|
||||
const [list, setList] = useState<ShopGoods[]>([])
|
||||
const [goods, setGoods] = useState<ShopGoods>()
|
||||
|
||||
const reload = () => {
|
||||
pageShopGoods({}).then(res => {
|
||||
@@ -20,6 +21,40 @@ const BestSellers = () => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
// 分享给好友
|
||||
useShareAppMessage(() => {
|
||||
return {
|
||||
title: goods?.name || '精选商品',
|
||||
path: `/shop/goodsDetail/index?id=${goods?.goodsId}`,
|
||||
imageUrl: goods?.image, // 分享图片
|
||||
success: function (res: any) {
|
||||
console.log('分享成功', res);
|
||||
Taro.showToast({
|
||||
title: '分享成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
},
|
||||
fail: function (res: any) {
|
||||
console.log('分享失败', res);
|
||||
Taro.showToast({
|
||||
title: '分享失败',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// 分享到朋友圈
|
||||
useShareTimeline(() => {
|
||||
return {
|
||||
title: `${goods?.name || '精选商品'} - 云上商店`,
|
||||
path: `/shop/goodsDetail/index?id=${goods?.goodsId}`,
|
||||
imageUrl: goods?.image
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={'py-3'}>
|
||||
@@ -43,9 +78,18 @@ const BestSellers = () => {
|
||||
<span className={'font-bold text-2xl'}>{item.price}</span>
|
||||
</div>
|
||||
<div className={'buy-btn'}>
|
||||
<div className={'cart-icon'}>
|
||||
<Share size={20} className={'mx-4 mt-2'}
|
||||
onClick={() => Taro.navigateTo({url: '/shop/goodsDetail/index?id=' + item.goodsId})}/>
|
||||
<div className={'cart-icon flex items-center'}>
|
||||
<button
|
||||
className={'flex flex-col justify-center items-center text-gray-500 px-3 gap-1 text-nowrap whitespace-nowrap'}
|
||||
open-type="share"
|
||||
onClick={() => {
|
||||
setGoods(item)
|
||||
}}
|
||||
>
|
||||
<Share className={'text-white'} size={20}/>
|
||||
</button>
|
||||
{/*<Share size={20} className={'mx-4 mt-2'}*/}
|
||||
{/* onClick={() => Taro.navigateTo({url: '/shop/goodsDetail/index?id=' + item.goodsId})}/>*/}
|
||||
</div>
|
||||
<div className={'text-white pl-4 pr-5'}
|
||||
onClick={() => Taro.navigateTo({url: '/shop/goodsDetail/index?id=' + item.goodsId})}>购买
|
||||
|
||||
@@ -6,3 +6,11 @@
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
}
|
||||
.header-bg2{
|
||||
background: linear-gradient(to bottom, #03605c, #18ae4f);
|
||||
height: 200px;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import Taro from '@tarojs/taro';
|
||||
import {Button, Space} from '@nutui/nutui-react-taro'
|
||||
import {TriangleDown} from '@nutui/icons-react-taro'
|
||||
import {TriangleDown, Search} from '@nutui/icons-react-taro'
|
||||
import {Popup, Avatar, NavBar} from '@nutui/nutui-react-taro'
|
||||
import {getSiteInfo, getUserInfo, getWxOpenId} from "@/api/layout";
|
||||
import {TenantId} from "@/config/app";
|
||||
@@ -12,7 +12,7 @@ import {User} from "@/api/system/user/model";
|
||||
import MySearch from "./MySearch";
|
||||
import './Header.scss';
|
||||
|
||||
const Header = () => {
|
||||
const Header = (props: any) => {
|
||||
const [userInfo, setUserInfo] = useState<User>()
|
||||
const [IsLogin, setIsLogin] = useState<boolean>(true)
|
||||
const [config, setConfig] = useState<CmsWebsite>()
|
||||
@@ -140,8 +140,10 @@ const Header = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={'fixed top-0 header-bg'}>
|
||||
<MySearch done={reload}/>
|
||||
<div className={'fixed top-0 header-bg'} style={{
|
||||
height: !props.stickyStatus ? '180px' : '94px',
|
||||
}}>
|
||||
{!props.stickyStatus && <MySearch done={reload}/>}
|
||||
</div>
|
||||
<NavBar
|
||||
style={{marginTop: `${statusBarHeight}px`, marginBottom: '0px', backgroundColor: 'transparent'}}
|
||||
@@ -171,6 +173,11 @@ const Header = () => {
|
||||
<TriangleDown className={'text-white'} size={9}/>
|
||||
</div>
|
||||
)}>
|
||||
{props.stickyStatus && (
|
||||
<Space>
|
||||
<Search className={'text-white mx-2'} size={18}/>
|
||||
</Space>
|
||||
)}
|
||||
</NavBar>
|
||||
<Popup
|
||||
visible={showBasic}
|
||||
|
||||
@@ -2,7 +2,7 @@ import Header from './Header';
|
||||
import BestSellers from './BestSellers';
|
||||
import Taro from '@tarojs/taro';
|
||||
import {useShareAppMessage, useShareTimeline} from "@tarojs/taro"
|
||||
import {useEffect} from "react";
|
||||
import {useEffect, useState} from "react";
|
||||
import {getSiteInfo} from "@/api/layout";
|
||||
import {Sticky} from '@nutui/nutui-react-taro'
|
||||
import Menu from "./Menu";
|
||||
@@ -12,6 +12,8 @@ import './index.scss'
|
||||
// import GoodsList from "./GoodsList";
|
||||
|
||||
function Home() {
|
||||
// 吸顶状态
|
||||
const [stickyStatus, setStickyStatus] = useState<boolean>(false)
|
||||
|
||||
useShareTimeline(() => {
|
||||
return {
|
||||
@@ -70,6 +72,12 @@ function Home() {
|
||||
});
|
||||
};
|
||||
|
||||
const onSticky = (item) => {
|
||||
if(item){
|
||||
setStickyStatus(!stickyStatus)
|
||||
}
|
||||
}
|
||||
|
||||
const reload = () => {
|
||||
|
||||
};
|
||||
@@ -104,8 +112,8 @@ function Home() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Sticky threshold={0}>
|
||||
<Header/>
|
||||
<Sticky threshold={0} onChange={() => onSticky(arguments)}>
|
||||
<Header stickyStatus={stickyStatus}/>
|
||||
</Sticky>
|
||||
<div className={'flex flex-col mt-12'}>
|
||||
<Menu/>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '订单列表',
|
||||
navigationBarTextStyle: 'black',
|
||||
navigationStyle: 'custom'
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {useState} from "react"; // 添加 useCallback 引入
|
||||
import Taro, {useDidShow} from '@tarojs/taro'
|
||||
import {NavBar, Space} from '@nutui/nutui-react-taro'
|
||||
import {NavBar, Space, Empty, Button, ConfigProvider} from '@nutui/nutui-react-taro'
|
||||
import {Search} from '@nutui/icons-react-taro'
|
||||
import OrderList from "./components/OrderList";
|
||||
import {ShopOrder} from "@/api/shop/shopOrder/model";
|
||||
@@ -38,8 +38,6 @@ function Order() {
|
||||
<NavBar
|
||||
fixed={true}
|
||||
style={{marginTop: `${statusBarHeight}px`, backgroundColor: 'transparent'}}
|
||||
onBackClick={() => {
|
||||
}}
|
||||
left={
|
||||
<>
|
||||
<div className={'flex justify-between items-center w-full'}>
|
||||
@@ -56,9 +54,33 @@ function Order() {
|
||||
</>
|
||||
}
|
||||
>
|
||||
<span>订单</span>
|
||||
<span>我的订单</span>
|
||||
</NavBar>
|
||||
<OrderList data={list}/>
|
||||
{/*暂无订单*/}
|
||||
{list.length == 0 && (
|
||||
<ConfigProvider>
|
||||
<div className={'h-full flex flex-col justify-center items-center'} style={{
|
||||
height: 'calc(100vh - 150px)',
|
||||
}}>
|
||||
<Empty
|
||||
style={{
|
||||
backgroundColor: 'transparent'
|
||||
}}
|
||||
description="您还没有订单哦"
|
||||
/>
|
||||
<Space>
|
||||
<Button type="success" fill="dashed"
|
||||
onClick={() => Taro.switchTab({url: '/pages/index/index'})}>去挑选商品</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</ConfigProvider>
|
||||
)}
|
||||
{/*订单列表*/}
|
||||
{
|
||||
list.length > 0 && (
|
||||
<OrderList data={list}/>
|
||||
)
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {RichText, View} from '@tarojs/components'
|
||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||
import {getShopGoods} from "@/api/shop/shopGoods";
|
||||
import {Swiper} from '@nutui/nutui-react-taro'
|
||||
import {wxParse} from "@/utils/common";
|
||||
import navTo, {wxParse} from "@/utils/common";
|
||||
import "./index.scss";
|
||||
import {useCart} from "@/hooks/useCart";
|
||||
|
||||
@@ -23,6 +23,14 @@ const GoodsDetail = () => {
|
||||
const handleAddToCart = () => {
|
||||
if (!goods) return;
|
||||
|
||||
if(!Taro.getStorageSync('UserId')){
|
||||
return Taro.showToast({
|
||||
title: '请先登录',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
|
||||
addToCart({
|
||||
goodsId: goods.goodsId!,
|
||||
name: goods.name || '',
|
||||
@@ -117,7 +125,7 @@ const GoodsDetail = () => {
|
||||
top: "50px",
|
||||
right: "110px",
|
||||
}}
|
||||
onClick={() => Taro.navigateTo({url: '/pages/cart/cart'})}>
|
||||
onClick={() => navTo(`/pages/cart/cart`,true)}>
|
||||
<Badge value={cartCount} top="-2" right="2">
|
||||
<div style={{display: 'flex', alignItems: 'center'}}>
|
||||
<Cart size={16}/>
|
||||
@@ -201,7 +209,7 @@ const GoodsDetail = () => {
|
||||
onClick={() => handleAddToCart()}>加入购物车
|
||||
</div>
|
||||
<div className={'cart-buy pl-4 pr-5 text-sm'}
|
||||
onClick={() => Taro.navigateTo({url: `/shop/orderConfirm/index?goodsId=${goods?.goodsId}`})}>立即购买
|
||||
onClick={() => navTo(`/shop/orderConfirm/index?goodsId=${goods?.goodsId}`,true)}>立即购买
|
||||
</div>
|
||||
</div>
|
||||
</View>
|
||||
|
||||
@@ -12,6 +12,7 @@ import Gap from "@/components/Gap";
|
||||
import {TenantId} from "@/config/app";
|
||||
import {payByBalance, selectPayment} from "@/api/system/payment";
|
||||
import {Payment} from "@/api/system/payment/model";
|
||||
import {API_BASE_URL} from "@/config/env";
|
||||
|
||||
const OrderConfirm = () => {
|
||||
const [goods, setGoods] = useState<ShopGoods | null>(null);
|
||||
@@ -60,9 +61,10 @@ const OrderConfirm = () => {
|
||||
const onBalancePay = async (goods: ShopGoods) => {
|
||||
Taro.showLoading({title: '支付中...'})
|
||||
payByBalance({
|
||||
payType: goods.type,
|
||||
payType: 0, // 余额支付
|
||||
payPrice: goods.price,
|
||||
totalPrice: goods.price,
|
||||
addressId: address?.id,
|
||||
userId: Taro.getStorageSync('UserId'),
|
||||
tenantId: Number(TenantId)
|
||||
}).then().finally(() => {
|
||||
@@ -73,7 +75,7 @@ const OrderConfirm = () => {
|
||||
})
|
||||
Taro.hideLoading()
|
||||
setTimeout(() => {
|
||||
// Taro.switchTab({url: '/pages/order/order'})
|
||||
Taro.switchTab({url: '/pages/order/order'})
|
||||
}, 2000)
|
||||
}).catch(() => {
|
||||
Taro.hideLoading()
|
||||
@@ -83,8 +85,8 @@ const OrderConfirm = () => {
|
||||
const onWxPay = async (goods: ShopGoods) => {
|
||||
Taro.showLoading({title: '支付中...'})
|
||||
Taro.request({
|
||||
// url: 'https://cms-api.websoft.top/api/shop/shop-order',
|
||||
url: 'http://127.0.0.1:9200/api/shop/shop-order',
|
||||
url: API_BASE_URL + '/shop/shop-order',
|
||||
// url: 'http://127.0.0.1:9200/api/shop/shop-order',
|
||||
method: 'POST',
|
||||
header: {
|
||||
'content-type': 'application/json',
|
||||
@@ -92,15 +94,26 @@ const OrderConfirm = () => {
|
||||
TenantId
|
||||
},
|
||||
data: {
|
||||
payType: 1,
|
||||
totalPrice: goods.price,
|
||||
payPrice: goods.price,
|
||||
userId: Taro.getStorageSync('UserId'),
|
||||
tenantId: TenantId,
|
||||
payType: goods.type,
|
||||
comments: goods.name,
|
||||
name: goods.name
|
||||
name: goods.name,
|
||||
addressId: address?.id,
|
||||
},
|
||||
success: function (res) {
|
||||
Taro.hideLoading()
|
||||
if(res.data.code != 0){
|
||||
Taro.showToast({
|
||||
title: res.data.message,
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
return false;
|
||||
}
|
||||
// 支付结果
|
||||
const data = res.data.data
|
||||
console.log(data, 'payInfo')
|
||||
// Taro.showToast({
|
||||
@@ -131,13 +144,8 @@ const OrderConfirm = () => {
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: function (msg) {
|
||||
console.log('支付失败')
|
||||
complete: function () {
|
||||
Taro.hideLoading()
|
||||
Taro.showToast({
|
||||
title: `${msg}`,
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import Taro from '@tarojs/taro'
|
||||
|
||||
export default function navTo(url: string, isLogin = false) {
|
||||
if (isLogin) {
|
||||
if (!Taro.getStorageSync('access_token')) {
|
||||
if (!Taro.getStorageSync('access_token') || !Taro.getStorageSync('UserId')) {
|
||||
Taro.showToast({
|
||||
title: '请先登录',
|
||||
icon: 'none',
|
||||
|
||||
@@ -5,7 +5,7 @@ let baseUrl = BaseUrl
|
||||
|
||||
// 开发环境
|
||||
if(process.env.NODE_ENV === 'development'){
|
||||
// baseUrl = 'http://localhost:9000/api'
|
||||
// baseUrl = 'http://localhost:9200/api'
|
||||
}
|
||||
export function request<T>(options:any) {
|
||||
const token = Taro.getStorageSync('access_token');
|
||||
|
||||
@@ -4,7 +4,7 @@ import {User} from "@/api/system/user/model";
|
||||
// 模版套餐ID - 请根据实际情况修改
|
||||
export const TEMPLATE_ID = '10550';
|
||||
// 服务接口 - 请根据实际情况修改
|
||||
export const SERVER_API_URL = 'https://server.gxwebsoft.com/api';
|
||||
export const SERVER_API_URL = 'https://server.s209.websoft.top/api';
|
||||
// export const SERVER_API_URL = 'http://127.0.0.1:8000/api';
|
||||
/**
|
||||
* 保存用户信息到本地存储
|
||||
|
||||
Reference in New Issue
Block a user