Browse Source

Merge branch 'master' of http://39.106.8.246:3003/BDTP/adm-frontend

qule 3 years ago
parent
commit
1b7df2c231

+ 31 - 0
docker/dockerfiles/adm-front/Dockerfile

@@ -0,0 +1,31 @@
+FROM nginx:1.16.1
+
+MAINTAINER lijie<lijie@persagy.com>
+
+ARG PROGRAM_ID
+ARG PORT_LOCAL
+
+LABEL tier=frontend
+LABEL product=bdtp
+LABEL project=adm-front
+LABEL name=$PROGRAM_ID
+
+#ENV JAVA_OPTS -Dfile.encoding=UTF-8 -Xms300m -Xmx1024m
+ENV TZ Asia/Shanghai
+ENV WORKER_HOME /usr/persagy/saas-web
+ENV CONFIG_PATH /data/SpringCloud
+ENV PROGRAM_NAME $PROGRAM_ID
+
+WORKDIR $WORKER_HOME
+
+RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list \
+    && apt-get update \
+    && apt-get install -y --no-install-recommends tzdata unzip \
+    && apt-get autoclean \
+    && apt-get clean \
+    && rm -rf /var/lib/apt/lists/*
+
+RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
+COPY *.zip $WORKER_HOME/
+RUN unzip *.zip
+RUN rm -rf ./*.zip

+ 59 - 0
docker/k8sfiles/adm-front.yml

@@ -0,0 +1,59 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: adm-front
+  labels:
+    app: adm-front
+spec:
+  selector:
+    app: adm-front
+  ports:
+    - port: 80
+      targetPort: 80
+      name: server-port
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: adm-front
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: adm-front
+  template:
+    metadata:
+      labels:
+        app: adm-front
+    spec:
+      containers:
+        - name: adm-front
+          image: labisenlin.persagy.com/library/adm-front:latest
+          imagePullPolicy: Always
+          ports:
+            - containerPort: 80
+              name: server-port
+          resources:
+            limits:
+              memory: 1Gi
+            requests:
+              memory: 512Mi
+          env:
+            - name: TZ
+              value: Asia/Shanghai
+            - name: SERVER_PORT
+              value: "80"
+          volumeMounts:
+            - name: config
+              mountPath: /etc/nginx/nginx.conf
+              subPath: path/to/nginx.conf.js
+      volumes:
+        - name: config
+          configMap:
+            name: public-config
+            defaultMode: 0777
+            items:
+              - key: nginx.conf
+                path: path/to/nginx.conf.js

+ 80 - 0
docker/k8sfiles/configmap.yml

@@ -0,0 +1,80 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: adm-front
+  namespace: persagy
+  labels:
+    name: adm-front
+data:
+  nginx.conf: |
+    #user tony;
+    worker_processes 4;
+    error_log /var/log/nginx/error.log;
+    pid /run/nginx.pid;
+    worker_rlimit_nofile 100001;
+    # Load dynamic modules. See /usr/share/nginx/README.dynamic.
+    include /usr/share/nginx/modules/*.conf;
+
+    events {
+        worker_connections 1024;
+    }
+
+    http {
+        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                          '$status $body_bytes_sent "$http_referer" '
+                          '"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
+
+        access_log  /var/log/nginx/access.log  main;
+
+        sendfile            on;
+        tcp_nopush          on;
+        tcp_nodelay         on;
+        keepalive_timeout   65;
+        types_hash_max_size 2048;
+
+        include             /etc/nginx/mime.types;
+        default_type        application/octet-stream;
+
+        gzip  on;
+        gzip_min_length 1k;
+        gzip_buffers 4 16k;
+        gzip_http_version 1.1;
+        gzip_comp_level 2;
+        gzip_types text/plain application/x-javascript application/css  text/css application/xml text/javascript application/x-httpd-php
+        gzip_vary on;
+
+        server {
+            listen 80 default_server;
+            root /usr/persagy/saas-web;
+
+            # FMS
+            location /admplus {
+                try_files $uri $uri/ /adm-front/index.html;
+            }
+    
+            location @rewrites {
+                rewrite ^(.+)$ /index.html last;
+            }
+
+            location ~* \.(?:ico|css|js|woff|eot|otf|ttf)$ {
+                # Some basic cache-control for static files to be sent to the browser
+                add_header  Access-Control-Allow-Origin *;
+            }
+            location ~index.html
+            {
+                    add_header Cache-Control no-cache;
+            }
+        }
+
+    }
+  vue.config.js: |
+    module.exports = {
+        devServer: {
+            proxy: {
+                '/admplus': {
+                    target: 'http://adm-front:8838',
+                },
+            },
+        },
+    }

+ 1 - 0
package.json

@@ -8,6 +8,7 @@
     "build": "vue-cli-service build"
   },
   "dependencies": {
+    "@amap/amap-jsapi-loader": "^1.0.1",
     "@saga-web/base": "^2.1.28",
     "@saga-web/cad-engine": "^2.0.595",
     "@saga-web/draw": "^2.1.114",

+ 5 - 0
public/index.html

@@ -6,6 +6,11 @@
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <title><%=htmlWebpackPlugin.options.title %></title>
     <script type="text/javascript" src="<%=htmlWebpackPlugin.files.publicPath %>systemConf.js"></script>
+    <script type="text/javascript">
+      window._AMapSecurityConfig = {
+          securityJsCode:'206d40d052767b54cb13500ada5c97fa',
+      }
+</script>
   </head>
   <body>
     <noscript>

+ 2 - 0
public/systemConf.js

@@ -3,6 +3,8 @@ var __systemConf = {
   baseServiceUrl: '/baseService',
   //系统图服务域名
   sysGraphServiceUrl: '/sysGraphService',
+  // 地图key
+  mapKey: 'd42beb96e0e4fb0d49482975abeae1b7',
   //导航菜单
   menus: [{
     "id": "ready",

+ 37 - 0
src/components/project-manage/components/anchor.vue

@@ -0,0 +1,37 @@
+<template>
+    <div>
+        <div v-for="item in points" :key="item.value" @click="go(item.value)">{{item.label}}</div>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            points: [
+                {
+                    label: '基本信息',
+                    value: 'basic'
+                },
+                {
+                    label: '地理信息',
+                    value: 'geo'
+                },
+                {
+                    label: '项目信息',
+                    value: 'project'
+                },
+                {
+                    label: '商业信息',
+                    value: 'business'
+                }
+            ]
+        }
+    },
+    methods: {
+        go(value) {
+            this.$emit('goAnchor', value)
+        }
+    }
+}
+</script>
+<style lang="less" scoped></style>

+ 48 - 0
src/components/project-manage/components/basic.vue

@@ -0,0 +1,48 @@
+<template>
+  <div class="basic-container">
+    <Title :name="name" />
+    <div class="basic-content">
+      <div class="basic-line">
+        项目ID:<span>{{ "XXXXXXXXX" }}</span>
+      </div>
+      <div class="basic-line">
+        项目本地名称:<span>{{ "XXXXXXXXX" }}</span>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import Title from "./title.vue";
+export default {
+  components: {
+    Title,
+  },
+  props: {
+    name: {
+      type: String,
+      default: "",
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.basic {
+  &-container {
+    padding-bottom: 40px;
+  }
+  &-content {
+    display: flex;
+    padding-left: 16px;
+  }
+  &-line {
+    font-size: 14px;
+    color: #646c73;
+    span {
+      color: #1f2429;
+    }
+    &:nth-child(2) {
+      margin-left: 157px;
+    }
+  }
+}
+</style>

+ 16 - 0
src/components/project-manage/components/business.vue

@@ -0,0 +1,16 @@
+<template>
+  <div class="business-container">
+    <Title name="商业信息" />
+  </div>
+</template>
+
+<script>
+import Title from "./title.vue";
+export default {
+  components: {
+    Title,
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 127 - 0
src/components/project-manage/components/formItem.vue

@@ -0,0 +1,127 @@
+<template>
+  <div class="formitem">
+    <!-- 标题 -->
+    <div class="label" :style="{ width: labelWidth + 'px' }">
+      {{ label }}
+      <!-- 提示 -->
+      <Popover v-if="showPop" type="base" placement="top-left">
+        <template #content>
+          <article>
+            {{ popText }}
+          </article>
+        </template>
+        <Icon class="icon" :name="'tagError'" />
+      </Popover>
+      :
+    </div>
+    <!-- 输出框 -->
+    <Input
+      v-if="formType === 'input'"
+      v-model="value"
+      :placeholder="placeholder"
+    ></Input>
+    <!-- 输出框带单位 -->
+    <Input
+      v-if="formType === 'input-unit'"
+      v-model="value"
+      :placeholder="placeholder"
+      :right-button="[
+        {
+          id: '1',
+          name: unit,
+          checked: 'checked',
+        },
+      ]"
+    />
+    <!-- 选择框 -->
+    <MSelect
+      v-if="formType === 'select'"
+      width="180"
+      v-model="value"
+      :data="selectData"
+    />
+    <!-- 上传图片 -->
+    <section class="list" v-if="formType === 'upload'">
+      <ImageUpload
+        hosts="http://47.95.122.141:8209/domita/backend"
+        action="/base/attachment/uploadX"
+        :defaultFileList="value"
+        :previewMode="false"
+        :multiple="true"
+      />
+    </section>
+    <Input
+      v-if="formType === 'textarea'"
+      v-model="value"
+      type="textarea"
+      :rows="6"
+      :autofocus="false"
+      :max-length="10"
+    />
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    label: String,
+    formType: {
+      type: String,
+      default: "input",
+    },
+    initValue: [String, Number, Array, Object],
+    placeholder: "请输入",
+    labelWidth: {
+      type: Number,
+      default: 100,
+    },
+    unit: String,
+    selectData: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    showPop: {
+      type: Boolean,
+      default: false,
+    },
+    popText: String,
+  },
+  data() {
+    return {
+      value: this.initValue,
+    };
+  },
+  watch: {
+    initValue(val, old) {
+      if (val !== old) {
+        this.value = val;
+      }
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.formitem {
+  display: flex;
+  align-items: center;
+  margin-bottom: 24px;
+  .label {
+    font-size: 14px;
+    text-align: right;
+    color: #646c73;
+    margin-right: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    .icon {
+      width: 11.5px;
+      height: 11.5px;
+      /deep/ .v-svg-tagError {
+        width: 11.5px !important;
+        height: 11.5px !important;
+      }
+    }
+  }
+}
+</style>

+ 169 - 0
src/components/project-manage/components/geo.vue

@@ -0,0 +1,169 @@
+<template>
+  <div class="geo-container">
+    <Title name="地理信息" />
+    <div class="geo-content">
+      <div id="map-container"></div>
+      <div class="map-search-input">
+        <el-input id="tipinput" placeholder="搜索" v-model="inputVal2">
+          <i slot="prefix" class="el-input__icon el-icon-search"></i>
+        </el-input>
+      </div>
+      <div class="form-content">
+        <FormItem label="省市区县" :initValue="geoFormData.district" />
+        <FormItem label="详细地址" :initValue="geoFormData.address" />
+        <el-row>
+          <el-col :span="12">
+            <FormItem
+              label="经度"
+              :initValue="geoFormData.lng"
+              formType="input-unit"
+              unit="度"
+            />
+          </el-col>
+          <el-col :span="12"
+            ><FormItem
+              label="纬度"
+              :initValue="geoFormData.lat"
+              formType="input-unit"
+              unit="度"
+          /></el-col>
+        </el-row>
+        <FormItem
+          label="抗震设防烈度"
+          :initValue="geoFormData.level"
+          formType="select"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import Title from "./title.vue";
+import AMapLoader from "@amap/amap-jsapi-loader";
+import FormItem from "./formItem.vue";
+export default {
+  components: {
+    Title,
+    FormItem,
+  },
+  data() {
+    return {
+      map: null,
+      inputVal2: "",
+      autocomplete: null,
+      markers: [], // 标记数组
+
+      geoFormData: {
+        // 地理信息数据
+        district: "", // 省市区县
+        address: "", // 详细地址
+        lng: "", // 经度
+        lat: "", // 纬度
+        level: null, // 抗震设防烈度
+      },
+    };
+  },
+  mounted() {
+    this.initMap();
+  },
+  methods: {
+    // 初始化地图
+    initMap() {
+      AMapLoader.load({
+        key: window.__systemConf.mapKey,
+        version: "2.0",
+        plugins: [],
+      }).then((Amap) => {
+        this.map = new Amap.Map("map-container", {
+          zoom: 11,
+          resizeEnable: true,
+        });
+        Amap.plugin(["AMap.PlaceSearch", "AMap.AutoComplete"], () => {
+          const autoOptions = {
+            input: "tipinput",
+          };
+          this.autocomplete = new Amap.Autocomplete(autoOptions);
+
+          this.autocomplete.on("select", (e) => {
+            console.log(e);
+            const location = e.poi.location;
+            if (location) {
+              this.setLocation(location);
+              this.addMarker(Amap, location, e.poi.name);
+              const { district, address } = e.poi;
+              this.geoFormData.district = district;
+              this.geoFormData.address = address;
+              this.geoFormData.lng = location.lng.toString();
+              this.geoFormData.lat = location.lat.toString();
+              this.geoFormData.level = null;
+            }
+          });
+        });
+      });
+    },
+    getDicData() {},
+    /**
+     * 设置当前定位
+     * @param {*} location
+     */
+    setLocation(location) {
+      if (location) {
+        this.map.setCenter([location.lng, location.lat], true);
+      }
+    },
+    /**
+     * 添加标记点
+     * @param {*} Amap
+     * @param {*} location
+     * @param {*} name 标记点的标签内容
+     */
+    addMarker(Amap, location, name) {
+      this.clearMarker();
+      const marker = new Amap.Marker({
+        position: [location.lng, location.lat],
+        title: name,
+      });
+      marker.setLabel({
+        offset: new AMap.Pixel(0, 0), //设置文本标注偏移量
+        content: `<div class='info'>${name}</div>`, //设置文本标注内容
+        direction: "right", //设置文本标注方位
+      });
+      this.markers.push(marker);
+      this.map.add(marker);
+    },
+    /**
+     * 清除地图所有标记点
+     */
+    clearMarker() {
+      this.markers.forEach((marker) => this.map.remove(marker));
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.geo-container {
+  width: 100%;
+  .geo-content {
+    width: 100%;
+    height: 100%;
+    padding: 0 16px;
+    position: relative;
+    #map-container {
+      width: 100%;
+      height: 200px;
+    }
+    .map-search-input {
+      position: absolute;
+      top: 12px;
+      left: 24px;
+      background-color: #fff;
+    }
+    .form-content {
+      margin-top: 24px;
+    }
+  }
+}
+/deep/ .amap-marker-label {
+  background-color: red;
+}
+</style>

