提交 b17849f9 作者: 曹云

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

const config = {
baseUrl: 'http://192.168.3.111:8099'
}
export default config;
\ No newline at end of file
import useSWR, { SWRResponse } from "swr";
import config from './config';
/** /**
* 请求封装 * 请求封装
* @param url 请求url * @param url 请求url
...@@ -6,7 +7,7 @@ import useSWR, { SWRResponse } from "swr"; ...@@ -6,7 +7,7 @@ import useSWR, { SWRResponse } from "swr";
* @param data 请求的参数 * @param data 请求的参数
* @returns Promise<Response> * @returns Promise<Response>
*/ */
export default function request(url: string, method: String = 'get', data: any): SWRResponse { export default function request(url: string, method: String = 'get', data?: any): Promise<Response<any>> {
let options = {}; let options = {};
switch (method.toLowerCase()) { switch (method.toLowerCase()) {
...@@ -32,11 +33,27 @@ export default function request(url: string, method: String = 'get', data: any): ...@@ -32,11 +33,27 @@ export default function request(url: string, method: String = 'get', data: any):
break; break;
} }
const fetcher = (url:string) => fetch(url, options) return fetch(config.baseUrl + url, options)
.then((r) => r.json()) .then((r) => {
try{
return r.json()
}catch(e){
console.error(e);
}
return {
code: '-1',
message: '请求失败',
result: null
}
})
.then((data) => { .then((data) => {
return data; return data;
}); });
}
return useSWR(url, fetcher) //准备响应结构
export interface Response<T> {
code: string,
message: string,
result: T
} }
\ No newline at end of file
import useSWR, { SWRResponse } from "swr";
import config from './config';
/**
* 请求封装
* @param url 请求url
* @param method 请求方法类型
* @param data 请求的参数
* @returns Promise<Response>
*/
export default function request(url: string, method: String = 'get', data?: any): SWRResponse {
let options = {};
switch (method.toLowerCase()) {
case 'get':
let params = new URLSearchParams();
if (data) {
Object.keys(data).forEach((key) => {
params.append(key, data[key]);
})
url += params;
}
break;
case 'post':
options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}
break;
}
const fetcher = (url:string) => fetch(config.baseUrl + url, options)
.then((r) => r.json())
.then((data) => {
return data;
});
return useSWR(url, fetcher)
}
\ No newline at end of file
import request, { Response } from '~/api/request';
export interface FilterOptionResp {
id: number,
name: string
}
//商城接口
export const mallApi = {
category: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webProductMall/category');
},
brand: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webDevice/brand');
},
model: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webDevice/model');
},
part: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webProductMall/parts');
},
quality: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webProductMall/quality');
},
region: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webDevice/getSecondDistrictInfo');
},
}
//设备租赁接口
export const leasingApi = {
category: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webProductMall/category');
},
brand: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webDevice/brand');
},
model: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webDevice/model');
},
part: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webProductMall/parts');
},
quality: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webProductMall/quality');
},
region: (): Promise<Response<Array<FilterOptionResp>>> => {
return request('/pms/webDevice/getSecondDistrictInfo');
},
}
\ No newline at end of file
import { Space, Button, Select } from 'antd';
import styles from '../../index.module.scss';
import { FilterOptionResp } from "../../api";
type Props = {
data: Array<FilterOptionResp>;
onChange: (id: FilterOptionResp) => void;
};
export default function BrandItem(props: Props) {
const onClick = (item: FilterOptionResp) => {
props.onChange({
id: item.id,
name: "品牌:" + item.name,
});
};
return (
<div className={styles.filterItem}>
<div className={styles.filterItemTitle}>品牌:</div>
<div className={styles.filterItemMain}>
<Space size={40}>
{
props?.data?.map(item => {
return <Button type="link" key={item.id} onClick={(e) => onClick(item)}>{item.name}</Button>;
})
}
</Space>
</div>
</div>
);
}
\ No newline at end of file
import { Space, Button, Select } from 'antd';
import styles from '../../index.module.scss';
import { FilterOptionResp } from "../../api";
type Props = {
data: Array<FilterOptionResp>;
onChange: (id: FilterOptionResp) => void;
};
export default function CategoryItem(props: Props) {
const onClick = (item: FilterOptionResp) => {
props.onChange({
id: item.id,
name: "类目:" + item.name,
});
};
return (
<div className={styles.filterItem}>
<div className={styles.filterItemTitle}>类目:</div>
<div className={styles.filterItemMain}>
<Space size={40}>
{
props?.data?.map(item => {
return <Button type="link" key={item.id} onClick={(e) => onClick(item)}>{item.name}</Button>;
})
}
</Space>
</div>
</div>
);
}
\ No newline at end of file
import { Space, Button, Select } from 'antd';
import styles from '../../index.module.scss';
import { FilterOptionResp } from "../../api";
type Props = {
data: Array<FilterOptionResp>;
onChange: (id: FilterOptionResp) => void;
};
export default function ModelItem(props: Props) {
const onClick = (item: FilterOptionResp) => {
props.onChange({
id: item.id,
name: "型号:" + item.name,
});
};
return (
<div className={styles.filterItem}>
<div className={styles.filterItemTitle}>型号:</div>
<div className={styles.filterItemMain}>
<Space size={40}>
{
props?.data?.map(item => {
return <Button type="link" key={item.id} onClick={(e) => onClick(item)}>{item.name}</Button>;
})
}
</Space>
</div>
</div>
);
}
\ No newline at end of file
import { Space, Button, Select } from 'antd';
import styles from '../../index.module.scss';
import { FilterOptionResp } from "../../api";
type Props = {
data: Array<FilterOptionResp>;
onChange: (id: FilterOptionResp) => void;
};
export default function PartItem(props: Props) {
const onClick = (item: FilterOptionResp) => {
props.onChange({
id: item.id,
name: "部件:" + item.name,
});
};
return (
<div className={styles.filterItem}>
<div className={styles.filterItemTitle}>部件:</div>
<div className={styles.filterItemMain}>
<Space size={40}>
{props?.data?.map((item) => {
return (
<Button type="link" key={item.id} onClick={(e) => onClick(item)}>
{item.name}
</Button>
);
})}
</Space>
</div>
</div>
);
}
\ No newline at end of file
import { Space, Button, Select } from 'antd';
import styles from '../../index.module.scss';
import { FilterOptionResp } from "../../api";
type Props = {
data: Array<FilterOptionResp>;
onChange: (id: FilterOptionResp) => void;
};
export default function QualityItem(props: Props) {
const onClick = (item: FilterOptionResp) => {
props.onChange({
id: item.id,
name: "成色:" + item.name,
});
};
return (
<div className={styles.filterItem}>
<div className={styles.filterItemTitle}>成色:</div>
<div className={styles.filterItemMain}>
<Space size={40}>
{props?.data?.map((item) => {
return (
<Button type="link" key={item.id} onClick={(e) => onClick(item)}>
{item.name}
</Button>
);
})}
</Space>
</div>
</div>
);
}
\ No newline at end of file
import { Space, Select } from 'antd';
import { useEffect, useState } from 'react';
import styles from '../../index.module.scss';
export default function RegionItem(){
const [productList, setProductList] = useState(Array<{}>);
useEffect(() => {
setProductList([{}, {}, {}, {}, {}, {}]);
}, []);
const onProvinceChange = (value: string) => {
console.log("省", value);
};
const onCityChange = (value: string) => {
console.log("市", value);
};
return (
<div className={styles.filterItem}>
<div className={styles.filterItemTitle}>地域:</div>
<div className={styles.filterItemMain}>
<Space size={40}>
<Select
bordered={false}
dropdownMatchSelectWidth={false}
placeholder="选择省"
onChange={onProvinceChange}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
<Select
bordered={false}
dropdownMatchSelectWidth={false}
placeholder="选择市"
onChange={onCityChange}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
</Space>
</div>
</div>
);
}
import { Space, Tag } from "antd";
import { FilterResult } from "../..";
import styles from "../../index.module.scss";
type Props = {
data: FilterResult;
onDel: (key: string) => void;
};
export default function ResultItem({data, onDel}: Props) {
return (
<div className={styles.filterItem}>
<div className={styles.filterItemTitle}>已选:</div>
<div className={styles.filterItemMain}>
<Space size={10}>
{data &&
Object.keys(data).map((key, i) => {
//@ts-ignore
let item = data[key];
return (
<Tag
closable
onClose={(e: React.MouseEvent<HTMLElement, MouseEvent>) => {
onDel(key);
}}
key={i}
>
{item?.name}
</Tag>
);
})}
</Space>
</div>
</div>
);
}
.filterWrap {
padding: 0px 32px;
background: #ffffff;
border-radius: 6px;
* {
font-size: 14px !important;
}
}
.filterItem {
height: 42px;
border-bottom: 1px dashed RGBA(222, 222, 222, 1);
display: flex;
align-items: center;
&:nth-last-child(1) {
border-bottom: none;
}
.filterItemTitle {
width: 80px;
margin-right: 8px;
font-family: MicrosoftYaHei;
color: rgba(153, 153, 153, 1);
line-height: 20px;
}
.filterItemMain {
flex: 1;
display: flex;
justify-content: space-between;
}
:global .ant-select-selector {
padding: 0 12px 0 0;
.ant-select-selection-item,
.ant-select-selection-placeholder {
font-size: 16px;
font-family: MicrosoftYaHei;
color: #3e4149;
}
}
:global .ant-select-arrow {
color: #3e4149;
}
:global .ant-btn-link {
font-size: 16px;
font-family: MicrosoftYaHei;
color: #3e4149;
padding: 0;
}
:global .ant-tag {
padding: 4px 9px;
}
}
import CategoryItem from "./compoents/categoryItem";
import { FilterOptionResp, leasingApi, mallApi } from "./api";
import ResultItem from "./compoents/resultItem";
import RegionItem from "./compoents/regionItem";
import styles from "./index.module.scss";
import { useEffect, useState } from "react";
import BrandItem from "./compoents/brandItem";
import ModelItem from "./compoents/modelItem";
import PartItem from "./compoents/partItem";
import QualityItem from "./compoents/qualityItem";
export type FilterResult = {
category?: FilterOptionResp | undefined;
};
type itemType = "类目" | "地域" | "品牌" | "部件" | "型号" | "成色";
type Props = {
types: [itemType, itemType, itemType, itemType, itemType, itemType]; //需要包含的筛选条件项
showResultItem: Boolean; //显示结果栏
categoryData?: Array<FilterOptionResp>;
regionData?: Array<FilterOptionResp>;
brandData?: Array<FilterOptionResp>;
modelData?: Array<FilterOptionResp>;
partData?: Array<FilterOptionResp>;
qualityData?: Array<FilterOptionResp>;
onChange: (filterResult: FilterResult) => void; //筛选条件更改事件
};
export default function Filter(props: Props) {
const [result, setResult] = useState<FilterResult>({});
const onChange = (item: FilterOptionResp, type: string) => {
let data: { [key: string]: FilterOptionResp } = {};
data[type] = item;
setResult({ ...result, ...data });
};
useEffect(() => {
props.onChange(result);
}, [result]);
const onDel = (key: string) => {
//@ts-ignore
delete result[key];
setResult({
...result,
});
};
return (
<>
{props.types.includes("地域") && (
<div
className={styles.filterWrap}
style={{
marginBottom: 18,
}}
>
<RegionItem></RegionItem>
</div>
)}
<div className={styles.filterWrap}>
{props.types.includes("品牌") && (
<BrandItem
data={props.brandData || []}
onChange={(item: FilterOptionResp) => onChange(item, "brand")}
></BrandItem>
)}
{props.types.includes("类目") && (
<CategoryItem
data={props.categoryData || []}
onChange={(item: FilterOptionResp) => onChange(item, "category")}
></CategoryItem>
)}
{props.types.includes("部件") && (
<PartItem
data={props.partData || []}
onChange={(item: FilterOptionResp) => onChange(item, "part")}
></PartItem>
)}
{props.types.includes("型号") && (
<ModelItem
data={props.modelData || []}
onChange={(item: FilterOptionResp) => onChange(item, "model")}
></ModelItem>
)}
{props.types.includes("成色") && (
<QualityItem
data={props.qualityData || []}
onChange={(item: FilterOptionResp) => onChange(item, "quality")}
></QualityItem>
)}
{props.showResultItem && (
<ResultItem data={result} onDel={onDel}></ResultItem>
)}
</div>
</>
);
}
Filter.mallApi = mallApi;
Filter.leasingApi = leasingApi;
import { useEffect } from "react"; import { useEffect } from "react";
import Router from "next/router"; import Router from "next/router";
import request from '~/api/request'; import request from '~/api/request';
import useSWR, { SWRResponse } from "swr";
/* /*
const fetcher = (url) => const fetcher = (url) =>
fetch(url) fetch(url)
...@@ -10,7 +11,8 @@ const fetcher = (url) => ...@@ -10,7 +11,8 @@ const fetcher = (url) =>
}); */ }); */
export function useUser({ redirectTo, redirectIfFound } = {}) { export function useUser({ redirectTo, redirectIfFound } = {}) {
const { data, error } = request("/api/user"); return {};
const { data, error } = useSWR("/api/user", request);
const user = data?.user; const user = data?.user;
const finished = Boolean(data); const finished = Boolean(data);
const hasUser = Boolean(user); const hasUser = Boolean(user);
......
...@@ -4,193 +4,69 @@ import Layout from "~/components/layout"; ...@@ -4,193 +4,69 @@ 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 Image from 'next/image';
import Filter, { FilterResult } from "~/components/filter";
import { FilterOptionResp, mallApi } from "~/components/filter/api";
export default function Mall() { // 此函数在构建时被调用
const router = useRouter(); export async function getStaticProps() {
const [productList, setProductList] = useState(Array<{}>); //获取筛选数据,进行静态渲染
const brand = Filter.mallApi.brand();
useEffect(() => { const category = Filter.mallApi.category();
setProductList([{}, {}, {}, {}, {}, {}]); const model = Filter.mallApi.model();
}, []); const part = Filter.mallApi.part();
const quality = Filter.mallApi.quality();
const onProvinceChange = (value: string) => {
console.log("省", value);
};
const onCityChange = (value: string) => { const res = await Promise.all([brand, category, part, model, quality]);
console.log("市", value);
};
const onMoreChange = (value: string) => { return {
console.log("更多", value); props: {
brandData: res[0].result || [],
categoryData: res[1].result || [],
partData: res[2].result || [],
modelData: res[3].result || [],
qualityData: res[4].result || [],
},
}; };
}
const onCloseTag = (e: React.MouseEvent<HTMLElement, MouseEvent>) => { type Props = {
console.log("删除", e); brandData: Array<FilterOptionResp>;
}; categoryData: Array<FilterOptionResp>;
partData: Array<FilterOptionResp>;
modelData: Array<FilterOptionResp>;
qualityData: Array<FilterOptionResp>;
};
export default function Mall(props: Props) {
const router = useRouter();
const [productList, setProductList] = useState(Array<{}>);
const onFilterChange = (filterResult: FilterResult) => {
console.log('filterResult', filterResult)
}
return ( return (
<Layout> <Layout>
<div className="page" style={{ paddingTop: "29px" }}> <div className="page" style={{ paddingTop: "18px" }}>
<div className="filter-wrap" style={{ marginBottom: "11px" }}> <Filter
<div className="filter-item"> types={["类目", "地域", "品牌", "部件", "型号", "成色"]}
<div className="filter-item__title">地域:</div> showResultItem
<div className="filter-item-main"> brandData={props.brandData}
<Space size={40}> categoryData={props.categoryData}
<Select partData={props.partData}
bordered={false} modelData={props.modelData}
dropdownMatchSelectWidth={false} qualityData={props.qualityData}
placeholder="选择省" onChange={onFilterChange}
onChange={onProvinceChange} ></Filter>
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
<Select
bordered={false}
dropdownMatchSelectWidth={false}
placeholder="选择市"
onChange={onCityChange}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
</Space>
</div>
</div>
</div>
<div className="filter-wrap">
<div className="filter-item">
<div className="filter-item__title">类目:</div>
<div className="filter-item-main">
<Space size={40}>
<Button type="link">不限</Button>
<Button type="link">无人机</Button>
<Button type="link">挂载</Button>
<Button type="link">地面站</Button>
</Space>
<Select
placeholder="更多"
onChange={onMoreChange}
bordered={false}
dropdownMatchSelectWidth={false}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
</div>
</div>
<div className="filter-item">
<div className="filter-item__title">品牌:</div>
<div className="filter-item-main">
<Space size={40}>
<Button type="link">不限</Button>
<Button type="link">无人机</Button>
<Button type="link">挂载</Button>
<Button type="link">地面站</Button>
</Space>
<Select
placeholder="更多"
onChange={onMoreChange}
bordered={false}
dropdownMatchSelectWidth={false}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
</div>
</div>
<div className="filter-item">
<div className="filter-item__title">部件:</div>
<div className="filter-item-main">
<Space size={40}>
<Button type="link">不限</Button>
<Button type="link">无人机</Button>
<Button type="link">挂载</Button>
<Button type="link">地面站</Button>
</Space>
<Select
placeholder="更多"
onChange={onMoreChange}
bordered={false}
dropdownMatchSelectWidth={false}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
</div>
</div>
<div className="filter-item">
<div className="filter-item__title">型号:</div>
<div className="filter-item-main">
<Space size={40}>
<Button type="link">不限</Button>
<Button type="link">无人机</Button>
<Button type="link">挂载</Button>
<Button type="link">地面站</Button>
</Space>
<Select
placeholder="更多"
onChange={onMoreChange}
bordered={false}
dropdownMatchSelectWidth={false}
options={[
{ value: "jack", label: "Jack" },
{ value: "lucy", label: "Lucy" },
{ value: "Yiminghe", label: "yiminghe" },
{ value: "disabled", label: "Disabled", disabled: true },
]}
/>
</div>
</div>
<div className="filter-item">
<div className="filter-item__title">成色:</div>
<div className="filter-item-main">
<Space size={40}>
<Button type="link">不限</Button>
<Button type="link">无人机</Button>
<Button type="link">挂载</Button>
<Button type="link">地面站</Button>
</Space>
</div>
</div>
<div className="filter-item">
<div className="filter-item__title">已选:</div>
<div className="filter-item-main">
<Space size={10}>
<Tag closable onClose={onCloseTag}>
无人机
</Tag>
<Tag closable onClose={onCloseTag}>
无人机
</Tag>
</Space>
</div>
</div>
</div>
<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}> <ul className={styles.listWrap}>
{productList.map((item) => { {productList.map((item) => {
return ( return (
<li className={styles.item} onClick={() => router.push('/mall/detail/1')}> <li
<Image className={styles.img}></Image> className={styles.item}
onClick={() => router.push("/mall/detail/1")}
>
<Image alt="" src="" className={styles.img}></Image>
<div className={styles.title}> <div className={styles.title}>
入云龙ll 1550入云龙ll 1550入云龙ll 1550入云龙ll 1550 入云龙ll 1550入云龙ll 1550入云龙ll 1550入云龙ll 1550
</div> </div>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论