提交 2df70eb2 作者: ZhangLingKun

功能:服务详情页面

上级 e3710b06
流水线 #7672 已通过 于阶段
in 5 分 3 秒
......@@ -124,3 +124,97 @@ export type ListInspectionPriceUnit = InterFunction<
unitName: string;
}[]
>;
// 单位服务详情
export type GetCompanyInspectionById = InterFunction<
{
id: number;
},
{
companyInfoId: number;
companyName: string;
detailPage: string;
id: number;
industryTypeDTO: {
createTime: string;
description: string;
id: number;
inspectionDTOS: Array<{
caseImg: string;
caseVideo: string;
companyInspectionDTOS: null;
id: number;
industryTypeId: number;
inspectionDescription: string;
inspectionImg: string;
inspectionName: string;
inspectionNo: string;
saleState: number;
}>;
saleState: number;
typeImg: string;
typeName: string;
};
inspectionDTO: {
caseImg: string;
caseVideo: string;
companyInspectionDTOS: null;
id: number;
industryTypeId: number;
inspectionDescription: string;
inspectionImg: string;
inspectionName: string;
inspectionNo: string;
saleState: number;
};
inspectionFileDTOS: Array<{
companyInspectionId: number;
fileType: number;
fileUrl: string;
first: number;
id: number;
}>;
inspectionFirstImg: string;
inspectionId: number;
inspectionPriceUnitId: number;
inspectionTagDTO: {
id: number;
inspectionId: number;
tagName: string;
};
inspectionTagId: number;
price: number;
priceRemark: string;
remark: string;
saleState: number;
serviceArea: string;
}
>;
// 单位查询
export type GetCompanyInfoById = InterFunction<
{
id: number;
},
{
address: string;
brandLogo: string;
brandName: string;
companyName: string;
companyType: number;
companyUserName: string;
content: string;
creditCode: string;
fullName: string;
id: number;
lat: number;
leader: number;
licenseImg: string;
lon: number;
phoneNum: number;
remark: string;
score: string;
userAccountId: number;
backImg: string;
backUserAccountId: number;
backUserId: number;
}
>;
import {
GetCompanyInfoById,
GetCompanyInspectionById,
GetIndustryListPagesType,
GetListAPPCompanyInspectionPageType,
ListInspectionPriceUnit,
......@@ -21,4 +23,12 @@ export class ServiceAPI {
// 价格单位列表
static listInspectionPriceUnit: ListInspectionPriceUnit = (params) =>
request.get('/pms/company-inspection/listInspectionPriceUnit', params);
// 单位服务详情
static getCompanyInspectionById: GetCompanyInspectionById = (params) =>
request.get('/pms/company-inspection/getCompanyInspectionById', { params });
// 单位查询
static getCompanyInfoById: GetCompanyInfoById = (params) =>
request.get('/userapp/company/getCompanyInfoById', { params });
}
......@@ -30,6 +30,7 @@ const BreadcrumbView: React.FC = () => {
{ name: '商品详情', path: 'product' },
{ name: '购物车', path: 'cart' },
{ name: '提交订单', path: 'submit' },
{ name: '服务详情', path: 'detail' },
];
// 转换路由
const getCurrentRouter = () => {
......
import React, { useEffect, useState } from 'react';
import { Button } from 'antd';
import { useRouter } from 'next/router';
import styled from 'styled-components';
import { HomeAPI } from '@/api';
import { InterListType } from '@/api/interface';
......@@ -9,6 +10,8 @@ import { IndustryListPagesType } from '@/api/interface/home';
type ListType = InterListType<IndustryListPagesType>;
const TabView02 = () => {
// 导航钩子
const router = useRouter();
// 列表数据
const [tabList, setTabList] = useState<ListType>([]);
// 获取分类列表
......@@ -22,6 +25,17 @@ const TabView02 = () => {
// console.log('获取分类列表 --->', res.result);
}
};
// 跳转一级分类详情
const handleMain = (i: ListType[0]) => {
router.push(`/service/${i?.id}`).then();
};
// 跳转二级分类详情
const handleSecond = (
i: ListType[0],
n: ListType[0]['inspectionDTOS'][0],
) => {
router.push(`/service/${i?.id}/${n?.id}`).then();
};
// 组件挂载
useEffect(() => {
getIndustryListPages().then();
......@@ -34,11 +48,22 @@ const TabView02 = () => {
{!!i.typeImg && (
<img src={i.typeImg} alt={i.typeName} className="title-image" />
)}
<div className="title-name">{i.typeName}</div>
<Button
type={'link'}
className="title-name"
onClick={() => handleMain(i)}
>
{i.typeName}
</Button>
</div>
<div className="tab-list flex-start">
{i.inspectionDTOS?.map((n, m) => (
<Button type={'link'} key={m} className="list-item">
<Button
type={'link'}
key={m}
className="list-item"
onClick={() => handleSecond(i, n)}
>
{n.inspectionName}
</Button>
))}
......@@ -65,7 +90,6 @@ const TabViewWrap = styled.div`
.title-image {
width: 1.68rem;
height: 1.68rem;
margin-right: 0.5rem;
}
.title-name {
font-size: 0.75rem;
......
import React, { useEffect } from 'react';
import { EnvironmentFilled, LogoutOutlined } from '@ant-design/icons';
import {
EnvironmentFilled,
LogoutOutlined,
ReloadOutlined,
} from '@ant-design/icons';
import { Button, Dropdown, MenuProps, Modal } from 'antd';
import dayjs from 'dayjs';
import Cookies from 'js-cookie';
import { useRouter } from 'next/router';
import { useDispatch, useSelector } from 'react-redux';
import { CommonAPI } from '@/api';
import { HeaderWrap } from '@/components/layout/header/styled';
......@@ -20,7 +23,7 @@ const HeaderView: React.FC<{
}> = ({ placeholder }) => {
const token = Cookies.get('SHAREFLY-WEB-TOKEN');
// 当前的路由数据
const router = useRouter();
// const router = useRouter();
// store
const dispatch = useDispatch();
// system
......@@ -51,12 +54,20 @@ const HeaderView: React.FC<{
};
// 计算天数与当前时间的差值
const getDiffDay = (date: string) => dayjs().diff(dayjs(date), 'day');
// 组件挂载
useEffect(() => {
// 获取当前地址
// 重新获取用户的地址信息
const handleReload = () => {
getLocationByIP().then((res) => {
dispatch(setAddress(res));
});
};
// 组件挂载
useEffect(() => {
if (!address?.city) {
// 获取当前地址
getLocationByIP().then((res) => {
dispatch(setAddress(res));
});
}
// 当前是否登录
if (!token) {
dispatch(setSystem({ token: undefined }));
......@@ -129,6 +140,13 @@ const HeaderView: React.FC<{
<Button type={'link'} className="location-address">
{address?.city || '定位中...'}
</Button>
<Button
type={'link'}
icon={<ReloadOutlined style={{ fontSize: '10px' }} />}
className="location-reload"
title={'刷新位置'}
onClick={() => handleReload()}
></Button>
<div className="location-hello">Hi,欢迎来到云享飞</div>
</div>
<div className="header-nav">
......
......@@ -27,7 +27,7 @@ export const HeaderWrap = styled.div`
align-items: center;
justify-content: flex-start;
.location-icon {
margin: 0 0 0.2rem 0;
margin: 0 0.5rem 0 0;
}
.location-address,
.location-hello {
......@@ -38,6 +38,15 @@ export const HeaderWrap = styled.div`
.location-hello {
width: 8rem;
}
.location-address {
margin: 0 0.25rem 0 0 !important;
}
.location-reload,
.location-address {
width: auto;
margin: 0 0.5rem 0 0;
padding: 0;
}
}
.header-nav {
display: flex;
......
import React from 'react';
import { PhoneOutlined, ShopOutlined } from '@ant-design/icons';
import { Rate } from 'antd';
import { Button, Rate } from 'antd';
import styled from 'styled-components';
import { InterDataType } from '@/api/interface';
import {
AppMallGoodsDetails,
GetCompanyInfoByBUId,
} from '@/api/interface/mall';
import QrcodePopover from '@/components/qrcodePopover';
// 商品详情类型
type DetailType = InterDataType<AppMallGoodsDetails>;
// 商城详情类型
......@@ -42,16 +43,26 @@ const ProductStoreView: React.FC<{ detail: DetailType; store: StoreType }> = ({
<div className="item-value">{store?.phoneNum || '18626051369'}</div>
</div>
<div className="store-action flex-start">
<div className="action-item flex-start">
<ShopOutlined style={{ color: '#A8A8A8' }} />
<div className="text">进店逛逛</div>
</div>
<div className="action-item flex-start">
<PhoneOutlined
style={{ color: '#FF552D', transform: 'rotateY(180deg)' }}
/>
<div className="text">联系方式</div>
</div>
<QrcodePopover
path="page-service/service-store/index"
scene={`id=${Number(store?.id)}`}
>
<Button className="action-item flex-start">
<ShopOutlined style={{ color: '#FF552D' }} />
<div className="text">进店逛逛</div>
</Button>
</QrcodePopover>
<QrcodePopover
path="page-service/service-store/index"
scene={`id=${Number(store?.id)}`}
>
<Button className="action-item flex-start">
<PhoneOutlined
style={{ color: '#FF552D', transform: 'rotateY(180deg)' }}
/>
<div className="text">联系方式</div>
</Button>
</QrcodePopover>
</div>
</ProductStoreWrap>
);
......@@ -138,18 +149,16 @@ const ProductStoreWrap = styled.div`
position: relative;
background: #ffffff;
box-sizing: border-box;
padding: 0.33rem 1rem;
padding: 0 1rem;
border: 0.04rem solid #a8a8a8;
cursor: pointer;
margin-right: 0.83rem;
.text {
color: #a8a8a8;
font-weight: 400;
font-size: 12px;
margin-left: 0.33rem;
}
&:not(:last-child) {
margin-right: 0.83rem;
}
&:last-child {
border: 0.04rem solid #ff552d;
.text {
......
......@@ -6,9 +6,11 @@ const QrcodePopover: React.FC<{
children?: React.ReactNode;
text?: string;
path?: string;
}> = ({ children, text, path }) => {
scene?: string;
}> = ({ children, text, path, scene }) => {
QrcodePopover.defaultProps = {
path: 'pages/welcome/index',
scene: 'type=share',
};
// 登录二维码的地址
const [qrCodeData, setQrCodeData] = useState<string>();
......@@ -17,7 +19,7 @@ const QrcodePopover: React.FC<{
// 获取二维码
const res = await CommonAPI.getAppletQRCode({
page: path || 'pages/welcome/index',
scene: 'type=share',
scene: scene || 'type=share',
});
if (res && res.code === '200') {
if (!res.result) {
......
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { InterDataType } from '@/api/interface';
import { GetCompanyInspectionById } from '@/api/interface/service';
import ProductSwiperView from '@/components/product-swiper';
import { GlobalDataState, setGlobalData } from '@/store/module/globalData';
import { UserInfoState } from '@/store/module/userInfo';
import { formatMoney } from '@/utils/money';
// 商品详情类型
type DetailType = InterDataType<GetCompanyInspectionById>;
const ServiceHeadView: React.FC<{ detail: DetailType }> = ({ detail }) => {
// 当前的路由数据
// const router = useRouter();
// store
const dispatch = useDispatch();
// userInfo
const userInfo = useSelector((state: any) => state.userInfo) as UserInfoState;
// globalData
const globalData = useSelector(
(state: any) => state.globalData,
) as GlobalDataState;
// 提交事件
const handleSubmit = async (type: number) => {
// 判断是否登录
if (!userInfo?.id) {
dispatch(
setGlobalData({
loginModalVisible: true,
}),
);
return;
}
// 立即购买
if (type === 1) {
dispatch(
setGlobalData({
qrcodeModalVisible: true,
qrcodeModalPath: 'page-service/service-flyer/index',
qrcodeModalScene: `id=${Number(detail?.id)}`,
}),
);
return;
}
// 在线沟通
if (type === 2) {
dispatch(
setGlobalData({
qrcodeModalVisible: true,
qrcodeModalPath: 'page-service/service-detail/index',
qrcodeModalScene: `id=${Number(detail?.id)}`,
}),
);
}
};
// 转换swiper图片
const getSwiperList = () => {
return detail?.inspectionFileDTOS
?.filter((i) => i.fileType !== 1)
?.sort((a, b) => b.first - a.first)
?.map((i) => ({ id: i.id, url: i.fileUrl }));
};
// 获取商品的单位
const getPriceUnit = () => {
const unit = globalData?.priceUnitList?.find(
(i) => i.id === detail?.inspectionPriceUnitId,
);
return unit?.unitName || '次';
};
return (
<ServiceHeadWrap>
<div className="product-swiper">
<ProductSwiperView list={getSwiperList()} />
</div>
<div className="product-content">
<div className="content-title">
【{detail?.industryTypeDTO?.typeName}】
{detail?.inspectionDTO?.inspectionName}
</div>
<div className="content-price flex-start">
<div className="price-label">价格</div>
<div className="price-money">
{detail?.price ? (
<>
<span className="label">¥</span>
<span
className="num"
title={`${formatMoney(detail?.price)}元起每${getPriceUnit()}`}
>
{formatMoney(detail?.price)}
</span>
<span
className="unit text-ellipsis"
title={`${formatMoney(detail?.price)}元起每${getPriceUnit()}`}
>
起/{getPriceUnit()}
</span>
</>
) : (
<span className="label">咨询报价</span>
)}
</div>
</div>
<div className="content-item flex-start">
<div className="item-label">团队</div>
<div className="item-content flex-start">
<img
className="team-label"
src="https://file.iuav.com/file/sharefly-service-label01.png"
alt="专业飞手"
/>
<div className="team-text">飞手已通过认证培训</div>
</div>
</div>
<div className="content-item flex-start item-bottom">
<div className="item-label">服务</div>
<div className="item-content flex-start">
<div className="item-tag">7x24小时服务</div>
<div className="item-tag">已售{Math.floor(detail.id * 2.22)}</div>
</div>
</div>
<div className="content-action flex-start select-none">
<div className="action-item" onClick={() => handleSubmit(2)}>
在线沟通
</div>
<div className="action-item" onClick={() => handleSubmit(1)}>
马上预约
</div>
</div>
</div>
</ServiceHeadWrap>
);
};
export default ServiceHeadView;
// 样式
const ServiceHeadWrap = styled.div`
position: relative;
width: calc((100% - 0.83rem) / 10 * 7.5);
min-height: 28rem;
background: #ffffff;
border: 0.04rem solid #e3e3e3;
box-sizing: border-box;
margin-right: 0.83rem;
display: flex;
align-items: flex-start;
justify-content: flex-start;
padding: 2rem 1rem 2rem 1rem;
.product-swiper {
position: relative;
width: 22rem;
height: 26rem;
box-sizing: border-box;
}
.product-content {
position: relative;
width: calc(100% - 22rem);
height: 100%;
box-sizing: border-box;
padding: 0 0 0 1rem;
//background: lightblue;
.content-title {
width: 100%;
font-size: 24px;
font-weight: 500;
color: #212121;
margin-bottom: 0.71rem;
// 双行省略
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
}
.content-desc {
font-weight: 400;
color: #666666;
margin-bottom: 0.71rem;
}
.content-price {
position: relative;
width: 100%;
background: #f3f3f3;
box-sizing: border-box;
padding: 0.8rem;
margin-bottom: 1rem;
align-items: baseline;
.price-label {
width: 2.5rem;
color: #999999;
text-align: justify;
text-align-last: justify;
margin-right: 1rem;
transform: translateY(-0.1rem);
}
.price-money {
font-size: 24px;
//line-height: 1;
color: #ff6700;
.label {
font-size: 18px;
}
.unit {
font-size: 13px;
color: #999999;
margin-left: 0.5rem;
}
}
}
.content-item {
margin-bottom: 1rem;
padding: 0 0.8rem;
//flex-wrap: nowrap;
.item-label {
width: 2.5rem;
color: #999999;
text-align: justify;
text-align-last: justify;
margin-right: 1rem;
}
.item-content {
width: calc(100% - 3.5rem);
.team-label {
height: 2rem;
width: 6rem;
object-fit: contain;
margin-right: 0.5rem;
}
.team-text {
color: #666666;
}
.item-tag {
box-sizing: border-box;
background: #f4f4f4;
border-radius: 0.13rem;
padding: 0 0.33rem 0 0.33rem;
color: #333333;
&:not(:last-child) {
margin-right: 0.5rem;
}
}
.content-address {
font-size: 12px;
&:first-child {
margin-bottom: 0.3rem;
.text {
color: #8e8e8e;
}
}
.text {
margin-left: 0.3rem;
font-weight: 400;
}
}
.content-spec {
//min-width: max-content;
height: 2rem;
background: #f2f2f2;
border-radius: 0.08rem;
text-align: center;
line-height: 2rem;
font-weight: 400;
box-sizing: border-box;
padding: 0 1rem;
border: 0.04rem solid #f2f2f2;
margin: 0 0.5rem 0.5rem 0;
&:last-child {
margin-right: 0;
}
}
.spec-active {
background: #ffede8;
border: 0.04rem solid #ff552d;
color: #ff552d;
}
}
}
.item-bottom {
margin-bottom: 6.8rem;
}
.content-action {
//position: absolute;
//left: 1rem;
//bottom: 0;
position: relative;
width: 100%;
margin-top: 2rem;
.action-item {
width: 8.63rem;
height: 2.33rem;
background: #fff0e5;
border: 0.04rem solid #ff552d;
text-align: center;
line-height: 2.33rem;
font-size: 13px;
font-weight: 400;
color: #ff552d;
cursor: pointer;
&:hover,
&:active {
filter: brightness(0.95);
}
}
.action-item:not(:last-child) {
margin-right: 0.8rem;
}
.action-item:last-child {
background: #ff552d;
color: #fff;
}
}
}
`;
import React from 'react';
import { PhoneOutlined, ShopOutlined } from '@ant-design/icons';
import { Button, Rate } from 'antd';
import styled from 'styled-components';
import { InterDataType } from '@/api/interface';
import {
GetCompanyInfoById,
GetCompanyInspectionById,
} from '@/api/interface/service';
import QrcodePopover from '@/components/qrcodePopover';
// 商品详情类型
type DetailType = InterDataType<GetCompanyInspectionById>;
// 商城详情类型
type StoreType = InterDataType<GetCompanyInfoById>;
const ServiceStoreView: React.FC<{ detail: DetailType; store: StoreType }> = ({
store,
}) => {
return (
<ServiceStoreWrap>
<div className="store-card flex-start">
<img
className="image"
src={store?.brandLogo}
alt={store?.companyName}
/>
<div className="card-content">
<div className="title">{store?.companyName}</div>
<div className="star flex-start">
<div className="tag select-none">店铺星级</div>
<Rate allowHalf defaultValue={5} style={{ fontSize: '10px' }} />
</div>
<div className="text two-line-ellipsis" title={store?.content}>
{store?.content}
</div>
</div>
</div>
<div className="store-item flex-start">
<div className="item-label">地址:</div>
<div className="item-value">{store?.address}</div>
</div>
<div className="store-item flex-start">
<div className="item-label">电话:</div>
<div className="item-value">{store?.phoneNum || '18626051369'}</div>
</div>
<div className="store-action flex-start">
<QrcodePopover
path="page-service/service-store/index"
scene={`id=${Number(store?.id)}`}
>
<Button className="action-item flex-start">
<ShopOutlined style={{ color: '#FF552D' }} />
<div className="text">进店逛逛</div>
</Button>
</QrcodePopover>
<QrcodePopover
path="page-service/service-store/index"
scene={`id=${Number(store?.id)}`}
>
<Button className="action-item flex-start">
<PhoneOutlined
style={{ color: '#FF552D', transform: 'rotateY(180deg)' }}
/>
<div className="text">联系方式</div>
</Button>
</QrcodePopover>
</div>
</ServiceStoreWrap>
);
};
export default ServiceStoreView;
// 样式
const ServiceStoreWrap = styled.div`
position: relative;
width: calc((100% - 0.83rem) / 10 * 2.5);
min-height: 18rem;
//height: 100%;
background: #ffffff;
border: 0.04rem solid #e3e3e3;
box-sizing: border-box;
padding: 1rem;
.store-card {
width: 100%;
min-height: 8em;
background: linear-gradient(270deg, #5f5f5f 0%, #060606 100%);
border-radius: 0.33rem;
box-sizing: border-box;
padding: 0.58rem 1rem;
margin-bottom: 1rem;
align-items: flex-start;
.image {
width: 3.25rem;
height: 3.25rem;
border: 0.02rem solid #e3e3e3;
margin-right: 0.67rem;
}
.card-content {
position: relative;
width: calc(100% - 3.25rem - 0.67rem);
.title {
font-weight: 500;
color: #ffffff;
}
.star {
margin-bottom: 0.5rem;
.tag {
position: relative;
height: 1.2rem;
line-height: 1rem;
background: #fff3ee;
border-radius: 0.13rem;
border: 0.02rem solid #ff552d;
box-sizing: border-box;
padding: 0 0.33rem;
text-align: center;
font-size: 10px;
color: #ff552d;
margin-right: 0.25rem;
transform: scale(0.8);
}
}
.text {
font-size: 12px;
font-weight: 400;
color: rgba(255, 255, 255, 0.8);
}
}
}
.store-item {
align-items: flex-start;
flex-wrap: nowrap;
margin-bottom: 1rem;
.item-label {
width: 3rem;
color: #666666;
}
.item-value {
width: calc(100% - 3rem);
font-size: 12px;
font-weight: 400;
color: #666666;
}
}
.store-action {
position: relative;
width: 100%;
.action-item {
position: relative;
background: #ffffff;
box-sizing: border-box;
padding: 0 1rem;
border: 0.04rem solid #a8a8a8;
cursor: pointer;
margin-right: 0.83rem;
.text {
color: #a8a8a8;
font-weight: 400;
font-size: 12px;
margin-left: 0.33rem;
}
&:not(:last-child) {
margin-right: 0.83rem;
}
&:last-child {
border: 0.04rem solid #ff552d;
.text {
color: #ff552d;
}
}
&:hover {
filter: brightness(0.95);
}
}
}
`;
import React from 'react';
import { InterListType } from '@/api/interface';
import { GetIndustryListPagesType } from '@/api/interface/service';
import { ServiceAPI } from '@/api/modules/service';
import ServiceView from '@/components/service-comp';
import { wrapper } from '@/store';
import { setGlobalData } from '@/store/module/globalData';
// 分类列表类型
type CategoryListType = InterListType<GetIndustryListPagesType>;
// 使用wrapper.getServerSideProps高阶函数包裹getServerSideProps函数
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async () => {
// 分类数据
let categoryList: CategoryListType = [];
// 获取各个目录及分类信息
const getIndustryListPages = async () => {
const res = await ServiceAPI.getIndustryListPages({
pageNo: 1,
pageSize: 999,
});
if (res && res.code === '200') {
categoryList = res?.result?.list || [];
}
};
// 获取价格单位列表
const getPriceUnitList = async () => {
const res = await ServiceAPI.listInspectionPriceUnit();
if (res && res.code === '200') {
store.dispatch(setGlobalData({ priceUnitList: res?.result || [] }));
}
};
// 依次获取接口数据
await (async () => {
await getIndustryListPages();
await getPriceUnitList();
})();
return { props: { categoryList } };
},
);
const ServiceSecondView: React.FC<{
categoryList: CategoryListType;
}> = (props) => <ServiceView {...props} />;
export default ServiceSecondView;
import React from 'react';
import { InterListType } from '@/api/interface';
import { GetIndustryListPagesType } from '@/api/interface/service';
import { ServiceAPI } from '@/api/modules/service';
import ServiceView from '@/components/service-comp';
import { wrapper } from '@/store';
import { setGlobalData } from '@/store/module/globalData';
// 分类列表类型
type CategoryListType = InterListType<GetIndustryListPagesType>;
// 使用wrapper.getServerSideProps高阶函数包裹getServerSideProps函数
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async () => {
// 分类数据
let categoryList: CategoryListType = [];
// 获取各个目录及分类信息
const getIndustryListPages = async () => {
const res = await ServiceAPI.getIndustryListPages({
pageNo: 1,
pageSize: 999,
});
if (res && res.code === '200') {
categoryList = res?.result?.list || [];
}
};
// 获取价格单位列表
const getPriceUnitList = async () => {
const res = await ServiceAPI.listInspectionPriceUnit();
if (res && res.code === '200') {
store.dispatch(setGlobalData({ priceUnitList: res?.result || [] }));
}
};
// 依次获取接口数据
await (async () => {
await getIndustryListPages();
await getPriceUnitList();
})();
return { props: { categoryList } };
},
);
const ServiceMainView: React.FC<{
categoryList: CategoryListType;
}> = (props) => <ServiceView {...props} />;
export default ServiceMainView;
import React from 'react';
import styled from 'styled-components';
import { InterDataType } from '@/api/interface';
import {
GetCompanyInfoById,
GetCompanyInspectionById,
} from '@/api/interface/service';
import { ServiceAPI } from '@/api/modules/service';
import BreadcrumbView from '@/components/breadcrumb';
import LayoutView from '@/components/layout';
import ServiceHeadView from '@/components/service-detail/comp/detail-head';
import ServiceStoreView from '@/components/service-detail/comp/detail-store';
import { wrapper } from '@/store';
import { setGlobalData } from '@/store/module/globalData';
// 商品详情类型
type DetailType = InterDataType<GetCompanyInspectionById>;
// 商城详情类型
type StoreType = InterDataType<GetCompanyInfoById>;
// 使用wrapper.getServerSideProps高阶函数包裹getServerSideProps函数
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async (context) => {
// 商品id
const id: number = Number(context.params?.id);
// 商品详情
let serviceDetail: DetailType | undefined;
// 店铺详情
let storeDetail: StoreType | undefined;
// 获取服务详情
const getCompanyInspection = async () => {
const res = await ServiceAPI.getCompanyInspectionById({ id });
if (res && res.code === '200') {
serviceDetail = res.result;
// console.log('获取服务详情 --->', serviceDetail);
}
};
// 获取店铺详情
const getCompanyInfo = async () => {
const res = await ServiceAPI.getCompanyInfoById({
id: Number(serviceDetail?.companyInfoId),
});
if (res && res.code === '200') {
storeDetail = res.result;
}
};
// 获取价格单位列表
const getPriceUnitList = async () => {
const res = await ServiceAPI.listInspectionPriceUnit();
if (res && res.code === '200') {
store.dispatch(setGlobalData({ priceUnitList: res?.result || [] }));
}
};
// 依次获取接口数据
await (async () => {
await getCompanyInspection();
await getCompanyInfo();
await getPriceUnitList();
})();
return { props: { serviceDetail, storeDetail } };
},
);
const ServiceDetailView: React.FC<{
id: number;
serviceDetail: DetailType;
storeDetail: StoreType;
}> = ({ serviceDetail, storeDetail }) => {
return (
<LayoutView>
<ServiceDetailWrap>
<BreadcrumbView />
<div className="flex-start align-start">
<ServiceHeadView detail={serviceDetail} />
<ServiceStoreView detail={serviceDetail} store={storeDetail} />
</div>
<div className="product-title">商品详情</div>
<div className="product-richText">
{serviceDetail?.detailPage && (
<div
className="content-html"
dangerouslySetInnerHTML={{ __html: serviceDetail?.detailPage }}
/>
)}
</div>
</ServiceDetailWrap>
</LayoutView>
);
};
export default ServiceDetailView;
// 样式
const ServiceDetailWrap = styled.div`
position: relative;
max-width: 1190px;
box-sizing: border-box;
padding: 2rem 0 0 0;
margin: 0 auto;
.product-title {
position: relative;
width: 100%;
text-align: center;
padding: 1.5rem 0;
color: #989898;
font-size: 14px;
&::after,
&::before {
position: absolute;
content: '';
top: 50%;
left: 40%;
width: 4.74rem;
height: 0.02rem;
background: #d4d4d4;
}
&::before {
left: auto;
right: 40%;
}
}
.product-richText {
position: relative;
width: 100%;
margin-bottom: 3.5rem;
.content-html {
width: 100%;
img {
width: 100%;
}
}
}
`;
import React from 'react';
import { InterDataType, InterListType } from '@/api/interface';
import {
GetIndustryListPagesType,
ListInspectionPriceUnit,
} from '@/api/interface/service';
import { InterListType } from '@/api/interface';
import { GetIndustryListPagesType } from '@/api/interface/service';
import { ServiceAPI } from '@/api/modules/service';
import ServiceView from '@/components/service-comp';
import { wrapper } from '@/store';
......@@ -11,8 +8,6 @@ import { setGlobalData } from '@/store/module/globalData';
// 分类列表类型
type CategoryListType = InterListType<GetIndustryListPagesType>;
// 单位列表类型
type PriceUnitListType = InterDataType<ListInspectionPriceUnit>;
// 使用wrapper.getServerSideProps高阶函数包裹getServerSideProps函数
export const getServerSideProps = wrapper.getServerSideProps(
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论