+ 102 - 0
src/components/project-manage/components/project.vue

@@ -0,0 +1,102 @@
+<template>
+  <div class="project-container">
+    <Title name="项目信息" />
+    <div class="form-content">
+      <el-row>
+        <el-col :span="12">
+          <FormItem
+            label="总建筑面积"
+            :initValue="formData.buildArea"
+            formType="input-unit"
+            unit="m²"
+            :showPop="true"
+            popText="各建筑“建筑面积”之和"
+          />
+        </el-col>
+        <el-col :span="12"
+          ><FormItem
+            label="占地面积"
+            :initValue="formData.coverArea"
+            formType="input-unit"
+            unit="m²"
+            :showPop="true"
+            popText="红线面积"
+        /></el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <FormItem
+            label="项目高度"
+            :initValue="formData.height"
+            formType="input-unit"
+            unit="m²"
+          />
+        </el-col>
+        <el-col :span="12"
+          ><FormItem
+            label="耐火等级"
+            :initValue="formData.level"
+            formType="select"
+            :showPop="true"
+        /></el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <FormItem
+            label="项目功能类型"
+            :initValue="formData.type"
+            formType="select"
+          />
+        </el-col>
+        <el-col :span="12"
+          ><FormItem
+            label="地下楼层数"
+            :initValue="formData.floor"
+            formType="input-unit"
+            unit="层"
+        /></el-col>
+      </el-row>
+      <FormItem
+        label="项目Logo"
+        :initValue="formData.logos"
+        formType="upload"
+      />
+      <FormItem
+        label="区位图(城市)"
+        :initValue="formData.citys"
+        formType="upload"
+      />
+      <FormItem
+        label="项目简介"
+        :initValue="formData.desc"
+        formType="textarea"
+      />
+    </div>
+  </div>
+</template>
+<script>
+import Title from "./title.vue";
+import FormItem from "./formItem.vue";
+export default {
+  components: {
+    Title,
+    FormItem,
+  },
+  data() {
+    return {
+      formData: {
+        buildArea: "",
+        coverArea: "",
+        height: "",
+        level: "",
+        type: "",
+        floor: "",
+        logos: [],
+        citys: [],
+        desc: "",
+      },
+    };
+  },
+};
+</script>
+<style lang="less" scoped></style>

