Commit e2dc7161 authored by 田翔's avatar 田翔

fix: 工作台搭建优化

parent d2ff4995
Pipeline #80173 failed with stages
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
import React, { useRef, useContext } from 'react' import React, { useState, useRef, useContext, useEffect, useCallback } from 'react'
import styles from './index.less' import styles from './index.less'
import { useDrag, useDrop, DndProvider } from 'react-dnd' import { useDrag, useDrop, DndProvider } from 'react-dnd'
import { GlobalStore } from '../../index' import { GlobalStore } from '../../index'
import { message } from 'antd'
const Group = (props) => { const Group = (props) => {
const { shema, setShema } = useContext(GlobalStore) const { shema, setShema } = useContext(GlobalStore)
const ref = useRef(null) const ref = useRef(null)
const [, drop] = useDrop(() => { const swapIndex = useCallback((index1, index2) => {
return { const cardList = shema.work
accept: 'card', const tmp = cardList[index1];
drop(card) { cardList[index1] = cardList[index2];
setShema(shema => { cardList[index2] = tmp;
let array = [] setShema({ ...shema, work: cardList })
shema?.work?.forEach(v => { }, [shema.work])
let children = [...v.children]
if (props.id === v.id) { const [, drag] = useDrag({
children = [...v.children, card] type: 'card',
} item: {
array.push({ ...v, children: children }) id: props.id,
index: props.index,
widget: props.widget,
},
})
const [, drop] = useDrop({
accept: 'card',
drop(item) {
if (item.widget !== '通栏布局') {
const isHave = props.children.some(v => v.widget === item.widget)
if (isHave) {
message.info({ type: 'info', content: '同一个分组不允许组件重复!' })
} else {
setShema(shema => {
let array = []
shema?.work?.forEach(v => {
let children = [...v.children]
if (props.id === v.id) {
children = [...v.children, item]
}
array.push({ ...v, children: children })
})
return { ...shema, work: array }
}) })
return { ...shema, work: array } }
}) }
},
hover(item) {
console.log('item', item)
if (item.widget === '通栏布局') {
swapIndex(props.index, item.index)
item.index = props.index
} }
} }
}) })
drop(ref) useEffect(() => {
drag(ref)
drop(ref)
}, [])
const groupClick = (e, item) => { const groupClick = (e, item) => {
e.stopPropagation() e.stopPropagation()
......
...@@ -42,7 +42,7 @@ const Container = (props) => { ...@@ -42,7 +42,7 @@ const Container = (props) => {
<div className={styles.moblieCenter} name={shema.theme}> <div className={styles.moblieCenter} name={shema.theme}>
<div style={{ padding: '10px' }}> <div style={{ padding: '10px' }}>
{ {
shema?.work?.map(v => <Group key={v.id} {...v} />) shema?.work?.map((v, i) => <Group key={v.id} index={i} {...v} />)
} }
</div> </div>
</div> </div>
......
@imgSrc: '@/assets/images/mobileConfig/WorkDesign'; @imgSrc: '@/assets/images/mobileConfig/WorkDesign';
.container { .container {
width: calc(100% - 620px); width: calc(100% - 660px);
height: 100%; height: 100%;
background: white; background: white;
margin: 0 10px; margin: 0 10px;
......
import React, { useState, useRef, useContext } from 'react' import React, { useState, useRef, useContext } from 'react'
import { useDrag, useDrop, DndProvider } from 'react-dnd' import { useDrag, useDrop, DndProvider } from 'react-dnd'
import { GlobalStore } from '../index' import { GlobalStore } from '../index'
import { CaretRightOutlined } from '@ant-design/icons'
import styles from './index.less' import styles from './index.less'
const getNanoid = (len = 10) => { const getNanoid = (len = 10) => {
...@@ -49,8 +50,6 @@ const Group = (props) => { ...@@ -49,8 +50,6 @@ const Group = (props) => {
) )
} }
//111
const Card = (props) => { const Card = (props) => {
const ref = useRef(null) const ref = useRef(null)
...@@ -81,6 +80,26 @@ const Card = (props) => { ...@@ -81,6 +80,26 @@ const Card = (props) => {
) )
} }
//卡片分组
const CardGroup = (props) => {
const [shrink, setShrink] = useState(false)
return (
<div className={styles.cardGroup}>
<div className={styles['g-top']} onClick={() => setShrink(!shrink)}>
<CaretRightOutlined style={{ transition: '0.5s all', transform: !shrink ? 'rotate(90deg)' : '' }} />
<span>{props.title}</span>
<span>{`(${props.count})`}</span>
</div>
<div className={styles['g-cards']} style={{ height: shrink ? '0px' : 'unset' }}>
{props.children}
</div>
</div>
)
}
const Left = () => { const Left = () => {
return ( return (
...@@ -96,22 +115,27 @@ const Left = () => { ...@@ -96,22 +115,27 @@ const Left = () => {
<div className={styles.item}> <div className={styles.item}>
<div className={styles['g-title']}>卡片组件</div> <div className={styles['g-title']}>卡片组件</div>
<div className={styles['g-content']}> <div className={styles['g-content']}>
<div>运营总览</div> <CardGroup title={'运营总览'} count={1}>
<Card name={'运营总览'} widget={'OVERVIEW'}></Card> <Card name={'运营总览'} widget={'OVERVIEW'}></Card>
<div>水厂</div> </CardGroup>
<Card name={'水厂总览'} widget={'WATER_OVERVIEW'}></Card> <CardGroup title={'水厂'} count={2}>
<Card name={'供水量曲线'} widget={'WATER_CHART'}></Card> <Card name={'水厂总览'} widget={'WATER_OVERVIEW'}></Card>
<div>管网</div> <Card name={'供水量曲线'} widget={'WATER_CHART'}></Card>
<Card name={'管网监控'} widget={'PIPEMONITORING'}></Card> </CardGroup>
<Card name={'管网采集'} widget={'PIPEGATHER'}></Card> <CardGroup title={'管网'} count={4}>
<Card name={'管网巡检'} widget={'PIPEINSPECTION'}></Card> <Card name={'管网监控'} widget={'PIPEMONITORING'}></Card>
<Card name={'维修工单'} widget={'MAINTENANCEORDER'}></Card> <Card name={'管网采集'} widget={'PIPEGATHER'}></Card>
<div>二供</div> <Card name={'管网巡检'} widget={'PIPEINSPECTION'}></Card>
<Card name={'二供总览'} widget={'OPERATIONAL_OVERVIEW'}></Card> <Card name={'维修工单'} widget={'MAINTENANCEORDER'}></Card>
<Card name={'泵房运行状态'} widget={'PUMP_STATUS'}></Card> </CardGroup>
<Card name={'泵房维修保养'} widget={'PUMP_MAINTAIN'}></Card> <CardGroup title={'二供'} count={4}>
<div>营收</div> <Card name={'二供总览'} widget={'OPERATIONAL_OVERVIEW'}></Card>
<Card name={'营收总览'} widget={'REVENUE_OVERVIEW'}></Card> <Card name={'泵房运行状态'} widget={'PUMP_STATUS'}></Card>
<Card name={'泵房维修保养'} widget={'PUMP_MAINTAIN'}></Card>
</CardGroup>
<CardGroup title={'营收'} count={1}>
<Card name={'营收总览'} widget={'REVENUE_OVERVIEW'}></Card>
</CardGroup>
</div> </div>
</div> </div>
</div> </div>
......
@imgSrc: '@/assets/images/mobileConfig/WorkDesign'; @imgSrc: '@/assets/images/mobileConfig/WorkDesign';
.left { .left {
width: 300px; width: 320px;
height: 100%; height: 100%;
background: white; background: white;
.header { .header {
...@@ -97,4 +97,19 @@ ...@@ -97,4 +97,19 @@
} }
} }
} }
}
.cardGroup {
padding-left: 10px;
font-size: 14px;
.g-top {
display: inline;
&:hover {
cursor: pointer;
color: #1890ff;
}
}
.g-cards {
overflow: hidden;
}
} }
\ No newline at end of file
@imgSrc: '@/assets/images/mobileConfig/WorkDesign'; @imgSrc: '@/assets/images/mobileConfig/WorkDesign';
.right { .right {
width: 300px; width: 320px;
height: 100%; height: 100%;
background: white; background: white;
.header { .header {
......
...@@ -9,11 +9,15 @@ import Right from './Right' ...@@ -9,11 +9,15 @@ import Right from './Right'
export const GlobalStore = createContext(null) export const GlobalStore = createContext(null)
const initShema = {
work: [],
active: true,
type: '运营组件',
}
const Designer = (props) => { const Designer = (props) => {
const { currentCard, } = props const { currentCard, } = props
const [shema, setShema] = useState(currentCard['卡片结构'] ? { ...JSON.parse(currentCard['卡片结构']) } : { work: [], active: true }) const [shema, setShema] = useState(currentCard['卡片结构'] ? { ...JSON.parse(currentCard['卡片结构']) } : initShema)
const goBack = () => { const goBack = () => {
props?.goBack?.() props?.goBack?.()
......
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import styles from './index.less' import styles from './index.less'
import { Form, Modal, Input, message, Button, TreeSelect } from 'antd' import { Form, Modal, Input, message, Button, TreeSelect } from 'antd'
import { RightOutlined, ExclamationCircleOutlined } from '@ant-design/icons'
import { getSchemeList, saveScheme, deleteScheme, roleGroupList } from '@/services/mobileConfig/api' import { getSchemeList, saveScheme, deleteScheme, roleGroupList } from '@/services/mobileConfig/api'
import Designer from './components/Designer' import Designer from './components/Designer'
const WorkDesign = (props) => { const WorkDesign = (props) => {
const userName = sessionStorage.getItem('userName') const userName = sessionStorage.getItem('userName')
const [isCardList, setIsCardList] = useState(true)
const [cardList, setCardList] = useState([]) const [cardList, setCardList] = useState([])
const [roleList, setRoleList] = useState([]) const [roleList, setRoleList] = useState([])
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
...@@ -15,6 +17,7 @@ const WorkDesign = (props) => { ...@@ -15,6 +17,7 @@ const WorkDesign = (props) => {
const [form] = Form.useForm() const [form] = Form.useForm()
const addCard = () => { const addCard = () => {
form.setFieldsValue({ '名称': '', '关联角色ID': [], '描述': '' })
setCurrentCard({}) setCurrentCard({})
setVisible(true) setVisible(true)
} }
...@@ -29,6 +32,9 @@ const WorkDesign = (props) => { ...@@ -29,6 +32,9 @@ const WorkDesign = (props) => {
const { code, data } = await getSchemeList() const { code, data } = await getSchemeList()
if (code === 0) { if (code === 0) {
setCardList(data) setCardList(data)
if (data.length) {
setIsCardList(false)
}
} }
} }
...@@ -45,6 +51,7 @@ const WorkDesign = (props) => { ...@@ -45,6 +51,7 @@ const WorkDesign = (props) => {
if (v.roleList) { if (v.roleList) {
v.roleID = v.visibleTitle v.roleID = v.visibleTitle
v.roleName = v.visibleTitle v.roleName = v.visibleTitle
v.disabled = true
} }
v.roleList = v.roleList || [] v.roleList = v.roleList || []
}) })
...@@ -78,13 +85,27 @@ const WorkDesign = (props) => { ...@@ -78,13 +85,27 @@ const WorkDesign = (props) => {
} }
const deleteDesgin = async (item) => { const deleteDesgin = async (item) => {
const { code, data, msg } = await deleteScheme({ ID: item.ID }) Modal.confirm({
if (code === 0) { title: '是否确定删除该工作方案?',
getCardList() icon: <ExclamationCircleOutlined />,
message.success({ content: '删除成功!' }) centered: true,
} else { onOk() {
message.error({ content: msg }) return new Promise(async (resolve, reject) => {
} const { code, data, msg } = await deleteScheme({ ID: item.ID })
if (code === 0) {
resolve()
getCardList()
message.success({ content: '删除成功!' })
} else {
reject()
message.error({ content: msg })
}
})
},
onCancel() {
console.log('Cancel');
},
})
} }
const saveDesgin = async (card) => { const saveDesgin = async (card) => {
...@@ -108,58 +129,72 @@ const WorkDesign = (props) => { ...@@ -108,58 +129,72 @@ const WorkDesign = (props) => {
return ( return (
<div className={styles.workDesign}> <div className={styles.workDesign}>
{ {
!isDesign ? ( isCardList ? (
<div className={styles.content}> <div className={styles.workBg}>
<div className={styles.cardList}> <div className={styles['b-text']}>
<div className={styles.cardAdd}> <span onClick={() => addCard()}>开始搭建工作台</span>
<div className={styles.content}> <RightOutlined style={{ position: 'relative', top: '1px', marginLeft: '5px' }} />
<div className={styles.text} onClick={() => addCard()}> </div>
<span className={styles.addIcon}></span> </div>
<span>新建工作台</span> ) :
!isDesign ? (
<div className={styles.content}>
<div className={styles.cardList}>
<div className={styles.cardAdd}>
<div className={styles.content}>
<div className={styles.text} onClick={() => addCard()}>
<span className={styles.addIcon}></span>
<span>新建工作台</span>
</div>
</div> </div>
</div> </div>
</div> {
{ cardList.map(v => {
cardList.map(v => { return (
return ( <div className={styles.card} key={v.ID}>
<div className={styles.card} key={v.ID}> <div className={styles['card-type']} type={v?.scheme?.type || '运营组件'}>{v?.scheme?.type || '运营组件'}</div>
<div className={styles.title} onClick={() => editCard(v)}>{v['名称']}</div> <div className={styles.title}>
<div className={styles.img}> <div className={styles['title-click']} onClick={() => editCard(v)}>
<div className={styles.imgCenter}> <span className={styles['title-text']}>{v['名称']}</span>
<div> <span className={styles['title-icon']}></span>
<Button type="primary" onClick={() => toDesign(v)}>编辑</Button>
</div>
<div style={{ marginTop: '10px' }}>
<Button type="primary" danger onClick={() => deleteDesgin(v)}>删除</Button>
</div> </div>
</div> </div>
</div> <div className={styles.img}>
<div className={styles.footer}> <div className={styles.imgCenter}>
<div> <div>
<span className={styles.label}>角色名称:</span> <Button type="primary" onClick={() => toDesign(v)}>编辑</Button>
<span>{v['角色名称']}</span> </div>
<div style={{ marginTop: '10px' }}>
<Button type="primary" danger onClick={() => deleteDesgin(v)}>删除</Button>
</div>
</div>
</div> </div>
<div> <div className={styles.footer}>
<span className={styles.label}>更新时间:</span> <div>
<span>{v['更新时间']}</span> <span className={styles.label}>角色名称:</span>
<span>{v['角色名称']}</span>
</div>
<div>
<span className={styles.label}>更新时间:</span>
<span>{v['更新时间']}</span>
</div>
</div> </div>
</div> </div>
</div> )
) })
}) }
} </div>
</div> </div>
</div> ) : (
) : ( <Designer
<Designer currentCard={currentCard}
currentCard={currentCard} goBack={goBack}
goBack={goBack} saveDesgin={saveDesgin}
saveDesgin={saveDesgin} />
/> )
)
} }
<Modal <Modal
title={'创建工作台'} title={currentCard.ID ? '编辑工作台' : '创建工作台'}
visible={visible} visible={visible}
onCancel={() => setVisible(false)} onCancel={() => setVisible(false)}
onOk={onOk} onOk={onOk}
...@@ -168,6 +203,7 @@ const WorkDesign = (props) => { ...@@ -168,6 +203,7 @@ const WorkDesign = (props) => {
<Form <Form
layout="vertical" layout="vertical"
form={form} form={form}
initialValues={{ '名称': '', '关联角色ID': '', '描述': '' }}
> >
<Form.Item <Form.Item
label={'工作台名称'} label={'工作台名称'}
...@@ -191,6 +227,13 @@ const WorkDesign = (props) => { ...@@ -191,6 +227,13 @@ const WorkDesign = (props) => {
> >
</TreeSelect> </TreeSelect>
</Form.Item> </Form.Item>
{/* <Form.Item
label={'组件类型'}
name={'类型'}
rules={[{ required: true }]}
>
<Input />
</Form.Item> */}
<Form.Item <Form.Item
label={'工作台描述'} label={'工作台描述'}
name={'描述'} name={'描述'}
...@@ -199,7 +242,7 @@ const WorkDesign = (props) => { ...@@ -199,7 +242,7 @@ const WorkDesign = (props) => {
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
</div> </div >
) )
} }
......
...@@ -3,18 +3,35 @@ ...@@ -3,18 +3,35 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
background: #efefef; background: #efefef;
.workBg {
width: 100%;
height: 100%;
background: url('@{imgSrc}/新建工作台初始页.png');
background-size: 100% 100%;
.b-text {
text-align: center;
padding: 7.5% 2% 0 0;
font-size: 20px;
font-weight: 700;
color: #0082F0;
&:hover {
cursor: pointer;
}
}
}
.content { .content {
width: 100%; width: 100%;
height: 100%; height: 100%;
border: 1px solid #dbdbdb; border: 1px solid #dbdbdb;
padding: 0 0 0.5% 0.5%; padding: 0 0 0.5% 1.5%;
overflow: auto;
.cardList { .cardList {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
.cardAdd { .cardAdd {
margin-right: 0.55%; margin-right: 1.5%;
margin-top: 0.5%; margin-top: 0.5%;
width: 13.8%; width: 18%;
border-radius: 5px; border-radius: 5px;
background: white; background: white;
padding: 10px; padding: 10px;
...@@ -44,24 +61,51 @@ ...@@ -44,24 +61,51 @@
} }
} }
.card { .card {
margin-right: 0.55%; margin-right: 1.5%;
margin-top: 0.5%; margin-top: 0.5%;
width: 13.7%; width: 18%;
border-radius: 5px; border-radius: 5px;
background: white; background: white;
padding: 10px; padding: 15px;
box-shadow: 1px -2px 7px gainsboro; box-shadow: 1px -2px 7px gainsboro;
position: relative;
.card-type {
position: absolute;
right: -12px;
top: 16px;
width: 80px;
height: 36px;
background: url('@{imgSrc}/运营组件.png');
background-size: 100% 100%;
color: white;
padding-left: 10px;
}
.title { .title {
font-size: 12px; font-size: 12px;
font-weight: 700; font-weight: 700;
&:hover { .title-click {
cursor: pointer; display: inline-block;
color: #1890ff; &:hover {
cursor: pointer;
color: #1890ff;
}
.title-text {
font-size: 16px;
}
.title-icon {
display: inline-block;
margin-left: 5px;
width: 14px;
height: 14px;
background: url('@{imgSrc}/编辑.png');
background-size: 100% 100%;
}
} }
.card-type {}
} }
.img { .img {
width: 100%; width: 100%;
height: 200px; height: 300px;
transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out;
position: relative; position: relative;
background: url('@{imgSrc}/预览图.jpg'); background: url('@{imgSrc}/预览图.jpg');
...@@ -73,7 +117,7 @@ ...@@ -73,7 +117,7 @@
cursor: pointer; cursor: pointer;
.imgCenter { .imgCenter {
width: 100%; width: 100%;
height: 200px; height: 300px;
} }
} }
.imgCenter { .imgCenter {
......
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