首页结构调整

This commit is contained in:
xixi 2024-04-29 17:22:26 +08:00
parent 2b0b71a06f
commit 74b06a84fa
36 changed files with 1008 additions and 295 deletions

View File

@ -1,16 +1,20 @@
import './balance-head.css'
import {useContext} from "react";
import {GlobalContext} from "../../context/GlobalContext.ts";
import moneyImg from '../../static/head/money.png'
export default function BalanceHead() {
const globalContext = useContext(GlobalContext);
return (
<div className="head-item balance-head">
<span className="label"></span>
<span className="balance" onClick={() => {
return (
<div className="head-item balance-head">
<div className="label">
<img src={moneyImg} alt="" />
<div></div>
</div>
<div className="balance" onClick={() => {
console.log('查看余额')
}}>{globalContext.user.balance}</span>
}}>{globalContext.user.balance}</div>
</div>
)
}

View File

@ -1,10 +1,20 @@
.balance-head {
/* background-color: #edf063; */
}
.balance-head .label {
font-size: 14px;
display: flex;
}
.balance-head .label img{
width: 17px;
height: 19px;
margin-right: 5px;
}
.balance-head .balance {
font-size: 20px;
font-size: 18px;
color: #f78e4c;
margin-top: 8px;
}

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import './card-proj.css';
import {
CheckOutlined,
@ -12,13 +13,16 @@ import {
SettingOutlined,
WarningOutlined
} from '@ant-design/icons';
import {Button, ConfigProvider, Dropdown, Tag} from 'antd';
import {GenerateStatus, IProj, PayStatus, ProjChargeType} from "../../interfaces/proj/IProj.ts";
import {useNavigate} from "react-router-dom";
import {Axios, put} from "../../util/AjaxUtils.ts";
import {useContext, useEffect, useState} from "react";
import {IndexListContext} from "../../context/IndexListContext.ts";
import { Button, ConfigProvider, Dropdown, Tag } from 'antd';
import { GenerateStatus, IProj, PayStatus, ProjChargeType } from "../../interfaces/proj/IProj.ts";
import { useNavigate } from "react-router-dom";
import { Axios, put } from "../../util/AjaxUtils.ts";
import { useContext, useEffect, useState } from "react";
import { IndexListContext } from "../../context/IndexListContext.ts";
import useMessage from "antd/es/message/useMessage";
import setImg from '../../static/right/set.png'
import orderImg from '../../static/right/order.png'
import menuImg from '../../static/right/menu.png'
export default function CardProj(props: { item: IProj }) {
const nav = useNavigate();
@ -35,21 +39,21 @@ export default function CardProj(props: { item: IProj }) {
*/
const renderGenerateStatus = () => {
if (data.generate.generateStatus == GenerateStatus.PENDING) {
return <Tag color="cyan"><ClockCircleOutlined/> </Tag>
return <Tag color="cyan"><ClockCircleOutlined /> </Tag>
}
if (data.generate.generateStatus == GenerateStatus.GENERATING) {
return <Tag color="magenta"><LoadingOutlined/> </Tag>
return <Tag color="magenta"><LoadingOutlined /> </Tag>
}
if (data.generate.generateStatus == GenerateStatus.SUCCESS) {
return <Tag color="green"><CheckOutlined/> </Tag>
return <Tag color="green"><CheckOutlined /> </Tag>
}
if (data.generate.generateStatus == GenerateStatus.FAILED) {
return <Tag color="red"><WarningOutlined/> </Tag>
return <Tag color="red"><WarningOutlined /> </Tag>
}
if (data.generate.generateStatus == GenerateStatus.NONE) {
return <Tag color="cyan"></Tag>
}
return <Tag color="red"><CloseCircleOutlined/> </Tag>
return <Tag color="red"><CloseCircleOutlined /> </Tag>
}
const renderOption = () => {
@ -57,7 +61,7 @@ export default function CardProj(props: { item: IProj }) {
return (
<>
<div className="option">
<Button size="small" type="text"><CreditCardOutlined/> </Button>
<Button size="small" type="text"><CreditCardOutlined /> </Button>
</div>
</>
)
@ -71,14 +75,14 @@ export default function CardProj(props: { item: IProj }) {
} else {
nav(`/proj-edit/config-loginpage/${data.projId}`)
}
}}><SettingOutlined/> </Button>
}}><SettingOutlined /> </Button>
<Button size="small" type="text" onClick={() => {
if (data.generate.generateStatus == GenerateStatus.SUCCESS) {
nav(`/proj-edit/config-mod-list-show/${data.projId}`)
} else {
nav(`/proj-edit/config-mod-list/${data.projId}`)
}
}}><SettingOutlined/> ({data.projModCount})</Button>
}}><SettingOutlined /> ({data.projModCount})</Button>
<Button size="small" type="text" onClick={() => {
if (data.generate.generateStatus == GenerateStatus.SUCCESS) {
nav(`/proj-edit/config-menu-list-show/${data.projId}`)
@ -86,23 +90,23 @@ export default function CardProj(props: { item: IProj }) {
nav(`/proj-edit/config-menu-list/${data.projId}`)
}
}}><SettingOutlined/> ({data.projModCount})</Button>
}}><SettingOutlined /> ({data.projModCount})</Button>
</div>
{
data.generate.generateStatus == GenerateStatus.SUCCESS ? (
<div className="option">
<Button size="small" type="text" onClick={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/apply/${data.projId}`)
}}><DownloadOutlined/> </Button>
}}><DownloadOutlined /> </Button>
<Button size="small" type="text" onClick={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/manual/${data.projId}`)
}}><DownloadOutlined/> </Button>
}}><DownloadOutlined /> </Button>
<Button size="small" type="text" onClick={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/code-zip/${data.projId}`)
}}><DownloadOutlined/> </Button>
}}><DownloadOutlined /> </Button>
<Button size="small" type="text" onClick={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/code/${data.projId}`)
}}><DownloadOutlined/> </Button>
}}><DownloadOutlined /> </Button>
</div>
) : <></>
}
@ -111,9 +115,9 @@ export default function CardProj(props: { item: IProj }) {
}
const goEdit = () => {
if(charge == ProjChargeType.ALL) {
if (charge == ProjChargeType.ALL) {
nav(`/proj-eall/${data.projId}`);
} else if(charge == ProjChargeType.FREE) {
} else if (charge == ProjChargeType.FREE) {
nav(`/proj-efree/${data.projId}`);
} else {
nav(`/proj-edit/${data.projId}`);
@ -142,23 +146,107 @@ export default function CardProj(props: { item: IProj }) {
<>
<div className="card-proj">
<div className="title">
<div className="left">
<span className="text-btn" onClick={goEdit}>{data.projName}</span>
<div className='titleLift'>
<div className="left">
<div className='boxline'></div>
<span className="text-btn" onClick={goEdit}>{data.projName}</span>
</div>
<div className="right">
<span className="context">{data.projContext}</span>
<span className='line'></span>
<span className="date">{data.gmtCreate}</span>
{/* 状态标签 */}
{/* <span className="status">{renderGenerateStatus()}</span> */}
</div>
</div>
<div className="right">
<span className="context">{data.projContext}</span>
<span className="date">{data.gmtCreate}</span>
<span className="status">{renderGenerateStatus()}</span>
<div className="titleRight">
{
data.generate.generateStatus == GenerateStatus.SUCCESS ? (
<span>
<SearchOutlined />
<span className="text-btn" onClick={goEdit}></span>
</span>
) : (
<span>
<EditOutlined />
<span className="text-btn" onClick={goEdit}></span>
</span>
)
}
<span className='orignLine'>|</span>
<span>
<EyeOutlined />
<span className="text-btn" onClick={() => {
window.open(`${Axios.defaults?.baseURL}/${data.previewUrl}`, '_blank')
}}></span>
</span>
</div>
</div>
<hr/>
{/* <hr/> */}
<div className="body">
<div className="line">
<div className="left">
<Tag color="magenta">{payCharge}</Tag>
<Tag color="gold">{data.pay.payment / 100}</Tag>
{/* <Tag color="magenta">{payCharge}</Tag> */}
{/* 金额 */}
{/* <Tag color="gold">¥{data.pay.payment / 100}</Tag> */}
</div>
<div className="right">
<div className='centerl'>
<div className='c-top'>
<span className='money'>() : </span>
<span className='num'>{data.pay.payment / 100}</span>
</div>
<div className='c-bot'>
<div className='set' onClick={() => {
if (data.generate.generateStatus == GenerateStatus.SUCCESS) {
nav(`/proj-edit/config-loginpage-show/${data.projId}`)
} else {
nav(`/proj-edit/config-loginpage/${data.projId}`)
}
}}>
<img src={setImg} alt="" />
<div></div>
</div>
<div className='set' onClick={() => {
if (data.generate.generateStatus == GenerateStatus.SUCCESS) {
nav(`/proj-edit/config-mod-list-show/${data.projId}`)
} else {
nav(`/proj-edit/config-mod-list/${data.projId}`)
}
}}>
<img src={menuImg} alt="" />
<div>({data.projModCount})</div>
</div>
<div className='set' onClick={() => {
if (data.generate.generateStatus == GenerateStatus.SUCCESS) {
nav(`/proj-edit/config-menu-list-show/${data.projId}`)
} else {
nav(`/proj-edit/config-menu-list/${data.projId}`)
}
}}>
<img src={orderImg} alt="" />
<div>({data.projModCount})</div>
</div>
</div>
</div>
{/* 目录层级结构*/}
<div className='centerr'>
</div>
<div className='right'>
<div className='rigth-t'>
- -
</div>
<div className="status">{renderGenerateStatus()}</div>
</div>
{/* <div className="right">
{
data.generate.generateStatus == GenerateStatus.SUCCESS ? (
<span>
@ -178,9 +266,9 @@ export default function CardProj(props: { item: IProj }) {
window.open(`${Axios.defaults?.baseURL}/${data.previewUrl}`, '_blank')
}}></span>
</span>
</div>
</div> */}
</div>
<div className="line">
{/* <div className="line">
<div className="left">
{
data.generate.generateStatus == GenerateStatus.SUCCESS ? (
@ -231,10 +319,10 @@ export default function CardProj(props: { item: IProj }) {
) : <></>
}
</div>
</div>
</div> */}
</div>
<hr/>
<div className="foot">
{/* <hr/> */}
{/* <div className="foot">
<ConfigProvider theme={{
components: {
Button: {
@ -244,7 +332,7 @@ export default function CardProj(props: { item: IProj }) {
}}>
{renderOption()}
</ConfigProvider>
</div>
</div> */}
</div>
{messageContext}
</>

View File

@ -1,24 +1,37 @@
.card-proj {
border-radius: 6px;
background-color: var(--color-light);
padding: 5px 15px;
/* padding: 5px 15px; */
height: 240px;
}
.card-proj .left {
position: unset;
}
.card-proj .title {
display: flex;
justify-content: space-between;
}
.card-proj .titleLift {
display: flex;
}
.card-proj .right {
margin: 0;
}
.card-proj .title {
display: flex;
justify-content: space-between;
/* justify-content: space-between; */
align-items: center;
height: 60px;
/* background-color: pink; */
border-bottom: 1px solid var(--color-border);
}
.card-proj hr {
/* .card-proj hr {
border-color: var(--color-border);
border-style: dashed;
border-left: 0;
@ -26,28 +39,70 @@
border-right: 0;
margin-block-start: 5px;
margin-block-end: 5px;
}
} */
.card-proj .title .left {
padding: 5px;
/* padding: 5px; */
font-weight: bold;
/* background-color: red; */
display: flex;
align-items: center;
margin-left: 21px;
font-weight: 700;
font-size: 19px;
color: #292929;
}
.card-proj .title .left .boxline {
width: 2px;
height: 18px;
border: 2px dotted #adadad;
margin-right: 18px;
}
.card-proj .title .right {
padding: 5px;
width: 380px;
display: flex;
justify-content: space-between;
/* justify-content: space-between; */
align-items: center;
}
.card-proj .title .right span {
margin-inline-end: 0;
font-size: 14px;
color: #888888;
}
.card-proj .title .right span:first-child {
.card-proj .title .right .line {
width: 1px;
height: 16px;
border-left: 1px solid #adadad;
margin-left: 12px;
margin-right: 12px;
}
/* .card-proj .title .right .date{
margin-left: 24px;
} */
.card-proj .titleRight {
margin-right: 29px;
font-size: 14px;
color: #FFA415;
}
.card-proj .titleRight .orignLine {
margin-left: 27px;
margin-right: 27px;
}
.card-proj .titleRight .text-btn {
margin-left: 11px;
}
.card-proj .title .right span:first-child {}
.card-proj .body {
width: unset;
border: unset !important;
@ -58,15 +113,106 @@
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px 0;
padding: 24px 0;
}
.card-proj .body .line .left {
width: unset;
/* width: unset;
display: flex; */
width: 209px;
height: 128px;
background: #C4C4C4;
border-radius: 6px;
margin-left: 46px;
}
.card-proj .body .line .centerl {
margin-left: 27px;
}
.card-proj .body .line .centerl .c-top {
width: 175px;
height: 39px;
background: #FFF9E6;
border-radius: 19px;
color: #FF5D15;
line-height: 39px;
text-align: center;
}
.card-proj .body .line .centerl .c-top .money {
font-weight: 300;
font-size: 14px;
}
.card-proj .body .line .centerl .c-top .num {
font-weight: bold;
font-size: 20px;
}
.card-proj .body .line .centerl .c-bot {
display: flex;
}
.card-proj .body .line .left span {
.card-proj .body .line .centerl .c-bot .set {
display: flex;
align-items: center;
margin-top: 20px;
font-weight: 300;
font-size: 15px;
color: #707070;
cursor: pointer;
margin-left: 31px;
}
.card-proj .body .line .centerl .c-bot img {
width: 30px;
height: 30px;
}
.card-proj .body .line .centerr {
width: 428px;
height: 110px;
/* border-left: 1px dotted #737373; */
/* border-right: 1px dotted #737373; */
margin-left: 174px;
}
.card-proj .body .line .right {
height: 110px;
width: 197px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
/* background-color: red; */
/* margin-left: 600px; */
border-left: 1px dotted #737373;
}
.card-proj .body .line .right .rigth-t {
font-weight: 300;
font-size: 12px;
color: #707070;
text-align: center;
/* background-color: pink; */
}
.card-proj .body .line .right .status {
/* background-color: red; */
display: flex;
align-items: center;
justify-content: center;
margin-left: 10px;
}
/* .card-proj .body .line .left span {
margin-right: 10px;
}
@ -84,4 +230,4 @@
display: flex;
justify-content: space-between;
align-items: center;
}
} */

View File

@ -1,14 +1,17 @@
import './list-proj.css'
import CardProj from "../card/CardProj.tsx";
import {useRef, MutableRefObject, useState, useEffect, useContext} from "react";
import {Input, Pagination, message, Spin, Tag, Image} from 'antd';
import {get} from "../../util/AjaxUtils.ts";
import {IndexListContext} from "../../context/IndexListContext.ts";
import {IListPage} from "../../interfaces/listpage/IListPage.ts";
import {IProj} from "../../interfaces/proj/IProj.ts";
import { useRef, MutableRefObject, useState, useEffect, useContext } from "react";
import { Input, Pagination, message, Spin, Image } from 'antd';
import { get } from "../../util/AjaxUtils.ts";
import { IndexListContext } from "../../context/IndexListContext.ts";
import { IListPage } from "../../interfaces/listpage/IListPage.ts";
import { IProj } from "../../interfaces/proj/IProj.ts";
import NoData from "../../assets/no-data.png";
const {Search} = Input;
import gpsImg from '../../static/right/gps.png'
import { Link } from "react-router-dom";
import { Breadcrumb } from 'antd';
import backImg from '../../static/right/back.png'
const { Search } = Input;
export default function ListProj() {
const indexListContext = useContext(IndexListContext);
@ -40,7 +43,7 @@ export default function ListProj() {
onBefore() {
setIsLoading(true);
},
onSuccess({data}) {
onSuccess({ data }) {
setPage(data.page);
setTotal(data.total);
setProjs(data.rows);
@ -63,13 +66,13 @@ export default function ListProj() {
justifyContent: 'center',
alignItems: 'center'
}}>
<Image src={NoData} preview={false}/>
<Image src={NoData} preview={false} />
<span></span>
</div>
)
}
return projs.map((item) => {
return <CardProj item={item} key={new Date().getTime() + ':' + item.projId}/>;
return <CardProj item={item} key={new Date().getTime() + ':' + item.projId} />;
});
}
@ -83,36 +86,56 @@ export default function ListProj() {
}
}, [indexListContext.status, indexListContext.categoryChangeCount, indexListContext.category, keywords, page])
const renderStatus = () => {
if (indexListContext.status == 'ALL') {
return <Tag color="blue"></Tag>
} else if (indexListContext.status == 'PROCESSING') {
return <Tag color="blue"></Tag>
} else if (indexListContext.status == 'COMPLETE') {
return <Tag color="blue"></Tag>
}
return <></>
}
// const renderStatus = () => {
// if (indexListContext.status == 'ALL') {
// return <Tag color="blue">项目:全部项目</Tag>
// } else if (indexListContext.status == 'PROCESSING') {
// return <Tag color="blue">项目:进行中的</Tag>
// } else if (indexListContext.status == 'COMPLETE') {
// return <Tag color="blue">项目:已完成的</Tag>
// }
// return <></>
// }
return (
<>
{contextHolder}
<div className="list-proj" ref={listProjRef}>
<div className="top">
{renderStatus()}
<Search placeholder="按项目名搜索" onSearch={(value) => {
{/* 标签 */}
{/* {renderStatus()} */}
<div className='gps'>
<img src={gpsImg} alt="" />
<div>当前位置:首页</div>
</div>
<div className='line'></div>
<Search placeholder="输入项目名称" onSearch={(value) => {
setKeywords(value)
}} style={{width: 200}}/>
}} style={{
width: '253px',
height: '31px',
}} />
<div className='nowPosition'>
<img src={backImg} alt="" />
<div>
<Breadcrumb
separator="|"
items={[
{ title: <Link to={'/'}></Link> },
]}
/>
</div>
</div>
</div>
<div className="body">
<Spin tip="加载中..." spinning={isLoading}>
<div className="list" ref={listRef} style={{height: `${domHeight}px`}}>
<div className="list" ref={listRef} style={{ height: `${domHeight}px` }}>
{renderList()}
</div>
<div className="page">
<Pagination defaultCurrent={page} total={total} onChange={(page) => {
setPage(page);
}}/>
}} />
</div>
</Spin>
</div>

View File

@ -1,16 +1,73 @@
.list-proj {
width: 100%;
padding-top: 26px;
padding-right: 33px;
box-sizing: border-box;
}
.list-proj .top {
padding: 10px 15px;
/* padding: 10px 15px; */
box-sizing: border-box;
height: 62px;
display: flex;
justify-content: space-between;
/* justify-content: space-between; */
align-items: center;
border-bottom: 1px solid var(--color-border);
background-color: var(--color-light);
}
.list-proj .top .gps {
display: flex;
align-items: center;
font-size: 14px;
}
.list-proj .top .gps img {
width: 18px;
height: 21px;
margin-left: 22px;
margin-right: 16px;
}
.list-proj .top .line {
width: 1px;
height: 23px;
border-left: 1px solid #d8d8d8;
margin-left: 33px;
margin-right: 31px;
}
/* .list-proj .top .search {
width: 253px;
height: 31px;
background: #FFF5E6;
border-radius: 15px;
border: 1px solid #FFD99C
} */
.nowPosition {
display: flex;
align-items: center;
/* width: 349px; */
height: 100%;
margin-left: 98px;
font-weight: 300;
font-size: 13px;
color: #676767;
/* background: url(../../static//right/back.png); */
/* background-color: rgb(228, 191, 191); */
position: relative;
}
.nowPosition img{
width: 349px;
height: 62px;
position: absolute;
left: 0;
top: 0;
}
.nowPosition div{
margin-left: 133px;
z-index: 99;
}
.list-proj .body {
width: unset;
margin: 0;
@ -24,6 +81,7 @@
.list-proj .body .card-proj {
margin-bottom: 10px;
}
.list-proj .body .card-proj:last-child {
margin-bottom: 0;
}

View File

@ -1,6 +1,7 @@
import './menu-tree.css';
import {
CaretRightOutlined,
FolderOutlined,
CaretDownOutlined,
PlusOutlined,
CloseOutlined,
@ -67,7 +68,7 @@ export default function MenuTree(props: IMenuTree) {
const width = 180 - 50 - (item.level * 10) - (5 + (item.isParent ? 8.75 : 0));
return (
<>
{item.isParent ? icon : <></>}
{item.isParent ? icon : <></>}<FolderOutlined />
<span
className={item.active ? 'active' : ''}
style={{width: width}}

View File

@ -1,12 +1,13 @@
import './menu-tree-with-top-button.css';
import MenuTree from "./MenuTree.tsx";
import {IMenuTreeItem} from "../../interfaces/menu/IMenuTree.ts";
import {useContext, useEffect, useState} from "react";
import {del, get, post, put} from "../../util/AjaxUtils.ts";
import { IMenuTreeItem } from "../../interfaces/menu/IMenuTree.ts";
import { useContext, useEffect, useState } from "react";
import { del, get, post, put } from "../../util/AjaxUtils.ts";
import useMessage from "antd/es/message/useMessage";
import {IndexListDataType, IndexListDispatchContext,} from "../../context/IndexListContext.ts";
import {Input, MenuProps, Modal} from "antd";
import { IndexListDataType, IndexListDispatchContext, } from "../../context/IndexListContext.ts";
import { Input, MenuProps, Modal } from "antd";
import srcImg from '../../static/left/src.png'
import newImg from '../../static/left/new.png'
type ProjCategoryDTO = {
projCategoryId: string;
@ -88,7 +89,7 @@ export default function MenuTreeWithTopButton() {
const clearActive = (array: IMenuTreeItem[]) => {
array.forEach(item => {
item.active = false;
if(item.children) {
if (item.children) {
clearActive(item.children)
}
})
@ -98,7 +99,7 @@ export default function MenuTreeWithTopButton() {
get<ProjCategoryDTO[]>({
messageApi,
url: '/api/proj/category/listallbyparentid/0',
onSuccess({data}) {
onSuccess({ data }) {
const menus = menuArray(data, 1);
setMenuTreeArray(menus);
indexListDispatchContext({
@ -111,11 +112,31 @@ export default function MenuTreeWithTopButton() {
return (
<>
<div className="menu-tree-with-top-button">
<button type="button" className="btn btn-orange" onClick={() => {
{/* <div className="center-top">
<div className="center-top-lift">
<img src={srcImg} alt="" />
<div ></div>
</div>
<div className='center-top-right' onClick={() => {
setSaveCategory(new MenuTreeItem('-1', '0', '新目录', 1));
setSaveModal(true)
}}>
}}>
<img src={newImg} alt="" />
<div></div>
</div> */}
<div className="menu-tree-with-top-button">
<button type="button" className="btn-cennter" >
<div className="center-top-lift">
<img src={srcImg} alt="" />
<div ></div>
</div>
<div className='center-top-right' onClick={() => {
setSaveCategory(new MenuTreeItem('-1', '0', '新目录', 1));
setSaveModal(true)
}}>
<img src={newImg} alt="" />
<div></div>
</div>
</button>
<MenuTree
menus={menuTreeArray}
@ -181,110 +202,110 @@ export default function MenuTreeWithTopButton() {
/>
</div>
<Modal open={saveModal}
title="添加目录"
okText="确定"
cancelText="取消"
okButtonProps={{
style: {
backgroundColor: 'var(--color-primary)'
}
}}
onCancel={() => {
setSaveModal(false);
}}
onOk={() => {
if(!saveCategory.name) {
messageApi.error('请输入名称');
return;
}
// 新增
post<any>({
messageApi,
url: '/api/proj/category/save',
body: {
projCategoryParentId: saveCategory.pId,
projCategoryName: saveCategory.name
},
onSuccess({data}) {
if (!saveCategory.parent) {
const menuTreeItem = new MenuTreeItem(`${data.data}`, '0', saveCategory.name, 1);
menuTreeItem.isParent = false;
menuTreeArray.push(menuTreeItem);
setMenuTreeArray([...menuTreeArray]);
indexListDispatchContext({
type: IndexListDataType.CATEGORY,
value: menus2Dropdowns(menuTreeArray)
})
} else {
saveCategory.parent.isParent = true;
saveCategory.parent.isOpen = true;
if (!saveCategory.parent.children) {
saveCategory.parent.children = new Array<IMenuTreeItem>();
}
const menuTreeItem = new MenuTreeItem(`${data.data}`, saveCategory.id, saveCategory.name, saveCategory.level);
menuTreeItem.isParent = false;
saveCategory.parent.children.push(menuTreeItem);
setMenuTreeArray([
...menuTreeArray
])
indexListDispatchContext({
type: IndexListDataType.CATEGORY,
value: menus2Dropdowns(menuTreeArray)
})
}
title="添加目录"
okText="确定"
cancelText="取消"
okButtonProps={{
style: {
backgroundColor: 'var(--color-primary)'
}
}}
onCancel={() => {
setSaveModal(false);
}}
onOk={() => {
if (!saveCategory.name) {
messageApi.error('请输入名称');
return;
}
// 新增
post<any>({
messageApi,
url: '/api/proj/category/save',
body: {
projCategoryParentId: saveCategory.pId,
projCategoryName: saveCategory.name
},
onSuccess({ data }) {
if (!saveCategory.parent) {
const menuTreeItem = new MenuTreeItem(`${data.data}`, '0', saveCategory.name, 1);
menuTreeItem.isParent = false;
menuTreeArray.push(menuTreeItem);
setMenuTreeArray([...menuTreeArray]);
indexListDispatchContext({
type: IndexListDataType.CATEGORY,
value: menus2Dropdowns(menuTreeArray)
})
} else {
saveCategory.parent.isParent = true;
saveCategory.parent.isOpen = true;
if (!saveCategory.parent.children) {
saveCategory.parent.children = new Array<IMenuTreeItem>();
}
const menuTreeItem = new MenuTreeItem(`${data.data}`, saveCategory.id, saveCategory.name, saveCategory.level);
menuTreeItem.isParent = false;
saveCategory.parent.children.push(menuTreeItem);
setMenuTreeArray([
...menuTreeArray
])
indexListDispatchContext({
type: IndexListDataType.CATEGORY,
value: menus2Dropdowns(menuTreeArray)
})
}
setSaveModal(false);
}
})
}}
setSaveModal(false);
}
})
}}
>
<Input value={saveCategory?.name} placeholder="请输入目录标题" maxLength={10} onChange={(e) => {
saveCategory.name = e.target.value;
setSaveCategory({...saveCategory})
}}/>
setSaveCategory({ ...saveCategory })
}} />
</Modal>
<Modal open={editModal}
title="编辑目录"
okText="确定"
cancelText="取消"
okButtonProps={{
style: {
backgroundColor: 'var(--color-primary)'
}
}}
onCancel={() => {
setEditModal(false);
}}
onOk={() => {
if (editCategory.name === '') {
messageApi.error('请输入名称');
return;
}
put<any>({
messageApi,
url: `/api/proj/category/update/${editCategory.id}`,
body: {
projCategoryParentId: editCategory.pId,
projCategoryName: editCategory.name
},
onSuccess() {
editCategory.oldName = editCategory.name;
setMenuTreeArray([
...menuTreeArray
])
indexListDispatchContext({
type: IndexListDataType.CATEGORY,
value: menus2Dropdowns(menuTreeArray)
})
setEditModal(false);
}
})
}}
title="编辑目录"
okText="确定"
cancelText="取消"
okButtonProps={{
style: {
backgroundColor: 'var(--color-primary)'
}
}}
onCancel={() => {
setEditModal(false);
}}
onOk={() => {
if (editCategory.name === '') {
messageApi.error('请输入名称');
return;
}
put<any>({
messageApi,
url: `/api/proj/category/update/${editCategory.id}`,
body: {
projCategoryParentId: editCategory.pId,
projCategoryName: editCategory.name
},
onSuccess() {
editCategory.oldName = editCategory.name;
setMenuTreeArray([
...menuTreeArray
])
indexListDispatchContext({
type: IndexListDataType.CATEGORY,
value: menus2Dropdowns(menuTreeArray)
})
setEditModal(false);
}
})
}}
>
<Input value={editCategory?.name} placeholder="请输入目录标题" maxLength={10} onChange={(e) => {
editCategory.name = e.target.value;
setEditCategory({...editCategory})
}}/>
setEditCategory({ ...editCategory })
}} />
</Modal>
{messageContext}
</>

View File

@ -0,0 +1,54 @@
import './menu-with-bottom-button.css'
import { IMenuWithTopButton } from "../../interfaces/menu/IMenuWithTopButton.ts";
import serveImg from '../../static/left/serves.png'
// import newImg from '../../static/left/new.png'
// import {
// RightOutlined
// } from '@ant-design/icons';
export default function MenuWithTopButton(props: IMenuWithTopButton) {
const list = props.list.map((item, index) => (
// 创建项目下三个选项
<li className={item.active ? 'active' : ''} key={item.id} onClick={(e) => {
props.handleListItem(e, index, item);
}}>
{item.icon ? (<img src={item.icon} className="menu-icon" alt="加载失败" />) : <></>}
<span className="menu-name">{item.name}</span>
{/* <span className='icon'><RightOutlined /></span> */}
</li>
));
return (
<div className="menu-with-bot-button">
{/* button 是三个黄色按钮 */}
<div className='bot' onClick={(e) => {
props.button.handle(e);
}}>
<div className='bot-lift'>
<img src={serveImg} alt="" />
<div> {props.button.name}</div>
</div>
{/* <div className='bot-right' onClick={(e) => {
props.button.handle(e);
}}>
<img src={newImg} alt="" />
<div></div>
</div> */}
</div>
{/* <button className="btn btn-orange top-button"
onClick={(e) => {
props.button.handle(e);
console.log(e);
}}
>
{props.button.name}
</button> */}
<ul>{list}</ul>
</div>
)
}

View File

@ -1,27 +1,50 @@
import './menu-with-top-button.css'
import {IMenuWithTopButton} from "../../interfaces/menu/IMenuWithTopButton.ts";
import { IMenuWithTopButton } from "../../interfaces/menu/IMenuWithTopButton.ts";
import objImg from '../../static/left/obj.png'
import newImg from '../../static/left/new.png'
import {
RightOutlined
} from '@ant-design/icons';
export default function MenuWithTopButton(props: IMenuWithTopButton) {
const list = props.list.map((item, index) => (
// 创建项目下三个选项
<li className={item.active ? 'active' : ''} key={item.id} onClick={(e) => {
props.handleListItem(e, index, item);
}}>
{item.icon ? (<img src={item.icon} className="menu-icon" alt="加载失败"/>) : <></>}
{item.icon ? (<img src={item.icon} className="menu-icon" alt="加载失败" />) : <></>}
<span className="menu-name">{item.name}</span>
<span className='topIcon'><RightOutlined /></span>
</li>
));
return (
<div className="menu-with-top-button">
{/* button 是三个黄色按钮 */}
<button className="btn btn-orange top-button"
<div className='top'>
<div className='top-lift'>
<img src={objImg} alt="" />
<div> {props.button.name}</div>
</div>
<div className='top-right' onClick={(e) => {
props.button.handle(e);
}}>
<img src={newImg} alt="" />
<div></div>
</div>
</div>
{/* <button className="btn btn-orange top-button"
onClick={(e) => {
props.button.handle(e);
console.log(e);
}}
>
{props.button.name}
</button>
</button> */}
<ul>{list}</ul>
</div>
)

View File

@ -1,7 +1,45 @@
.menu-tree-with-top-button {
padding: 0 15px;
/* padding: 0 15px; */
}
.menu-tree-with-top-button .btn {
width: 100%;
}
}
.btn-cennter{
width: 268px;
height: 56px;
font-size: 18px;
background: #FFFBEF;
color: #FFAF22;
display: flex;
align-items: center;
border-top: 1px solid #fde9ab;
border-bottom: 1px solid #fde9ab;
border-left: 0;
border-right: 0;
}
.center-top-lift{
display: flex;
align-items: center;
font-size: 18px;
}
.center-top-lift img{
width: 19px;
height: 15px;
margin-left: 30px;
margin-right: 14px;
}
.center-top-right{
display: flex;
align-items: center;
font-size: 14px;
cursor: pointer;
width: 53px;
margin-left: 96px;
}
.center-top-right img{
margin-right: 10px;
width: 14px;
height: 13px;
}

View File

@ -1,10 +1,18 @@
.menu-tree {
margin-top: 10px;
}
.menu-tree ul {
margin-left: 10px;
/* margin-left: 10px; */
}
.menu-tree ul li {
font-size: 15px;
margin-top: 10px;
margin-bottom: 10px;
padding-right: 10px;
padding-left: 10px;
/* background-color: aquamarine; */
}
.menu-tree ul li .menu-title {
@ -14,11 +22,13 @@
height: 22px;
line-height: 22px;
}
.menu-tree ul li .menu-title .label {
cursor: pointer;
display: flex;
align-items: center;
}
.menu-tree ul li .menu-title .label span {
margin-left: 5px;
display: inline-block;
@ -31,9 +41,12 @@
user-select: none;
-webkit-user-select: none;
}
.menu-tree ul li .menu-title .label span.active {
text-decoration-line: underline;
text-underline-offset: 5px;
background-color: rgb(221, 221, 221);
text-align: center;
}
.menu-tree ul li .menu-title .label .menu-name-input {
@ -52,6 +65,7 @@
display: flex;
justify-content: right;
}
.menu-tree ul li .menu-title .icon-group .icon {
cursor: pointer;
padding-left: 2px;

View File

@ -0,0 +1,129 @@
.menu-with-top-button {
/* padding: 15px; */
}
.bot {
width: 268px;
height: 56px;
font-size: 18px;
/* color: #FFAF22; */
background: #FFFBEF;
color: #FFAF22;
display: flex;
align-items: center;
border-top: 1px solid #fde9ab;
border-bottom: 1px solid #fde9ab;
}
.bot-lift {
display: flex;
align-items: center;
font-size: 18px;
}
.bot-lift img {
width: 15px;
height: 15px;
margin-left: 39px;
margin-right: 9px;
}
.bot-right {
display: flex;
align-items: center;
font-size: 14px;
cursor: pointer;
width: 53px;
/* background-color: red; */
margin-left: 96px;
}
.bot-right img {
/* margin-left: 96px; */
margin-right: 10px;
width: 14px;
height: 13px;
}
.menu-with-bot-button ul {
padding-top: 12px;
padding-bottom: 12px;
}
.menu-with-bot-button ul li {
height: 50px;
margin-left: 66px;
font-weight: 400;
font-size: 16px;
color: #313131;
line-height: 50px;
cursor: pointer;
}
.menu-with-bot-button ul li.active {
text-decoration-line: underline;
}
/* .icon{
color: white;
margin-left: 101px;
} */
/*
.menu-with-top-button .top-button {
width: 268px;
height: 56px;
background: #FFFBEF;
font-size: 18px;
color: #FFAF22;
} */
/* .menu-with-top-button ul {
padding: 10px;
} */
/* .menu-with-top-button ul li {
display: flex;
align-items: center;
justify-content: center;
padding: 5px;
cursor: pointer;
} */
/* .menu-with-top-button ul li.active {
text-decoration-line: underline;
text-underline-offset: 5px;
} */
/* .menu-with-top-button ul li:hover {
text-decoration-line: underline;
text-underline-offset: 5px;
} */
/* .menu-with-top-button ul li:last-child {
margin-bottom: 0;
}
.menu-with-top-button ul li .menu-icon {
width: 30px;
height: 30px;
}
.menu-with-top-button ul li .menu-name {
padding-left: 5px;
} */

View File

@ -1,33 +1,104 @@
.menu-with-top-button {
padding: 15px;
/* padding: 15px; */
}
.menu-with-top-button .top-button {
width: 100%;
.menu-with-top-button .top {
width: 268px;
height: 56px;
font-size: 18px;
/* color: #FFAF22; */
background: #FFFBEF;
color: #FFAF22;
display: flex;
align-items: center;
border-top: 1px solid #fde9ab;
border-bottom: 1px solid #fde9ab;
}
.menu-with-top-button .top .top-lift {
display: flex;
align-items: center;
font-size: 18px;
}
.menu-with-top-button .top .top-lift img {
width: 19px;
height: 19px;
margin-left: 30px;
margin-right: 14px;
}
.menu-with-top-button .top .top-right {
display: flex;
align-items: center;
font-size: 14px;
cursor: pointer;
width: 53px;
/* background-color: red; */
margin-left: 96px;
}
.menu-with-top-button .top .top-right img {
/* margin-left: 96px; */
margin-right: 10px;
width: 14px;
height: 13px;
}
.menu-with-top-button ul {
padding: 10px;
padding-top: 12px;
padding-bottom: 12px;
}
.menu-with-top-button ul li {
display: flex;
align-items: center;
justify-content: center;
padding: 5px;
height: 50px;
margin-left: 66px;
font-weight: 400;
font-size: 16px;
color: #313131;
line-height: 50px;
cursor: pointer;
}
.menu-with-top-button ul li.active {
text-decoration-line: underline;
text-underline-offset: 5px;
width: 223px;
height: 50px;
background: #FF9F08;
border-radius: 25px;
color: white;
text-indent: 26px;
}
.topIcon{
color: white;
margin-left: 101px;
}
.menu-with-top-button ul li:hover {
text-decoration-line: underline;
text-underline-offset: 5px;
/* .menu-with-top-button .top-button {
width: 268px;
height: 56px;
background: #FFFBEF;
font-size: 18px;
color: #FFAF22;
}
.menu-with-top-button ul li:last-child {
margin-bottom: 0;
}
@ -39,4 +110,4 @@
.menu-with-top-button ul li .menu-name {
padding-left: 5px;
}
} */

View File

@ -10,9 +10,9 @@ export default function RechargeHead() {
return (
<>
<div className="head-item recharge-head">
<span onClick={() => {
setIsPaymentModalOpen(true);
}}></span>
<div onClick={() => {
setIsPaymentModalOpen(true);
}}></div>
</div>
<Modal open={isPaymentModalOpen}
title="充值"

View File

@ -1,3 +1,14 @@
.recharge-head {
cursor: pointer;
width: 81px;
height: 36px;
border-radius: 18px;
background-color:#FF6508;
color: white;
text-align: center;
line-height: 36px;
font-weight: 300;
font-size: 16px;
color: #FFFFFF;
margin-left: 43px;
}

View File

@ -15,7 +15,8 @@
--color-note: rgba(68, 72, 88, 0.5);
--color-disabled: #D9D9D9;
--font-size-head: 14px;
--width-workspace: 1280px;
/* --width-workspace: 1280px; */
--width-workspace: 100vw;
--height-head: 60px;
--height-foot: 30px;
}
@ -25,6 +26,8 @@ html, body {
padding: 0;
font-size: 14px;
background-color: #EEEEEE;
/* 禁止书香滚动条占位 隐藏浏览器默认的滚动条样式 */
scrollbar-width: none;
}
a {

View File

@ -10,7 +10,7 @@ export interface IMenuListItem {
export interface IMenuButton {
name: string;
handle(e: MouseEvent<HTMLButtonElement>): void;
handle(e: MouseEvent<HTMLDivElement>): void;
}
export interface IMenuWithTopButton {

View File

@ -1,5 +1,5 @@
.body {
margin: 65px auto 10px auto;
margin: 80px auto 10px auto;
width: var(--width-workspace);
}

View File

@ -1,17 +1,16 @@
import './head.css'
import BalanceHead from '../../components/balance/BalanceHead.tsx';
import RechargeHead from '../../components/recharge/RechargeHead.tsx';
import {Divider, Dropdown, MenuProps, message, Modal, Space, Spin} from "antd";
import {DownOutlined, UserOutlined, KeyOutlined, LogoutOutlined, AccountBookOutlined} from "@ant-design/icons";
import {useContext, useEffect, useState} from "react";
import {put} from "../../util/AjaxUtils.ts";
import {GlobalContext, GlobalDispatchContext, reloadUser} from "../../context/GlobalContext.ts";
import { Dropdown, MenuProps, message, Modal, Space, Spin } from "antd";
import { DownOutlined, UserOutlined, KeyOutlined, LogoutOutlined, AccountBookOutlined } from "@ant-design/icons";
import { useContext, useEffect, useState } from "react";
import { put } from "../../util/AjaxUtils.ts";
import { GlobalContext, GlobalDispatchContext, reloadUser } from "../../context/GlobalContext.ts";
import UserEdit from "../../components/user/UserEdit.tsx";
import PasswordChange from "../../components/password/PasswordChange.tsx";
import headRightBg from '../../assets/head-right-bg.png';
// import headRightBg from '../../assets/head-right-bg.png';
import InvoiceList from "../../components/invoice/InvoiceList.tsx";
import logoImg from '../../static/head/logo.png'
export default function Head() {
const globalContext = useContext(GlobalContext);
const globalDispatchContext = useContext(GlobalDispatchContext);
@ -35,7 +34,7 @@ export default function Head() {
key: 'userinfo',
label: (
<div className="dropdown-item">
<UserOutlined/>
<UserOutlined />
<span className="title"></span>
</div>
),
@ -47,7 +46,7 @@ export default function Head() {
key: 'changePass',
label: (
<div className="dropdown-item">
<KeyOutlined/>
<KeyOutlined />
<span className="title"></span>
</div>
),
@ -71,7 +70,7 @@ export default function Head() {
key: 'logout',
label: (
<div className="dropdown-item">
<LogoutOutlined/>
<LogoutOutlined />
<span className="title">退</span>
</div>
),
@ -86,21 +85,25 @@ export default function Head() {
<div className="head">
<div className="center">
<div className="left">
<span className="sys-title">AI引擎软著</span>
{/* <span className="sys-title">AI</span>
<Divider type="vertical"/>
<span className="sys-title-sub"></span>
<span className="sys-title-sub"></span> */}
<img src={logoImg} alt="" />
</div>
<div className="right" style={{backgroundImage: `url(${headRightBg})`}}>
<BalanceHead/>
<RechargeHead/>
{/* <div className="right" style={{backgroundImage: `url(${headRightBg})`}}> */}
<div className="right">
<BalanceHead />
<RechargeHead />
{/*<MessageHead/>*/}
<div style={{display: 'flex', alignContent: 'center', padding: '0 10px', cursor: 'pointer'}}>
<div style={{ display: 'flex', alignContent: 'center', padding: '0 10px', cursor: 'pointer' }}>
<div style={{ width: '50px', height: '50px', borderRadius: '25px', backgroundColor: '#c4c1c0', marginLeft: '20px', marginRight: '10px' }} />
<Dropdown menu={{
items: items
}}>
<Space>
{globalContext.user.nickname}
<DownOutlined/>
{/* 您好:{globalContext.user.nickname} */}
<DownOutlined />
</Space>
</Dropdown>
</div>
@ -108,15 +111,15 @@ export default function Head() {
</div>
</div>
<Modal open={isSelfModalOpen}
title="个人信息"
footer={false}
onCancel={() => {
if (!globalContext.user.hasUserInfo) {
messageApi.info('请完善个人信息');
return;
}
setIsSelfModalOpen(false)
}}>
title="个人信息"
footer={false}
onCancel={() => {
if (!globalContext.user.hasUserInfo) {
messageApi.info('请完善个人信息');
return;
}
setIsSelfModalOpen(false)
}}>
<UserEdit handleConfirm={(data) => {
modal.confirm({
title: '提示',
@ -146,14 +149,14 @@ export default function Head() {
})
}
});
}}/>
}} />
</Modal>
<Modal open={isPasswordModalOpen}
title="修改密码"
footer={false}
onCancel={() => {
setIsPasswordModalOpen(false)
}}>
title="修改密码"
footer={false}
onCancel={() => {
setIsPasswordModalOpen(false)
}}>
<PasswordChange handleConfirm={(data) => {
modal.confirm({
title: '提示',
@ -183,17 +186,17 @@ export default function Head() {
})
}
});
}}/>
}} />
</Modal>
<Modal open={isInvoiceModalOpen}
title="发票管理"
width={1100}
footer={false}
onCancel={() => setIsInvoiceModalOpen(false)}
title="发票管理"
width={1100}
footer={false}
onCancel={() => setIsInvoiceModalOpen(false)}
>
<InvoiceList/>
<InvoiceList />
</Modal>
<Spin tip="正在提交..." spinning={loading} fullscreen/>
<Spin tip="正在提交..." spinning={loading} fullscreen />
{contextHolder}
{modalHolder}
</>

View File

@ -1,46 +1,61 @@
.head {
width: 100%;
height: var(--height-head);
width: 100vw;
height: 84px;
position: fixed;
top: 0;
left: 0;
background-color: var(--color-light);
box-shadow: 0 2px 6px 0 var(--color-box-shadow);
z-index: 99;
color: var(--color-dark);
background: url('../../static/head/background.png');
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
/* background-color: rgb(248, 211, 211); */
}
.head .center {
margin: 0 auto;
width: var(--width-workspace);
/* margin: 0 auto; */
width: 100vw;
height: 100%;
display: flex;
justify-content: space-between;
position: relative;
}
.head .center .left {
min-width: 180px;
.head .center .left img {
width: 263px;
height: 41px;
/* background-color: red;
*/
margin-left: 176px;
margin-top: 21px;
}
.head .center .right {
height: 100%;
/* padding-left: 60px; */
margin-right: 33px;
display: flex;
justify-content: right;
align-items: center;
font-size: 18px;
font-weight: 800;
color: var(--color-text-header-left);
}
/*
.head .center .left .logo {
width: 38px;
height: 38px;
}
} */
.head .center .left .sys-title {}
/* .head .center .left .sys-title {}
.head .center .left .sys-title-sub {
font-size: 14px;
font-weight: unset;
}
} */
.head .center .right {
/* .head .center .right {
height: 100%;
padding-left: 60px;
display: flex;
@ -66,4 +81,4 @@
.ant-dropdown .dropdown-item .title {
margin-left: 5px;
}
} */

View File

@ -1,12 +1,13 @@
import './index.css';
import {MouseEvent, Reducer, useEffect, useReducer, useState} from "react";
import {Link, useNavigate, useSearchParams} from "react-router-dom";
import { useNavigate, useSearchParams} from "react-router-dom";
import {IMenuListItem, IMenuWithTopButton} from "../../interfaces/menu/IMenuWithTopButton.ts";
import MenuWithTopButton from "../../components/menu/MenuWithTopButton.tsx";
import MenuWithBottomButtom from '../../components/menu/MenuWithBottomButton.tsx'
import MenuTreeWithTopButton from "../../components/menu/MenuTreeWithTopButton.tsx";
import ListProj from "../../components/list/ListProj.tsx";
import ListProjAgent from "../../components/list/ListProjAgent.tsx";
import {Breadcrumb, MenuProps} from 'antd';
import { MenuProps} from 'antd';
import {
IndexListContext,
IndexListDataType,
@ -49,13 +50,13 @@ export default function Index() {
const [projMenu, setProjMenu] = useState<IMenuWithTopButton>({
button: {
name: '创建项目',
name: '项目',
handle() {
nav('/proj-create')
}
},
list: [
{id: 'ALL', name: '全部项目'},
{id: 'ALL', name: '全部项目',active:true},
{id: 'PROCESSING', name: '进行中的'},
{id: 'COMPLETE', name: '已完成的'}
],
@ -70,7 +71,8 @@ export default function Index() {
type: IndexListDataType.PROJ,
value: item.id
})
}
},
});
const [agentMenu, setAgentMenu] = useState<IMenuWithTopButton>({
@ -101,7 +103,6 @@ export default function Index() {
})
}
})
useEffect(() => {
if (searchParams.get('type') == 'agent') {
dispatch({
@ -110,14 +111,13 @@ export default function Index() {
})
}
}, []);
return (
<>
<Breadcrumb
{/* <Breadcrumb
items={[
{title: <Link to={'/'}></Link>}
]}
/>
/> */}
<IndexListContext.Provider value={listData}>
<IndexListDispatchContext.Provider value={dispatch}>
<div className="index">
@ -127,8 +127,8 @@ export default function Index() {
list={projMenu.list}
handleListItem={projMenu.handleListItem}
/>
<MenuTreeWithTopButton/>
<MenuWithTopButton
<MenuTreeWithTopButton />
<MenuWithBottomButtom
button={agentMenu.button}
list={agentMenu.list}
handleListItem={agentMenu.handleListItem}

View File

@ -1,20 +1,21 @@
.index {
position: relative;
height: 100%;
/* position: relative; */
height: 100vh;
/* margin-top: 74px; */
}
.index .left {
position: absolute;
width: 220px;
position: fixed;
width: 268px;
height: 100%;
overflow: auto;
top: 0;
/* overflow: auto; */
top: 80px;
left: 0;
background-color: var(--color-light);
}
.index .right {
margin-left: 235px;
margin-left: 300px;
box-sizing: border-box;
height: 100%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

BIN
src/static/head/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
src/static/head/money.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/static/left/new.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/static/left/obj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/static/left/serves.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

BIN
src/static/left/src.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/static/right/back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
src/static/right/del.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/static/right/gps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/static/right/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src/static/right/order.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/static/right/set.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB