Commit ec87ef93 authored by wuhao's avatar wuhao 🎯

asder

parent 31f3612d
......@@ -19,6 +19,8 @@
"antd-img-crop": "^4.5.2",
"antd-mobile": "^5.1.4",
"crypto-js": "^4.1.1",
"echarts": "^5.4.1",
"echarts-for-react": "^3.0.2",
"umi-request": "^1.4.0"
},
"devDependencies": {
......
......@@ -16,6 +16,10 @@ import { theme } from 'antd';
export const antd = (memo) => {
memo.theme ||= {};
memo.theme.algorithm = theme.darkAlgorithm;
memo.theme.token = {
colorPrimary: '#3878e4',
}
return memo;
};
......
......@@ -96,7 +96,7 @@ export default (props) => {
<div className={styles.header}>
<div className="center">
<div className={styles.left}>
<div
{/* <div
className="center"
style={{ width: 30, height: 30, marginRight: 8 }}
onClick={() => {
......@@ -104,7 +104,7 @@ export default (props) => {
}}
>
<FilterFilled />
</div>
</div> */}
<SearchBar
style={{ flex: 1 }}
......@@ -141,11 +141,13 @@ export default (props) => {
await reFresh();
}}
>
<Empty
style={{ padding: '64px 0' }}
imageStyle={{ width: '30vw' }}
description="暂无数据"
/>
<div style={{ minHeight: 'calc(100vh - 172px)' }}>
<Empty
style={{ padding: '64px 0' }}
imageStyle={{ width: '30vw' }}
description="暂无数据"
/>
</div>
</PullToRefresh>
)}
</>
......
/* stylelint-disable rule-empty-line-before */
.header {
background-color: rgb(18 19 33 / 50%);
display: flex;
align-items: center;
position: sticky;
......
......@@ -29,19 +29,60 @@ body,
}
}
a {
color: #4ddaec;
color: #3878e4;
}
:root:root {
--adm-color-primary: #4ddaec;
--adm-color-background: #0d0e1f;
--adm-color-primary: #3878e4;
--adm-color-background: #0d2152;
}
.adm-list-item{
background-color: transparent;
a:hover{
color: #fff !important;
}
}
.adm-list-item-content {
border: none !important;
}
.adm-search-bar-input-box {
background-color: #0d2152 !important;
input {
color: #f0f0f0;
}
}
.adm-list {
background-color: transparent !important;
}
.adm-list-body {
border-top: 1px solid #2c2d4a;
border-bottom: 1px solid #2c2d4a;
border-top: none !important;
border-bottom: none !important;
border-radius: 0;
background-color: transparent !important;
}
.ant-input-affix-wrapper,
.ant-checkbox-inner {
background-color: #0d2152 !important ;
input {
background-color: transparent !important;
}
}
.split{
padding: 6px 0;
margin: 0px 12px;
border-top: 1px dashed #f0f0f01d;
border-bottom: 1px dashed #f0f0f01a;
}
.ant-drawer-content{
background: linear-gradient(to bottom, #142f4d, #657b90) !important;
}
*:focus {
outline: none;
}
.spread{
display: flex;
justify-content: space-between;
align-items: center;
}
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { Outlet, history, useLocation, useAppData } from '@umijs/max';
import { NavBar, TabBar } from 'antd-mobile';
import { NavBar, TabBar, List } from 'antd-mobile';
import {
AppOutline,
MessageOutline,
UnorderedListOutline,
UserOutline,
PayCircleOutline,
SetOutline,
} from 'antd-mobile-icons';
import './index.less';
import { useMemo } from 'react';
import { MenuOutlined, ArrowLeftOutlined } from '@ant-design/icons';
import { Drawer } from 'antd';
import {
MenuOutlined,
ArrowLeftOutlined,
EditOutlined,
UsergroupAddOutlined,
HomeOutlined,
LogoutOutlined,
LockOutlined
} from '@ant-design/icons';
import { Drawer, Avatar, Button, Divider } from 'antd';
import { UserOutlined } from '@ant-design/icons';
/*
menulist 中的表示主路由菜单上左上角是打开 drawer 否则为返回上一页
......@@ -60,6 +70,30 @@ function BasicLayout() {
const [drawer, setdrawer] = useState({ open: false });
const [startX, setStartX] = useState(null);
const [startY, setStartY] = useState(null);
function handleTouchStart(event) {
setStartX(event.touches[0].clientX);
setStartY(event.touches[0].clientY);
}
function handleTouchMove(event) {
const { clientX, clientY } = event.touches[0];
const distance = clientX - startX;
const distancey = clientY - startY;
if (distancey > 10 || distancey < -10) {
return;
}
if (distance > 20) {
// 执行左滑操作
setdrawer((s) => ({
...s,
open: true,
}));
}
}
return (
<div className="container">
<Drawer
......@@ -73,7 +107,32 @@ function BasicLayout() {
{...drawer}
width={'80%'}
placement="left"
></Drawer>
>
<div className="userinfo" style={{position:"relative",height:"100%"}}>
<Avatar size={56} icon={<UserOutlined />}></Avatar>
<div className="spread" style={{ alignItems: 'flex-end',paddingBottom:8 }}>
<div>
<h2>UserName</h2>
<p style={{ margin: 0 }}>13512555441</p>
</div>
<Button
style={{ color: '#fff', borderColor: '#fff' }}
ghost
type="primary"
icon={<EditOutlined />}
></Button>
</div>
<Divider></Divider>
<List header="个人信息" style={{marginLeft:-12}}>
<List.Item prefix={<UserOutline />} extra="李翰林">用户名</List.Item>
<List.Item prefix={<UsergroupAddOutlined />} extra="维修部">组织</List.Item>
<List.Item prefix={<HomeOutlined style={{fontSize:14,paddingLeft:3}}/>} extra="天华院">公司</List.Item>
<List.Item prefix={<LockOutlined/>} onClick={()=>{}} style={{backgroundColor:"rgba(0,0,0,0.2)",borderRadius:8}}>修改密码</List.Item>
</List>
<Button icon={<LogoutOutlined/>} size='large' style={{width:"100%",marginTop:12,position:"absolute",bottom:0,left:0,right:0,backgroundColor:"rgba(0,0,0,0.2)"}} type="ghost">退出</Button>
</div>
</Drawer>
<div className="top">
<NavBar
backArrow={
......@@ -98,8 +157,10 @@ function BasicLayout() {
</NavBar>
</div>
<div style={{ height: 45 }}></div>
<div onTouchStart={handleTouchStart} onTouchMove={handleTouchMove}>
<Outlet></Outlet>
</div>
<Outlet></Outlet>
<div style={{ height: 66 }}></div>
<div className="bottom">
<TabBar
......
.container {
background-color: #0e0e1f;
background: linear-gradient(to bottom, #142f4d, #657b90) !important;
min-height: 100vh;
div {
color: #fff;
}
......@@ -12,7 +12,7 @@
z-index: 999;
left: 0;
width: 100%;
background-color: rgb(18 19 33 / 50%);
background-color: rgb(18 19 33 / 0%);
right: 0;
margin: auto;
backdrop-filter: blur(2px);
......@@ -23,8 +23,8 @@
bottom: 0;
z-index: 999;
left: 0;
width: 96%;
background-color: #121321;
width: 100%;
background: linear-gradient(to bottom, #324d6b, #395471) !important;
right: 0;
margin: auto;
height: 66px;
......@@ -32,8 +32,13 @@
justify-content: center;
align-items: center;
border-radius: 12px 12px 0 0;
box-shadow: 0px -2px 16px rgba(0, 0, 0, 0.8);
> div {
width: 100%;
}
}
.userinfo{
color: #fff;
}
\ No newline at end of file
......@@ -4,39 +4,101 @@ import DrawerPro from '@/components/DrawerPro';
import AutoTable from '@/components/AutoTable';
import PremButton from '@/components/PremButton';
import getcolumns from './columns';
import { useRequest } from 'ahooks';
import { useAsyncEffect, useRequest } from 'ahooks';
import { doFetch } from '@/utils/doFetch';
import { List } from 'antd-mobile';
const Extra = ({ it, item }) => {
return (
<div>{it?.render?.(item[it?.dataIndex], item) ?? item[it?.dataIndex]}</div>
);
};
import ReactECharts from 'echarts-for-react';
function cropImage(url) {
return new Promise(resolve => {
const img = new Image();
img.crossOrigin = 'Anonymous';
img.src = url;
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const size = Math.min(img.width, img.height);
canvas.width = size;
canvas.height = size;
ctx.beginPath();
ctx.arc(size / 2, size / 2, size / 2, 0, 2 * Math.PI);
ctx.clip();
ctx.drawImage(img, (img.width - size) / 2, (img.height - size) / 2, size, size, 0, 0, size, size);
canvas.toBlob(blob => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
resolve(reader.result);
};
}, 'image/png');
};
});
}
const Cards = ({ item, columns }) => {
const [option, setoption] = useState({});
useAsyncEffect(async ()=>{
const image = await cropImage("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fci.xiaohongshu.com%2F5fa1e703-a04f-b373-0e3f-f0afd5e12a9d%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fci.xiaohongshu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1679472844&t=e0db0d99ce81259343ab29af461e7722")
const options = {
series: [
{
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
data: [
{ value: 335, name: '直接访问' },
{ value: 310, name: '邮件营销' },
{ value: 234, name: '联盟广告' },
{ value: 135, name: '视频广告' },
{ value: 1548, name: '搜索引擎' },
],
},
],
graphic: {
elements: [
{
type: 'image',
style: {
image: image,
width: 56,
height: 56,
},
left:"center",
top:"center"
},
],
},
};
setoption(options)
},[item])
return (
<List
mode="card"
key={item.dataIndex}
onClick={() => {
alert(0);
}}
>
{columns
?.filter((it) => !(it.valueType === 'split' || it?.hideInTable))
?.map((it) => {
return (
<List.Item
key={it?.dataIndex}
extra={<Extra it={it} item={item} />}
arrow={false}
>
{it?.title}
</List.Item>
);
})}
</List>
<div className="split">
<div className="spread" style={{justifyContent:"flex-start"}}>
<div style={{width:120,height:120,flexShrink:0}}>
<ReactECharts option={option} style={{height:"100%"}}/>
</div>
<div style={{flex:1}}>
{columns
?.filter((it) => !(it.valueType === 'split' || it?.hideInTable))
?.map((it) => {
return (
<div key={it?.dataIndex} arrow={false} style={{fontSize:15}}>
{it?.title}
{item[it?.dataIndex]}
</div>
);
})}
</div>
</div>
</div>
);
};
......@@ -61,91 +123,11 @@ function Home(props) {
},
});
const detail = (text, row, _, action) => {
return (
<PremButton
btn={{
size: 'small',
type: 'link',
onClick: () => {
setdrawer((s) => ({
...s,
open: true,
item: row,
title: '详情',
val: 'detail',
title: '详细信息',
}));
},
}}
>
详情
</PremButton>
);
};
const edit = (text, row, _, action) => {
return (
<PremButton
btn={{
size: 'small',
onClick: () => {
setdrawer((s) => ({
...s,
open: true,
item: row,
title: '编辑',
val: 'edit',
}));
},
}}
>
编辑
</PremButton>
);
};
const remove = (text, row, _, action) => {
return (
<PremButton
pop={{
title: '是否删除?',
okText: '确认',
cancelText: '取消',
onConfirm: () => {
run({
url: pathconfig?.delete || '/delete',
params: { id: row?.id },
});
},
}}
btn={{
size: 'small',
type: 'danger',
}}
>
删除
</PremButton>
);
};
const columns = useMemo(() => {
let defcolumn = getcolumns(setdrawer).filter(
(it) => it.key === activeTabKey,
)[0]?.columns;
let defpath =
getcolumns(setdrawer).filter((it) => it.key === activeTabKey)[0]
?.pathconfig ?? {};
return defcolumn.concat({
title: '操作',
valueType: 'option',
width: 150,
render: (text, row, _, action) => [
defpath?.enabledetail && detail(text, row, _, action),
defpath?.enableedit && edit(text, row, _, action),
defpath?.enabledelete && remove(text, row, _, action),
],
});
return defcolumn;
}, [activeTabKey]);
const pathconfig = useMemo(() => {
......
......@@ -177,7 +177,7 @@
height: 116px;
object-fit: cover;
}
h2{
color: #fff
h2 {
color: #fff;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment