Browse Source

Merge wzy

Merge wzy
XieYongHong 3 years ago
parent
commit
3ea0405366

BIN
public/images/cloud/dueros-doc1.png


BIN
public/images/cloud/dueros-doc2.png


BIN
public/images/cloud/dueros-doc3.png


BIN
public/images/home/guide-home1.png


BIN
public/images/home/guide-home2.png


BIN
public/images/home/guide-home3.png


BIN
public/images/home/guide-home4.png


BIN
public/images/home/guide-home5.png


BIN
public/images/home/guide-home6.png


BIN
public/images/home/home-1.png


BIN
public/images/home/home-2.png


BIN
public/images/home/home-3.png


+ 35 - 1
src/pages/Northbound/DuerOS/Detail/Doc.tsx

@@ -1,6 +1,10 @@
-import { Image } from 'antd';
+import { InfoCircleFilled } from '@ant-design/icons';
+import { Alert, Image } from 'antd';
 
 const image = require('/public/images/cloud/dueros-doc.jpg');
+const image1 = require('/public/images/cloud/dueros-doc1.png');
+const image2 = require('/public/images/cloud/dueros-doc2.png');
+const image3 = require('/public/images/cloud/dueros-doc3.png');
 
 const Doc = () => {
   return (
@@ -25,6 +29,36 @@ const Doc = () => {
         <div className={'image'}>
           <Image width="100%" src={image} />
         </div>
+        <h1>授权地址</h1>
+        <div>物联网平台的登录地址。注意需要为https。</div>
+        <div>请复制并填写: https://pro.baidu.cn/#/user/login</div>
+        <div className={'image'}>
+          <Image width="100%" src={image1} />
+        </div>
+        <h1>Client_Id</h1>
+        <div>请填写物联网平台-第三方平台的clientId。</div>
+        <div className={'image'}>
+          <Image width="100%" src={image2} />
+        </div>
+        <h1>Token地址</h1>
+        <div>请复制DuerOS平台中的值,填写到第三方平台-redirectUrl中</div>
+        <div>
+          <Alert
+            icon={<InfoCircleFilled style={{ fontSize: 16, marginTop: 5 }} />}
+            description="注:需要将OAth2设置为开启状态。"
+            showIcon
+          />
+        </div>
+        <div className={'image'}>
+          <Image width="100%" src={image3} />
+        </div>
+        <h1>Token地址</h1>
+        <div>请复制并填写:HTTPS://【IP:端口】/api/v1/token</div>
+        <h2>ClientSecret</h2>
+        <div>请复制物联网平台-第三方平台中的secureKey,填写到DuerOS平台。</div>
+        <div></div>
+        <h1>WebService</h1>
+        <div>请复制并填写:/dueros/product/_query</div>
         <h2>2、登录物联网平台,进行平台内产品与dueros产品的数据映射。</h2>
         <h2>
           3、智能家居用户通过物联网平台中的用户,登录小度APP,获取平台内当前用户的所属设备。获取后即可进行语音控制。

+ 13 - 0
src/pages/device/Product/Detail/PropertyImport/index.tsx

@@ -128,6 +128,11 @@ const PropertyImport = (props: Props) => {
           };
         });
       });
+      onFieldValueChange('fileType', (field) => {
+        if (field.value === 'csv') {
+          field.title = '文件格式:  仅支持UTF-8格式编码格式';
+        } else field.title = '文件格式';
+      });
     },
   });
 
@@ -153,6 +158,14 @@ const PropertyImport = (props: Props) => {
               buttonStyle: 'solid',
               optionType: 'button',
             },
