提交 5239364a 作者: 曹云

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

...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
/out/ /out/
# production # production
/build /.dist/
# misc # misc
.DS_Store .DS_Store
......
const dev = { const dev = {
baseUrl: '' baseUrl: 'local'
} }
const prod = { const prod = {
baseUrl: 'http://120.77.247.178' baseUrl: 'https://iuav.mmcuav.cn'
} }
export default process.env.NODE_ENV === 'development' ? dev : prod; export default process.env.NODE_ENV === 'development' ? dev : prod;
\ No newline at end of file
...@@ -5,10 +5,10 @@ import config from './config'; ...@@ -5,10 +5,10 @@ import config from './config';
* @param url 请求url * @param url 请求url
* @param method 请求方法类型 * @param method 请求方法类型
* @param data 请求的参数 * @param data 请求的参数
* @param options 额外参数
* @returns Promise<Response> * @returns Promise<Response>
*/ */
export default function request(url: string, method: String = 'get', data?: any): Promise<Response<any>> { export default function request(url: string, method: String = 'get', data?: any, options = {}): Promise<Response<any>> {
let options = {};
switch (method.toLowerCase()) { switch (method.toLowerCase()) {
case 'get': case 'get':
...@@ -24,6 +24,7 @@ export default function request(url: string, method: String = 'get', data?: any) ...@@ -24,6 +24,7 @@ export default function request(url: string, method: String = 'get', data?: any)
case 'post': case 'post':
options = { options = {
...options,
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
...@@ -48,6 +49,19 @@ export default function request(url: string, method: String = 'get', data?: any) ...@@ -48,6 +49,19 @@ export default function request(url: string, method: String = 'get', data?: any)
}) })
.then((data) => { .then((data) => {
return data; return data;
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('请求已中断');
console.log(error);
} else {
console.error('请求出错', error);
}
return {
code: '-1',
message: '请求失败',
result: null
}
}); });
} }
...@@ -55,5 +69,5 @@ export default function request(url: string, method: String = 'get', data?: any) ...@@ -55,5 +69,5 @@ export default function request(url: string, method: String = 'get', data?: any)
export interface Response<T> { export interface Response<T> {
code: string, code: string,
message: string, message: string,
result: T result?: T | null
} }
\ No newline at end of file
import { Space, Button, Select } from 'antd'; import { Space, Button, Select, Collapse } from "antd";
import styles from '../../index.module.scss'; import styles from "../../index.module.scss";
import api, { FilterOptionResp } from "../../api"; import api, { FilterOptionResp } from "../../api";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
...@@ -8,13 +8,13 @@ type Props = { ...@@ -8,13 +8,13 @@ type Props = {
}; };
export default function BrandItem(props: Props) { export default function BrandItem(props: Props) {
const [data, setData] = useState<FilterOptionResp[]>([]) const [data, setData] = useState<FilterOptionResp[]>([]);
useEffect(() => { useEffect(() => {
api.brand().then(res => { api.brand().then((res) => {
setData(res?.result || []); setData(res?.result || []);
}); });
}, []) }, []);
const onClick = (item: FilterOptionResp) => { const onClick = (item: FilterOptionResp) => {
props.onChange({ props.onChange({
...@@ -26,15 +26,47 @@ export default function BrandItem(props: Props) { ...@@ -26,15 +26,47 @@ export default function BrandItem(props: Props) {
return ( return (
<div className={styles.filterItem}> <div className={styles.filterItem}>
<div className={styles.filterItemTitle}>品牌:</div> <div className={styles.filterItemTitle}>品牌:</div>
<div className={styles.filterItemMain}> <div className={`${styles.filterItemMain} ${data.length <= 10 && styles.disabled}`}>
<Space size={40}> <Collapse
{ ghost
data.map(item => { collapsible="icon"
return <Button type="link" key={item.id} onClick={(e) => onClick(item)}>{item.name}</Button>; expandIconPosition="end"
})
} >
</Space> <Collapse.Panel
header={
<Space size={40}>
{data.slice(0, 10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
}
key="1"
>
<Space size={40}>
{data.slice(10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
</Collapse.Panel>
</Collapse>
</div> </div>
</div> </div>
); );
} }
\ No newline at end of file
import { Space, Button, Select } from 'antd'; import { Space, Button, Select, Collapse } from 'antd';
import styles from '../../index.module.scss'; import styles from '../../index.module.scss';
import api, { FilterOptionResp } from "../../api"; import api, { FilterOptionResp } from "../../api";
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
...@@ -26,14 +26,45 @@ export default function CategoryItem(props: Props) { ...@@ -26,14 +26,45 @@ export default function CategoryItem(props: Props) {
return ( return (
<div className={styles.filterItem}> <div className={styles.filterItem}>
<div className={styles.filterItemTitle}>类目:</div> <div className={styles.filterItemTitle}>类目:</div>
<div className={styles.filterItemMain}> <div
<Space size={40}> className={`${styles.filterItemMain} ${
{ data.length <= 10 && styles.disabled
data.map(item => { }`}
return <Button type="link" key={item.id} onClick={(e) => onClick(item)}>{item.name}</Button>; >
}) <Collapse ghost collapsible="icon" expandIconPosition="end">
} <Collapse.Panel
</Space> header={
<Space size={40}>
{data.slice(0, 10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
}
key="1"
>
<Space size={40}>
{data.slice(10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
</Collapse.Panel>
</Collapse>
</div> </div>
</div> </div>
); );
......
import { Space, Button, Select } from 'antd'; import { Space, Button, Select, Collapse } from 'antd';
import styles from '../../index.module.scss'; import styles from '../../index.module.scss';
import api, { FilterOptionResp } from "../../api"; import api, { FilterOptionResp } from "../../api";
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
...@@ -26,14 +26,45 @@ export default function ModelItem(props: Props) { ...@@ -26,14 +26,45 @@ export default function ModelItem(props: Props) {
return ( return (
<div className={styles.filterItem}> <div className={styles.filterItem}>
<div className={styles.filterItemTitle}>型号:</div> <div className={styles.filterItemTitle}>型号:</div>
<div className={styles.filterItemMain}> <div
<Space size={40}> className={`${styles.filterItemMain} ${
{ data.length <= 10 && styles.disabled
data?.map(item => { }`}
return <Button type="link" key={item.id} onClick={(e) => onClick(item)}>{item.name}</Button>; >
}) <Collapse ghost collapsible="icon" expandIconPosition="end">
} <Collapse.Panel
</Space> header={
<Space size={40}>
{data.slice(0, 10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
}
key="1"
>
<Space size={40}>
{data.slice(10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
</Collapse.Panel>
</Collapse>
</div> </div>
</div> </div>
); );
......
import { Space, Button, Select } from 'antd'; import { Space, Button, Select, Collapse } from 'antd';
import styles from '../../index.module.scss'; import styles from '../../index.module.scss';
import api, { FilterOptionResp } from "../../api"; import api, { FilterOptionResp } from "../../api";
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
...@@ -26,16 +26,45 @@ export default function PartItem(props: Props) { ...@@ -26,16 +26,45 @@ export default function PartItem(props: Props) {
return ( return (
<div className={styles.filterItem}> <div className={styles.filterItem}>
<div className={styles.filterItemTitle}>部件:</div> <div className={styles.filterItemTitle}>部件:</div>
<div className={styles.filterItemMain}> <div
<Space size={40}> className={`${styles.filterItemMain} ${
{data?.map((item) => { data.length <= 10 && styles.disabled
return ( }`}
<Button type="link" key={item.id} onClick={(e) => onClick(item)}> >
{item.name} <Collapse ghost collapsible="icon" expandIconPosition="end">
</Button> <Collapse.Panel
); header={
})} <Space size={40}>
</Space> {data.slice(0, 10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
}
key="1"
>
<Space size={40}>
{data.slice(10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
</Collapse.Panel>
</Collapse>
</div> </div>
</div> </div>
); );
......
import { Space, Button, Select } from 'antd'; import { Space, Button, Select, Collapse } from 'antd';
import styles from '../../index.module.scss'; import styles from '../../index.module.scss';
import api, { FilterOptionResp } from "../../api"; import api, { FilterOptionResp } from "../../api";
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
...@@ -26,16 +26,45 @@ export default function QualityItem(props: Props) { ...@@ -26,16 +26,45 @@ export default function QualityItem(props: Props) {
return ( return (
<div className={styles.filterItem}> <div className={styles.filterItem}>
<div className={styles.filterItemTitle}>成色:</div> <div className={styles.filterItemTitle}>成色:</div>
<div className={styles.filterItemMain}> <div
<Space size={40}> className={`${styles.filterItemMain} ${
{data?.map((item) => { data.length <= 10 && styles.disabled
return ( }`}
<Button type="link" key={item.id} onClick={(e) => onClick(item)}> >
{item.name} <Collapse ghost collapsible="icon" expandIconPosition="end">
</Button> <Collapse.Panel
); header={
})} <Space size={40}>
</Space> {data.slice(0, 10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
}
key="1"
>
<Space size={40}>
{data.slice(10).map((item) => {
return (
<Button
type="link"
key={item.id}
onClick={(e) => onClick(item)}
>
{item.name}
</Button>
);
})}
</Space>
</Collapse.Panel>
</Collapse>
</div> </div>
</div> </div>
); );
......
...@@ -9,27 +9,47 @@ ...@@ -9,27 +9,47 @@
} }
.filterItem { .filterItem {
height: 42px; min-height: 42px;
border-bottom: 1px dashed RGBA(222, 222, 222, 1); border-bottom: 1px dashed RGBA(222, 222, 222, 1);
display: flex; display: flex;
align-items: center;
&:nth-last-child(1) { &:nth-last-child(1) {
border-bottom: none; border-bottom: none;
} }
.filterItemTitle { .filterItemTitle {
flex-shrink: 0;
width: 80px; width: 80px;
margin-right: 8px; margin-right: 8px;
font-family: MicrosoftYaHei; font-family: MicrosoftYaHei;
color: rgba(153, 153, 153, 1); color: rgba(153, 153, 153, 1);
line-height: 20px; line-height: 20px;
height: auto;
margin-top: 10px;
} }
.filterItemMain { .filterItemMain {
flex: 1; flex: 1;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
&.disabled {
:global .ant-collapse-expand-icon {
display: none;
}
}
:global .ant-collapse-item {
.ant-collapse-expand-icon {
margin-top: 10px;
}
.ant-collapse-header {
padding: 0;
height: 42px;
line-height: 42px;
}
}
} }
:global .ant-select-selector { :global .ant-select-selector {
......
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
let distDir = ".next"; //默认输出目录
if (process.env.NODE_ENV === "production") {
//生产环境用另一个目录构建,防止与dev冲突
distDir = ".dist";
}
const nextConfig = { const nextConfig = {
distDir,
reactStrictMode: true, reactStrictMode: true,
transpilePackages: ["antd"], transpilePackages: ["antd"],
redirects() { redirects() {
...@@ -14,8 +22,8 @@ const nextConfig = { ...@@ -14,8 +22,8 @@ const nextConfig = {
async rewrites() { async rewrites() {
return [ return [
{ {
source: "/:path*", source: "/local/:path*",
destination: "http://120.77.247.178/:path*", destination: "https://iuav.mmcuav.cn/:path*",
}, },
]; ];
}, },
......
...@@ -46,7 +46,7 @@ export default function FlyingHandService() { ...@@ -46,7 +46,7 @@ export default function FlyingHandService() {
pageSize: 10, pageSize: 10,
}) })
.then((res) => { .then((res) => {
setProductList(res.result?.list.map(item=>{return { element:leftDom(item) }})) setProductList(res.result?.list.map(item=>{return { element:leftDom(item) }}) || [])
}); });
}, []); }, []);
......
import request, { Response } from "~/api/request";
export interface DynamicListParams {
pageNo: number,
pageSize: number,
userId: number
}
export interface Dynamic {
userId: number;
id: number;
title: string;
description: string;
location: string;
lat: number;
lon: number;
mediaVO: {
picture: string[];
videoUrl: string;
};
likesCount: number;
commentCount: number;
likes: boolean;
}
export interface DynamicListResp {
pageNo: 1;
pageSize: 10;
list: Array<Dynamic>;
totalCount: 0;
totalPage: 0;
}
export default {
/**
* 论坛动态列表
* @param params
* @returns
*/
dynamicList(params: DynamicListParams): Promise<Response<DynamicListResp>> {
return request("/release/dynamic/dynamicList", "get", params);
},
};
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
.item { .item {
padding: 18px 0 0; padding: 18px 0 0;
background: #ffffff; background: #ffffff;
width: 100%;
.headImg { .headImg {
margin-left: 16px; margin-left: 16px;
......
...@@ -35,7 +35,7 @@ export interface ListPageGoodsInfoResp { ...@@ -35,7 +35,7 @@ export interface ListPageGoodsInfoResp {
export default { export default {
//web-商品信息-分页 //web-商品信息-分页
listPageGoodsInfo: (params: ListPageGoodsInfoParams): Promise<Response<ListPageGoodsInfoResp>> => { listPageGoodsInfo: (params: ListPageGoodsInfoParams, options = {}): Promise<Response<ListPageGoodsInfoResp>> => {
return request('/pms/webProductMall/listPageGoodsInfo', 'post', params) return request('/pms/webProductMall/listPageGoodsInfo', 'post', params, options)
} }
} }
\ No newline at end of file
...@@ -24,11 +24,15 @@ ...@@ -24,11 +24,15 @@
} }
} }
.listContent{
width: 100%;
}
.listWrap { .listWrap {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 12px; gap: 12px;
height: fit-content; height: 856px;
.item { .item {
cursor: pointer; cursor: pointer;
......
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Button, Pagination, Select, Space, Tag } from "antd"; import { Button, Empty, Pagination, Select, Space, Tag } 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";
...@@ -25,23 +25,35 @@ export default function Mall(props: Props) { ...@@ -25,23 +25,35 @@ export default function Mall(props: Props) {
pageSize: 16, pageSize: 16,
}); });
const [count, setCount] = useState(0); const [count, setCount] = useState(0);
const [abort, setAbort] = useState<AbortController | null>(null);
useEffect(() => {
//中断前一次请求
abort?.abort();
setAbort(new AbortController());
}, [filterResult, pageParams]);
useEffect(() => { useEffect(() => {
api api
.listPageGoodsInfo({ .listPageGoodsInfo(
brandId: filterResult.brand?.id, {
districtId: filterResult.region?.id, brandId: filterResult.brand?.id,
modelId: filterResult.model?.id, districtId: filterResult.region?.id,
partsId: filterResult.part?.id, modelId: filterResult.model?.id,
productCategoryId: filterResult.category?.id, partsId: filterResult.part?.id,
qualityId: filterResult.quality?.id, productCategoryId: filterResult.category?.id,
...pageParams, qualityId: filterResult.quality?.id,
}) ...pageParams,
},
{
signal: abort?.signal,
}
)
.then((res) => { .then((res) => {
setProductList(res.result?.list || []); setProductList(res.result?.list || []);
setCount(res.result?.totalCount); setCount(res.result?.totalCount || 0);
}); });
}, [filterResult, pageParams]); }, [abort]);
const onFilterChange = (filterResult: FilterResult) => { const onFilterChange = (filterResult: FilterResult) => {
console.log("filterResult", filterResult); console.log("filterResult", filterResult);
...@@ -52,8 +64,8 @@ export default function Mall(props: Props) { ...@@ -52,8 +64,8 @@ export default function Mall(props: Props) {
setPageParams({ setPageParams({
...pageParams, ...pageParams,
pageNo: page, pageNo: page,
}) });
} };
return ( return (
<Layout> <Layout>
<div className="page" style={{ paddingTop: "18px" }}> <div className="page" style={{ paddingTop: "18px" }}>
...@@ -65,36 +77,47 @@ export default function Mall(props: Props) { ...@@ -65,36 +77,47 @@ export default function Mall(props: Props) {
<div className={styles.productList}> <div className={styles.productList}>
<div className={styles.title}>四旋翼无人机</div> <div className={styles.title}>四旋翼无人机</div>
<div className={styles.main}> <div className={styles.main}>
<ul className={styles.listWrap}> <div className={styles.listContent}>
{productList.map((item, i) => { <ul className={styles.listWrap}>
return ( {productList.map((item, i) => {
<li return (
key={i} <li
className={styles.item} key={i}
onClick={() => router.push("/mall/detail/1")} className={styles.item}
> onClick={() => router.push("/mall/detail/1")}
<div className={styles.imgBox}> >
<Image <div className={styles.imgBox}>
alt="" <Image
src={item.imgUrl} alt=""
className={styles.img} src={item.imgUrl}
width={116} className={styles.img}
height={116} width={116}
></Image> height={116}
</div> ></Image>
<div className={styles.title}>{item.goodsName}</div> </div>
<div className={styles.sellCount}>半年售{(Math.floor(Math.random() * 901) + 100).toFixed(0)}</div> <div className={styles.title}>{item.goodsName}</div>
</li> <div className={styles.sellCount}>
); 半年售
})} {(Math.floor(Math.random() * 901) + 100).toFixed(0)}
</div>
</li>
);
})}
{productList.length === 0 && (
<Empty style={{ paddingTop: 20, width: '100%', textAlign: "center" }}></Empty>
)}
</ul>
<Pagination <Pagination
current={pageParams.pageNo} current={pageParams.pageNo}
showSizeChanger={false} showSizeChanger={false}
showQuickJumper showQuickJumper
total={count} total={count}
onChange={onPageChange} onChange={onPageChange}
hideOnSinglePage={true}
style={{marginTop: 20}}
/> />
</ul> </div>
<div className={styles.adList}> <div className={styles.adList}>
<div className={styles.ad}></div> <div className={styles.ad}></div>
<div className={styles.ad}></div> <div className={styles.ad}></div>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论