Ver Fonte

first edition of AI

Ubuntu há 2 meses atrás
pai
commit
4318ea1d8c
7 ficheiros alterados com 207 adições e 9 exclusões
  1. 1 0
      package.json
  2. 46 0
      src/App2.js
  3. 30 6
      src/Qingdan3.js
  4. 122 0
      src/Service.js
  5. 2 2
      src/SimpleService.js
  6. 3 0
      src/editor.js
  7. 3 1
      src/index.js

+ 1 - 0
package.json

@@ -14,6 +14,7 @@
     "@testing-library/jest-dom": "6.6.3",
     "@testing-library/react": "12.0.0",
     "@testing-library/user-event": "13.5.0",
+    "notistack": "^2.0.8",
     "react": "17.0.2",
     "react-arborist": "^3.4.3",
     "react-dom": "17.0.2",

+ 46 - 0
src/App2.js

@@ -60,6 +60,7 @@ import CloseIcon from '@mui/icons-material/Close';
 import SearchIcon from '@mui/icons-material/Search';
 import Button from '@mui/material/Button';
 import { useNavigate } from "react-router";
+import {SnackbarProvider, useSnackbar} from 'notistack';
 
 
 import Tooltip from '@mui/material/Tooltip';
@@ -165,9 +166,11 @@ function a11yProps(index) {
     const [jxde, setJxde] = React.useState(null);
     const [open, setOpen] = React.useState(false);
     const [dopen, setDopen] = React.useState(false);
+    const [bopen, setBopen] = React.useState(false);
 
     const [dopen2, setDopen2] = React.useState(false);
     const [dopen3, setDopen3] = React.useState(false);
+    const [AIClick, setAIClick] = React.useState(null);
 
     const [dingeclick, setDingeclick] = React.useState(null);
     const [tihuanClick, setTihuanClick] = React.useState(null);
@@ -202,6 +205,7 @@ function a11yProps(index) {
     const [options, setOptions] = React.useState([]);
     const [suanshiError, setSuanshiError] = React.useState(false);
     const [helperText, setHelperText] = React.useState('');
+    const {enqueueSnackbar} = useSnackbar();
 
     
     const traverse = (shu) => {
@@ -240,6 +244,8 @@ function a11yProps(index) {
       setRgde(null);
       setJxde(null);
       setClde(null);
+      setAIClick(null);
+
     };
     const handleChangeTihuan = (event, newValue) => {
       setTihuanValue(newValue);
@@ -267,6 +273,13 @@ function a11yProps(index) {
       });
     };
 
+ const AICallback = (data) => {
+        setBopen(true); 
+        Service.pushTask(data, navigate);
+    };
+
+
+
     const suanshiCallback = () => {
       setDopen2(true);
     };
@@ -1154,6 +1167,31 @@ function a11yProps(index) {
 
       
     }, 1000));