+ 32 - 0
src/components/project-manage/components/title.vue

@@ -0,0 +1,32 @@
+<template>
+    <div class="name">{{name}}</div>
+</template>
+<script>
+export default {
+    props: {
+        name: {
+            type: String,
+            default: ''
+        }
+    }
+}
+</script>
+<style lang="less" scoped>
+.name {
+    height: 20px;
+    line-height: 20px;
+    display: flex;
+    align-items: center;
+    font-size: 16px;
+    color: #1f2429;
+    margin-bottom: 20px;
+    &::before {
+        content: '';
+        display: inline-block;  
+        width: 3px;
+        height:100%;
+        background-color: #0091FF;
+        margin-right: 12px;
+    }
+}
+</style>

+ 40 - 10
src/components/project-manage/index.vue

@@ -1,16 +1,46 @@
 <template>
-    <div>
-        <Button>123123</Button>
+  <div class="container">
+    <div class="left">
+      <Anchor />
     </div>
+    <div class="right">
+      <Basic name="基本信息" />
+      <Geo />
+      <Project />
+      <Business />
+    </div>
+  </div>
 </template>
 <script>
+import Anchor from "./components/anchor.vue";
+import Basic from "./components/basic.vue";
+import Geo from "./components/geo.vue";
+import Project from "./components/project.vue";
+import Business from "./components/business.vue";
 export default {
-    mounted() {
-        
-    },
-    methods: {
-
-    }
-}
+  components: {
+    Anchor,
+    Basic,
+    Geo,
+    Project,
+    Business,
+  },
+  mounted() {},
+  methods: {},
+};
 </script>
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.container {
+  width: 100%;
+  display: flex;
+  .left {
+    flex: 0 0 143px;
+  }
+  .right {
+    width: 100%;
+    padding: 20px;
+    background-color: #ffffff;
+    overflow-y: auto;
+  }
+}
+</style>

