提交 ad36d9c6 作者: 18928357778

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

......@@ -83,8 +83,13 @@ export default function request(url: string, method: String = 'get', data?: any,
}
if (data.code !== '200') {
//未登录判断
if(data.code === '5008'){
errMsg('请先登录');
}else{
errMsg(data.message || '请求出错');
}
}
return data;
})
......
......@@ -4,7 +4,6 @@ import type { TabsProps } from "antd";
import styles from "./index.module.scss";
import { useRouter } from "next/router";
import LoginModal from "~/components/loginModal";
import { useUser } from "~/lib/hooks";
import PublishModal from "./publishModal";
import JoinModal from "./joinModal";
import { UserContext } from "~/lib/userProvider";
......@@ -43,7 +42,8 @@ const items: TabsProps["items"] = [
export default function NavHeader() {
const router = useRouter();
const [currentPath, setCurrentPath] = useState("");
const { userInfo, testLogin, logout } = useContext(UserContext);
const { userInfo, testLogin, logout, setNeedLogin, needLogin } =
useContext(UserContext);
useEffect(() => {
const routerTo = items?.filter(item=>router.route.includes(item.key))[0]
......@@ -97,6 +97,13 @@ export default function NavHeader() {
}
}
//从其它组件通知需要登录
useEffect(() => {
if (needLogin) {
setOpenLoginModal(true);
}
}, [needLogin]);
return (
<div className={styles.navHeader}>
<div className={styles.nav}>
......@@ -134,7 +141,7 @@ export default function NavHeader() {
) : (
<Button
type="text"
onClick={() => testLogin()}
onClick={() => setOpenLoginModal(true)}
style={{ fontWeight: "bold", fontSize: 16 }}
>
登录
......@@ -143,7 +150,10 @@ export default function NavHeader() {
</div>
<LoginModal
open={openLoginModal}
onCancel={() => setOpenLoginModal(false)}
onCancel={() => {
setOpenLoginModal(false);
setNeedLogin(false);
}}
></LoginModal>
<PublishModal
open={openPublishModal}
......
.identityBtn {
box-sizing: border-box;
padding: 0 5px;
position: absolute;
bottom: 0;
left: 50%;
transform:translate(-50%, 0);
min-width: 100%;
height: 24px;
background: #e26329;
border-radius: 6px;
opacity: 0.95;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #fff;
white-space: nowrap;
text-align: center;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #000000;
flex-wrap: nowrap;
}
.modal {
:global .ant-modal-content {
border-radius: 6px;
.ant-modal-title{
.ant-modal-title {
text-align: center;
}
}
......
......@@ -6,6 +6,18 @@ import { useEffect, useState } from "react";
import api, { ListTagResp } from "./api";
import { useRouter } from "next/router";
const imgs = [
require("./assets/生产制造商.png"),
require("./assets/品牌企业.png"),
require("./assets/商务公关机构.png"),
require("./assets/无人机自媒体.png"),
require("./assets/投资机构.png"),
require("./assets/飞手团队.png"),
require("./assets/二手服务商.png"),
require("./assets/飞手培训机构.png"),
require("./assets/推广合作商.png"),
];
type Props = {
open?: boolean;
onOk?: () => void;
......@@ -16,10 +28,10 @@ export default function JoinModal(props: Props) {
const [tagList, setTagList] = useState<ListTagResp[]>([]);
useEffect(() => {
api.listTag().then(res => {
api.listTag().then((res) => {
setTagList(res.result || []);
})
}, [])
});
}, []);
const onClickTag = (item: ListTagResp) => {
router.replace("/JoinPolicy?tagId=" + item.id);
......@@ -35,15 +47,20 @@ export default function JoinModal(props: Props) {
width={460}
footer={null}
>
<Row style={{ padding: "22px 16px 20px 16px", gap: "16px 40px" }}>
{tagList.map((item) => {
<Row style={{rowGap: 29, paddingTop: 21, paddingBottom: 21}}>
{tagList.map((item, i) => {
return (
<Col
key={item.id}
style={{ cursor: "pointer", height: 100, padding: 0 }}
span={8}
style={{
cursor: "pointer",
padding: 0,
textAlign: "center",
}}
onClick={() => onClickTag(item)}
>
<Image src={img} width={100} height={100} alt=""></Image>
<Image src={imgs[i]} width={64} height={64} alt=""></Image>
<div className={styles.identityBtn}>
{item.tagName}
{">"}
......
......@@ -6,11 +6,11 @@ export interface TypeResp {
}
export interface PublishParams {
userAccountId: number; //账号id
publishPhone: number; //手机号
publishName: string; //发布名称
requirementTypeId: number; //需求类型
requireDescription: string; //需求描述
provinceCode?: string; //省编码
}
export default {
......
import { Button, Form, Input, Modal, Select } from "antd";
import { useEffect, useState } from "react";
import { useGeolocation } from "~/lib/hooks";
import api, { PublishParams, TypeResp } from "./api";
import styles from "./index.module.scss";
......@@ -11,14 +12,14 @@ type Props = {
export default function PublishModal(props: Props) {
const [types, setTypes] = useState<Array<TypeResp>>([]); //需求类型
const [params, setParams] = useState<PublishParams>({
userAccountId: -1,
publishName: "",
publishPhone: -1,
requireDescription: "",
requirementTypeId: -1,
});
const [form] = Form.useForm();
console.log("form", form);
const position = useGeolocation();
console.log("position", position);
useEffect(() => {
api.listType().then((res) => {
......@@ -33,10 +34,12 @@ export default function PublishModal(props: Props) {
.publish({
...params,
...values,
provinceCode: position?.address?.addressComponent?.adcode
})
.then((res) => {
if (res.code !== "-1") {
if (res.code === "200") {
props.onCancel && props.onCancel();
window.messageApi.success("发布成功");
setTimeout(() => {
form.resetFields();
}, 500);
......
......@@ -33,6 +33,11 @@ export default function LoginModal(props: Props) {
}
setRandomLoginCode(String(Date.now()));
}, [props.open]);
useEffect(() => {
if (randomLoginCode) {
//获取登录码
api
.getAppletQRCode({
randomLoginCode,
......@@ -44,9 +49,8 @@ export default function LoginModal(props: Props) {
window.messageApi.error("获取登录二维码失败");
}
});
}, [props.open]);
}
useEffect(() => {
if (randomLoginCode && !userInfo) {
if (timeHandle) {
clearTimeout(timeHandle);
......@@ -58,14 +62,15 @@ export default function LoginModal(props: Props) {
})
.then((res) => {
if (res.code === "200") {
setUserInfo({
...res.result,
id: res.result?.userAccountId,
});
window.messageApi.success("登录成功");
clearInterval(handle);
setTimeHandle(null);
window.localStorage.setItem("token", res.result.token);
api.userInfo().then((res) => {
setUserInfo(res.result || "");
window.messageApi.success("登录成功");
props.onCancel();
});
}
});
}, 1000);
......
import { useEffect, useState } from "react";
import api, { UserInfoResp } from "~/api";
/*
const fetcher = (url) =>
fetch(url)
.then((r) => r.json())
.then((data) => {
return { user: data?.user || null };
}); */
export function useUser() {
const [user, setUser] = useState<UserInfoResp | null>(null);
const [userAccountId, setUserAccountId] = useState<number | "">('');
useEffect(() => {
setUserAccountId(Number(window.localStorage.getItem('userId')));
try {
let userInfo = JSON.parse(window.localStorage.getItem('userInfo') || '') || null;
setUser(userInfo);
} catch (e) { }
}, [])
useEffect(() => {
if (!user) {
api
.userInfo()
.then((res) => {
if(res.code == '200'){
setUser(res.result || null);
}else{
setUserAccountId('');
}
window.localStorage.setItem('userInfo', JSON.stringify(res.result || ''));
});
}
//退出登录
if(userAccountId === ''){
setUser(null);
window.localStorage.setItem('userInfo', '');
}
}, [userAccountId]);
return user;
}
export function useGeolocation() {
const [position, setPosition] = useState<{
......
import React, { createContext, Dispatch, SetStateAction, useEffect, useState } from "react";
import React, {
createContext,
Dispatch,
SetStateAction,
useEffect,
useState,
} from "react";
import api, { UserInfoResp } from "~/api";
export const UserContext = createContext<{
testLogin: () => void;
logout: () => void;
userInfo: UserInfoResp | null;
setUserInfo: Dispatch<SetStateAction<UserInfoResp | null>>;
userInfo: UserInfoResp | null | "";
setUserInfo: Dispatch<SetStateAction<UserInfoResp | null | "">>;
needLogin: Boolean;
setNeedLogin: Dispatch<SetStateAction<Boolean>>;
}>({
testLogin() {},
logout() {},
userInfo: null,
setUserInfo() {},
needLogin: false,
setNeedLogin() {},
});
type Props = {
children: React.ReactNode;
};
const UserProvider = ({ children }: Props) => {
const [userInfo, setUserInfo] = useState<UserInfoResp | null>(null);
const [userInfo, setUserInfo] = useState<UserInfoResp | null | ''>(null);
const [needLogin, setNeedLogin] = useState<Boolean>(false); //用于通知登录modal需要打开
useEffect(() => {
try {
......@@ -26,7 +37,9 @@ const UserProvider = ({ children }: Props) => {
}, []);
useEffect(() => {
if (userInfo !== null) {
localStorage.setItem("userInfo", JSON.stringify(userInfo || ""));
}
}, [userInfo]);
//测试登录
......@@ -35,7 +48,7 @@ const UserProvider = ({ children }: Props) => {
if (res.code == "200") {
window.localStorage.setItem("token", res.result?.token || "");
api.userInfo().then((res) => {
setUserInfo(res.result || null);
setUserInfo(res.result || '');
});
}
});
......@@ -44,11 +57,20 @@ const UserProvider = ({ children }: Props) => {
//登出
function logout() {
localStorage.setItem("token", "");
setUserInfo(null);
setUserInfo('');
}
return (
<UserContext.Provider value={{ userInfo, setUserInfo, testLogin, logout }}>
<UserContext.Provider
value={{
userInfo,
setUserInfo,
testLogin,
logout,
needLogin,
setNeedLogin,
}}
>
{children}
</UserContext.Provider>
);
......
......@@ -8,9 +8,21 @@ export interface CooperationApplyParams {
cooperationTagId: number
}
export interface GetTagIdResp {
id: number,
tagName: string,
tagImg: string,
tagDescription: string,
createTime: string
}
export default {
//请加盟
cooperationApply(params: CooperationApplyParams):Promise<Response<string>>{
//请加盟
cooperationApply(params: CooperationApplyParams): Promise<Response<string>> {
return request('/userapp/cooperation/apply', 'post', params)
},
//加盟标签相关内容
getTagById(params: { id: number }): Promise<Response<GetTagIdResp>> {
return request('/userapp/cooperation/getTagById', 'get', params)
}
}
\ No newline at end of file
import { Button, Col, Divider, Form, Input, Row } from "antd";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import LayoutView from "~/components/layout";
import api from "./api";
import styles from "./index.module.scss";
export default function JoinPolicy() {
const router = useRouter();
const [content, setContent] = useState(""); //福利内容
const tagId = Number(router.query.tagId);
useEffect(() => {
if (tagId) {
api
.getTagById({
id: tagId,
})
.then((res) => {
setContent(res.result?.tagDescription.replace("\n", "<br/>") || "");
});
}
}, []);
//提交
const onFinish = (values: any) => {
console.log(values);
api
.cooperationApply({
...values,
userAccountId: 1,
cooperationTagId: router.query.tagId,
cooperationTagId: tagId,
})
.then((res) => {
console.log("提交结果", res);
if (res.result === "已通过") {
window.messageApi.success(res.result);
if (res.code === "200") {
window.messageApi.success('提交成功');
setTimeout(() => {
router.push("/");
}, 1500);
} else {
window.messageApi.error(res.message);
}
});
};
......@@ -50,24 +62,8 @@ export default function JoinPolicy() {
<div
className={styles.font2}
style={{ paddingLeft: 50, paddingRight: 50 }}
>
1.每月自动获取一张高额度优惠券
<br /> 2.流量扶持和店铺曝光度
<br />
3成为科比特指定官方生态合作伙伴
<br /> 4.享受不低于1亿制造采购补贴
<br /> 5.无人机产业链资源共享
<br /> 6.享受价值5亿产业链订单
<br /> 7.享受一对一代运营服务
<br /> 8.享受无人机生态圈资源
<br /> 9.成为科比特指定官方生态
<br />
10.享受无人机生态圈资源合作伙伴
<br />
11.受价值5亿产业链订单
<br />
12.成为科比特指定官方生态合作伙伴
</div>
dangerouslySetInnerHTML={{ __html: content }}
></div>
<Divider />
<div
className={styles.font1}
......
......@@ -2,13 +2,14 @@ import { LoadingOutlined, PlusOutlined } from "@ant-design/icons";
import { Col, Form, Input, Row, Upload, message, Button, Image } from "antd";
import type { UploadChangeParam } from "antd/es/upload";
import type { RcFile, UploadFile, UploadProps } from "antd/es/upload/interface";
import { useState } from "react";
import { useContext, useState } from "react";
import config from "~/api/config";
import Layout from "~/components/layout";
import api from "./api";
import styles from "./index.module.scss";
import gApi from '~/api';
import gApi from "~/api";
import Router from "next/router";
import { UserContext } from "~/lib/userProvider";
const beforeUpload = (file: RcFile) => {
const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
......@@ -34,6 +35,7 @@ const normFile = (e: any) => {
export default function Certification() {
const [loading, setLoading] = useState(false);
const [imageUrl, setImageUrl] = useState<string>();
const { userInfo, setUserInfo } = useContext(UserContext);
//上传change事件
const handleChange: UploadProps["onChange"] = (
......@@ -60,12 +62,18 @@ export default function Certification() {
licenseImg: imageUrl,
})
.then((res) => {
console.log('提交结果', res);
if(res.code === '200'){
window.messageApi.success(res.result);
console.log("提交结果", res);
if (res.code === "200") {
window.messageApi.success("提交成功,请等待审核");
if (userInfo) {
setUserInfo({
...userInfo,
companyAuthStatus: 1,
});
}
setTimeout(() => {
Router.push('/');
}, 1000)
Router.push("/");
}, 1000);
}
});
};
......
......@@ -21,6 +21,11 @@ export interface Dynamic {
likesCount: number;
commentCount: number;
likes: boolean;
userBaseInfo: {
id: number,
nickName: string,
userImg: string
}
}
export interface DynamicListResp {
......
......@@ -2,11 +2,12 @@ import { PlusOutlined } from "@ant-design/icons";
import { Form, Input, Modal, Upload, Image, Button, Row, Col } from "antd";
import type { RcFile, UploadProps } from "antd/es/upload";
import type { UploadFile } from "antd/es/upload/interface";
import { useState } from "react";
import { useContext, useState } from "react";
import gApi from "~/api";
import NImage from "next/image";
import api from "./api";
import { useGeolocation, useUser } from "~/lib/hooks";
import { useGeolocation } from "~/lib/hooks";
import { UserContext } from "~/lib/userProvider";
type Props = {
open: boolean;
......@@ -30,7 +31,7 @@ export default function PublishMessage(props: Props) {
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [showLoading, setShowLoad] = useState(false);
const [form] = Form.useForm();
const user = useUser();
const { userInfo, setNeedLogin } = useContext(UserContext);
const position = useGeolocation();
//预览关闭
......@@ -84,17 +85,21 @@ export default function PublishMessage(props: Props) {
const onFinish = (values: any) => {
console.log(values);
setShowLoad(true);
if (userInfo) {
api
.publish({
lat: position?.position?.lat, //纬度
lon: position?.position?.lng, //经度
title: '', //标题
title: "", //标题
description: values.description, //描述
userId: user!.id, //用户id
userId: userInfo.id, //用户id
mediaVO: {
//发布图片
//@ts-ignore
picture: fileList.filter((item) => item.url).map((item) => item.url),
picture: fileList
.filter((item) => item.url)
.map((item) => item.url),
},
})
.then((res) => {
......@@ -111,6 +116,7 @@ export default function PublishMessage(props: Props) {
}, 500);
}
});
}
};
return (
......
......@@ -58,6 +58,7 @@
font-family: MicrosoftYaHei;
color: #000000;
margin-bottom: 16px;
padding-right: 10px;
}
}
......
......@@ -13,11 +13,11 @@ import Layout from "~/components/layout";
import styles from "./index.module.scss";
import errImg from "~/assets/errImg";
import { RightOutlined } from "@ant-design/icons";
import { useEffect, useState } from "react";
import { useContext, useEffect, useState } from "react";
import PublishMessage from "./components/publishMessage";
import api, { ByDynamicParams, Dynamic } from "./api";
import InfiniteScroll from "react-infinite-scroll-component";
import { useUser } from "~/lib/hooks";
import { UserContext } from "~/lib/userProvider";
interface Item extends Dynamic {
openComment?: boolean; //是否开启评论
......@@ -33,7 +33,7 @@ export default function Forum() {
pageSize: 16,
});
const [count, setCount] = useState(0); //动态总数
const userInfo = useUser(); //获取信息
const { userInfo, setNeedLogin } = useContext(UserContext);
useEffect(() => {
api
......@@ -56,7 +56,11 @@ export default function Forum() {
* 展示发布模态框
*/
const showModal = () => {
if (userInfo) {
setIsModalOpen(true);
} else {
setNeedLogin(true);
}
};
/**
......@@ -78,15 +82,22 @@ export default function Forum() {
//评论内容
const onComment = (values: any, id: number, i: number) => {
api.comment({
if (userInfo) {
api
.comment({
content: values.content,
dynamicId: id,
userId: userInfo!.id,
}).then(res => {
if(res.code === '200'){
userId: userInfo.id,
})
.then((res) => {
if (res.code === "200") {
window.messageApi.success("评论成功");
}
});
} else {
setNeedLogin(true);
}
};
return (
<Layout>
......@@ -112,9 +123,15 @@ export default function Forum() {
return (
<div key={item.id} className={styles.item}>
<Space size={10} align="start">
<Image alt="" className={styles.headImg}></Image>
<Image
alt=""
className={styles.headImg}
src={item.userBaseInfo.userImg}
></Image>
<div className={styles.info}>
<div className={styles.name}>给**的</div>
<div className={styles.name}>
{item.userBaseInfo.nickName}
</div>
<div className={styles.desc}>{item.description}</div>
<div className={styles.imgs}>
<Image.PreviewGroup
......@@ -165,8 +182,17 @@ export default function Forum() {
</Space>
{item.openComment && (
<div className={styles.commentWrap}>
<Form onFinish={(values) => {onComment(values, item.id, i)}}>
<Form.Item name="content" rules={[{ required: true }]} help="" style={{marginBottom: 0}}>
<Form
onFinish={(values) => {
onComment(values, item.id, i);
}}
>
<Form.Item
name="content"
rules={[{ required: true }]}
help=""
style={{ marginBottom: 0 }}
>
<div className={styles.draftWrap}>
<div className={styles.commentHeadImg}>自已</div>
<Input
......@@ -176,7 +202,11 @@ export default function Forum() {
</div>
</Form.Item>
<div className={styles.btnCommentWrap}>
<Button type="primary" htmlType="submit" className="btnComment">
<Button
type="primary"
htmlType="submit"
className="btnComment"
>
评论
</Button>
</div>
......
import styles from "./index.module.scss";
import Layout from "~/components/layout";
import { Space, Image as AImage, Row, Col, Button, Divider, Badge } from "antd";
import { useEffect, useState } from "react";
import { useContext, useEffect, useState } from "react";
import { DownOutlined, RightOutlined } from "@ant-design/icons";
import Image from "next/image";
import errImg from "~/assets/errImg";
......@@ -15,9 +15,11 @@ import "swiper/css";
import "swiper/css/navigation";
import api, { GetAppGoodsInfoDetailResult } from "./api";
import IntentionModal from "./components/intentionModal";
import { UserContext } from "~/lib/userProvider";
export default function MallDetail() {
const [visible, setVisible] = useState(false);
const { userInfo, setNeedLogin } = useContext(UserContext);
const [visible, setVisible] = useState(false); //商品图预览
const router = useRouter();
const [id, setId] = useState<number | null>(null);
const [detail, setDetail] = useState<GetAppGoodsInfoDetailResult | null>(
......@@ -25,6 +27,16 @@ export default function MallDetail() {
); //详情数据
const [intentionModalOpen, setIntentionModalOpen] = useState(false); //意向弹窗
//打开意向modal
const openIntentionModal = () => {
if (userInfo) {
setIntentionModalOpen(true);
} else {
setNeedLogin(true);
}
};
//提交意向
const handleIntentionOk = () => {
setIntentionModalOpen(false);
};
......@@ -52,7 +64,12 @@ export default function MallDetail() {
return (
<Layout>
{/* 意向弹窗 */}
<IntentionModal open={intentionModalOpen} onOk={handleIntentionOk} onCancel={handleIntentionCancel}></IntentionModal>
<IntentionModal
open={intentionModalOpen}
detail={detail}
onOk={handleIntentionOk}
onCancel={handleIntentionCancel}
></IntentionModal>
<div className="page" style={{ marginTop: 20, backgroundColor: "#fff" }}>
<div style={{ display: "none" }}>
<AImage.PreviewGroup
......@@ -134,7 +151,9 @@ export default function MallDetail() {
</Col>
<Col>
<Row align="middle" style={{ cursor: "pointer" }}>
<Col className={styles.font4} onClick={() => setIntentionModalOpen(true)}>共3种可选</Col>
<Col className={styles.font4} onClick={openIntentionModal}>
共3种可选
</Col>
<Col style={{ marginLeft: 9 }}>
<DownOutlined
style={{
......@@ -169,8 +188,14 @@ export default function MallDetail() {
</Row>
</Space>
<Space size={12} style={{ marginTop: 123 }}>
<Button className={styles.btn1}>加入购物车</Button>
<Button className={styles.btn2} type="primary" onClick={() => setIntentionModalOpen(true)}>
<Button className={styles.btn1} onClick={openIntentionModal}>
加入购物车
</Button>
<Button
className={styles.btn2}
type="primary"
onClick={openIntentionModal}
>
提交意向
</Button>
<Space size={20} style={{ marginLeft: 19 }}>
......
......@@ -46,7 +46,7 @@ export interface GoodsSpec {
skuId: number;
brandInfoId: number;
skuName: string;
productSpecList: ProductSpecList[];
productSpecList: ProductSpec[];
industrySpecList?: any;
chooseType: number;
skuUnitId: number;
......@@ -55,7 +55,7 @@ export interface GoodsSpec {
flag?: any;
}
export interface ProductSpecList {
export interface ProductSpec {
id: number;
productSpec: number;
productSkuId: number;
......
import { Button, Col, Image, Modal, Row, Space } from "antd";
import { useState } from "react";
import errImg from "~/assets/errImg";
import { GetAppGoodsInfoDetailResult } from "../../api";
import styles from "./index.module.scss";
type Props = {
open?: boolean;
onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;
onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;
onCancel: (e: React.MouseEvent<HTMLButtonElement>) => void;
detail: GetAppGoodsInfoDetailResult | null;
};
export default function IntentionModal(props: Props) {
const list = [1, 1, 1, 1, 1, 1, 1, 1, 1];
const [checkedMap, setCheckedMap] = useState<{ string?: boolean }>({}); //通过索引记录选中的产品规格 例: {'1,1': true|false}
//添加规格到购物车
function addProductSpec(goodsSpecIndex: number, productSpecIndex: number) {
let temp = {};
//@ts-ignore
temp[`${goodsSpecIndex},${productSpecIndex}`] =
//@ts-ignore
!checkedMap[`${goodsSpecIndex},${productSpecIndex}`];
setCheckedMap({
...checkedMap,
...temp,
});
}
return (
<Modal
......@@ -21,7 +37,13 @@ export default function IntentionModal(props: Props) {
className={styles.model}
footer={
<div style={{ padding: "13px 36px" }}>
<Button type="primary" className={styles.font5} style={{width: '100%', height: 44}}>提交意向</Button>
<Button
type="primary"
className={styles.font5}
style={{ width: "100%", height: 44 }}
>
提交意向
</Button>
</div>
}
>
......@@ -32,6 +54,7 @@ export default function IntentionModal(props: Props) {
height={100}
fallback={errImg}
style={{ borderRadius: 8 }}
src={props.detail?.images?.[0]?.imgUrl}
></Image>
</Col>
<Col flex="auto" style={{ marginLeft: 13, width: 230 }}>
......@@ -39,13 +62,13 @@ export default function IntentionModal(props: Props) {
className={`${styles.font1} ${styles.ellipsis1}`}
style={{ marginTop: 28 }}
>
垂直起降固定翼 插翅虎M9
{props.detail?.goodsName}
</div>
<div
className={`${styles.font2} ${styles.ellipsis2}`}
style={{ marginTop: 7 }}
>
已选:入云龙【机壳喷绘】+金眼彪Z40【222222222222222222222222233333555555555555555
已选:
</div>
</Col>
</Row>
......@@ -54,40 +77,59 @@ export default function IntentionModal(props: Props) {
<div className={styles.font3} style={{}}>
无人机
</div>
<div>
{props.detail?.goodsSpec?.map((item, goodsSpecIndex) => {
return (
<div key={item.id}>
<div
className={styles.font2}
style={{ marginBottom: 5, marginTop: 11 }}
>
入云龙
{item.goodsSpecName}
</div>
<Space size={10} direction="vertical" style={{ width: "100%" }}>
{list.map((item, i) => {
{item.productSpecList?.map((product, productSpecIndex) => {
return (
<Row
key={i}
key={product.id}
align="middle"
wrap={false}
style={{
borderRadius: 5,
border: "1px solid #d6d6d6",
//@ts-ignore
border: checkedMap[
`${goodsSpecIndex},${productSpecIndex}`
]
? "1px solid #FF552D"
: "1px solid #d6d6d6",
height: 50,
cursor: "pointer",
}}
onClick={() =>
addProductSpec(goodsSpecIndex, productSpecIndex)
}
>
<Col style={{ marginLeft: 7 }}>
<Image width={52} height={36} src="" fallback={errImg} preview={false}></Image>
<Image
width={52}
height={36}
src={product.specImage}
fallback={errImg}
preview={false}
></Image>
</Col>
<Col
className={`${styles.ellipsis1} ${styles.font4}`}
style={{ width: 238, marginLeft: 18 }}
>
入云龙1-机壳喷绘
{product.specName}
</Col>
</Row>
);
})}
</Space>
</div>
);
})}
</div>
</div>
</Modal>
......
......@@ -27,6 +27,11 @@ export interface Item {
apply: 0 | 1;
}
export interface ApplyParams {
tenderInfoId?: number; //招标详情id
tenderNewsId?: number; //招标id
}
export default {
/**
......@@ -36,5 +41,9 @@ export default {
*/
listNewTenderInfo(params: ListNewTenderInfoParams, options = {}): Promise<Response<ListNewTenderInfoResp>> {
return request('/release/tender/listNewTenderInfo', 'post', params, options);
},
//合作申请提交
apply(params: ApplyParams){
return request('/release/tender/apply', 'post', params);
}
}
\ No newline at end of file
import { Button, Empty, Pagination, Spin } from "antd";
import { useState, useEffect } from "react";
import { useState, useEffect, useContext } from "react";
import { UserContext } from "~/lib/userProvider";
import api, { Item } from "./api";
import styles from "./index.module.scss";
......@@ -21,6 +22,7 @@ export default function Bids(props: Props) {
const [count, setCount] = useState(0);
const [abort, setAbort] = useState<AbortController | null>(null);
const [loading, setLoading] = useState(false);
const {userInfo, setNeedLogin} = useContext(UserContext);
useEffect(() => {
//中断前一次请求
......@@ -57,6 +59,24 @@ export default function Bids(props: Props) {
});
};
//申请合作
const onApply = (item: Item) => {
if (userInfo) {
api
.apply({
tenderNewsId: item.tenderNewsId,
tenderInfoId: item.id,
})
.then((res) => {
if (res.code === "200") {
window.messageApi.success("申请成功");
}
});
} else {
setNeedLogin(true);
}
};
return (
<Spin spinning={loading} delay={500}>
<div className={styles.bids} style={{ height: 610 }}>
......@@ -64,9 +84,7 @@ export default function Bids(props: Props) {
return (
<div className={styles.item} key={item.id}>
<div className={styles.info}>
<div className={styles.title}>
{item.tenderContent}
</div>
<div className={styles.title}>{item.tenderContent}</div>
</div>
{item.apply ? (
<Button
......@@ -80,7 +98,9 @@ export default function Bids(props: Props) {
) : (
<Button type="primary" className={styles.btn}>
<div className={styles.text1}>{item.tenderPrice}</div>
<div className={styles.text2}>申请合作</div>
<div className={styles.text2} onClick={() => onApply(item)}>
申请合作
</div>
</Button>
)}
</div>
......
......@@ -67,15 +67,19 @@ export default function Cases(props: Props) {
return (
<div className={styles.item} key={item.id}>
<div className={styles.info}>
<div className={styles.title}>{item.caseTitle}</div>
</div>
<div className={styles.title}>
<Button
type="primary"
className={styles.btn}
type="link"
style={{ padding: "0 0" }}
onClick={() =>
Router.push("/projectInfo/caseArticle/" + item.id)
}
>
{item.caseTitle}
</Button>
</div>
</div>
<Button type="primary" className={styles.btn}>
申请合作
</Button>
</div>
......
......@@ -23,9 +23,6 @@
flex: auto;
.title {
white-space: nowrap; /* 防止换行 */
overflow: hidden; /* 隐藏溢出部分 */
text-overflow: ellipsis; /* 使用省略号代替溢出部分 */
font-size: 16px;
font-family: MicrosoftYaHeiUI-Bold, MicrosoftYaHeiUI;
font-weight: bold;
......@@ -35,9 +32,6 @@
}
.desc {
white-space: nowrap; /* 防止换行 */
overflow: hidden; /* 隐藏溢出部分 */
text-overflow: ellipsis; /* 使用省略号代替溢出部分 */
font-size: 14px;
font-family: MicrosoftYaHei;
color: RGBA(135, 135, 135, 0.4);
......
......@@ -68,18 +68,18 @@ export default function Requirements(props: Props) {
* 确认解决
* @param e
*/
const confirmSolved = (
item: Item
) => {
api.solveRequire({
const confirmSolved = (item: Item) => {
api
.solveRequire({
requirementsInfoId: item.id,
userAccountId: userId
}).then(res => {
if(res.code === '200'){
window.messageApi.success('提交完成');
userAccountId: userId,
})
.then((res) => {
if (res.code === "200") {
window.messageApi.success("提交完成");
setReload(!reload);
}
})
});
};
return (
......@@ -94,13 +94,14 @@ export default function Requirements(props: Props) {
<div className={styles.logo}></div>
<div className={styles.info}>
<div className={styles.title}>
项目需求:电力巡检需要5名飞手
项目需求:{item.requireDescription}
</div>
{/*
<div className={styles.desc}>
具体需求:{item.requireDescription}
</div> */}
</div>
</div>
{item.userAccountId === userId && (
{item.userAccountId === userId ? (
<Popconfirm
title="提示"
description="确认该需求已经解决了吗?"
......@@ -117,6 +118,8 @@ export default function Requirements(props: Props) {
已解决
</Button>
</Popconfirm>
) : (
<div style={{ width: 120, flexShrink: 0 }}></div>
)}
</div>
);
......
......@@ -20,6 +20,8 @@ const withTheme = (node: JSX.Element) => (
theme={{
token: {
borderRadius: 6,
colorLink: "#333",
colorLinkHover: "#ff552d",
},
}}
>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论