+
+
+    React.useEffect(() => {
+        const interval = setInterval(() => {
+        Service.checkTask().then(x=>{
+            if (x=="success") {
+                setAIClick(Service.getTaskResult());
+                enqueueSnackbar("小造同学给出了组价结果");
+                Service.clearTask();
+                setBopen(false);
+            } else if (x == "failed") {
+                console.log(x);
+                enqueueSnackbar("小造同学遇到了麻烦");
+                Service.clearTask();
+                setBopen(false);
+                }
+        });
+    }, 1000);
+
+    return () => clearInterval(interval);
+    }, []);
+
+
+
+
     React.useEffect(
       () => {
         throttled.current(zhuanye2, acinputvalue);
@@ -1374,6 +1412,8 @@ function a11yProps(index) {
                                 beizhu={beizhu}
                                 beizhuFK={beizhuFK}
                                 clickCallback={clickCallback}
+	                        AICallback={AICallback}
+                                AIClick={AIClick}
                                 loadingCallback={loadingCallback}
                                 dingeclick={dingeclick}
                                 tihuanCallback={tihuanCallback}
@@ -1424,6 +1464,12 @@ function a11yProps(index) {
 
           </Grid>
 
+          <Backdrop
+              sx={(theme) => ({ color: '#fff', zIndex: theme.zIndex.drawer + 1 })}
+              open={bopen}
+          >
+                <CircularProgress color="inherit" />
+         </Backdrop>
           <Backdrop
               sx={(theme) => ({ color: '#fff', zIndex: theme.zIndex.drawer + 1 })}
               open={open}

+ 30 - 6
src/Qingdan3.js

@@ -24,10 +24,11 @@ import TabList from "@mui/lab/TabList";
 import TabPanel from "@mui/lab/TabPanel";
 import Stack from "@mui/material/Stack";
 import Service from './Service';
+import SimpleService from './SimpleService';
 import Button from '@mui/material/Button';
 import ButtonGroup from '@mui/material/ButtonGroup';
 import {extractFuzhu} from './utils';
-import {shanchu, undo, redo, danxiangdinge, updateDercj, changguidinge, handleBeizhu, huan, updateShuliang, handleYuban, updateDeMingcheng, handleRcjbc} from './editor';
+import {handleAI, shanchu, undo, redo, danxiangdinge, updateDercj, changguidinge, handleBeizhu, huan, updateShuliang, handleYuban, updateDeMingcheng, handleRcjbc} from './editor';
 
 import { DataGrid, GridActionsCellItem, zhCN as zhCN_MUI, GridToolbarContainer } from '@mui/x-data-grid';
 
@@ -57,9 +58,9 @@ const {Column, HeaderCell, Cell} = Table;
 
 
 
+export default function Qingdan3({name, bh, bt,  beizhu/*后台传回来的附注信息,要整理后才能成为展示用的行*/ , beizhuFK, clickCallback, loadingCallback, AICallback, dingeclick, tihuanCallback, tihuanClick, bctihuanClick, bctihuanCallback, suanshiCallback, AIClick}) {
 
 
-export default function Qingdan3({name, bh, bt,  beizhu/*后台传回来的附注信息,要整理后才能成为展示用的行*/ , beizhuFK, clickCallback, loadingCallback, dingeclick, tihuanCallback, tihuanClick, bctihuanClick, bctihuanCallback, suanshiCallback}) {
     
      const myTable = React.useRef(null);
      const myRef = React.useRef(null);
@@ -453,7 +454,7 @@ export default function Qingdan3({name, bh, bt,  beizhu/*后台传回来的附
                   isQdrcj.current = true;
                   highlight.current = [];
                });
-               Service.generateQingdanTuijian(name, bh,bt,row._row.data['清单编码']).then(x=>{
+               SimpleService.generateQingdanTuijian(name, bh,bt,row._row.data['清单编码']).then(x=>{
                 setTuijian(x);
                 if (tuijianTable.current) tuijianTable.current.replaceData(x);
                 
@@ -723,7 +724,7 @@ export default function Qingdan3({name, bh, bt,  beizhu/*后台传回来的附
                                           let former = myTable.current.element.children[1].scrollTop;
                                           let former2 = myTable.current.element.children[1].scrollLeft;
                                           myTable.current.deselectRow();
-               myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
+                                           myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
                                             myTable.current.element.children[1].scrollTop = former;
                                             myTable.current.element.children[1].scrollLeft = former2;
                                               let getRow = myTable.current.getRows(); //get array of currently selected row components.
@@ -1030,7 +1031,22 @@ export default function Qingdan3({name, bh, bt,  beizhu/*后台传回来的附
           }, [beizhuFK]
       );
 
-  
+      React.useEffect(
+          () => {
+              if (AIClick!=null){
+                 const [success, data, key] = handleAI(AIClick);
+                         if(success) {
+                                          let former = myTable.current.element.children[1].scrollTop;
+                                          let former2 = myTable.current.element.children[1].scrollLeft;
+                              myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
+                                     myTable.current.element.children[1].scrollTop = former;
+                                     myTable.current.element.children[1].scrollLeft = former2;
+                                   resetUI();
+                                 });
+                         }
+              }
+          }, [AIClick]//AI添加定额
+      );  
 
 
       React.useEffect(
@@ -1436,7 +1452,15 @@ const EditableCell = ({ rowData, dataType, dataKey, onChange, ...props }) => {
                       
                       }}
                    >保存</Button>
-                  
+                    <Button variant="outlined" size="small" onClick={() => {
+                            console.log("AI");
+                            console.log(selectedRowKeysTableParent.current);
+                            let target = myTable.current.getRows().filter(x=>x._row['data']['key']==selectedRowKeysTableParent.current);
+                            if (target.length > 0)
+                                AICallback(target[0]._row['data']);
+                      
+                      }}
+                   >小造AI</Button>
                    </Stack>
                    <div style={{width: "70vw"}}>
                    <div ref={myRef}> 

+ 122 - 0
src/Service.js

@@ -27,6 +27,7 @@ class Service{
             '04050101' : ['道碴 40~80mm', 47],
             '04034103' : ['石屑(米砂)', 40]
         };
+	this.task={};
         
     }
     setToken(token) {
@@ -46,6 +47,7 @@ class Service{
         this.cache_djcs = [];
         this.memory_djcs = [];
         this.mem_pointer_djcs = -1;
+	this.task={};
     }
 
     setQufei(data) {
@@ -2053,7 +2055,40 @@ class Service{
         }
     }
 
+    handleAI(result) {
+        let keys = Object.keys(result);
+        let datakey = null;
+        for (let i = 0; i < keys.length; i++) {
+            let key = keys[i]
+            let hits = this.cache.filter(x=>x['清单编码']==key);
+            let qd = hits[0]
+            let r = result[key]
+            let rr = r['result']
+            let rrr = rr['result'][0]
+            //console.log(rrr)
+            //console.log(qd)
+            datakey = qd['key']
+            qd['rcj']=rrr['rcj']
+            qd['主材费'] = String(rrr['主材费'])
+            qd['人工费'] = String(rrr['人工费'])
+            qd['利润'] = String(rrr['利润'])
+            qd['合价'] = String(rrr['合价'])
+            qd['暂估价'] = String(rrr['暂估价'])
+            qd['机械费'] = String(rrr['机械费'])
+            qd['材料费'] = String(rrr['材料费'])
+            qd['管理费'] = String(rrr['管理费'])
+            qd['综合人工工日'] = String(rrr['综合人工工日'])
+            qd['综合单价'] = String(rrr['综合单价'])
+            qd['设备费'] = String(rrr['设备费'])
+            qd['辅材费'] = String(rrr['辅材费'])
+            qd['_children'] = rrr['_children']
+        }
+                this.push_op(copy(this.cache));
+            
+                this.updateFootprint(datakey);
 
+                return [true, copy(this.cache), datakey];
+    }
 
     changguidinge(dingeclick, row) {
         if (this.cache.filter(x=>x['key'] == row).length > 0) {
@@ -2363,6 +2398,93 @@ class Service{
         return input;
     }
 
+ async   pushTask(data, navigate) {
+        let data2 = copy(data);
+        data2['now'] = Date.now();
+        const response = await fetch(this.ip().concat( "/pushtask/"), {
+            method : "POST",
+            headers: {
+                "Content-type": "application/json",
+                'Authorization': `Bearer ${this.token_}`
+
+            },
+            body: JSON.stringify({
+               "bianma": data['清单编码'],
+               "mc" : data['名称'],
+               "tz" : data['项目特征'],
+               "dw" : data['单位'] ,
+               "sl" : data['数量']
+            } )
+        });
+        if (!response.ok) {
+            if (response.status == 401) {
+                 navigate("/editor/signin");
+            }
+        }
+        else {
+        
+            const r = await response.json();
+            data2['celery_id']=r['id'];
+            this.task[data['清单编码']]=data2;
+            return r;
+        }
+    }
+
+
+clearTask() {
+   this.task={};
+
+}
+getTaskResult() {
+    return copy(this.task);
+}
+async checkTask() {
+    let keys = Object.keys(this.task);
+    if (keys.length == 0)return "empty";
+    for(let i = 0; i < keys.length; i++){
+        let entry = this.task[keys[i]];
+        if (entry.hasOwnProperty("result")) {
+            if (entry["result"]=='failed') return "failed";
+            else continue;
+        }else {
+            let now = entry['now'];
+            let current = Date.now();
+            if (current - now > 100000){
+                entry['result']="failed";
+                return "failed";
+            } else {
+                const response = await fetch(this.ip().concat( "/checktask/".concat(entry['celery_id'])), {
+                    method : "GET",
+                    headers : {
+                         'Authorization': `Bearer ${this.token_}`
+                          }           
+            
+                });
+                if (!response.ok) {
+                    console.error('error');
+                    entry['result'] = "failed";
+                    return "failed";
+                } else {
+                    const data = await response.json();
+                    console.log(data);
+                    if (data['status']=='FAILURE') {
+                         entry['result']='failed';
+                         return 'failed';
+                    } else if (data['status']=='SUCCESS') {
+                         entry['result']=data['result'];
+                         return "progress";
+                    } else {
+                         return "progress";
+                    }
+                }
+            
+          }
+       }
+    }
+    return "success";
+        
+}
+
     
 }
 

+ 2 - 2
src/SimpleService.js

@@ -569,7 +569,7 @@ async generateQingdanTuijian(name, bh, bt, bm) {
             return data;
         }
     }
-    async generateSingleDingeXilie(zhuanye, debh, mc) {//清单页面展示用
+    async generateSingleDingeXilie(zhuanye, debh, mc) {//要猜专业
         const response = await fetch(this.ip().concat( "/singledexilie/").concat(zhuanye.toString()).concat("/").concat(debh).concat("/").concat(encodeURIComponent(mc.replace(/\//g, ''))), {
             method : "GET",
            
@@ -582,7 +582,7 @@ async generateQingdanTuijian(name, bh, bt, bm) {
             return data;
         }
     }
-    async generateSingleDingeXilie2(zhuanye, debh) {//清单页面展示用
+    async generateSingleDingeXilie2(zhuanye, debh) {//不要猜专业
         const response = await fetch(this.ip().concat( "/singledexilie2/").concat(zhuanye.toString()).concat("/").concat(debh.replace(/\//g, '')), {
             method : "GET",
            

+ 3 - 0
src/editor.js

@@ -129,7 +129,10 @@ export const handleBeizhu = (beizhuFK/**辅库json */, derow, fuzhuSelect/*被
     return Service.updateBeizhu(derow, result, xuhao);
 };
 
+export const handleAI = (result ) => {
+    return Service.handleAI(result);
 
+};
 ///////////////////////////////////////////DJCS///////////////////////////////////////////
 
 export const handleBeizhu_djcs = (beizhuFK, derow, fuzhuSelect, fuzhu ) => {

+ 3 - 1
src/index.js

@@ -3,6 +3,8 @@ import ReactDOM from 'react-dom';
 import './index.css';
 import reportWebVitals from './reportWebVitals';
 import {createBrowserRouter, RouterProvider, Route, Link} from "react-router-dom";
+import {SnackbarProvider} from 'notistack';
+
 const Home2 = React.lazy(() => import('./Home2'));
 const App2 = React.lazy(() => import('./App2'));
 const AI = React.lazy(() => import('./AI'));
@@ -10,7 +12,7 @@ const Signin = React.lazy(() => import('./Signin'));
 
 const router = createBrowserRouter([
    {path: "/editor/qingdan/:id",
-     element: (<Suspense fallback={<div></div>}><App2></App2></Suspense>)
+     element: (<Suspense fallback={<div></div>}><SnackbarProvider><App2></App2></SnackbarProvider></Suspense>)
    },
    {path: "/editor/index.html",
    element: (<Suspense fallback={<div></div>}><Home2></Home2></Suspense>)