提交 44017cef 作者: 曹云

Merge branch 'master' of ssh://git.mmcuav.cn:8222/root/sharefly-web-nextjs into caoyun

const dev = { const dev = {
baseUrl: 'local' baseUrl: '/local'
} }
const prod = { const prod = {
......
...@@ -9,6 +9,15 @@ import ModelItem from "./compoents/modelItem"; ...@@ -9,6 +9,15 @@ import ModelItem from "./compoents/modelItem";
import PartItem from "./compoents/partItem"; import PartItem from "./compoents/partItem";
import QualityItem from "./compoents/qualityItem"; import QualityItem from "./compoents/qualityItem";
export type AdapterResult = {
brandId?: number;
districtId?: number;
modelId?: number;
partsId?: number;
productCategoryId?: number;
qualityId?: number;
};
export type FilterResult = { export type FilterResult = {
region?: RegionResp; region?: RegionResp;
brand?: FilterOptionResp; brand?: FilterOptionResp;
...@@ -23,7 +32,10 @@ type itemType = "类目" | "地域" | "品牌" | "部件" | "型号" | "成色"; ...@@ -23,7 +32,10 @@ type itemType = "类目" | "地域" | "品牌" | "部件" | "型号" | "成色";
type Props = { type Props = {
types: itemType[]; //需要包含的筛选条件项 types: itemType[]; //需要包含的筛选条件项
showResultItem: Boolean; //显示结果栏 showResultItem: Boolean; //显示结果栏
onChange: (filterResult: FilterResult) => void; //筛选条件更改事件 onChange: (
filterResult: FilterResult,
adapterFilterResult: AdapterResult, //适配器,直接用于接口请求
) => void; //筛选条件更改事件
}; };
export default function Filter(props: Props) { export default function Filter(props: Props) {
const [result, setResult] = useState<FilterResult>({}); const [result, setResult] = useState<FilterResult>({});
...@@ -34,8 +46,18 @@ export default function Filter(props: Props) { ...@@ -34,8 +46,18 @@ export default function Filter(props: Props) {
}; };
useEffect(() => { useEffect(() => {
props.onChange(result); props.onChange(
}, [result, props]); result,
{
brandId: result.brand?.id,
districtId: result.region?.id,
modelId: result.model?.id,
partsId: result.part?.id,
productCategoryId: result.category?.id,
qualityId: result.quality?.id,
}
);
}, [result]);
const onDel = (key: string) => { const onDel = (key: string) => {
//@ts-ignore //@ts-ignore
delete result[key]; delete result[key];
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"pinyin-pro": "^3.14.0", "pinyin-pro": "^3.14.0",
"styled-components": "^6.0.0-rc.1", "styled-components": "^6.0.0-rc.1",
"swiper": "^9.3.2",
"swr": "^2.1.5", "swr": "^2.1.5",
"uuid": "^9.0.0" "uuid": "^9.0.0"
} }
......
...@@ -50,7 +50,7 @@ export default function Forum() { ...@@ -50,7 +50,7 @@ export default function Forum() {
* @param item 当前点击项 * @param item 当前点击项
*/ */
const openComment = (item: Item) => { const openComment = (item: Item) => {
item.openComment = true; item.openComment = !item.openComment;
const temp = [...list]; const temp = [...list];
setList(temp); setList(temp);
}; };
...@@ -63,7 +63,7 @@ export default function Forum() { ...@@ -63,7 +63,7 @@ export default function Forum() {
发布动态 发布动态
</Button> </Button>
</div> </div>
<Space direction="vertical" size={8}> <Space direction="vertical" size={8} style={{width: '100%'}}>
{list.map((item) => { {list.map((item) => {
return ( return (
<div key={item.id} className={styles.item}> <div key={item.id} className={styles.item}>
...@@ -99,10 +99,12 @@ export default function Forum() { ...@@ -99,10 +99,12 @@ export default function Forum() {
</Image.PreviewGroup> </Image.PreviewGroup>
</div> </div>
<div className={styles.ctrls}> <div className={styles.ctrls}>
<div className={styles.ctrlsItem}>
<div <div
className={`${styles.ctrlsItemIcon} ${styles.iconComment}`} className={styles.ctrlsItem}
onClick={() => openComment(item)} onClick={() => openComment(item)}
>
<div
className={`${styles.ctrlsItemIcon} ${styles.iconComment}`}
></div> ></div>
{item.commentCount}评论 {item.commentCount}评论
</div> </div>
......
...@@ -32,10 +32,18 @@ export interface ListPageGoodsInfoResp { ...@@ -32,10 +32,18 @@ export interface ListPageGoodsInfoResp {
"totalPage": 0 "totalPage": 0
} }
export interface Ad {
id: number;
imageUrl: string;
}
export default { export default {
//web-商品信息-分页 //web-商品信息-分页
listPageGoodsInfo: (params: ListPageGoodsInfoParams, options = {}): Promise<Response<ListPageGoodsInfoResp>> => { listPageGoodsInfo: (params: ListPageGoodsInfoParams, options = {}): Promise<Response<ListPageGoodsInfoResp>> => {
return request('/pms/webProductMall/listPageGoodsInfo', 'post', params, options) return request('/pms/webProductMall/listPageGoodsInfo', 'post', params, options)
},
//产品商城广告位
ad: (): Promise<Response<Array<Ad>>> => {
return request('/pms/webProductMall/ad')
} }
} }
\ No newline at end of file
import styles from "./index.module.scss"; import styles from "./index.module.scss";
import Layout from "~/components/layout"; import Layout from "~/components/layout";
import { Space, Image as AImage, Row, Col, Button, Divider, Badge } from "antd"; import { Space, Image as AImage, Row, Col, Button, Divider, Badge } from "antd";
import { useState } from "react"; import { useEffect, useState } from "react";
import { RightOutlined } from "@ant-design/icons"; import { RightOutlined } from "@ant-design/icons";
import Image from "next/image"; import Image from "next/image";
import errImg from "~/assets/errImg"; import errImg from "~/assets/errImg";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
// Import Swiper React components
import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation } from "swiper";
// Import Swiper styles
import "swiper/css";
import "swiper/css/navigation";
import api, { GetAppGoodsInfoDetailResult } from "./api";
export default function MallDetail() { export default function MallDetail() {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const router = useRouter(); const router = useRouter();
const { pid } = router.query; const [id, setId] = useState<number | null>(null);
const [detail, setDetail] = useState<GetAppGoodsInfoDetailResult | null>(
null
);
useEffect(() => {
setId(Number(router.query.id));
}, [router]);
useEffect(() => {
if (id) {
api
.getAppGoodsInfoDetail({
id: id,
})
.then((res) => {
setDetail(res.result || null);
});
}
}, [id]);
return ( return (
<Layout> <Layout>
...@@ -19,22 +46,48 @@ export default function MallDetail() { ...@@ -19,22 +46,48 @@ export default function MallDetail() {
<AImage.PreviewGroup <AImage.PreviewGroup
preview={{ visible, onVisibleChange: (vis) => setVisible(vis) }} preview={{ visible, onVisibleChange: (vis) => setVisible(vis) }}
> >
<AImage src="https://gw.alipayobjects.com/zos/antfincdn/LlvErxo8H9/photo-1503185912284-5271ff81b9a8.webp" /> {detail?.images?.map((item) => {
<AImage src="https://gw.alipayobjects.com/zos/antfincdn/cV16ZqzMjW/photo-1473091540282-9b846e7965e3.webp" /> return <AImage key={item.id} src={item.imgUrl} />;
<AImage src="https://gw.alipayobjects.com/zos/antfincdn/x43I27A55%26/photo-1438109491414-7198515b166b.webp" /> })}
</AImage.PreviewGroup> </AImage.PreviewGroup>
</div> </div>
<Space size={30} style={{ padding: "22px 24px 0" }}> <Space size={30} style={{ padding: "22px 24px 0" }}>
{/* 商品图 */} {/* 商品图 */}
<Space size={17} direction="vertical" style={{ width: 300 }}>
<AImage <AImage
preview={{ visible: false }} preview={{ visible: false }}
width={200} width={300}
src="https://gw.alipayobjects.com/zos/antfincdn/LlvErxo8H9/photo-1503185912284-5271ff81b9a8.webp" height={300}
src={detail?.images && detail.images[0].imgUrl}
onClick={() => setVisible(true)} onClick={() => setVisible(true)}
fallback={errImg}
/> />
<Swiper
modules={[Navigation]}
spaceBetween={6}
slidesPerView={5}
onSlideChange={() => console.log("slide change")}
onSwiper={(swiper) => console.log(swiper)}
>
{detail?.images?.map((item) => {
return (
<SwiperSlide key={item.id}>
<AImage
preview={false}
width={50}
height={50}
src={item.imgUrl}
fallback={errImg}
/>
</SwiperSlide>
);
})}
</Swiper>
</Space>
<Space direction="vertical" size={17}> <Space direction="vertical" size={17}>
<div className={`${styles.font1} ${styles.ellipsis}`}> <div className={`${styles.font1} ${styles.ellipsis}`}>
入云龙1550 {detail?.goodsName}
</div> </div>
<div className={`${styles.font2} ${styles.ellipsis}`}> <div className={`${styles.font2} ${styles.ellipsis}`}>
交通事故处理、违章取证、指挥调度、日常巡 交通事故处理、违章取证、指挥调度、日常巡
...@@ -43,8 +96,7 @@ export default function MallDetail() { ...@@ -43,8 +96,7 @@ export default function MallDetail() {
size={24} size={24}
direction="vertical" direction="vertical"
style={{ style={{
padding: "24px 40px 24px 23px", padding: "24px 40px 24px 0",
border: "1px solid #EDEDED",
width: 470, width: 470,
}} }}
> >
...@@ -59,9 +111,6 @@ export default function MallDetail() { ...@@ -59,9 +111,6 @@ export default function MallDetail() {
> >
已选:1件 已选:1件
</Col> </Col>
<Col style={{ cursor: "pointer" }}>
<RightOutlined />
</Col>
</Row> </Row>
<Row wrap={false}> <Row wrap={false}>
<Col flex="60px" className={styles.font3}> <Col flex="60px" className={styles.font3}>
...@@ -121,7 +170,11 @@ export default function MallDetail() { ...@@ -121,7 +170,11 @@ export default function MallDetail() {
</Space> </Space>
<Divider className={styles.divider}>商品详情</Divider> <Divider className={styles.divider}>商品详情</Divider>
<div style={{ textAlign: "center" }}> <div style={{ textAlign: "center" }}>
<AImage fallback={errImg} width={1080}></AImage> <div
dangerouslySetInnerHTML={{
__html: detail?.goodsDetail?.content || "",
}}
></div>
</div> </div>
</div> </div>
</Layout> </Layout>
......
import request, { Response } from "~/api/request"
export interface GetAppGoodsInfoDetailParams {
id: number
}
export interface GetAppGoodsInfoDetailResult {
id: number;
pid?: number;
goodsName?: string;
shareFlyServiceId?: number;
repoId?: number;
goodsSpec?: GoodsSpec[];
images?: Image[];
goodsVideo?: string;
goodsVideoId?: number;
goodsDetail?: GoodsDetail;
sortTypeId?: number;
masterTypeId?: number;
slaveTypeId?: number;
tag?: string;
shelfStatus?: number;
otherService?: OtherService[];
question?: Question[];
}
export interface GoodsDetail {
id: number;
goodsDesc: string;
content: string;
remark?: any;
}
export interface Image {
id: number;
imgUrl: string;
imgType: number;
}
export interface GoodsSpec {
id: number;
goodsSpecName: string;
goodsTypeId: number;
typeName: string;
skuId: number;
brandInfoId: number;
skuName: string;
productSpecList: ProductSpecList[];
industrySpecList?: any;
chooseType: number;
skuUnitId: number;
unitName: string;
must: number;
flag?: any;
}
export interface ProductSpecList {
id: number;
productSpec: number;
productSkuId: number;
specName: string;
specImage: string;
partNo: string;
versionDesc: string;
createTime?: any;
productSpecCPQVO?: any;
}
export interface Question {
answer: string,
id: number,
question: string
}
//其他服务: 1:免费配送,2:专业飞手培训2日, 3:半年保修, 4:一年保修
export interface OtherService {
id: number,
saleServiceId: number,
serviceName: string
}
export default {
//web-获取商品详细信息--共多少种选择
getAppGoodsInfoDetail(params: GetAppGoodsInfoDetailParams): Promise<Response<GetAppGoodsInfoDetailResult>> {
return request('/pms/webProductMall/getAppGoodsInfoDetail', 'get', params)
}
}
\ No newline at end of file
...@@ -80,3 +80,10 @@ ...@@ -80,3 +80,10 @@
color: #989898; color: #989898;
} }
} }
.swiperButtonNext {
width: 20px;
height: 50px;
background: #d8d8d8;
opacity: 0.3;
}
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Button, Empty, Pagination, Select, Space, Tag } from "antd"; import { Empty, Pagination, Image } from "antd";
import Layout from "~/components/layout"; import Layout from "~/components/layout";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import Image from "next/image"; import Filter, { AdapterResult, FilterResult } from "~/components/filter";
import Filter, { FilterResult } from "~/components/filter"; import api, { Ad, Goods, ListPageGoodsInfoParams } from "./api";
import api, { Goods, ListPageGoodsInfoParams } from "./api";
// 此函数在构建时被调用 // 此函数在构建时被调用
export async function getServerSideProps() { export async function getServerSideProps() {
...@@ -18,31 +17,28 @@ type Props = {}; ...@@ -18,31 +17,28 @@ type Props = {};
export default function Mall(props: Props) { export default function Mall(props: Props) {
const router = useRouter(); const router = useRouter();
const [productList, setProductList] = useState(Array<Goods>); const [productList, setProductList] = useState<Array<Goods>>([]); //商品列表
const [filterResult, setFilterResult] = useState<FilterResult>({}); const [filterResult, setFilterResult] = useState<AdapterResult>({}); //筛选结果
const [pageParams, setPageParams] = useState({ const [pageParams, setPageParams] = useState({
pageNo: 1, pageNo: 1,
pageSize: 16, pageSize: 16,
}); }); //分页器对象
const [count, setCount] = useState(0); const [count, setCount] = useState(0); //商品总数
const [abort, setAbort] = useState<AbortController | null>(null); const [abort, setAbort] = useState<AbortController | null>(null); //请求中断对你
const [adList, setAdList] = useState<Array<Ad>>([]); //广告列表
useEffect(() => { useEffect(() => {
//中断前一次请求 //中断前一次列表请求
abort?.abort(); abort?.abort();
setAbort(new AbortController()); setAbort(new AbortController());
}, [filterResult, pageParams]); }, [filterResult, pageParams]);
//端口列表请求
useEffect(() => { useEffect(() => {
api api
.listPageGoodsInfo( .listPageGoodsInfo(
{ {
brandId: filterResult.brand?.id, ...filterResult,
districtId: filterResult.region?.id,
modelId: filterResult.model?.id,
partsId: filterResult.part?.id,
productCategoryId: filterResult.category?.id,
qualityId: filterResult.quality?.id,
...pageParams, ...pageParams,
}, },
{ {
...@@ -55,9 +51,19 @@ export default function Mall(props: Props) { ...@@ -55,9 +51,19 @@ export default function Mall(props: Props) {
}); });
}, [abort]); }, [abort]);
const onFilterChange = (filterResult: FilterResult) => { //广告请求
console.log("filterResult", filterResult); useEffect(() => {
setFilterResult(filterResult); api.ad().then((res) => {
setAdList(res.result || []);
});
}, []);
const onFilterChange = (
filterResult: FilterResult,
adapterFilterResult: AdapterResult
) => {
console.log("filterResult", filterResult, adapterFilterResult);
setFilterResult(adapterFilterResult);
}; };
const onPageChange = (page: number, pageSize: number) => { const onPageChange = (page: number, pageSize: number) => {
...@@ -84,7 +90,7 @@ export default function Mall(props: Props) { ...@@ -84,7 +90,7 @@ export default function Mall(props: Props) {
<li <li
key={i} key={i}
className={styles.item} className={styles.item}
onClick={() => router.push("/mall/detail/1")} onClick={() => router.push("/mall/detail/" + item.id)}
> >
<div className={styles.imgBox}> <div className={styles.imgBox}>
<Image <Image
...@@ -93,6 +99,7 @@ export default function Mall(props: Props) { ...@@ -93,6 +99,7 @@ export default function Mall(props: Props) {
className={styles.img} className={styles.img}
width={116} width={116}
height={116} height={116}
preview={false}
></Image> ></Image>
</div> </div>
<div className={styles.title}>{item.goodsName}</div> <div className={styles.title}>{item.goodsName}</div>
...@@ -104,7 +111,13 @@ export default function Mall(props: Props) { ...@@ -104,7 +111,13 @@ export default function Mall(props: Props) {
); );
})} })}
{productList.length === 0 && ( {productList.length === 0 && (
<Empty style={{ paddingTop: 20, width: '100%', textAlign: "center" }}></Empty> <Empty
style={{
paddingTop: 20,
width: "100%",
textAlign: "center",
}}
></Empty>
)} )}
</ul> </ul>
<Pagination <Pagination
...@@ -114,13 +127,23 @@ export default function Mall(props: Props) { ...@@ -114,13 +127,23 @@ export default function Mall(props: Props) {
total={count} total={count}
onChange={onPageChange} onChange={onPageChange}
hideOnSinglePage={true} hideOnSinglePage={true}
style={{marginTop: 20}} style={{ marginTop: 20 }}
/> />
</div> </div>
<div className={styles.adList}> <div className={styles.adList}>
<div className={styles.ad}></div> {adList.map((item) => {
<div className={styles.ad}></div> return (
<Image
key={item.id}
className={styles.ad}
src={item.imageUrl}
width="270"
height="270"
preview={false}
></Image>
);
})}
</div> </div>
</div> </div>
</div> </div>
......
import request, { Response } from '~/api/request';
export interface ListNewTenderInfoParams {
cityCode?: number;
date?: string;
districtCode?: number;
pageNo: number;
pageSize: number;
provinceCode?: number;
}
export interface ListNewTenderInfoResp {
pageNo: number;
pageSize: number;
list: Item[];
totalCount: number;
totalPage: number;
}
export interface Item {
id: number;
tenderNewsId: number;
tenderInfoNo: string;
tenderContent: string;
tenderPrice: number;
createTime: string;
apply: 0 | 1;
}
export default {
/**
* 招投标列表
* @param params
* @returns
*/
listNewTenderInfo(params: ListNewTenderInfoParams, options = {}): Promise<Response<ListNewTenderInfoResp>> {
return request('/release/tender/listNewTenderInfo', 'post', params, options);
}
}
\ No newline at end of file
import { Button } from "antd"; import { Button } from "antd";
import { useState, useEffect } from "react";
import api, { Item } from "./api";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
const list = [ export default function Bids() {
const [list, setList] = useState<Array<Item>>([]);
const [pageParams, setPageParams] = useState({
pageNo: 1,
pageSize: 5,
});
const [count, setCount] = useState(0);
const [abort, setAbort] = useState<AbortController | null>(null);
useEffect(() => {
//中断前一次请求
abort?.abort();
setAbort(new AbortController());
}, [pageParams]);
useEffect(() => {
api
.listNewTenderInfo(
{ {
isApply: false, ...pageParams,
}, },
{ {
isApply: true, signal: abort?.signal,
}, }
]; )
.then((res) => {
setList(res.result?.list || []);
setCount(res.result?.totalCount || 0);
});
}, [abort]);
export default function requirements() {
return ( return (
<div className={styles.bids}> <div className={styles.bids}>
{list.map((item, i) => { {list.map((item) => {
return ( return (
<div className={styles.item} key={i}> <div className={styles.item} key={item.id}>
<div className={styles.info}> <div className={styles.info}>
<div className={styles.title}>项目需求:电力巡检需要5名飞手</div> <div className={styles.title}>项目需求:{item.tenderContent}</div>
</div> </div>
{item.isApply ? ( {item.apply ? (
<Button <Button
type="primary" type="primary"
disabled disabled
className={`${styles.btn} ${styles.disabled}`} className={`${styles.btn} ${styles.disabled}`}
> >
<div className={styles.text1}>155W</div> <div className={styles.text1}>{item.tenderPrice}</div>
<div className={styles.text2}>已申请</div> <div className={styles.text2}>已申请</div>
</Button> </Button>
) : ( ) : (
<Button type="primary" className={styles.btn}> <Button type="primary" className={styles.btn}>
<div className={styles.text1}>155W</div> <div className={styles.text1}>{item.tenderPrice}</div>
<div className={styles.text2}>申请合作</div> <div className={styles.text2}>申请合作</div>
</Button> </Button>
)} )}
......
import request, { Response } from '~/api/request';
export interface ListCasePageParams {
cityCode?: number;
date?: string;
districtCode?: number;
pageNo: number;
pageSize: number;
provinceCode?: number;
}
export interface ListCasePageResp {
pageNo: number;
pageSize: number;
list: Item[];
totalCount: number;
totalPage: number;
}
export interface Item {
id: number;
newsTitle: string;
newsAuthor: string;
userAccountId: number;
surfaceImg: string;
newsContents: string;
createTime: string;
updateTime: string;
isApply: 0 | 1
}
export default {
/**
* 案例列表
* @param params
* @returns
*/
listCasePage(params: ListCasePageParams, options = {}): Promise<Response<ListCasePageResp>> {
return request('/release/industry-case/listCasePage', 'post', params, options);
}
}
\ No newline at end of file
import { Button } from "antd"; import { Button } from "antd";
import { useState, useEffect } from "react";
import api, { Item } from "./api";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
const list = [ const list = [
...@@ -10,24 +12,46 @@ const list = [ ...@@ -10,24 +12,46 @@ const list = [
}, },
]; ];
export default function requirements() { export default function Cases() {
const [list, setList] = useState<Array<Item>>([]);
const [pageParams, setPageParams] = useState({
pageNo: 1,
pageSize: 5,
});
const [count, setCount] = useState(0);
const [abort, setAbort] = useState<AbortController | null>(null);
useEffect(() => {
//中断前一次请求
abort?.abort();
setAbort(new AbortController());
}, [pageParams]);
useEffect(() => {
api
.listCasePage(
{
...pageParams,
},
{
signal: abort?.signal,
}
)
.then((res) => {
setList(res.result?.list || []);
setCount(res.result?.totalCount || 0);
});
}, [abort]);
return ( return (
<div className={styles.casas}> <div className={styles.casas}>
{list.map((item, i) => { {list.map((item) => {
return ( return (
<div className={styles.item} key={i}> <div className={styles.item} key={item.id}>
<div className={styles.info}> <div className={styles.info}>
<div className={styles.title}>项目需求:电力巡检需要5名飞手</div> <div className={styles.title}>{item.newsTitle}</div>
</div> </div>
{item.isApply ? ( <Button className={styles.btn}>查看案例</Button>
<Button disabled className={styles.btnDisabled}>
已申请
</Button>
) : (
<Button className={styles.btn}>
申请合作
</Button>
)}
</div> </div>
); );
})} })}
......
import request, { Response } from '~/api/request';
export interface ListNewsPageParams {
cityCode?: number;
date?: string;
districtCode?: number;
pageNo: number;
pageSize: number;
provinceCode?: number;
}
export interface ListNewsPageResp {
pageNo: number;
pageSize: number;
list: Item[];
totalCount: number;
totalPage: number;
}
export interface Item {
id: number;
newsTitle: string;
newsAuthor: string;
userAccountId: number;
surfaceImg: string;
newsContents: string;
createTime: string;
updateTime?: any;
}
export default {
/**
* 新闻列表
* @param params
* @returns
*/
listNewsPage(params: ListNewsPageParams, options = {}): Promise<Response<ListNewsPageResp>> {
return request('/release/industry-news/listNewsPage', 'post', params, options);
}
}
\ No newline at end of file
...@@ -2,31 +2,60 @@ import { RightOutlined } from "@ant-design/icons"; ...@@ -2,31 +2,60 @@ import { RightOutlined } from "@ant-design/icons";
import { Col, Row } from "antd"; import { Col, Row } from "antd";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
import Image from "next/image"; import Image from "next/image";
import { useState, useEffect } from "react";
import api, { Item } from "./api";
export default function News() {
const [list, setList] = useState<Array<Item>>([]);
const [pageParams, setPageParams] = useState({
pageNo: 1,
pageSize: 5,
});
const [count, setCount] = useState(0);
const [abort, setAbort] = useState<AbortController | null>(null);
useEffect(() => {
//中断前一次请求
abort?.abort();
setAbort(new AbortController());
}, [pageParams]);
useEffect(() => {
api
.listNewsPage(
{
...pageParams,
},
{
signal: abort?.signal,
}
)
.then((res) => {
setList(res.result?.list || []);
setCount(res.result?.totalCount || 0);
});
}, [abort]);
export default function requirements() {
return ( return (
<Row justify="space-between"> <Row justify="space-between">
<Col className={styles.new}> <Col className={styles.new}>
<div className={styles.item}> {list.map((item) => {
<div className={styles.logo}></div> return (
<div className={styles.item} key={item.id}>
<Image
className={styles.logo}
src={item.surfaceImg}
alt=""
width={120}
height={80}
></Image>
<div className={styles.info}> <div className={styles.info}>
<div className={styles.title}>项目需求:电力巡检需要5名飞手</div> <div className={styles.title}>{item.newsTitle}</div>
</div> </div>
</div> </div>
</Col> );
<Col className={styles.newsBox}> })}
<div className={styles.newsHeader}>
<div className={styles.newsHeaderTitle}>行业新闻</div>
<RightOutlined style={{ fontSize: 16 }} />
</div>
<ul className={styles.newList}>
<li className={styles.newItem}>
<div className={styles.newItemTitle}>
中国超音速无人机雨燕试飞成功好棒呀
</div>
<Image className={styles.newItemImg} src="" alt=""></Image>
</li>
</ul>
</Col> </Col>
</Row> </Row>
); );
......
import request, { Response } from '~/api/request';
export interface ListPublishPageParams {
cityCode?: number;
date?: string;
districtCode?: number;
pageNo: number;
pageSize: number;
provinceCode?: number;
}
export interface ListPublishPageResp {
pageNo: number;
pageSize: number;
list: Item[];
totalCount: number;
totalPage: number;
}
export interface Item {
id: number;
requirementTypeId: number;
userAccountId: number;
publishName: string;
publishPhone: string;
requireDescription: string;
solved?: 0 | 1;
createTime: string;
updateTime?: string;
}
export default {
/**
* 需求发布列表
* @param params
* @returns
*/
listPublishPage(params: ListPublishPageParams, options = {}): Promise<Response<ListPublishPageResp>> {
return request('/release/requirements/listPublishPage', 'post', params, options);
}
}
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import api, { Item } from "./api";
import styles from './index.module.scss'; import styles from './index.module.scss';
export default function requirements(){ export default function Requirements(){
const [list, setList] = useState<Array<Item>>([]);
const [pageParams, setPageParams] = useState({
pageNo: 1,
pageSize: 5,
});
const [count, setCount] = useState(0);
const [abort, setAbort] = useState<AbortController | null>(null);
useEffect(() => {
//中断前一次请求
abort?.abort();
setAbort(new AbortController());
}, [pageParams]);
useEffect(() => {
api
.listPublishPage(
{
...pageParams,
},
{
signal: abort?.signal,
}
)
.then((res) => {
setList(res.result?.list || []);
setCount(res.result?.totalCount || 0);
});
}, [abort]);
return ( return (
<div className={styles.requirements}> <div className={styles.requirements}>
<div className={styles.item}> {list.map(item => {
<div className={styles.logo}></div> return (
<div className={styles.info}> <div
<div className={styles.title}>项目需求:电力巡检需要5名飞手</div> className={`${styles.item} ${!item.solved && styles.noResolve}`}
<div className={styles.desc}> key={item.id}
具体需求:电力巡检需要5名飞手,山东临沂 >
</div>
</div>
</div>
<div className={`${styles.item} ${styles.noResolve}`}>
<div className={styles.logo}></div> <div className={styles.logo}></div>
<div className={styles.info}> <div className={styles.info}>
<div className={styles.title}>项目需求:电力巡检需要5名飞手</div> <div className={styles.title}>项目需求:电力巡检需要5名飞手</div>
<div className={styles.desc}> <div className={styles.desc}>
具体需求:电力巡检需要5名飞手,山东临沂 具体需求:{item.requireDescription}
</div> </div>
</div> </div>
</div> </div>
);
})}
</div> </div>
); );
} }
\ No newline at end of file
...@@ -9,10 +9,10 @@ import { ...@@ -9,10 +9,10 @@ import {
} from "antd"; } from "antd";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
import Layout from "~/components/layout"; import Layout from "~/components/layout";
import requirements from "./components/requirements"; //项目需求 import Requirements from "./components/requirements"; //项目需求
import bids from "./components/bids"; //招投标项目 import Bids from "./components/bids"; //招投标项目
import cases from "./components/cases"; //业务案例 import Cases from "./components/cases"; //业务案例
import news from "./components/news"; //行业新闻 import News from "./components/news"; //行业新闻
interface Option { interface Option {
value: string | number; value: string | number;
...@@ -84,19 +84,19 @@ const items = ["项目需求", "招投标项目", "业务案例", "行业新闻" ...@@ -84,19 +84,19 @@ const items = ["项目需求", "招投标项目", "业务案例", "行业新闻"
switch (value) { switch (value) {
case "项目需求": case "项目需求":
children = requirements(); children = <Requirements></Requirements>;
break; break;
case "招投标项目": case "招投标项目":
children = bids(); children = <Bids></Bids>;
break; break;
case "业务案例": case "业务案例":
children = cases(); children = <Cases></Cases>;
break; break;
case "行业新闻": case "行业新闻":
children = news(); children = <News></News>;
break; break;
} }
return { return {
...@@ -107,7 +107,7 @@ const items = ["项目需求", "招投标项目", "业务案例", "行业新闻" ...@@ -107,7 +107,7 @@ const items = ["项目需求", "招投标项目", "业务案例", "行业新闻"
} }
); );
export default function Mall() { export default function ProjectInfo() {
return ( return (
<Layout layoutStyle={{ backgroundColor: "#fff" }}> <Layout layoutStyle={{ backgroundColor: "#fff" }}>
<div style={{ backgroundColor: "#fff", minHeight: 820 }}> <div style={{ backgroundColor: "#fff", minHeight: 820 }}>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论