+ 13 - 2
src/components/systemGraph/addGraph.vue

@@ -65,6 +65,7 @@ import { mapState } from "vuex";
 import { sysGraphController } from "@/controller/systemGraph/sysGraphController";
 import { logicConfig } from "@/logicConfig";
 import { Message } from "element-ui";
+import packageConfig from "../../../package.json";
 
 export default {
   props: ["isVisible"],
@@ -165,10 +166,20 @@ export default {
         var createResult = await sysGraphController.createSysGraph(_paramObj);
         switch (createResult.result) {
           case logicConfig.resultObj.failure:
-            Message.error("新增失败,原因:" + createResult.reason);
+            Message.error("操作失败,原因:" + createResult.reason);
             break;
           case logicConfig.resultObj.success:
-            this.$emit("created", createResult.data);
+            // this.$emit("created", createResult.data);
+            let dataObj = createResult.data;
+            sysGraphController.openGraphPage(
+              1,
+              dataObj.id,
+              this.selProject.groupCode,
+              this.selProject.id,
+              this.selProject.name,
+              packageConfig.name,
+              false
+            );
             break;
         }
       } catch (error) {

+ 127 - 33
src/components/systemGraph/edit.vue

@@ -22,19 +22,31 @@
           >
         </div>
         <div class="operBtnDiv" v-if="operState === 1">
-          <span>保存图纸</span>
+          <span @click="saveGraph">保存图纸</span>
           <span @click="cancelClick">放弃编辑</span>
         </div>
         <span class="delBtn" @click="delGraph">删除图纸</span>
       </div>
       <div class="secondOperDivContainer">
         <img
+          @click="toggleLeft"
           class="imgBar"
           src="../../assets/images/systemGraph/barController.svg"
         />
-        <span class="el-icon-caret-bottom sanjiaoBar"></span>
+        <span
+          class="sanjiaoBar"
+          :class="{
+            'el-icon-caret-bottom': isVisibleLeft,
+            'el-icon-caret-top': !isVisibleLeft,
+          }"
+          @click="toggleLeft"
+        ></span>
         <hr class="splitLine" />
-        <el-select v-model="selectScale" value-key="value">
+        <el-select
+          v-model="selectScale"
+          value-key="value"
+          @change="selScaleChange"
+        >
           <el-option
             v-for="item in scaleArr"
             :key="item.value"
@@ -43,9 +55,9 @@
           >
           </el-option>
         </el-select>
-        <span class="el-icon-zoom-in zoomin"></span>
-        <span class="el-icon-zoom-out zoomout"></span>
-        <hr class="splitLine" v-if="operState == 1" />
+        <span class="el-icon-zoom-in zoomin" @click="scaleZoomin"></span>
+        <span class="el-icon-zoom-out zoomout" @click="scaleZoomout"></span>
+        <!-- <hr class="splitLine" v-if="operState == 1" />
         <img
           v-if="operState == 1"
           class="imgLeftTop"
@@ -61,53 +73,61 @@
           v-if="operState == 1"
           class="imgLeftTop"
           src="../../assets/images/systemGraph/text.svg"
-        />
+        /> -->
         <span class="resetBtn" v-if="operState == 1">重置为自动出图样式</span>
       </div>
     </div>
     <div class="secondRow">
-      <div class="graphInfoContainer" v-if="operState === 0 || operState === 1">
+      <div
+        class="graphInfoContainer"
+        v-if="(operState === 0 || operState === 1) && isVisibleLeft"
+      >
         <div class="graphInfoFirst">
           <span class="graphInfoName">系统图名称</span>
-          <span class="graphInfoFirstEdit" @click="intoEditState">编辑</span>
+          <span
+            class="graphInfoFirstEdit"
+            @click="intoEditState"
+            v-if="operState === 0"
+            >编辑</span
+          >
         </div>
         <div class="graphInfoContent">
-          <span>高压系统1#系统图</span>
+          <span v-text="graphInfo.name">高压系统1#系统图</span>
         </div>
 
         <div class="graphInfoName">
           <span>系统图类型</span>
         </div>
         <div class="graphInfoContent">
-          <span>高压配电</span>
+          <span v-text="graphInfo.graphTypeName">高压配电</span>
         </div>
 
         <div class="graphInfoName">
           <span>系统实例</span>
         </div>
         <div class="graphInfoContent">
-          <span>实例1</span>
+          <span v-text="graphInfo.systemInstanceName">实例1</span>
         </div>
 
         <div class="graphInfoName">
           <span>系统图模版</span>
         </div>
         <div class="graphInfoContent">
-          <span>模版1</span>
+          <span v-text="graphInfo.templateName">模版1</span>
         </div>
 
         <div class="graphInfoName">
           <span>所属项目</span>
         </div>
         <div class="graphInfoContent">
-          <span>银泰中心</span>
+          <span v-text="project.name">银泰中心</span>
         </div>
 
         <div class="graphInfoName">
           <span>当前状态</span>
         </div>
         <div class="graphInfoContent">
-          <span>草稿</span>
+          <span v-text="graphInfo.stateName">草稿</span>
         </div>
       </div>
       <div class="graphRegion">
@@ -254,11 +274,7 @@
       </div>
     </div>
 
-    <addGraph
-      :isVisible="operState == 2"
-      @created="createSuccessed"
-      v-if="operState == 2"
-    ></addGraph>
+    <addGraph :isVisible="operState == 2" v-if="operState == 2"></addGraph>
   </div>
 </template>
 <script>
@@ -304,6 +320,8 @@ export default {
       operState: -1,
       //系统图ID
       diagramId: "",
+      //项目信息
+      project: {},
       /**
        * 选择的系统图上的区域的类型
        * -1 什么也没选; 1 设备;    2 线;   3 文字
@@ -362,6 +380,8 @@ export default {
       fontColor: "#eb5757",
       //背景颜色
       backColor: "#ffffff",
+      //系统图原始数据
+      graphOriginInfo: {},
       //系统图数据
       graphInfo: {},
       /**
@@ -391,6 +411,8 @@ export default {
           }
        */
       selEquip: {},
+      //是否展示左侧系统图基础信息
+      isVisibleLeft: true,
     };
   },
   computed: {},