+            // 'x-reactions':{
+            //   dependencies:['properties'],
+            //   fulfill:{
+            //     state:{
+            //       title:'{{$deps[0]===csv?"文件格式: 仅支持UTF-8格式编码格式":"文件格式"}}'
+            //     }
+            //   }
+            // },
             enum: [
               {
                 label: 'xlsx',

+ 74 - 13
src/pages/device/Product/Save/index.tsx

@@ -3,10 +3,11 @@ import { service } from '@/pages/device/Product';
 import type { ProductItem } from '@/pages/device/Product/typings';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { RadioCard, UploadImage } from '@/components';
-import { Col, Form, Input, Modal, Row, TreeSelect } from 'antd';
-import { useRequest } from 'umi';
+import { Button, Col, Form, Input, Modal, Row, TreeSelect } from 'antd';
+import { useHistory, useRequest } from 'umi';
 import { debounce } from 'lodash';
 import { onlyMessage } from '@/utils/util';
+import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 
 interface Props {
   visible: boolean;
@@ -21,6 +22,7 @@ const Save = (props: Props) => {
   const intl = useIntl();
   const [form] = Form.useForm();
   const [loading, setLoading] = useState(false);
+  const history = useHistory<Record<string, string>>();
   const { data: classOptions, run: classRequest } = useRequest(service.category, {
     manual: true,
     formatResult: (response) => {
@@ -70,6 +72,47 @@ const Save = (props: Props) => {
     }
   }, [visible]);
 
+  const messageModel = (id: string) => {
+    return Modal.success({
+      title: <div style={{ fontWeight: 600 }}>产品创建成功</div>,
+      width: 600,
+      okText: '关闭',
+      content: (
+        <>
+          <div style={{ display: 'flex', alignItems: 'center', marginBottom: 10 }}>
+            <div>产品ID: {id}</div>
+            <Button
+              type="link"
+              onClick={() => {
+                history.push(`${getMenuPathByParams(MENUS_CODE['device/Product/Detail'], id)}`);
+                Modal.destroyAll();
+              }}
+            >
+              查看详情
+            </Button>
+          </div>
+          <div>接下来推荐操作:</div>
+          <div style={{ fontWeight: 600 }}> 1、配置产品接入方式</div>
+          <div style={{ color: '#757575' }}>
+            点击具体产品的查看按钮,进入“设备接入”tab页,并参照设备铭牌说明选择匹配的接入方式
+          </div>
+          <div style={{ fontWeight: 600 }}>2、添加测试设备:</div>
+          <div style={{ color: '#757575' }}>
+            进入设备列表,添加单个设备,用于验证产品模型是否配置正确
+          </div>
+          <div style={{ fontWeight: 600 }}> 3、功能调试:</div>
+          <div style={{ color: '#757575' }}>
+            点击查看具体设备,进入“设备诊断”对添加的测试设备进行功能调试,验证能否连接到平台,设备功能是否配置正确
+          </div>
+          <div style={{ fontWeight: 600 }}> 4、批量添加设备:</div>
+          <div style={{ color: '#757575' }}>
+            进入设备列表页面,点击批量导入设备,批量添加同一产品下的设备
+          </div>
+        </>
+      ),
+    });
+  };
+
   const handleSave = async () => {
     const formData = await form.validateFields();
     if (formData) {
@@ -79,18 +122,36 @@ const Save = (props: Props) => {
       const { deviceTypeId, ...extraFormData } = formData;
       extraFormData.deviceType = formData.deviceTypeId;
       setLoading(true);
-      const res = await service.update(extraFormData);
-      setLoading(false);
-      if (res.status === 200) {
-        onlyMessage('保存成功');
-        if (props.reload) {
-          props.reload();
+      if (props.model === 'add') {
+        const res: any = await service.save(extraFormData);
+        setLoading(false);
+        if (res.status === 200) {
+          // onlyMessage('保存成功');
+          messageModel(res.result.id);
+          if (props.reload) {
+            props.reload();
+          }
+          props.close();
+          form.resetFields();
+          if ((window as any).onTabSaveSuccess) {
+            (window as any).onTabSaveSuccess(res);
+            setTimeout(() => window.close(), 300);
+          }
         }
-        props.close();
-        form.resetFields();
-        if ((window as any).onTabSaveSuccess) {
-          (window as any).onTabSaveSuccess(res);
-          setTimeout(() => window.close(), 300);
+      } else {
+        const res = await service.update(extraFormData);
+        setLoading(false);
+        if (res.status === 200) {
+          onlyMessage('保存成功');
+          if (props.reload) {
+            props.reload();
+          }
+          props.close();
+          form.resetFields();
+          if ((window as any).onTabSaveSuccess) {
+            (window as any).onTabSaveSuccess(res);
+            setTimeout(() => window.close(), 300);
+          }
         }
       }
     }

+ 2 - 0
src/pages/device/components/Metadata/Base/index.tsx

@@ -19,6 +19,7 @@ import { asyncUpdateMedata, removeMetadata } from '../metadata';
 import type { permissionType } from '@/hooks/permission';
 import { PermissionButton } from '@/components';
 import { onlyMessage } from '@/utils/util';
+import { message } from 'antd';
 
 interface Props {
   type: MetadataType;
@@ -87,6 +88,7 @@ const BaseMetadata = observer((props: Props) => {
             MetadataModel.item = record;
             MetadataModel.type = type;
             MetadataModel.action = 'edit';
+            message.warning('修改物模型后会脱离产品物模型');
           }}
           tooltip={{
             title: operateLimits('add', type) ? '暂不支持' : '编辑',

+ 13 - 11
src/pages/device/components/Metadata/Cat/index.tsx

@@ -91,17 +91,19 @@ const Cat = observer((props: Props) => {
       <Tabs onChange={convertMetadata}>
         {codecs?.map((item) => (
           <Tabs.TabPane tab={item.name} tabKey={item.id} key={item.id}>
-            <MonacoEditor
-              height={350}
-              theme="vs"
-              language="json"
-              value={value}
-              editorDidMount={(editor) => {
-                editor.onDidScrollChange?.(() => {
-                  editor.getAction('editor.action.formatDocument').run();
-                });
-              }}
-            />
+            <div style={{ border: '1px solid #eee' }}>
+              <MonacoEditor
+                height={350}
+                theme="vs"
+                language="json"
+                value={value}
+                editorDidMount={(editor) => {
+                  editor.onDidScrollChange?.(() => {
+                    editor.getAction('editor.action.formatDocument').run();
+                  });
+                }}
+              />
+            </div>
           </Tabs.TabPane>
         ))}
       </Tabs>

+ 2 - 1
src/pages/device/components/Metadata/index.less

@@ -3,6 +3,7 @@
 .tips {
   position: absolute;
   top: 12px;
-  margin-left: 340px;
+  z-index: 1;
+  margin-left: 330px;
   font-weight: 100;
 }

+ 15 - 5
src/pages/device/components/Metadata/index.tsx

@@ -1,5 +1,5 @@
 import { observer } from '@formily/react';
-import { Space, Tabs } from 'antd';
+import { Space, Tabs, Tooltip } from 'antd';
 import BaseMetadata from './Base';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import Import from './Import';
@@ -50,10 +50,20 @@ const Metadata = observer((props: Props) => {
   return (
     <div className={'device-detail-metadata'} style={{ position: 'relative', minHeight }}>
       <div className={styles.tips}>
-        <InfoCircleOutlined style={{ marginRight: '3px' }} />
-        {InstanceModel.detail?.independentMetadata && props.type === 'device'
-          ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
-          : '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'}
+        <Tooltip
+          title={
+            InstanceModel.detail?.independentMetadata
+              ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
+              : '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'
+          }
+        >
+          <span>
+            <InfoCircleOutlined style={{ marginRight: '3px' }} />
+            {InstanceModel.detail?.independentMetadata
+              ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
+              : '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'}
+          </span>
+        </Tooltip>
       </div>
       <Tabs
         className={styles.metadataNav}

+ 82 - 0
src/pages/home/components/GuideHome.tsx

@@ -0,0 +1,82 @@
+import './index.less';
+import { message } from 'antd';
+import useHistory from '@/hooks/route/useHistory';
+import Title from './Title';
+
+const Image = {
+  1: require('/public/images/home/home-1.png'),
+  2: require('/public/images/home/home-2.png'),
+  3: require('/public/images/home/home-3.png'),
+};
+
+interface GuideProps {
+  title: string;
+  data: GuideItemProps[];
+}
+
+interface GuideItemProps {
+  key: string;
+  name: string;
+  english: string;
+  url: string;
+  param?: Record<string, any>;
+  index?: number;
+  auth: boolean;
+  img?: string;
+}
+
+const GuideItem = (props: GuideItemProps) => {
+  const history = useHistory();
+
+  const jumpPage = () => {
+    if (props.url && props.auth) {
+      history.push(`${props.url}`, props.param);
+    } else {
+      message.warning('暂无权限,请联系管理员');
+    }
+  };
+
+  return (
+    <div
+      className={'home-guide-item step-bar'}
+      onClick={jumpPage}
+      style={{ marginTop: 12, padding: 10, border: '1px solid #eee' }}
+    >
+      <div style={{ display: 'flex', alignItems: 'center' }}>
+        <div>
+          <img src={props.img} />
+        </div>
+        <div>
+          <div className={'item-english'}>{`STP${props.index}`}</div>
+          <div
+            className={'item-title'}
+            style={{
+              margin: 0,
+              fontSize: '18px',
+            }}
+          >
+            {props.name}
+          </div>
+        </div>
+      </div>
+      <div className={`item-index`} style={{ width: 37 }}>
+        <img src={Image[props.index!]} />
+      </div>
+    </div>
+  );
+};
+
+const GuideHome = (props: GuideProps) => {
+  return (
+    <div className={'home-guide'}>
+      <Title title={props.title} />
+      <div>
+        {props.data.map((item, index) => (
+          <GuideItem {...item} index={index + 1} key={item.key} />
+        ))}
+      </div>
+    </div>
+  );
+};
+
+export default GuideHome;

+ 1 - 0
src/pages/home/components/index.less

@@ -90,6 +90,7 @@
 .home-body {
   .home-base;
 
+  min-height: 440px;
   margin-bottom: @margin;
   padding-bottom: 26.5%;
   overflow: hidden;

+ 85 - 74
src/pages/home/comprehensive/index.tsx

@@ -3,7 +3,7 @@ import useHistory from '@/hooks/route/useHistory';
 import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import { Col, message, Row, Tooltip } from 'antd';
 import Body from '../components/Body';
-import Guide from '../components/Guide';
+// import Guide from '../components/Guide';
 import Statistics from '../components/Statistics';
 import Steps from '../components/Steps';
 import { service } from '..';
@@ -14,6 +14,7 @@ import Pie from '../components/Pie';
 import { QuestionCircleOutlined } from '@ant-design/icons';
 import ProductChoose from '../components/ProductChoose';
 import DeviceChoose from '../components/DeviceChoose';
+import GuideHome from '../components/GuideHome';
 
 const Comprehensive = () => {
   const [subscribeTopic] = useSendWebsocketMessage();
@@ -91,6 +92,7 @@ const Comprehensive = () => {
     {
       key: 'product',
       name: '创建产品',
+      img: require('/public/images/home/guide-home1.png'),
       english: 'CREATE PRODUCT',
       auth: !!productPermission.add,
       url: 'device/Product',
@@ -102,6 +104,7 @@ const Comprehensive = () => {
       key: 'device',
       name: '创建设备',
       english: 'CREATE DEVICE',
+      img: require('/public/images/home/guide-home2.png'),
       auth: !!devicePermission.add,
       url: 'device/Instance',
       param: {
@@ -112,6 +115,7 @@ const Comprehensive = () => {
       key: 'rule-engine',
       name: '规则引擎',
       english: 'RULE ENGINE',
+      img: require('/public/images/home/guide-home3.png'),
       auth: !!rulePermission.add,
       url: 'rule-engine/Instance',
       param: {
@@ -124,6 +128,7 @@ const Comprehensive = () => {
     {
       key: 'access',
       name: '设备接入配置',
+      img: require('/public/images/home/guide-home4.png'),
       english: 'DEVICE ACCESS CONFIGURATION',
       auth: !!accessPermission,
       url: accessPermission,
@@ -132,6 +137,7 @@ const Comprehensive = () => {
       key: 'logger',
       name: '日志排查',
       english: 'LOG SCREEN',
+      img: require('/public/images/home/guide-home5.png'),
       auth: !!logPermission,
       url: logPermission,
       param: {
@@ -141,6 +147,7 @@ const Comprehensive = () => {
     {
       key: 'realtime',
       name: '实时监控',
+      img: require('/public/images/home/guide-home6.png'),
       english: 'REAL-TIME MONITORING',
       auth: !!linkPermission,
       url: linkPermission,
@@ -152,80 +159,84 @@ const Comprehensive = () => {
 
   return (
     <Row gutter={24}>
-      <Col span={14}>
-        <Guide title="物联网引导" data={guideList} />
+      <Col span={6}>
+        <GuideHome title="物联网引导" data={guideList} />
+        <GuideHome title="运维引导" data={guideOpsList} />
       </Col>
-      <Col span={10}>
-        <Statistics
-          data={[
-            {
-              name: '产品数量',
-              value: productCount,
-              children: '',
-            },
-            {
-              name: '设备数量',
-              value: deviceCount,
-              children: '',
-            },
-          ]}
-          title="设备统计"
-          extra={
-            <div style={{ fontSize: 14, fontWeight: 400 }}>
-              <a
-                onClick={() => {
-                  const url = getMenuPathByCode(MENUS_CODE['device/DashBoard']);
-                  if (!!url) {
-                    history.push(`${url}`);
-                  } else {
-                    message.warning('暂无权限,请联系管理员');
-                  }
-                }}
-              >
-                详情
-              </a>
-            </div>
-          }
-        />
-      </Col>
-      <Col span={14}>
-        <Guide title="运维引导" data={guideOpsList} />
-      </Col>
-      <Col span={10}>
-        <Statistics
-          data={[
-            {
-              name: 'CPU使用率',
-              value: String(cpuValue) + '%',
-              children: <Pie value={cpuValue} />,
-            },
-            {
-              name: 'JVM内存',
-              value: String(jvmValue) + '%',
-              children: <Pie value={jvmValue} />,
-            },
-          ]}
-          title="基础统计"
-          extra={
-            <div style={{ fontSize: 14, fontWeight: 400 }}>
-              <a
-                onClick={() => {
-                  const url = getMenuPathByCode(MENUS_CODE['link/DashBoard']);
-                  if (!!url) {
-                    history.push(`${url}`);
-                  } else {
-                    message.warning('暂无权限,请联系管理员');
-                  }
-                }}
-              >
-                详情
-              </a>
-            </div>
-          }
-        />
-      </Col>
-      <Col span={24}>
-        <Body title={'平台架构图'} english={'PLATFORM ARCHITECTURE DIAGRAM'} />
+      <Col span={18}>
+        <Row gutter={24}>
+          <Col span={12}>
+            <Statistics
+              data={[
+                {
+                  name: '产品数量',
+                  value: productCount,
+                  children: '',
+                },
+                {
+                  name: '设备数量',
+                  value: deviceCount,
+                  children: '',
+                },
+              ]}
+              title="设备统计"
+              extra={
+                <div style={{ fontSize: 14, fontWeight: 400 }}>
+                  <a
+                    onClick={() => {
+                      const url = getMenuPathByCode(MENUS_CODE['device/DashBoard']);
+                      if (!!url) {
+                        history.push(`${url}`);
+                      } else {
+                        message.warning('暂无权限,请联系管理员');
+                      }
+                    }}
+                  >
+                    详情
+                  </a>
+                </div>
+              }
+            />
+          </Col>
+          <Col span={12}>
+            <Statistics
+              data={[
+                {
+                  name: 'CPU使用率',
+                  value: String(cpuValue) + '%',
+                  children: <Pie value={cpuValue} />,
+                },
+                {
+                  name: 'JVM内存',
+                  value: String(jvmValue) + '%',
+                  children: <Pie value={jvmValue} />,
+                },
+              ]}
+              title="基础统计"
+              extra={
+                <div style={{ fontSize: 14, fontWeight: 400 }}>
+                  <a
+                    onClick={() => {
+                      const url = getMenuPathByCode(MENUS_CODE['link/DashBoard']);
+                      if (!!url) {
+                        history.push(`${url}`);
+                      } else {
+                        message.warning('暂无权限,请联系管理员');
+                      }
+                    }}
+                  >
+                    详情
+                  </a>
+                </div>
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={24}>
+          <Col span={24} style={{ marginTop: 24 }}>
+            <Body title={'平台架构图'} english={'PLATFORM ARCHITECTURE DIAGRAM'} />
+          </Col>
+        </Row>
       </Col>
       <Col span={24}>
         <Steps

+ 1 - 0
src/pages/user/Login/index.tsx

@@ -67,6 +67,7 @@ const Login: React.FC = () => {
 
   useEffect(getCode, []);
   useEffect(() => {
+    localStorage.clear();
     Service.bindInfo().then((res) => {
       if (res.status === 200) {
         setBindings(res.result);