提交 78473cb4 作者: 余乾开

Merge branch 'master' into feature/chuck

......@@ -8,11 +8,6 @@ export interface RegionResp {
name: string;
pid: number;
}
export interface UserInfoParams {
userAccountId: number;
}
export interface UserInfoResp {
id: number;
accountType: number;
......@@ -28,6 +23,17 @@ export interface UserInfoResp {
remark: string;
portType: number;
createTime: string;
companyAuthStatus: number;
token: string;
}
export interface TestAppletLoginResp {
userAccountId: number;
token: string;
uid: string;
phoneNum?: string;
nickName: string;
sessionKey?: any;
}
export default {
......@@ -35,12 +41,41 @@ export default {
region: (): Promise<Response<Array<RegionResp>>> => {
return request("/pms/webDevice/getSecondDistrictInfo");
},
//测试-小程序unionId登录-注册
testAppletLogin: (): Promise<Response<TestAppletLoginResp>> => {
let params = new URLSearchParams();
params.append("unionId", "oQZEd5hy0Qrwaj10BGtP8xq8vH--s88888");
return request(
"/userapp/auth/testAppletLogin",
"post",
{},
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: params,
}
);
},
//生成小程序码
getAppletQRCode: (params: { randomLoginCode: string }) => {
return request("/userapp/wx/getAppletQRCode", "get", {
page: "page-identity/identity-empower/index",
scene: "randomLoginCode=" + params.randomLoginCode,
});
},
//查询登录信息
getLoginInfo: (params: { randomLoginCode: string }) => {
return request("/userapp/temp-auth/getLoginInfo", "get", params, {
hideError: true //隐藏错误提示
});
},
//获取用户基本信息
userInfo: (params: UserInfoParams): Promise<Response<UserInfoResp>> => {
return request("/userapp/user-account/info", "get", params, {});
userInfo: (): Promise<Response<UserInfoResp>> => {
return request("/userapp/user-account/info", "get");
},
//图片上传地址
imgOss: () => {
return config.baseUrl + "/pms/upload/imgOss";
}
},
};
......@@ -8,7 +8,8 @@ import config from './config';
* @param options 额外参数
* @returns Promise<Response>
*/
export default function request(url: string, method: String = 'get', data?: any, options = {}): Promise<Response<any>> {
export default function request(url: string, method: String = 'get', data?: any, options: any & { hideError?: boolean, headers?: { token?: string } } = {}): Promise<Response<any>> {
let token = localStorage.getItem('token') || '';
switch (method.toLowerCase()) {
case 'get':
......@@ -24,16 +25,30 @@ export default function request(url: string, method: String = 'get', data?: any,
case 'post':
options = {
...options,
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
body: JSON.stringify(data),
...options,
}
break;
}
if(options.headers){
options.headers.token = token;
}else{
options.headers = {
token
}
}
function errMsg(msg: string) {
if (!options.hideError) {
window.messageApi.error(msg);
}
}
return fetch(config.baseUrl + url, options)
.then((r) => {
try {
......@@ -50,12 +65,12 @@ export default function request(url: string, method: String = 'get', data?: any,
.then((data) => {
if (data.errors) {
//全局消息提示
window.messageApi.error('请求出错')
errMsg('请求出错')
if (Array.isArray(data.errors)) {
data.errors.forEach((item: any) => {
if (item.defaultMessage){
window.messageApi.error(item.defaultMessage)
if (item.defaultMessage) {
errMsg(item.defaultMessage)
}
})
}
......@@ -66,6 +81,11 @@ export default function request(url: string, method: String = 'get', data?: any,
result: null
}
}
if (data.code !== '200') {
errMsg(data.message || '请求出错');
}
return data;
})
.catch(error => {
......
import React, { useEffect, useState } from "react";
import { Avatar, Button, Space, Tabs } from "antd";
import React, { useContext, useEffect, useState } from "react";
import { Avatar, Button, Dropdown, Space, Tabs } from "antd";
import type { TabsProps } from "antd";
import styles from "./index.module.scss";
import { useRouter } from "next/router";
......@@ -7,6 +7,7 @@ import LoginModal from "~/components/loginModal";
import { useUser } from "~/lib/hooks";
import PublishModal from "./publishModal";
import JoinModal from "./joinModal";
import { UserContext } from "~/lib/userProvider";
const items: TabsProps["items"] = [
{
......@@ -42,30 +43,55 @@ const items: TabsProps["items"] = [
export default function NavHeader() {
const router = useRouter();
const [currentPath, setCurrentPath] = useState("");
const user = useUser();
const { userInfo, testLogin, logout } = useContext(UserContext);
useEffect(() => {
setCurrentPath(router.route);
console.log("currentHash", currentPath);
}, [router.route]);
//导航更改
const onChange = (key: string) => {
router.push(key);
};
const [openLoginModal, setPpenLoginModal] = useState(false); //登录modal
const [openPublishModal, setOpenPublishModal] = useState(false); //发布modal
const showModal = () => {
setPpenLoginModal(true);
};
const handleCancel = () => {
setPpenLoginModal(false);
//退出登录
const onLogout = () => {
logout();
};
const [openLoginModal, setOpenLoginModal] = useState(false); //登录modal
const [openPublishModal, setOpenPublishModal] = useState(false); //发布modal
const [openJoinModal, setOpenJoinModal] = useState(false); //加盟modal
//发布按钮事件
function onPublish() {
//登录判断
if (!userInfo) {
setOpenLoginModal(true);
} else {
if (userInfo.companyAuthStatus) {
setOpenPublishModal(true);
} else {
router.push("/certification");
}
}
}
//加盟按钮事件
function onJoin() {
//登录判断
if (!userInfo) {
setOpenLoginModal(true);
} else {
if (userInfo.companyAuthStatus) {
setOpenJoinModal(true);
} else {
router.push("/certification");
}
}
}
return (
<div className={styles.navHeader}>
<div className={styles.nav}>
......@@ -77,39 +103,43 @@ export default function NavHeader() {
onChange={onChange}
/>
<Space size={16} className={styles.btns}>
<Button
type="primary"
className={styles.btn1}
onClick={() => setOpenPublishModal(true)}
>
<Button type="primary" className={styles.btn1} onClick={onPublish}>
+ 发布需求
</Button>
<Button
className={styles.btn2}
onClick={() => setOpenJoinModal(true)}
>
<Button className={styles.btn2} onClick={onJoin}>
加盟入驻
</Button>
</Space>
{user ? (
{userInfo ? (
<div className={styles.haedImg}>
<Dropdown
menu={{
items: [
{ key: "1", label: <div onClick={onLogout}>退出登录</div> },
],
}}
>
<Avatar
size={36}
style={{ background: "#bdbdbd" }}
src={user.userImg}
src={userInfo.userImg}
></Avatar>
</Dropdown>
</div>
) : (
<Button
type="text"
onClick={showModal}
onClick={() => testLogin()}
style={{ fontWeight: "bold", fontSize: 16 }}
>
登录
</Button>
)}
</div>
<LoginModal open={openLoginModal} onCancel={handleCancel}></LoginModal>
<LoginModal
open={openLoginModal}
onCancel={() => setOpenLoginModal(false)}
></LoginModal>
<PublishModal
open={openPublishModal}
onCancel={() => {
......
......@@ -24,12 +24,14 @@ const contentStyle: React.CSSProperties = {
};
const footerStyle: React.CSSProperties = {
width:"100%",
color: "",
backgroundColor: "",
lineHeight: "1",
padding: 0,
position: "relative",
marginTop: 60,
position: "fixed",
bottom:0,
// marginTop: 60,
};
type Props = {
......
import React, { useEffect, useState } from "react";
import { AutoComplete, Modal } from "antd";
import Image from "next/image";
import React, { useContext, useEffect, useState } from "react";
import { Modal, Image } from "antd";
import api from "~/api";
import { UserContext } from "~/lib/userProvider";
type Props = {
open: boolean;
......@@ -9,9 +9,13 @@ type Props = {
};
export default function LoginModal(props: Props) {
const [qrCode, setQrCode] = useState("");
const [randomLoginCode, setRandomLoginCode] = useState("");
const { userInfo, setUserInfo } = useContext(UserContext);
const [timeHandle, setTimeHandle] = useState<NodeJS.Timer | null>(null);
useEffect(() => {
if (props.open) {
var obj = new window.WxLogin({
/* if (props.open) {
new window.WxLogin({
self_redirect: true,
id: "login_container",
appid: "wx18b7883acd204278",
......@@ -21,11 +25,56 @@ export default function LoginModal(props: Props) {
style: "",
href: "",
});
} */
if (!props.open) {
return;
}
window.setUserId(1);
setRandomLoginCode(String(Date.now()));
api
.getAppletQRCode({
randomLoginCode,
})
.then((res) => {
if (res.code == "200") {
setQrCode("data:image/png;base64," + res.result || "");
}
});
}, [props.open]);
useEffect(() => {
if (randomLoginCode && !userInfo) {
if (timeHandle) {
clearTimeout(timeHandle);
}
const handle = setInterval(() => {
api
.getLoginInfo({
randomLoginCode: randomLoginCode,
})
.then((res) => {
if (res.code === "200") {
setUserInfo({
...res.result,
id: res.result?.userAccountId,
});
window.messageApi.success("登录成功");
clearInterval(handle);
setTimeHandle(null);
props.onCancel();
}
});
}, 1000);
setTimeHandle(handle);
}
}, [randomLoginCode]);
useEffect(() => {
if (!props.open && timeHandle) {
clearTimeout(timeHandle);
}
}, [timeHandle, props.open]);
return (
<>
<Modal
......@@ -47,13 +96,12 @@ export default function LoginModal(props: Props) {
>
欢迎来到云享飞
</div>
<div
id="login_container"
style={{ margin: "auto", display: "table" }}
></div>
<div id="login_container" style={{ margin: "auto", display: "table" }}>
<Image src={qrCode} width={150} height={150}></Image>
</div>
<div
style={{
marginTop: -120,
// marginTop: -120,
marginBottom: 52,
fontSize: 14,
fontFamily: "MicrosoftYaHei",
......
......@@ -14,10 +14,6 @@ export function useUser() {
useEffect(() => {
setUserAccountId(Number(window.localStorage.getItem('userId')));
window.setUserId = (id) => {
setUserAccountId(id);
window.localStorage.setItem('userId', id);
};
try {
let userInfo = JSON.parse(window.localStorage.getItem('userInfo') || '') || null;
......@@ -26,16 +22,25 @@ export function useUser() {
}, [])
useEffect(() => {
if (!user && userAccountId) {
if (!user) {
api
.userInfo({
userAccountId: userAccountId,
})
.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;
......
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>>;
}>({
testLogin() {},
logout() {},
userInfo: null,
setUserInfo() {},
});
type Props = {
children: React.ReactNode;
};
const UserProvider = ({ children }: Props) => {
const [userInfo, setUserInfo] = useState<UserInfoResp | null>(null);
useEffect(() => {
try {
setUserInfo(JSON.parse(window.localStorage.getItem("userInfo") || ""));
} catch (e) {}
}, []);
useEffect(() => {
localStorage.setItem("userInfo", JSON.stringify(userInfo || ""));
}, [userInfo]);
//测试登录
function testLogin() {
api.testAppletLogin().then((res) => {
if (res.code == "200") {
window.localStorage.setItem("token", res.result?.token || "");
api.userInfo().then((res) => {
setUserInfo(res.result || null);
});
}
});
}
//登出
function logout() {
localStorage.setItem("token", "");
setUserInfo(null);
}
return (
<UserContext.Provider value={{ userInfo, setUserInfo, testLogin, logout }}>
{children}
</UserContext.Provider>
);
};
export default UserProvider;
......@@ -27,6 +27,7 @@ const nextConfig = {
return [
{
source: "/local/:path*",
destination: "https://iuav.mmcuav.cn/:path*",
destination: "https://test.iuav.mmcuav.cn/:path*",
},
];
......
......@@ -45,7 +45,7 @@ export default function JoinPolicy() {
className={styles.font1}
style={{ textAlign: "center", paddingTop: 40, paddingBottom: 30 }}
>
加盟入驻政策
加盟入驻福利
</div>
<div
className={styles.font2}
......
......@@ -6,6 +6,7 @@ import { message } from 'antd';
import { useEffect } from 'react';
import Head from "next/head";
import Script from 'next/script';
import UserProvider, { UserContext } from "~/lib/userProvider";
export default function App({ Component, pageProps }: AppProps) {
const [messageApi, contextHolder] = message.useMessage();
......@@ -24,7 +25,9 @@ export default function App({ Component, pageProps }: AppProps) {
</Head>
<Script src="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></Script>
{contextHolder}
<UserProvider>
<Component {...pageProps} />
</UserProvider>
</>
);
}
......@@ -8,6 +8,7 @@ import Layout from "~/components/layout";
import api from "./api";
import styles from "./index.module.scss";
import gApi from '~/api';
import Router from "next/router";
const beforeUpload = (file: RcFile) => {
const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
......@@ -57,12 +58,14 @@ export default function Certification() {
.companyAuth({
...values,
licenseImg: imageUrl,
userAccountId: 1
})
.then((res) => {
console.log('提交结果', res);
if(res.result === '已通过'){
if(res.code === '200'){
window.messageApi.success(res.result);
setTimeout(() => {
Router.push('/');
}, 1000)
}
});
};
......
import React from "react";
import Layout from "~/components/layout";
import { Box } from "./styled";
import BrushQuestionZone from './components/brushQuestionZone'
import MockExam from './components/mockExam'
import { Tabs } from "antd";
import type { TabsProps } from "antd";
......@@ -12,19 +14,24 @@ export default function ExaminationDateil() {
const items: TabsProps["items"] = [
{
key: "1",
label: `Tab 1`,
children: `Content of Tab Pane 1`,
label: `刷题专区`,
children: <BrushQuestionZone />,
},
{
key: "2",
label: `Tab 2`,
children: `Content of Tab Pane 2`,
label: `模拟考试`,
children: <MockExam />,
},
];
return (
<Layout>
<Box>
<Tabs defaultActiveKey="1" items={items} onChange={onChange} />
<Tabs
defaultActiveKey="1"
items={items} onChange={onChange}
centered
size="large"
/>
</Box>
</Layout>
);
......
import React,{ useEffect ,useState} from 'react'
import {Box} from './styled'
import {Cascader,Select} from 'antd'
import api, { Flying, SkillsType, RegionResp } from "../../../api";
interface BrushQuestionZoneType {
}
export default function BrushQuestionZone() {
const [secondDistrictInfo, setSecondDistrictInfo] = useState(
Array<RegionResp>
);
const [skills, setSkills] = useState(Array<RegionResp>);
const [flightSkillsList, setFlightSkillsList] = useState(Array<SkillsType>);
const [list, setList] = useState<Array<BrushQuestionZoneType>>();
const handleChange = (value: string) => {
console.log(`selected ${value}`);
};
useEffect(() => {
setList([{}, {}, {}, {}, {}, {}]);
api.region().then((res) => {
setSecondDistrictInfo(res.result || []);
});
api.PilotLicense().then((res) => {
setSkills(res.result || []);
});
api.IndustryFlightSkills().then((res) => {
const list = res.result?.map((item) => {
item.label = item.skillsName;
item.value = item.id;
return item;
});
setFlightSkillsList(list || []);
});
}, []);
return (
<Box>
<div className="title">
<Cascader
allowClear
placeholder="地域"
className="selectItem"
size="large"
fieldNames={{
label: "name",
value: "id",
children: "childInfo",
}}
options={secondDistrictInfo}
// onChange={onChange}
changeOnSelect
/>
<Cascader
allowClear
placeholder="考证"
className="selectItem"
size="large"
fieldNames={{
label: "licenseType",
value: "id",
children: "childLicenses",
}}
options={skills}
// onChange={onChange}
changeOnSelect
/>
<Select
className="selectItem"
popupMatchSelectWidth={false}
placeholder="技能"
size="large"
// onChange={(value) => onProvinceChange(value, "技能")}
options={flightSkillsList}
fieldNames={{ value: "id", label: "skillsName" }}
allowClear
/>
<Cascader
allowClear
placeholder="选择课程"
className="selectItem"
style={{ width: 200 }}
size="large"
fieldNames={{
label: "name",
value: "id",
children: "childInfo",
}}
options={secondDistrictInfo}
// onChange={onChange}
changeOnSelect
/>
</div>
<div className="content">
{list?.map((item, i) => (
<div key={i} className="item">
<div className="img-box"></div>
<div className="item-content">
第一章 第1节 习题练习习题练习习题练习
</div>
</div>
))}
</div>
</Box>
);
}
import styled from "styled-components";
export default function Style() {
return <></>;
}
export const Box = styled.div`
box-sizing: border-box;
width: 1200px;
height: 859px;
background: #FFFFFF;
border-radius: 6px;
padding: 32px 26px 32px 24px;
.title{
display: flex;
align-items: center;
height: 60px;
.selectItem {
width: 120px;
height: 60px;
background-color: #fff;
border-radius: 5px;
color: red;
margin-right: 8px;
.ant-select-selection-placeholder {
color: #000;
line-height: 60px;
text-align: center;
}
.ant-select-selection-item{
line-height: 60px;
text-align: center;
}
.ant-select-selector{
height: 60px;
}
}
}
.content{
display: flex;
flex-wrap: wrap;
margin-top: 32px;
.item {
display: flex;
width: 360px;
height: 100px;
background: #FFFFFF;
border: 1px solid #F0F0F0;
margin: 0 16px 20px 0;
&:nth-child(3n){
margin-right: 0;
}
.img-box{
width: 120px;
height: 100px;
background: #E6E6E6;
}
.item-content{
display: flex;
align-items: center;
flex: 1;
padding: 12px 14px 11px 16px;
}
}
}
`
\ No newline at end of file
import React , {useEffect,useState} from 'react'
import {Box} from './styled'
interface MockExamType {
}
export default function MockExam() {
const [list, setList] = useState<Array<MockExamType>>();
useEffect(() => {
setList([{}, {}, {}, {}, {}, {}]);
}, []);
return (
<Box>
<div className="content">
{list?.map((item, i) => (
<div key={i} className="item">
<div className="img-box"></div>
<div className="item-content">
<div className="top">云飞手行业认证考核</div>
<div className="bottom">
<div className="user-img"></div>
<div className="application">77人报名</div>
</div>
</div>
</div>
))}
</div>
</Box>
);
}
import styled from "styled-components";
export default function Style() {
return <></>;
}
export const Box = styled.div`
box-sizing: border-box;
padding: 46px 64px 46px 24px;
background-color: #fff;
min-height: 845px;
border-radius: 6px;
.content{
display: flex;
flex-wrap: wrap;
.item {
display: flex;
width: 360px;
height: 100px;
background: #FFFFFF;
border: 1px solid #F0F0F0;
margin: 0 16px 20px 0;
&:nth-child(3n){
margin-right: 0;
}
.img-box{
width: 120px;
height: 100px;
background: #E6E6E6;
}
.item-content{
display: flex;
flex-direction: column;
justify-content: space-between;
flex: 1;
padding: 12px 14px 11px 16px;
.top{
width: 200px;
height: 20px;
font-size: 16px;
font-family: MicrosoftYaHei;
color: #34383F;
line-height: 20px;
letter-spacing: 1px;
-webkit-background-clip: text;
}
.bottom{
display: flex;
align-items: center;
.user-img{
width: 20px;
height: 20px;
border-radius: 50%;
background-color: pink;
}
.application{
margin-left: 6px;
height: 16px;
font-size: 11px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FE6000;
line-height: 16px;
}
}
}
}
}
`;
......@@ -160,6 +160,17 @@ export default function FlyingHandService() {
});
};
const onChangeRegion = (value: any) => {
setFilterParams((props) => {
return {
...props,
regionId: (value && value[value.length - 1]) || undefined,
};
});
};
useEffect(() => {
setRightDomList(
list.map((item: string) => {
......@@ -258,7 +269,7 @@ export default function FlyingHandService() {
children: "childInfo",
}}
options={secondDistrictInfo}
onChange={onChange}
onChange={onChangeRegion}
changeOnSelect
/>
<Cascader
......@@ -350,7 +361,6 @@ export default function FlyingHandService() {
allowClear
placeholder="城市"
className="selectItem"
size="large"
fieldNames={{
label: "name",
value: "id",
......@@ -376,7 +386,6 @@ export default function FlyingHandService() {
allowClear
placeholder="是否有无人机执照"
className="selectItem"
size="large"
fieldNames={{
label: "licenseType",
value: "id",
......
......@@ -3,6 +3,7 @@ import { message } from 'antd';
import { Box } from "./styled";
import api from "./api";
import icon from './assets/img.png'
import {useRouter} from 'next/router'
let MAP :any ;
let Amap:any;
......@@ -14,6 +15,7 @@ interface UserInfoType {
}
export default function MapComponent() {
const router = useRouter()
const [mapItem, setMapItem] = useState(0);
const [userPositioning, setUserPositioning] = useState<UserInfoType>();
const [markerCol, setMarkerCol] = useState<any>([]);
......@@ -44,7 +46,6 @@ export default function MapComponent() {
position:'RB', //定位按钮的停靠位置
offset: [10, 20], //定位按钮与设置的停靠位置的偏移量,默认:[10, 20]
zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
});
MAP.addControl(geolocation);
geolocation.getCurrentPosition(function(status:string,result:any){
......@@ -132,7 +133,7 @@ export default function MapComponent() {
}
//添加点位
const mapEntiy = async (index: number,data?:UserInfoType) => {
MAP.remove(markerCol);
MAP?.remove(markerCol);
if (index === 0) {
showPositioningInfo(index,data)
......@@ -141,7 +142,7 @@ export default function MapComponent() {
} else if(index === 2) {
showUavBitmap(index,data)
}else{
showFlyerBitmap(index,data,30)
router.push('/home/waterfallFlowBody/components/map/moreServicePoints')
}
setMapItem(index);
};
......
import React,{useState,useEffect} from 'react'
import Layout from "~/components/layout";
import {Box} from './styled'
import api from "../api";
import icon from '../assets/img.png'
import { message } from 'antd';
let MAP :any ;
let Amap:any;
interface UserInfoType {
lat: number;
lon: number;
pageNo?:number,
pageSize?:number
}
export default function MoreServicePoints() {
const [mapItem, setMapItem] = useState(0);
const [userPositioning, setUserPositioning] = useState<UserInfoType>();
const [markerCol, setMarkerCol] = useState<any>([]);
const [servicePoints, setServicePoints] = useState<any>([]);
//初始化地图
const init = async () => {
try {
const AMapLoader = await import(
/* webpackChunkName: "amap" */ "@amap/amap-jsapi-loader"
);
await AMapLoader.load({
key: "87b424e68754efc3ba9d11ae07475091", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [""], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then(async (AMap) => {
Amap = AMap;
MAP = new AMap.Map("container", {
// 设置地图容器id
viewMode: "3D", // 是否为3D地图模式
zoom: 9, // 初始化地图级别
center: [113.93029, 22.53291], // 初始化地图中心点位置
});
//用户定位
AMap.plugin("AMap.Geolocation", function () {
const geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //是否使用高精度定位,默认:true
timeout: 10000, //超过10秒后停止定位,默认:5s
position: "RB", //定位按钮的停靠位置
offset: [10, 20], //定位按钮与设置的停靠位置的偏移量,默认:[10, 20]
zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
});
MAP.addControl(geolocation);
geolocation.getCurrentPosition(function (
status: string,
result: any
) {
console.log(result);
if (status == "complete") {
onComplete(result);
} else {
onError(result);
}
});
});
//解析定位结果
async function onComplete(data: any) {
console.log("定位成功");
setUserPositioning(data.position);
// return await mapEntiy(0,data.position);
}
//解析定位错误信息
async function onError(data: any) {
// message.error(`定位失败
// 失败原因排查信息:${data.message}
// 浏览器返回信息:${data.originMessage}
// `)
}
await mapEntiy(0);
})
.catch((e) => {
console.log(e);
});
} catch (error) {
console.log(error);
}
};
const showPositioningInfo = async (index: number, data?: UserInfoType) => {
const res = await api.listPositioningInfo({
lon: userPositioning?.lon || data?.lon || 113.93029,
lat: userPositioning?.lat || data?.lat || 22.53291,
});
const list = res.result
?.map((item) => item.locationList)
.flat()
.filter((item: { dizhi: string }) => item.dizhi.includes("省"));
const markerList: any = [];
if (list?.length) {
list?.map((item) => {
const EntiyValue = addEntiy(item.jd, item.wd, item.dizhi);
markerList.push(EntiyValue);
});
setServicePoints(list);
if (markerList.length) MAP?.add(markerList);
setMarkerCol([...markerList]);
}
};
const showFlyerBitmap = async (
index: number,
data?: UserInfoType,
pageSize?: number
) => {
const res = await api.listFlyerBitmap({
lon: userPositioning?.lon || data?.lon || 113.93029,
lat: userPositioning?.lat || data?.lat || 22.53291,
pageNo: 1,
pageSize: pageSize || 40,
});
const list = res.result?.list;
const markerList: any = [];
if (list?.length) {
list?.map((item) => {
const EntiyValue = addEntiy(item.lon, item.lat, item.flyerName);
markerList.push(EntiyValue);
});
setServicePoints(list);
if (markerList.length) MAP?.add(markerList);
setMarkerCol(markerList);
}
};
const showUavBitmap = async (index: number, data?: UserInfoType) => {
console.log(MAP.panTo);
const res = await api.listUavBitmap({
lon: userPositioning?.lon || data?.lon || 113.93029,
lat: userPositioning?.lat || data?.lat || 22.53291,
pageNo: 1,
pageSize: 40,
});
const list = res.result?.list;
const markerList: any = [];
if (list?.length) {
list?.map((item) => {
const EntiyValue = addEntiy(item.lon, item.lat, item.uavName);
markerList.push(EntiyValue);
});
setServicePoints(list);
if (markerList.length) MAP?.add(markerList);
setMarkerCol(markerList);
}
};
//添加点位
const mapEntiy = async (index: number, data?: UserInfoType) => {
MAP?.remove(markerCol);
if (userPositioning) {
MAP?.setCenter([userPositioning.lon, userPositioning.lat]);
}
if (index === 0) {
showPositioningInfo(index, data);
} else if (index === 1) {
showFlyerBitmap(index, data, 30);
} else if (index === 2) {
showUavBitmap(index, data);
} else {
showFlyerBitmap(index, data, 30);
}
setMapItem(index);
};
const addEntiy = (lon: any, lat: any, name: string) => {
if (!Amap) return;
const icons = new Amap.Icon({
size: new Amap.Size(60, 60), // 图标尺寸
image: icon.src, // Icon的图像
imageSize: new Amap.Size(60, 60), // 根据所设置的大小拉伸或压缩图片
});
const marker = new Amap.Marker({
position: new Amap.LngLat(lon, lat),
offset: new Amap.Pixel(-10, -10),
icon: icons, // 添加 Icon 实例
title: name,
zoom: 13,
});
return marker;
};
const moveTo = (item: any) => {
console.log(markerCol);
if (item.dizhi) {
return MAP?.setCenter([item.jd, item.wd]);
} else if (item.flyerName || item.uavName) {
return MAP?.setCenter([item.lon, item.lat]);
}
return message.warning("暂无位置信息");
};
useEffect(() => {
(async () => {
await init();
})();
return MAP && MAP.destroy();
}, []);
return (
<Layout>
<Box>
<div className="title">
<div
onClick={() => mapEntiy(0)}
className={`item ${mapItem === 0 ? "active" : ""}`}
>
服务网点
</div>
<div
onClick={() => mapEntiy(1)}
className={`item ${mapItem === 1 ? "active" : ""}`}
>
租赁网点
</div>
<div
onClick={() => mapEntiy(2)}
className={`item ${mapItem === 2 ? "active" : ""}`}
>
培训网点
</div>
<div
onClick={() => mapEntiy(3)}
className={`item ${mapItem === 3 ? "active" : ""}`}
>
机构网点
</div>
</div>
<div className="content">
<div className="left">
<div className="left-title">服务网点</div>
<div className="left-content">
{servicePoints.map((item: any) => (
<div
key={item.id}
onClick={() => moveTo(item)}
className="left-content-item"
title={item.dizhi || item.flyerName || item.uavName}
>
{item.dizhi || item.flyerName || item.uavName}
</div>
))}
</div>
</div>
<div className="right">
<div id="container"></div>
</div>
</div>
</Box>
</Layout>
);
}
import styled from "styled-components";
export default function Style() {
return <></>;
}
export const Box = styled.div`
box-sizing: border-box;
.title{
display: flex;
align-items: center;
padding-left: 41px;
height: 42px;
background: #3D3D3D;
margin-top: 20px;
.item{
width: 64px;
height: 20px;
font-size: 16px;
font-family: MicrosoftYaHeiUI-Bold, MicrosoftYaHeiUI;
font-weight: bold;
color: #FFFFFF;
line-height: 20px;
cursor: pointer;
margin-right: 85px;
&.active{
color: #FC7237;
}
}
}
.content{
display: flex;
height: 800px;
background-color: #fff;
.left{
width: 270px;
padding: 23px 0 23px 21px;
&-title{
width: 56px;
height: 18px;
font-size: 14px;
font-family: MicrosoftYaHeiUI-Bold, MicrosoftYaHeiUI;
font-weight: bold;
color: #3D3D3D;
line-height: 18px;
}
&-content{
height: 731px;
overflow-y: auto;
margin-top: 9px;
&-item{
width: 182px;
height: 19px;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #666666;
line-height: 19px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
&:hover{
color: #FC7237;
}
}
}
}
.right{
flex: 1;
}
}
#container {
position: relative;
padding: 0px;
margin: 0px;
width: 100%;
height: 100%;
}
.amap-logo {
//去除高德地图水印
display: none !important;
visibility: hidden !important;
}
.amap-copyright {
//去除高德地图水印
display: none !important;
visibility: hidden !important;
}
`
\ No newline at end of file
......@@ -254,15 +254,11 @@ export default function WaterfallFlowBody() {
}, []);
const routerPath = (index: number, item?: AllType) => {
if (item) {
if (index === 0 || index === 1 || index === 3 || index === 4 ) {
router.push({
pathname: columns[index].router,
query: { [item?.type!]: item?.id! },
});
} else {
router.push({
pathname: columns[index].router,
});
}
};
......
......@@ -14,6 +14,7 @@ export default function JobServicesDetail() {
const [id, setId] = useState<number | null>(null);
const [detail,setDetail] = useState<ListPageJobInfoResp | null>()
const [sale,setSale] = useState<string | null>()
const onChange = (key: string) => {
console.log(key);
};
......@@ -43,9 +44,11 @@ export default function JobServicesDetail() {
setDetail(res.result || null);
});
}
console.log(id);
}, [id]);
useEffect(()=>{
setSale((Math.floor(Math.random() * 901) + 100).toFixed(0))
},[])
return (
<Layout>
<Box>
......@@ -65,6 +68,7 @@ export default function JobServicesDetail() {
<div className='more'>
<div className='tab filst'>测绘场景榜第1名</div>
<div className='tab'>7x24小时服务</div>
<div className='tab'>{`月售${sale}`}</div>
</div>
</div>
<div className='right-bottom'>
......
......@@ -96,8 +96,9 @@ export default function News(props: Props) {
);
})}
</Col>
{list.length === 0 && <Empty style={{ margin: "0 auto" }}></Empty>}
</Row>
{list.length === 0 && <Empty></Empty>}
<Pagination
current={pageParams.pageNo}
defaultPageSize={pageParams.pageSize}
......
......@@ -4,7 +4,6 @@ declare global {
interface Window {
messageApi: MessageInstance; //全局消息提示api
WxLogin: any; //微信登录对象
setUserId: (number) => void; //获取用户信息需要的userId
_AMapSecurityConfig: { securityJsCode: string }; //高德地图api密钥配置
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论