@@ -402,6 +424,7 @@ export default {
     createSuccessed: function (graphInfo) {
       //进入编辑状态
       this.operState = 1;
+      this.graphOriginInfo = JSON.parse(JSON.stringify(graphInfo));
       this.graphInfo = graphInfo;
       this.$refs.graphc.drawEntry(graphInfo);
     },
@@ -418,12 +441,17 @@ export default {
     //根据系统图ID获取系统图数据
     getDiagramById: async function () {
       this.fullscreenLoading = true;
-      var resultObj = await sysGraphController.getDiagramById(this.diagramId);
+      var resultObj = await sysGraphController.getDiagramById(
+        this.diagramId,
+        this.project.groupCode,
+        this.project.id
+      );
       if (resultObj.result != logicConfig.resultObj.success) {
         this.fullscreenLoading = false;
         Message.error(resultObj.reason);
         return;
       }
+      this.graphOriginInfo = JSON.parse(JSON.stringify(resultObj.data));
       this.graphInfo = resultObj.data;
       this.fullscreenLoading = false;
     },
@@ -445,9 +473,28 @@ export default {
       });
     },
     /**
+     * 保存图纸按钮事件
+     */
+    saveGraph: async function () {
+      this.fullscreenLoading = true;
+      var saveResultObj = await sysGraphController.saveSysGraph(this.graphInfo);
+      this.fullscreenLoading = false;
+      switch (saveResultObj.result) {
+        case logicConfig.resultObj.failure:
+          Message.error("保存失败:" + (saveResultObj.reason || ""));
+          return;
+        case logicConfig.resultObj.success:
+          Message.success("保存成功");
+          this.graphOriginInfo = JSON.parse(JSON.stringify(this.graphInfo));
+          break;
+      }
+    },
+    /**
      * 放弃编辑按钮事件
      */
     cancelClick: function () {
+      this.graphInfo = JSON.parse(JSON.stringify(this.graphOriginInfo));
+      this.$refs.graphc.drawEntry(this.graphInfo);
       this.operState = 0;
     },
     //上架系统图
@@ -457,6 +504,7 @@ export default {
       this.fullscreenLoading = false;
       switch (resultObj.result) {
         case logicConfig.resultObj.success:
+          this.graphOriginInfo.extraProps.state = graphStateEnum.Publish;
           this.graphInfo.extraProps.state = graphStateEnum.Publish;
           return Message.success("上架成功");
         case logicConfig.resultObj.failure:
@@ -470,6 +518,7 @@ export default {
       this.fullscreenLoading = false;
       switch (resultObj.result) {
         case logicConfig.resultObj.success:
+          this.graphOriginInfo.extraProps.state = graphStateEnum.Draft;
           this.graphInfo.extraProps.state = graphStateEnum.Draft;
           return Message.success("下架成功");
         case logicConfig.resultObj.failure:
@@ -477,18 +526,58 @@ export default {
       }
     },
     //删除系统图
-    delGraph: async function () {
-      this.fullscreenLoading = true;
-      var resultObj = await sysGraphController.delSysGraph(this.diagramId);
-      this.fullscreenLoading = false;
-      switch (resultObj.result) {
-        case logicConfig.resultObj.success:
-          return Message.success("删除图纸成功");
-        case logicConfig.resultObj.failure:
-          return Message.success(
-            "删除图纸失败,原因:" + (resultObj.reason || "")
-          );
-      }
+    delGraph: function () {
+      this.$confirm("图纸删除后将不可进行查看和编辑, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          this.fullscreenLoading = true;
+          var resultObj = await sysGraphController.delSysGraph(this.diagramId);
+          this.fullscreenLoading = false;
+          switch (resultObj.result) {
+            case logicConfig.resultObj.success:
+              this.$confirm("删除成功,页面将关闭", "提示", {
+                confirmButtonText: "确定",
+                type: "success",
+                showCancelButton: false,
+                closeOnClickModal: false,
+                showClose: false,
+                closeOnPressEscape: false,
+              }).then(async () => {
+                window.close();
+              });
+              return;
+            case logicConfig.resultObj.failure:
+              return Message.success(
+                "删除图纸失败,原因:" + (resultObj.reason || "")
+              );
+          }
+        })
+        .catch(() => {});
+    },
+    //左侧系统图基础信息面板打开或隐藏
+    toggleLeft: function () {
+      var _this = this;
+      this.isVisibleLeft = !this.isVisibleLeft;
+      Vue.nextTick(function () {
+        _this.$refs.graphc.resetDraw();
+      });
+    },
+    //缩放比例选择事件
+    selScaleChange: function () {
+      this.$refs.graphc.graphScale(this.selectScale.value / 100);
+    },
+    //比例放大按钮点击事件
+    scaleZoomin: function () {
+      var newScale = this.$refs.graphc.graphScaleCompute(0.25);
+      this.$refs.graphc.graphScale(newScale);
+    },
+    //比例缩小按钮点击事件
+    scaleZoomout: function () {
+      var newScale = this.$refs.graphc.graphScaleCompute(-0.25);
+      this.$refs.graphc.graphScale(newScale);
     },
   },
   created() {
@@ -497,6 +586,11 @@ export default {
       : parseInt(this.$route.query.ost);
     this.diagramId = !this.$route.query.did ? -1 : this.$route.query.did;
     this.selectScale = this.scaleArr[3];
+    this.project = {
+      id: this.$route.query.pri,
+      groupCode: this.$route.query.gc,
+      name: this.$route.query.prn,
+    };
   },
   mounted() {
     var _this = this;

+ 24 - 0
src/components/systemGraph/graph.vue

@@ -405,6 +405,30 @@ export default {
       })[0];
       this.$emit("click", dataObj, type);
     },
+    //图形缩放比例递进计算
+    graphScaleCompute: function (deepVal) {
+      return this.canvasProObj.pixiScale + deepVal;
+    },
+    //图形缩放
+    graphScale: function (newScale) {
+      newScale = Math.min(5, newScale);
+      newScale = Math.max(0.25, newScale);
+      //设置X、Y轴的缩放系数
+      this.pixiApp.stage.scale.x = newScale;
+      this.pixiApp.stage.scale.y = newScale;
+
+      //保存缩放系数
+      this.canvasProObj.pixiScale = newScale;
+      //重新计算原点
+      this.canvasProObj.positionPxX =
+        (1 - newScale) * this.canvasProObj.centerPointerPx.x;
+      this.canvasProObj.positionPxY =
+        (1 - newScale) * this.canvasProObj.centerPointerPx.y;
+      this.pixiApp.stage.position.set(
+        this.canvasProObj.positionPxX,
+        this.canvasProObj.positionPxY
+      );
+    },
   },
   created() {},
 

+ 9 - 8
src/components/systemGraph/index.vue

@@ -63,6 +63,7 @@ import { mapState } from "vuex";
 import { logicConfig } from "@/logicConfig";
 import packageConfig from "../../../package.json";
 import { sysGraphController } from "@/controller/systemGraph/sysGraphController";
+import { TextureLoader } from "@pixi/loaders";
 
 export default {
   props: [],
@@ -149,14 +150,14 @@ export default {
     },
     //打开系统图新增、预览、编辑页面
     openGraphPage: function () {
-      window.open(
-        "/" +
-          packageConfig.name +
-          logicConfig.routerNameConfig.systemGraphEditName +
-          "?ost=" +
-          this.state +
-          "&did=" +
-          (this.selDiagram.id || "")
+      sysGraphController.openGraphPage(
+        this.state,
+        this.selDiagram.id,
+        this.selectProject.groupCode,
+        this.selectProject.id,
+        this.selectProject.name,
+        packageConfig.name,
+        true
       );
     },
   },

+ 155 - 42
src/controller/systemGraph/sysGraphController.ts

@@ -1,10 +1,23 @@
 import { graphStateEnum } from "./graphStateEnum";
 import { sysGraphHttpUtils } from "@/utils/http/sysGraphHttpUtils";
 import { logicConfig } from "@/logicConfig";
-import moment, { Moment } from 'moment';
+import moment from 'moment';
 
 export class sysGraphController {
     private static sysGraphHttpUtilsInstance = new sysGraphHttpUtils();
+    //key为系统类型编码,值为 系统图类型 > 模板数据 的二级结构数组
+    private static _tempTemplateObj = {};
+    //三级数组 专业>系统类型>系统实例
+    private static zhuanyeArr = [];
+
+
+    //根据状态编码转状态名称
+    static getStateNameByCode(stateCode: string) {
+        return stateCode == graphStateEnum.Draft ? '草稿' :
+            stateCode == graphStateEnum.Publish ? '上架' :
+                stateCode == graphStateEnum.Recyle ? '回收站' : '';
+    }
+
     /**
      * 查询系统图列表
      * @param grpphName 系统图名称
@@ -14,32 +27,31 @@ export class sysGraphController {
         var resultObj = await this.sysGraphHttpUtilsInstance.postRequest('/diagram/getDiagrams', { name: grpphName });
         if (resultObj.result != logicConfig.resultObj.success)
             console.error(resultObj.reason);
+
+        //key为系统类型编码,值为系统类型数据
+        var _tempSystemTypeObj = {};
         var newDataArr = [];
-        var dataArr = resultObj.data || [];
-        console.log(JSON.parse(JSON.stringify(dataArr)));
+        var dataArr = (resultObj.data || []).filter(_c => {
+            return (_c.extraProps || {}).state != graphStateEnum.Recyle;
+        });
         dataArr.sort(function (a, b) {
             return b.createTime - a.createTime;
         });
 
 
         //取得专业>系统类型>系统实例  以和系统图列表中的系统类型编码 对应以获取系统类型名称
-        var url2 = '/diagram/major/system/instance';
-        var zhuanyeObj = await this.sysGraphHttpUtilsInstance.postRequest(url2, {});
-        var zhuanyeArr = zhuanyeObj.data || [];
+        if (this.zhuanyeArr.length == 0) {
+            var url2 = '/diagram/major/system/instance';
+            var zhuanyeObj = await this.sysGraphHttpUtilsInstance.postRequest(url2, {});
+            this.zhuanyeArr = zhuanyeObj.data || [];
+        }
 
 
-        //key为系统类型编码,值为系统类型数据
-        var _tempSystemTypeObj = {};
-        //key为系统类型编码,值为 系统图类型 > 模板数据 的二级结构数组
-        var _tempTemplateObj = {};
-
         for (let i = 0; i < dataArr.length; i++) {
             let _c = dataArr[i];
             let extraProps = _c.extraProps;
             //图状态(Draft: 未发布, WaitCheck: 待审核, Checked: 审核完成, Recyle: 回收站, Publish: 发布)
-            let stateName = extraProps.state == graphStateEnum.Draft ? '草稿' :
-                extraProps.state == graphStateEnum.Publish ? '上架' :
-                    extraProps.state == graphStateEnum.Recyle ? '下架' : '';
+            let stateName = this.getStateNameByCode(extraProps.state);
 
             //获取系统类型名称
             let systemTypeName = (_tempSystemTypeObj[_c.system] || {}).aliasName;
@@ -49,8 +61,8 @@ export class sysGraphController {
             }
 
             //获取模版名称
-            let _templateObj = await getTemplateBySysTypeCode(_c.system, _c.templateId);
-            let templateName = (_templateObj || {}).name || '';
+            let _templateObj = await this.getTemplateGraphTypeBySysTypeCode(_c.system, _c.templateId);
+            let templateName = ((_templateObj || {}).template || {}).name || '';
 
             //格式化日期时间
             let momentInstance = moment(_c.createTime);
@@ -73,9 +85,9 @@ export class sysGraphController {
 
 
         function getSystemTypeByCode(systemTypeCode: string) {
-            for (let i = 0; i < zhuanyeArr.length; i++) {
+            for (let i = 0; i < sysGraphController.zhuanyeArr.length; i++) {
                 //专业
-                let zhuanye = zhuanyeArr[i];
+                let zhuanye = sysGraphController.zhuanyeArr[i];
                 //系统类型数组
                 let systemTypeArr = zhuanye.children || [];
                 let isFind = false;
@@ -92,34 +104,44 @@ export class sysGraphController {
                     break;
             }
         };
+    }
 
-        async function getTemplateBySysTypeCode(sysTypeCode: string, templateId: string) {
-            var dataArr = _tempTemplateObj[sysTypeCode];
+    /**
+     * 根据系统类型查询系统图模板和系统图类型,数据结构:系统图类型 ->  系统图模版
+     * @param sysTypeCode 系统类型编码
+     * @param templateId 模版ID
+     * @return {template:{id:'',name:''},graphType:{id:'',name:''}}
+     */
+    static async getTemplateGraphTypeBySysTypeCode(sysTypeCode: string, templateId: string) {
+        var dataArr = this._tempTemplateObj[sysTypeCode];
 
-            if (!dataArr) {
-                let url = '/diagram/systemType/template';
-                let resultObj = await sysGraphController.sysGraphHttpUtilsInstance.postRequest(url, { system: sysTypeCode });
-                dataArr = resultObj.data || [];
-            }
+        if (!dataArr) {
+            let url = '/diagram/systemType/template';
+            let resultObj = await sysGraphController.sysGraphHttpUtilsInstance.postRequest(url, { system: sysTypeCode });
+            dataArr = resultObj.data || [];
+        }
+        this._tempTemplateObj[sysTypeCode] = dataArr;
 
-            for (let i = 0; i < dataArr.length; i++) {
-                //_sysGraphType为系统图类型
-                let sysGraphType = dataArr[i];
-                //模板数组
-                let templateArr = sysGraphType.children || [];
-                let isFind = false;
-                for (let j = 0; j < templateArr.length; j++) {
-                    //模板
-                    let template = templateArr[j];
-                    if (template.id == templateId) {
-                        return template;
-                    }
+        for (let i = 0; i < dataArr.length; i++) {
+            //_sysGraphType为系统图类型
+            let sysGraphType = dataArr[i];
+            //模板数组
+            let templateArr = sysGraphType.children || [];
+            for (let j = 0; j < templateArr.length; j++) {
+                //模板
+                let template = templateArr[j];
+                if (template.id == templateId) {
+                    return {
+                        template: { id: template.id, name: template.name },
+                        graphType: { id: sysGraphType.id, name: sysGraphType.name }
+                    };
                 }
             }
-            return null;
         }
+        return null;
     }
 
+
     /**
      * 根据项目查询该项目下的专业>系统类型>系统实例
      * @param projectId 项目ID
@@ -131,6 +153,7 @@ export class sysGraphController {
         if (resultObj.result != logicConfig.resultObj.success)
             console.error(resultObj.reason);
         var dataArr = resultObj.data || [];
+        this.zhuanyeArr = dataArr;
         var newDataArr = [];
 
         dataArr.forEach(_c => {
@@ -189,7 +212,7 @@ export class sysGraphController {
         var url = '/diagram/newDiagram';
         var resultObj = await this.sysGraphHttpUtilsInstance.postRequest(url, _paramObj);
         if (resultObj.result != logicConfig.resultObj.success) {
-            console.error(resultObj.reason);
+            resultObj.reason = '新建系统图失败:' + resultObj.reason;
             return resultObj;
         }
 
@@ -201,17 +224,36 @@ export class sysGraphController {
         var loadDataUrl = '/diagram/loadData';
         var loadResultObj = await this.sysGraphHttpUtilsInstance.postRequest(loadDataUrl, { id: dataObj.id });
         if (loadResultObj.result != logicConfig.resultObj.success) {
-            return { result: logicConfig.resultObj.failure, reason: '加载模板数据失败,原因:' + loadResultObj.reason };
+            loadResultObj.reason = '加载模板数据失败:' + loadResultObj.reason;
+            return loadResultObj;
+        }
+
+        //加载数据成功后保存数据
+        var saveResultObj = await this.saveSysGraph(loadResultObj.data);
+        if (saveResultObj.result != logicConfig.resultObj.success) {
+            saveResultObj.reason = '保存系统图数据失败:' + saveResultObj.reason;
+            return saveResultObj;
         }
-        console.log(JSON.stringify(loadResultObj.data));
+
+        //因为保存数据成功返回的data里的数据不全,所以返回加载数据成功后的数据给页面
         return loadResultObj;
     }
 
     /**
+     * 保存系统图数据
+     * @param _paramObj 参见后台loadData接口的返回
+     */
+    static async saveSysGraph(_paramObj: any) {
+        var saveUrl = '/diagram/newDiagram';
+        var saveResultObj = await this.sysGraphHttpUtilsInstance.postRequest(saveUrl, _paramObj);
+        return saveResultObj;
+    }
+
+    /**
      * 根据系统图ID查询系统图信息
      * @param id 系统图ID
      */
-    static async getDiagramById(id: string) {
+    static async getDiagramById(id: string, groupCode: string, projectId: string) {
         var url = '/diagram/getDiagram?diagramId=' + id;
         var resultObj = await this.sysGraphHttpUtilsInstance.getRequest(url, {});
         if (resultObj.result != logicConfig.resultObj.success) {
@@ -223,8 +265,55 @@ export class sysGraphController {
         if (!dataObj.id)
             return { result: logicConfig.resultObj.failure, reason: '缺少系统图ID' };
 
+        //取得专业>系统类型>系统实例  以和系统图列表中的系统类型编码 对应以获取系统实例名称
+        if (this.zhuanyeArr.length == 0) {
+            var url2 = '/diagram/major/system/instance?groupCode=' + groupCode + '&projectId=' + projectId;
+            var zhuanyeObj = await this.sysGraphHttpUtilsInstance.postRequest(url2, {});
+            this.zhuanyeArr = zhuanyeObj.data || [];
+        }
+
+        //获取系统实例名称
+        var _systemInstance = getSystemInstanceByCode(resultObj.data.systemId);
+        console.log(_systemInstance);
+        resultObj.data.systemInstanceName = _systemInstance.name || '';
+
+
+        //获取系统图类型和系统图模版
+        var _temoObj = await this.getTemplateGraphTypeBySysTypeCode(resultObj.data.system, resultObj.data.templateId);
+        resultObj.data.graphTypeName = ((_temoObj || {}).graphType || {}).name;
+        resultObj.data.templateName = ((_temoObj || {}).template || {}).name;
+
+        //状态名称
+        resultObj.data.stateName = this.getStateNameByCode(resultObj.data.extraProps.state);
+
 
         return resultObj;
+
+        //获取系统实例信息
+        function getSystemInstanceByCode(systemInstanceId: string) {
+            for (let i = 0; i < sysGraphController.zhuanyeArr.length; i++) {
+                //专业
+                let zhuanye = sysGraphController.zhuanyeArr[i];
+                //系统类型数组
+                let systemTypeArr = zhuanye.children || [];
+                let isFind = false;
+                for (let j = 0; j < systemTypeArr.length; j++) {
+                    //系统类型
+                    let systemType = systemTypeArr[j];
+                    //系统实例数组
+                    let systemInstanceArr = systemType.children || [];
+                    for (let k = 0; k < systemInstanceArr.length; k++) {
+                        //系统实例
+                        let systemInstance = systemInstanceArr[k];
+                        if (systemInstance.id == systemInstanceId)
+                            return systemInstance;
+                    }
+                }
+                if (isFind)
+                    break;
+            }
+        };
+
         return {
             result: 'success',
             data: {
@@ -10380,4 +10469,28 @@ export class sysGraphController {
         return resultObj;
     }
 
+    /**
+     * 打开系统图新增、预览、编辑页面
+     * @param state 打开新页面时的状态,0 预览; 1 编辑;  2 新建
+     * @param diagramId 系统图ID
+     * @param groupCode 集团编码
+     * @param projectId 项目ID
+     * @param projectName 项目名称
+     * @param baseUrl 根路径
+     * @param isOpenTarget 是否打开新页面
+     */
+    static openGraphPage(state: number, diagramId: string, groupCode: string, projectId: string, projectName: string, baseUrl: string, isOpenTarget: boolean) {
+        var url = "/" +
+            baseUrl +
+            logicConfig.routerNameConfig.systemGraphEditName +
+            "?ost=" +
+            state +
+            "&did=" +
+            (diagramId || "") +
+            '&gc=' + (groupCode || '') +
+            '&pri=' + (projectId || '') +
+            '&prn=' + encodeURIComponent(projectName || '');
+        isOpenTarget === true ? window.open(url) : window.location.href = url;
+    }
+
 }

+ 7 - 2
src/meri.js

@@ -1,4 +1,9 @@
 import Vue from 'vue'
-import {Button} from 'meri-design'
+import {Button, Input, MSelect, Icon, Popover, ImageUpload} from 'meri-design'
 
-Vue.use(Button)
+Vue.use(Button)
+Vue.use(Input)
+Vue.use(MSelect)
+Vue.use(Icon)
+Vue.use(Popover)
+Vue.use(ImageUpload)