Browse Source

Merge branch 'master' of http://git.cc-lotus.info/Information/cxyy-web

lrf 8 tháng trước cách đây
mục cha
commit
4e8f54c43e
41 tập tin đã thay đổi với 131682 bổ sung430 xóa
  1. 186 0
      package-lock.json
  2. 1 0
      package.json
  3. 40 0
      src/store/api/user/companyYear.js
  4. 40 0
      src/store/api/user/incubatorYear.js
  5. 57 12
      src/views/center/achievement.vue
  6. 10 1
      src/views/center/attestation.vue
  7. 9 4
      src/views/center/company.vue
  8. 57 13
      src/views/center/demand.vue
  9. 2 2
      src/views/center/notice.vue
  10. 357 105
      src/views/center/parts/company.vue
  11. 374 68
      src/views/center/parts/incubator.vue
  12. 56 11
      src/views/center/project.vue
  13. 54 11
      src/views/center/supply.vue
  14. 37 4
      src/views/detail/baseDetail.vue
  15. BIN
      src/views/elevenHatch copy/font/DS-DIGI.TTF
  16. BIN
      src/views/elevenHatch copy/font/DS-DIGIB.TTF
  17. BIN
      src/views/elevenHatch copy/font/DS-DIGII.TTF
  18. BIN
      src/views/elevenHatch copy/font/DS-DIGIT.TTF
  19. BIN
      src/views/elevenHatch copy/images/bg.jpg
  20. BIN
      src/views/elevenHatch copy/images/head_bg.png
  21. BIN
      src/views/elevenHatch copy/images/jt.png
  22. BIN
      src/views/elevenHatch copy/images/lbx.png
  23. BIN
      src/views/elevenHatch copy/images/line.png
  24. BIN
      src/views/elevenHatch copy/images/loading.gif
  25. BIN
      src/views/elevenHatch copy/images/map.png
  26. 343 0
      src/views/elevenHatch copy/index.vue
  27. 103310 0
      src/views/elevenHatch copy/json/china.json
  28. 25715 0
      src/views/elevenHatch copy/json/jilin.json
  29. 106 0
      src/views/elevenHatch copy/path/echarts1.vue
  30. 197 0
      src/views/elevenHatch copy/path/echarts2.vue
  31. 107 0
      src/views/elevenHatch copy/path/echarts3.vue
  32. 189 0
      src/views/elevenHatch copy/path/echarts4.vue
  33. 77 0
      src/views/elevenHatch copy/path/echarts5.vue
  34. 77 0
      src/views/elevenHatch copy/path/echarts6.vue
  35. 77 0
      src/views/elevenHatch copy/path/echarts7.vue
  36. BIN
      src/views/elevenHatch/images/img1.png
  37. BIN
      src/views/elevenHatch/images/img2.png
  38. 109 26
      src/views/elevenHatch/index.vue
  39. 13 23
      src/views/elevenHatch/path/echarts1.vue
  40. 76 149
      src/views/elevenHatch/path/echarts2.vue
  41. 6 1
      src/views/five/index.vue

+ 186 - 0
package-lock.json

@@ -31,6 +31,7 @@
         "postcss-px2rem": "^0.3.0",
         "qrcode.vue": "^3.4.1",
         "relation-graph-vue3": "^2.2.1",
+        "stompjs": "^2.3.3",
         "universal-cookie": "^7.1.0",
         "vue": "^3.4.15",
         "vue-i18n": "^9.9.1",
@@ -2011,6 +2012,19 @@
         "node": ">=8"
       }
     },
+    "node_modules/bufferutil": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmmirror.com/bufferutil/-/bufferutil-4.0.8.tgz",
+      "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==",
+      "hasInstallScript": true,
+      "optional": true,
+      "dependencies": {
+        "node-gyp-build": "^4.3.0"
+      },
+      "engines": {
+        "node": ">=6.14.2"
+      }
+    },
     "node_modules/bundle-name": {
       "version": "4.1.0",
       "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz",
@@ -4019,6 +4033,12 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
+      "optional": true
+    },
     "node_modules/is-url": {
       "version": "1.2.4",
       "resolved": "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz",
@@ -4665,6 +4685,17 @@
       "resolved": "https://registry.npmmirror.com/next-tick/-/next-tick-1.1.0.tgz",
       "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
     },
+    "node_modules/node-gyp-build": {
+      "version": "4.8.1",
+      "resolved": "https://registry.npmmirror.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz",
+      "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==",
+      "optional": true,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
     "node_modules/normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -6268,6 +6299,14 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/stompjs": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/stompjs/-/stompjs-2.3.3.tgz",
+      "integrity": "sha512-5l/Ogz0DTFW7TrpHF0LAETGqM/so8UxNJvYZjJKqcX31EVprSQgnGkO80tZctPC/lFBDUrSFiTG3xd0R27XAIA==",
+      "optionalDependencies": {
+        "websocket": "latest"
+      }
+    },
     "node_modules/strict-uri-encode": {
       "version": "1.1.0",
       "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -6826,6 +6865,15 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/typedarray-to-buffer": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmmirror.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+      "optional": true,
+      "dependencies": {
+        "is-typedarray": "^1.0.0"
+      }
+    },
     "node_modules/ufo": {
       "version": "1.5.3",
       "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.5.3.tgz",
@@ -7182,6 +7230,19 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/utf-8-validate": {
+      "version": "5.0.10",
+      "resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
+      "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
+      "hasInstallScript": true,
+      "optional": true,
+      "dependencies": {
+        "node-gyp-build": "^4.3.0"
+      },
+      "engines": {
+        "node": ">=6.14.2"
+      }
+    },
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -7471,6 +7532,38 @@
       "integrity": "sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==",
       "dev": true
     },
+    "node_modules/websocket": {
+      "version": "1.0.35",
+      "resolved": "https://registry.npmmirror.com/websocket/-/websocket-1.0.35.tgz",
+      "integrity": "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==",
+      "optional": true,
+      "dependencies": {
+        "bufferutil": "^4.0.1",
+        "debug": "^2.2.0",
+        "es5-ext": "^0.10.63",
+        "typedarray-to-buffer": "^3.1.5",
+        "utf-8-validate": "^5.0.2",
+        "yaeti": "^0.0.6"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/websocket/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "optional": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/websocket/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "optional": true
+    },
     "node_modules/which": {
       "version": "2.0.2",
       "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
@@ -7505,6 +7598,15 @@
         "node": ">=12"
       }
     },
+    "node_modules/yaeti": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmmirror.com/yaeti/-/yaeti-0.0.6.tgz",
+      "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==",
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.32"
+      }
+    },
     "node_modules/yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
@@ -8810,6 +8912,15 @@
         "fill-range": "^7.0.1"
       }
     },
+    "bufferutil": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmmirror.com/bufferutil/-/bufferutil-4.0.8.tgz",
+      "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==",
+      "optional": true,
+      "requires": {
+        "node-gyp-build": "^4.3.0"
+      }
+    },
     "bundle-name": {
       "version": "4.1.0",
       "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz",
@@ -10291,6 +10402,12 @@
       "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
       "dev": true
     },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
+      "optional": true
+    },
     "is-url": {
       "version": "1.2.4",
       "resolved": "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz",
@@ -10802,6 +10919,12 @@
       "resolved": "https://registry.npmmirror.com/next-tick/-/next-tick-1.1.0.tgz",
       "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
     },
+    "node-gyp-build": {
+      "version": "4.8.1",
+      "resolved": "https://registry.npmmirror.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz",
+      "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==",
+      "optional": true
+    },
     "normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -11961,6 +12084,14 @@
         }
       }
     },
+    "stompjs": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/stompjs/-/stompjs-2.3.3.tgz",
+      "integrity": "sha512-5l/Ogz0DTFW7TrpHF0LAETGqM/so8UxNJvYZjJKqcX31EVprSQgnGkO80tZctPC/lFBDUrSFiTG3xd0R27XAIA==",
+      "requires": {
+        "websocket": "latest"
+      }
+    },
     "strict-uri-encode": {
       "version": "1.1.0",
       "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -12391,6 +12522,15 @@
       "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
       "dev": true
     },
+    "typedarray-to-buffer": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmmirror.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+      "optional": true,
+      "requires": {
+        "is-typedarray": "^1.0.0"
+      }
+    },
     "ufo": {
       "version": "1.5.3",
       "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.5.3.tgz",
@@ -12641,6 +12781,15 @@
       "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
       "dev": true
     },
+    "utf-8-validate": {
+      "version": "5.0.10",
+      "resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
+      "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
+      "optional": true,
+      "requires": {
+        "node-gyp-build": "^4.3.0"
+      }
+    },
     "util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -12821,6 +12970,37 @@
       "integrity": "sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==",
       "dev": true
     },
+    "websocket": {
+      "version": "1.0.35",
+      "resolved": "https://registry.npmmirror.com/websocket/-/websocket-1.0.35.tgz",
+      "integrity": "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==",
+      "optional": true,
+      "requires": {
+        "bufferutil": "^4.0.1",
+        "debug": "^2.2.0",
+        "es5-ext": "^0.10.63",
+        "typedarray-to-buffer": "^3.1.5",
+        "utf-8-validate": "^5.0.2",
+        "yaeti": "^0.0.6"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+          "optional": true
+        }
+      }
+    },
     "which": {
       "version": "2.0.2",
       "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
@@ -12846,6 +13026,12 @@
       "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
       "dev": true
     },
+    "yaeti": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmmirror.com/yaeti/-/yaeti-0.0.6.tgz",
+      "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==",
+      "optional": true
+    },
     "yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",

+ 1 - 0
package.json

@@ -34,6 +34,7 @@
     "postcss-px2rem": "^0.3.0",
     "qrcode.vue": "^3.4.1",
     "relation-graph-vue3": "^2.2.1",
+    "stompjs": "^2.3.3",
     "universal-cookie": "^7.1.0",
     "vue": "^3.4.15",
     "vue-i18n": "^9.9.1",

+ 40 - 0
src/store/api/user/companyYear.js

@@ -0,0 +1,40 @@
+import { defineStore } from 'pinia'
+import { AxiosWrapper } from '@/utils/axios-wrapper'
+import { get } from 'lodash-es'
+const url = '/companyYear'
+const axios = new AxiosWrapper()
+
+export const CompanyYearStore = defineStore('companyYear', () => {
+  const query = async ({ skip = 0, limit = undefined, ...info } = {}) => {
+    let cond = {}
+    if (skip) cond.skip = skip
+    if (limit) cond.limit = limit
+    cond = { ...cond, ...info }
+    const res = await axios.$get(`${url}`, cond)
+    return res
+  }
+  const fetch = async (payload) => {
+    const res = await axios.$get(`${url}/${payload}`)
+    return res
+  }
+  const create = async (payload) => {
+    const res = await axios.$post(`${url}`, payload)
+    return res
+  }
+  const update = async (payload) => {
+    const id = get(payload, 'id', get(payload, '_id'))
+    const res = await axios.$post(`${url}/${id}`, payload)
+    return res
+  }
+  const del = async (payload) => {
+    const res = await axios.$delete(`${url}/${payload}`)
+    return res
+  }
+  return {
+    query,
+    fetch,
+    create,
+    update,
+    del
+  }
+})

+ 40 - 0
src/store/api/user/incubatorYear.js

@@ -0,0 +1,40 @@
+import { defineStore } from 'pinia'
+import { AxiosWrapper } from '@/utils/axios-wrapper'
+import { get } from 'lodash-es'
+const url = '/incubatorYear'
+const axios = new AxiosWrapper()
+
+export const IncubatorYearStore = defineStore('incubatorYear', () => {
+  const query = async ({ skip = 0, limit = undefined, ...info } = {}) => {
+    let cond = {}
+    if (skip) cond.skip = skip
+    if (limit) cond.limit = limit
+    cond = { ...cond, ...info }
+    const res = await axios.$get(`${url}`, cond)
+    return res
+  }
+  const fetch = async (payload) => {
+    const res = await axios.$get(`${url}/${payload}`)
+    return res
+  }
+  const create = async (payload) => {
+    const res = await axios.$post(`${url}`, payload)
+    return res
+  }
+  const update = async (payload) => {
+    const id = get(payload, 'id', get(payload, '_id'))
+    const res = await axios.$post(`${url}/${id}`, payload)
+    return res
+  }
+  const del = async (payload) => {
+    const res = await axios.$delete(`${url}/${payload}`)
+    return res
+  }
+  return {
+    query,
+    fetch,
+    create,
+    update,
+    del
+  }
+})

+ 57 - 12
src/views/center/achievement.vue

@@ -5,9 +5,8 @@
         <el-col :span="24" class="one">
           <div class="one_left">
             <div class="button" @click="toAdd">发布成果</div>
-            <div class="button" @click="toTemplate">下载导出模板</div>
-            <el-upload class="button" action="/files/web/cxyy_import/upload" :show-file-list="false" :on-success="onSuccess" accept=".xlsx"> 选择excel模板文件 </el-upload>
-            <div class="button" @click="toDownload">下载Excel</div>
+            <div class="button" @click="toExpert">导入数据</div>
+            <div class="button" @click="toDownload">导出数据</div>
           </div>
           <div class="one_right">
             <el-input v-model="searchForm.name" style="width: 250px" size="large" placeholder="搜索" @change="search" :suffix-icon="Search" />
@@ -90,13 +89,37 @@
             <el-button type="primary" size="mini" @click="toFile()">导出</el-button>
           </el-col>
         </el-col>
+        <el-col :span="24" class="dialog_four" v-if="dialog.type == '4'">
+          <el-row justify="center">
+            <el-col :span="16">
+              <el-steps style="max-width: 600px" :active="importActive" align-center>
+                <el-step title="下载导入模板">
+                  <template #description v-if="importActive == 0">
+                    <el-button type="primary" size="mini" @click="toTemplate">下载导入模板</el-button>
+                  </template>
+                </el-step>
+                <el-step title="上传导入模板" description="上传导入模板">
+                  <template #description v-if="importActive == 1">
+                    <el-upload action="/files/web/cxyy_import/upload" :show-file-list="false" :on-success="onSuccess" accept=".xlsx">
+                      <el-button type="primary" size="mini">上传导入文件</el-button>
+                    </el-upload>
+                  </template>
+                </el-step>
+                <el-step title="确定导入" description="确定导入">
+                  <template #description v-if="importActive == 2">
+                    <el-button type="primary" size="mini" @click="onImport">确定</el-button>
+                  </template>
+                </el-step>
+              </el-steps>
+            </el-col>
+          </el-row>
+        </el-col>
       </el-row>
     </el-dialog>
   </div>
 </template>
 
 <script setup>
-import axios from 'axios'
 import { Search } from '@element-plus/icons-vue'
 import { cloneDeep, get } from 'lodash-es'
 const $checkRes = inject('$checkRes')
@@ -166,6 +189,9 @@ const rules = reactive({ name: [{ required: true, message: '请输入成果名
 const checkAll = ref(false)
 const checkedExport = ref([])
 const isIndeterminate = ref(true)
+// 导入文件
+const importActive = ref(0)
+const url = ref('')
 // 请求
 onMounted(async () => {
   loading.value = true
@@ -294,6 +320,8 @@ const toExam = async (row) => {
     .catch(() => {})
 }
 const toClose = () => {
+  importActive.value = 0
+  url.value = ''
   checkedExport.value = []
   checkAll.value = false
   form.value = { time: [] }
@@ -310,15 +338,32 @@ const checkedExportChange = (value) => {
   checkAll.value = checkedCount === formFields.value.length
   isIndeterminate.value = checkedCount > 0 && checkedCount < formFields.value.length
 }
-// 下载导出模板
+// 导入数据
+const toExpert = () => {
+  dialog.value = { type: '4', show: true, title: '导入数据' }
+}
+// 导出数据
+const toDownload = () => {
+  dialog.value = { type: '3', show: true, title: '导出数据' }
+}
+
+// 下载导入模板
 const toTemplate = () => {
+  importActive.value = importActive.value + 1
   window.open('/cxyyWeb/产学研用成果模板.xlsx')
 }
+
 // 上传Excel
 const onSuccess = async (response, file) => {
+  importActive.value = importActive.value + 1
+  url.value = response.uri
+}
+
+// 确定导出
+const onImport = async () => {
   const msgbox = ElMessage({ message: '正在导入中,请稍后...', center: true, duration: 0 })
   try {
-    const res = await utilStore.toImport({ url: response.uri })
+    const res = await utilStore.toImport({ url: url.value })
     if (res.errcode == '0') {
       if (res.data[0].errorList) {
         ElMessageBox.alert(res.data[0].errorList, '错误提示', {
@@ -327,7 +372,8 @@ const onSuccess = async (response, file) => {
       } else {
         ElMessage({ message: '导入成功', type: 'success' })
       }
-      search({ skip, limit })
+      await search({ skip, limit })
+      await toClose()
     }
   } catch (error) {
     console.error(error)
@@ -335,12 +381,8 @@ const onSuccess = async (response, file) => {
     msgbox.close()
   }
 }
-// 下载Excel
-const toDownload = () => {
-  dialog.value = { type: '3', show: true, title: '下载Excel' }
-}
 
-// 导出Excel
+// 导出数据
 const toFile = async () => {
   if (checkedExport.value.length > 0) {
     const reqData = { table: 'achievement', config: checkedExport.value, user: user.value.id }
@@ -410,4 +452,7 @@ const sizeChange = (limits) => {
     margin: 20px 0 0 0;
   }
 }
+.dialog_four {
+  padding: 20px;
+}
 </style>

+ 10 - 1
src/views/center/attestation.vue

@@ -78,7 +78,8 @@ const cardTypeList = ref([])
 const contributionList = ref([])
 const plateList = ref([])
 const modeList = ref([])
-
+const statusList = ref([])
+const yearList = ref([])
 // 请求
 onMounted(async () => {
   loading.value = true
@@ -133,6 +134,12 @@ const searchOther = async () => {
   // 盈利模式
   result = await dictDataStore.query({ code: 'modeType', is_use: '0' })
   if ($checkRes(result)) modeList.value = result.data
+  // 状态
+  result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
+  if ($checkRes(result)) statusList.value = result.data
+  // 年度
+  result = await dictDataStore.query({ code: 'year', is_use: '0' })
+  if ($checkRes(result)) yearList.value = result.data
 }
 const search = async () => {
   if (user.value.id) {
@@ -156,6 +163,8 @@ provide('cardTypeList', cardTypeList)
 provide('contributionList', contributionList)
 provide('plateList', plateList)
 provide('modeList', modeList)
+provide('yearList', yearList)
+provide('statusList', statusList)
 </script>
 <style scoped lang="scss">
 .main {

+ 9 - 4
src/views/center/company.vue

@@ -104,14 +104,19 @@ const searchOther = async () => {
     }
   }
 }
-const search = async () => {
+const search = async (query = { skip, limit }) => {
+  skip = query.skip
+  limit = query.limit
   const info = {
-    skip: 0,
-    limit: 6,
+    skip: query.skip,
+    limit: query.limit,
     incubator: incubatorInfo.value.id
   }
   const res = await cirelationStore.list(info)
-  if (res.errcode == '0') list.value = res.data
+  if (res.errcode == '0') {
+    list.value = res.data
+    total.value = res.total
+  }
 }
 const remoteMethod = (query) => {
   if (query) {

+ 57 - 13
src/views/center/demand.vue

@@ -5,9 +5,8 @@
         <el-col :span="24" class="one">
           <div class="one_left">
             <div class="button" @click="toAdd">发布需求</div>
-            <div class="button" @click="toTemplate">下载导出模板</div>
-            <el-upload class="button" action="/files/web/cxyy_import/upload" :show-file-list="false" :on-success="onSuccess" accept=".xlsx"> 选择excel模板文件 </el-upload>
-            <div class="button" @click="toDownload">下载Excel</div>
+            <div class="button" @click="toExpert">导入数据</div>
+            <div class="button" @click="toDownload">导出数据</div>
           </div>
           <div class="one_right">
             <el-input v-model="searchForm.name" style="width: 250px" size="large" placeholder="搜索" @change="search" :suffix-icon="Search" />
@@ -104,9 +103,34 @@
             </el-checkbox-group>
           </el-col>
           <el-col :span="24" class="btn">
-            <el-button type="primary" size="mini" @click="toFile()">导出</el-button>
+            <el-button type="primary" size="mini" @click="toFile()">确定导出</el-button>
           </el-col>
         </el-col>
+        <el-col :span="24" class="dialog_four" v-if="dialog.type == '4'">
+          <el-row justify="center">
+            <el-col :span="16">
+              <el-steps style="max-width: 600px" :active="importActive" align-center>
+                <el-step title="下载导入模板">
+                  <template #description v-if="importActive == 0">
+                    <el-button type="primary" size="mini" @click="toTemplate">下载导入模板</el-button>
+                  </template>
+                </el-step>
+                <el-step title="上传导入模板" description="上传导入模板">
+                  <template #description v-if="importActive == 1">
+                    <el-upload action="/files/web/cxyy_import/upload" :show-file-list="false" :on-success="onSuccess" accept=".xlsx">
+                      <el-button type="primary" size="mini">上传导入文件</el-button>
+                    </el-upload>
+                  </template>
+                </el-step>
+                <el-step title="确定导入" description="确定导入">
+                  <template #description v-if="importActive == 2">
+                    <el-button type="primary" size="mini" @click="onImport">确定</el-button>
+                  </template>
+                </el-step>
+              </el-steps>
+            </el-col>
+          </el-row>
+        </el-col>
       </el-row>
     </el-dialog>
   </div>
@@ -198,6 +222,9 @@ const rules = reactive({ name: [{ required: true, message: '请输入需求名
 const checkAll = ref(false)
 const checkedExport = ref([])
 const isIndeterminate = ref(true)
+// 导入文件
+const importActive = ref(0)
+const url = ref('')
 // 请求
 onMounted(async () => {
   loading.value = true
@@ -349,6 +376,8 @@ const toView = (item) => {
   router.push({ path: '/supply/detail', query: { id: item.id || item._id } })
 }
 const toClose = () => {
+  importActive.value = 0
+  url.value = ''
   checkedExport.value = []
   checkAll.value = false
   form.value = { time: [] }
@@ -366,15 +395,31 @@ const checkedExportChange = (value) => {
   checkAll.value = checkedCount === formFields.value.length
   isIndeterminate.value = checkedCount > 0 && checkedCount < formFields.value.length
 }
-// 下载导出模板
+// 导入数据
+const toExpert = () => {
+  dialog.value = { type: '4', show: true, title: '导入数据' }
+}
+// 导出数据
+const toDownload = () => {
+  dialog.value = { type: '3', show: true, title: '导出数据' }
+}
+
+// 下载导入模板
 const toTemplate = () => {
+  importActive.value = importActive.value + 1
   window.open('/cxyyWeb/产学研用需求模板.xlsx')
 }
+
 // 上传Excel
 const onSuccess = async (response, file) => {
+  importActive.value = importActive.value + 1
+  url.value = response.uri
+}
+// 确定导出
+const onImport = async () => {
   const msgbox = ElMessage({ message: '正在导入中,请稍后...', center: true, duration: 0 })
   try {
-    const res = await utilStore.toImport({ url: response.uri })
+    const res = await utilStore.toImport({ url: url.value })
     if (res.errcode == '0') {
       if (res.data[0].errorList) {
         ElMessageBox.alert(res.data[0].errorList, '错误提示', {
@@ -383,7 +428,8 @@ const onSuccess = async (response, file) => {
       } else {
         ElMessage({ message: '导入成功', type: 'success' })
       }
-      search({ skip, limit })
+      await search({ skip, limit })
+      await toClose()
     }
   } catch (error) {
     console.error(error)
@@ -391,12 +437,7 @@ const onSuccess = async (response, file) => {
     msgbox.close()
   }
 }
-// 下载Excel
-const toDownload = () => {
-  dialog.value = { type: '3', show: true, title: '下载Excel' }
-}
-
-// 导出Excel
+// 导出数据
 const toFile = async () => {
   if (checkedExport.value.length > 0) {
     const reqData = { table: 'demand', config: checkedExport.value, user: user.value.id }
@@ -551,4 +592,7 @@ const sizeChange = (limits) => {
     margin: 20px 0 0 0;
   }
 }
+.dialog_four {
+  padding: 20px;
+}
 </style>

+ 2 - 2
src/views/center/notice.vue

@@ -8,13 +8,13 @@
               <el-empty description="暂无数据" />
             </template>
             <el-table-column prop="type" align="center" label="通知类型" width="100">
-              <template #="{ row }">
+              <template #default="{ row }">
                 {{ getDict(row, 'type') }}
               </template>
             </el-table-column>
             <el-table-column prop="content" align="center" label="内容" />
             <el-table-column prop="is_read" align="center" label="是否已读" width="100">
-              <template #="{ row }">
+              <template #default="{ row }">
                 {{ getDict(row, 'is_read') }}
               </template>
             </el-table-column>

+ 357 - 105
src/views/center/parts/company.vue

@@ -1,132 +1,252 @@
 <template>
   <div class="index">
-    <el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="auto" class="form" label-position="left">
-      <el-row>
-        <el-form-item label="企业Logo" prop="logo">
-          <custom-upload model="logo" :list="form.logo" :limit="1" url="/files/web/cxyy_company/upload" @change="onUpload" listType="picture-card"></custom-upload>
-        </el-form-item>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="企业名称" prop="name">
-            <el-input size="large" clearable v-model="form.name" placeholder="请输入企业名称" />
-          </el-form-item>
+    <el-tabs v-model="activeName" type="card" @tab-change="handleClick">
+      <el-tab-pane label="基本信息" name="first">
+        <el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="auto" class="form" label-position="left">
+          <el-row>
+            <el-form-item label="企业Logo" prop="logo">
+              <custom-upload model="logo" :list="form.logo" :limit="1" url="/files/web/cxyy_company/upload" @change="onUpload" listType="picture-card"></custom-upload>
+            </el-form-item>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="企业名称" prop="name">
+                <el-input size="large" clearable v-model="form.name" placeholder="请输入企业名称" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="企业类型" prop="pattern">
+                <el-select size="large" clearable v-model="form.pattern" placeholder="请选择企业类型">
+                  <el-option v-for="(item, index) in patternList" :key="index" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="企业规模" prop="scale">
+                <el-select size="large" clearable v-model="form.scale" placeholder="请选择企业规模">
+                  <el-option v-for="item in scaleList" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="统一信用代码" prop="code">
+                <el-input size="large" clearable v-model="form.code" placeholder="请输入统一信用代码" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="所属行业" prop="type">
+                <el-select size="large" clearable v-model="form.type" placeholder="请选择所属行业">
+                  <el-option v-for="(item, index) in IndustryList" :key="index" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="所在地区" prop="area">
+                <el-cascader size="large" v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" clearable placeholder="请选择所在地区" style="width: 100%" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="法定代表人" prop="representative">
+                <el-input size="large" clearable v-model="form.representative" placeholder="请输入法定代表人名称" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="电子邮箱" prop="email">
+                <el-input size="large" clearable v-model="form.email" type="email" placeholder="请输入电子邮箱" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="员工人数" prop="person">
+                <el-input size="large" clearable v-model="form.person" placeholder="请输入员工人数" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="注册资本" prop="register">
+                <el-input size="large" clearable v-model="form.register" placeholder="请输入注册资本(万元)" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="硕士研究生人数" prop="graduate_num">
+                <el-input size="large" clearable type="number" v-model="form.graduate_num" placeholder="请输入硕士研究生人数" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="博士人数" prop="doctor_num">
+                <el-input size="large" clearable type="number" v-model="form.doctor_num" placeholder="请输入博士人数" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="海归人数" prop="returnee_num">
+                <el-input size="large" clearable type="number" v-model="form.returnee_num" placeholder="请输入海归人数" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="知识产权数" prop="knowledge">
+                <el-input size="large" clearable type="number" v-model="form.knowledge" placeholder="请输入知识产权数" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="发明专利数" prop="patent">
+                <el-input size="large" clearable type="number" v-model="form.patent" placeholder="请输入发明专利数" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="实用新型数" prop="utility">
+                <el-input size="large" clearable type="number" v-model="form.utility" placeholder="请输入实用新型数" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="软件著作权数" prop="copyright">
+                <el-input size="large" clearable type="number" v-model="form.copyright" placeholder="请输入软件著作权数" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="是否为高新技术企业" prop="is_tech">
+                <el-radio-group size="large" v-model="form.is_tech">
+                  <el-radio v-for="i in isUseList" :key="i._id" :label="i.value">{{ i.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="是否为专精特新企业" prop="is_new">
+                <el-radio-group size="large" v-model="form.is_new">
+                  <el-radio v-for="i in isUseList" :key="i._id" :label="i.value">{{ i.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="企业地址" prop="address">
+                <el-input size="large" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" v-model="form.address" placeholder="请输入企业地址" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="是否公开" prop="is_show">
+                <el-radio-group size="large" v-model="form.is_show">
+                  <el-radio v-for="i in isUseList" :key="i._id" :label="i.value">{{ i.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="成立时间" prop="create_time">
+                <el-date-picker size="large" format="YYYY-MM-DD" value-format="YYYY-MM-DD" v-model="form.create_time" type="date" placeholder="请选择成立时间" style="width: 100%" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-col :span="24">
+            <el-form-item label="企业产品" prop="products">
+              <el-input size="large" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" v-model="form.products" placeholder="请输入企业产品" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="简介" prop="brief">
+              <el-input size="large" v-model="form.brief" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" placeholder="请输入简介" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" class="button">
+            <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
+          </el-col>
+        </el-form>
+      </el-tab-pane>
+      <el-tab-pane label="年度信息" name="second" v-if="form && form.id">
+        <el-col :span="24" class="one">
+          <div class="one_left">
+            <div class="button" @click="toAdd">发布年度信息</div>
+          </div>
+          <div class="one_right">
+            <el-input v-model="searchForm.year" style="width: 250px" size="large" placeholder="搜索年度" @change="search" :suffix-icon="Search" />
+          </div>
         </el-col>
-        <el-col :span="12">
-          <el-form-item label="企业类型" prop="pattern">
-            <el-select size="large" clearable v-model="form.pattern" placeholder="请选择企业类型">
-              <el-option v-for="(item, index) in patternList" :key="index" :label="item.label" :value="item.value" />
-            </el-select>
-          </el-form-item>
+        <el-col :span="24" class="two">
+          <el-table :data="list" style="width: 100%" size="large" :header-cell-style="{ backgroundColor: '#edf3ff' }">
+            <template #empty>
+              <el-empty description="暂无数据" />
+            </template>
+            <el-table-column prop="year" align="center" label="年度" />
+            <el-table-column prop="time" align="center" label="填写时间" width="180" />
+            <el-table-column prop="is_use" align="center" label="是否使用" width="180">
+              <template #default="scope">
+                <div>{{ getDict(scope.row.is_use, 'is_use') }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="status" align="center" label="状态" width="180">
+              <template #default="scope">
+                <div>{{ getDict(scope.row.status, 'status') }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="操作" width="180">
+              <template #default="{ row }">
+                <el-link v-if="row.status == '-2'" :underline="false" type="warning" size="mini" @click="toExam(row)" style="margin-right: 10px">提交审核</el-link>
+                <el-link :underline="false" type="primary" size="mini" @click="toEdit(row)" style="margin-right: 10px">修改</el-link>
+                <el-link :underline="false" type="danger" size="mini" @click="toDelete(row)"> 删除 </el-link>
+              </template>
+            </el-table-column>
+          </el-table>
         </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="企业规模" prop="scale">
-            <el-select size="large" clearable v-model="form.scale" placeholder="请选择企业规模">
-              <el-option v-for="item in scaleList" :key="item.value" :label="item.label" :value="item.value" />
-            </el-select>
-          </el-form-item>
+        <el-col :span="24" class="thr">
+          <el-pagination background layout="prev, pager, next" :total="total" :page-size="limit" v-model:current-page="currentPage" @current-change="changePage" @size-change="sizeChange" />
         </el-col>
-        <el-col :span="12">
-          <el-form-item label="统一信用代码" prop="code">
-            <el-input size="large" clearable v-model="form.code" placeholder="请输入统一信用代码" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="所属行业" prop="type">
-            <el-select size="large" clearable v-model="form.type" placeholder="请选择所属行业">
-              <el-option v-for="(item, index) in IndustryList" :key="index" :label="item.label" :value="item.value" />
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="所在地区" prop="area">
-            <el-cascader size="large" v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" clearable placeholder="请选择所在地区" style="width: 100%" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="法定代表人" prop="representative">
-            <el-input size="large" clearable v-model="form.representative" placeholder="请输入法定代表人名称" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="电子邮箱" prop="email">
-            <el-input size="large" clearable v-model="form.email" type="email" placeholder="请输入电子邮箱" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="员工人数" prop="person">
-            <el-input size="large" clearable v-model="form.person" placeholder="请输入员工人数" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="注册资本" prop="register">
-            <el-input size="large" clearable v-model="form.register" placeholder="请输入注册资本(万元)" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="成立时间" prop="create_time">
-            <el-date-picker size="large" format="YYYY-MM-DD" value-format="YYYY-MM-DD" v-model="form.create_time" type="date" placeholder="请选择成立时间" style="width: 100%" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="企业地址" prop="address">
-            <el-input size="large" clearable v-model="form.address" placeholder="请输入企业地址" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="是否公开" prop="is_show">
-            <el-radio-group size="large" v-model="form.is_show">
-              <el-radio v-for="i in isUseList" :key="i._id" :label="i.value">{{ i.label }}</el-radio>
-            </el-radio-group>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="企业产品" prop="products">
-            <el-input size="large" clearable v-model="form.products" placeholder="请输入企业产品" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-col :span="24">
-        <el-form-item label="简介" prop="brief">
-          <el-input size="large" v-model="form.brief" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" placeholder="请输入简介" />
-        </el-form-item>
-      </el-col>
-      <el-col :span="24" class="button">
-        <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
-      </el-col>
-    </el-form>
+      </el-tab-pane>
+    </el-tabs>
   </div>
+  <el-dialog v-model="dialog.show" :title="dialog.title" :destroy-on-close="false" @close="toClose">
+    <el-row>
+      <el-col :span="24" v-if="dialog.type == '1'">
+        <custom-form v-model="yearForm" :fields="formFields" :rules="yearRules" @save="toSave" @draftSave="toDraftSave">
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #year>
+            <el-option v-for="i in yearList" :key="i.id" :label="i.label" :value="i.label"></el-option>
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </el-dialog>
 </template>
 <script setup>
 // 基础
+import moment from 'moment'
+import { cloneDeep, get } from 'lodash-es'
 const $checkRes = inject('$checkRes')
-const cloneDeep = inject('cloneDeep')
 // 用户信息
 import { UserStore } from '@/store/user'
 const userStore = UserStore()
 const user = computed(() => userStore.user)
 // 表单
 const ruleFormRef = ref()
+const activeName = ref('first')
 // 字典表
 const patternList = inject('patternList')
 const scaleList = inject('scaleList')
 const IndustryList = inject('IndustryList')
 const cityList = inject('cityList')
+const statusList = inject('statusList')
+const yearList = inject('yearList')
 const isUseList = inject('isUseList')
 // 接口
 import { CompanyStore } from '@/store/api/user/company'
+import { CompanyYearStore } from '@/store/api/user/companyYear'
+const yearStore = CompanyYearStore()
 const companyStore = CompanyStore()
 const form = ref({ logo: [] })
 const rules = reactive({
@@ -148,6 +268,24 @@ const rules = reactive({
   products: [{ required: true, message: '请输入产品', trigger: 'blur' }],
   address: [{ required: true, message: '请输入地址', trigger: 'blur' }]
 })
+const yearForm = ref({})
+const dialog = ref({ type: '1', show: false, title: '发布年度信息' })
+const formFields = ref([
+  { label: '年度', model: 'year', type: 'select' },
+  { label: '预计营业收入(万元)', model: 'esincome_money', type: 'number' },
+  { label: '预计利润(万元)', model: 'esprofit_money', type: 'number' },
+  { label: '预计税金(万元)', model: 'estax_money', type: 'number' },
+  { label: '预计研发费用(万元)', model: 'essearch_money', type: 'number' },
+  { label: '是否使用', model: 'is_use', type: 'radio', mark: 'dict', code: 'isUse' }
+])
+const yearRules = reactive({ year: [{ required: true, message: '请选择年度', trigger: 'blur' }] })
+// 列表
+const list = ref([])
+let skip = 0
+let limit = inject('limit')
+const total = ref(0)
+const currentPage = ref(1)
+const searchForm = ref({})
 // 上传图片
 const onUpload = (e) => {
   const { model, value } = e
@@ -182,11 +320,125 @@ const search = async () => {
     if (res.errcode == '0') form.value = res.data[0] || { logo: [] }
   }
 }
+const handleClick = async (event) => {
+  if (event == 'second') await searchYear({ skip, limit })
+}
+const searchYear = async (query = { skip, limit }) => {
+  skip = query.skip
+  limit = query.limit
+  const info = {
+    skip: query.skip,
+    limit: query.limit,
+    company: form.value.id,
+    ...searchForm.value
+  }
+  if (form.value.id) {
+    const res = await yearStore.query(info)
+    if (res.errcode == '0') {
+      list.value = res.data
+      total.value = res.total
+    }
+  }
+}
+// 字典数据转换
+const getDict = (data, model) => {
+  if (data) {
+    let res
+    if (model == 'status') res = statusList.value.find((f) => f.value == data)
+    else if (model == 'is_use') res = isUseList.value.find((f) => f.value == data)
+    return get(res, 'label')
+  }
+}
+// 添加
+const toAdd = () => {
+  dialog.value = { type: '1', show: true, title: '发布年度信息' }
+}
+// 修改
+const toEdit = (data) => {
+  yearForm.value = data
+  dialog.value = { type: '1', show: true, title: '修改年度信息' }
+}
+// 删除
+const toDelete = (data) => {
+  ElMessageBox.confirm(`您确认删除该数据?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
+    .then(async () => {
+      const res = await yearStore.del(data.id)
+      if ($checkRes(res, true)) {
+        searchYear({ skip, limit })
+      }
+    })
+    .catch(() => {})
+}
+const toSave = async () => {
+  const data = cloneDeep(yearForm.value)
+  const other = { status: '0', user: user.value.id, company: form.value.id, time: moment().format('YYYY-MM-DD') }
+  let res
+  if (get(data, 'id')) res = await yearStore.update({ ...data, ...other })
+  else res = await yearStore.create({ ...data, ...other })
+  if ($checkRes(res, true)) {
+    await searchYear({ skip, limit })
+    await toClose()
+  }
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(yearForm.value)
+  const other = { status: '-2', user: user.value.id, company: form.value.id, time: moment().format('YYYY-MM-DD') }
+  let res
+  if (get(data, 'id')) res = await yearStore.update({ ...data, ...other })
+  else res = await yearStore.create({ ...data, ...other })
+  if ($checkRes(res, true)) {
+    await searchYear({ skip, limit })
+    await toClose()
+  }
+}
+// 审核保存
+const toExam = async (row) => {
+  ElMessageBox.confirm(`您确认保存并提交审核该数据?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
+    .then(async () => {
+      const data = cloneDeep(row)
+      let res = await yearStore.update({ id: data.id, status: '0', user: user.value.id, company: form.value.id, time: moment().format('YYYY-MM-DD') })
+      if ($checkRes(res, true)) {
+        await searchYear({ skip, limit })
+        await toClose()
+      }
+    })
+    .catch(() => {})
+}
+const toClose = () => {
+  yearForm.value = {}
+  dialog.value = { show: false }
+}
 </script>
 <style scoped lang="scss">
 .index {
   .button {
     text-align: center;
   }
+  .one {
+    height: 50px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin: 0 0 10px 0;
+    .one_left {
+      display: flex;
+      font-size: 16px;
+      .button {
+        background: #1875df;
+        padding: 0 10px;
+        height: 30px;
+        color: #fff;
+        line-height: 30px;
+        text-align: center;
+        cursor: default;
+        margin: 0 10px 0 0;
+      }
+    }
+  }
+  .thr {
+    display: flex;
+    justify-content: center;
+    margin: 20px 0 0 0;
+  }
 }
 </style>

+ 374 - 68
src/views/center/parts/incubator.vue

@@ -1,93 +1,262 @@
 <template>
   <div class="index">
-    <el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="auto" class="form" label-position="left">
-      <el-row>
-        <el-form-item label="Logo" prop="logo">
-          <custom-upload model="logo" :list="form.logo" :limit="1" url="/files/web/cxyy_incubator/upload" @change="onUpload" listType="picture-card"></custom-upload>
-        </el-form-item>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="孵化基地名称" prop="name">
-            <el-input size="large" clearable v-model="form.name" placeholder="请输入孵化基地名称" />
-          </el-form-item>
+    <el-tabs v-model="activeName" type="card" @tab-change="handleClick">
+      <el-tab-pane label="基本信息" name="first">
+        <el-form ref="ruleFormRef" :model="form" :rules="rules" class="form" label-position="left">
+          <el-row>
+            <el-form-item label="Logo" prop="logo">
+              <custom-upload model="logo" :list="form.logo" :limit="1" url="/files/web/cxyy_incubator/upload" @change="onUpload" listType="picture-card"></custom-upload>
+            </el-form-item>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="孵化基地名称" prop="name">
+                <el-input size="large" clearable v-model="form.name" placeholder="请输入孵化基地名称" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="运营单位名称" prop="unit">
+                <el-input size="large" clearable v-model="form.unit" placeholder="请输入运营单位名称" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="负责人姓名" prop="person">
+                <el-input size="large" clearable v-model="form.person" placeholder="请输入负责人姓名" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="负责人电话" prop="person_phone">
+                <el-input size="large" clearable v-model="form.person_phone" placeholder="请输入负责人电话" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="所在地区" prop="area">
+                <el-cascader size="large" v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" clearable placeholder="请选择所在地区" style="width: 100%" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="地址" prop="address">
+                <el-input size="large" v-model="form.address" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" placeholder="请输入地址" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="占地面积(平方米)" prop="cover_area">
+                <el-input size="large" clearable v-model="form.cover_area" placeholder="请输入占地面积(平方米)" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="建筑面积(平方米)" prop="build_area">
+                <el-input size="large" clearable v-model="form.build_area" placeholder="请输入建筑面积(平方米)" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="剩余面积(平方米)" prop="residue_area">
+                <el-input size="large" clearable v-model="form.residue_area" placeholder="请输入剩余面积(平方米)" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="房租(元/平方米/月)" prop="rent">
+                <el-input size="large" clearable v-model="form.rent" placeholder="请输入房租(元/平方米/月)" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="物业费(元/平方米/月)" prop="wy_money">
+                <el-input size="large" clearable v-model="form.wy_money" placeholder="请输入物业费(元/平方米/月)" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="是否具备中试场地" prop="is_have">
+                <el-radio-group size="large" v-model="form.is_have">
+                  <el-radio v-for="i in isUseList" :key="i._id" :label="i.value">{{ i.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="载体运营单位人数" prop="unit_num">
+                <el-input size="large" type="number" clearable v-model="form.unit_num" placeholder="请输入载体运营单位人数" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="载体运营单位的省级以上导师数" prop="teacher_num">
+                <el-input size="large" type="number" clearable v-model="form.teacher_num" placeholder="请输入载体运营单位的省级以上导师数" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="中试场地面积(平方米)" prop="site_area">
+                <el-input size="large" clearable v-model="form.site_area" placeholder="请输入中试场地面积(平方米)" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="累计参加活动人次" prop="activity_num">
+                <el-input size="large" type="number" clearable v-model="form.activity_num" placeholder="请输入累计参加活动人次" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="累计参加活动企业数量" prop="actCompany_num">
+                <el-input size="large" type="number" clearable v-model="form.actCompany_num" placeholder="请输入累计参加活动企业数量" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="市级以上活动数" prop="actCity_num">
+                <el-input size="large" type="number" clearable v-model="form.actCity_num" placeholder="请输入市级以上活动数" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="培训辅导类活动数" prop="actTrain_num">
+                <el-input size="large" type="number" clearable v-model="form.actTrain_num" placeholder="请输入培训辅导类活动数" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="高校院所类活动数" prop="actSchool_num">
+                <el-input size="large" type="number" clearable v-model="form.actSchool_num" placeholder="请输入高校院所类活动数" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="投资机构类活动数" prop="actInstitution_num">
+                <el-input size="large" type="number" clearable v-model="form.actInstitution_num" placeholder="请输入投资机构类活动数" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="中介服务类活动数" prop="actService_num">
+                <el-input size="large" type="number" clearable v-model="form.actService_num" placeholder="请输入中介服务类活动数" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-col :span="24">
+            <el-form-item label="入驻企业数" prop="company_num">
+              <el-input size="large" type="number" clearable v-model="form.company_num" placeholder="请输入入驻企业数" />
+            </el-form-item>
+          </el-col>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="是否公开" prop="is_show">
+                <el-radio-group size="large" v-model="form.is_show">
+                  <el-radio v-for="i in isUseList" :key="i._id" :label="i.value">{{ i.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="是否和平台合作标识" prop="cooperate">
+                <el-radio-group v-model="form.cooperate" disabled>
+                  <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-col :span="24">
+            <el-form-item label="基地风采" prop="file">
+              <custom-upload model="file" :list="form.file" :limit="4" url="/files/web/cxyy_incubator/upload" @change="onUpload" listType="picture-card"></custom-upload>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="简介" prop="brief">
+              <WangEditor v-model="form.brief" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" class="button">
+            <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
+          </el-col>
+        </el-form>
+      </el-tab-pane>
+      <el-tab-pane label="年度信息" name="second" v-if="form && form.id">
+        <el-col :span="24" class="one">
+          <div class="one_left">
+            <div class="button" @click="toAdd">发布年度信息</div>
+          </div>
+          <div class="one_right">
+            <el-input v-model="searchForm.year" style="width: 250px" size="large" placeholder="搜索年度" @change="search" :suffix-icon="Search" />
+          </div>
         </el-col>
-        <el-col :span="12">
-          <el-form-item label="负责人姓名" prop="person">
-            <el-input size="large" clearable v-model="form.person" placeholder="请输入负责人姓名" />
-          </el-form-item>
+        <el-col :span="24" class="two">
+          <el-table :data="list" style="width: 100%" size="large" :header-cell-style="{ backgroundColor: '#edf3ff' }">
+            <template #empty>
+              <el-empty description="暂无数据" />
+            </template>
+            <el-table-column prop="year" align="center" label="年度" />
+            <el-table-column prop="act_num" align="center" label="活动总数" width="180" />
+            <el-table-column prop="time" align="center" label="填写时间" width="180" />
+            <el-table-column prop="is_use" align="center" label="是否使用" width="180">
+              <template #default="scope">
+                <div>{{ getDict(scope.row.is_use, 'is_use') }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="status" align="center" label="状态" width="180">
+              <template #default="scope">
+                <div>{{ getDict(scope.row.status, 'status') }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="操作" width="180">
+              <template #default="{ row }">
+                <el-link v-if="row.status == '-2'" :underline="false" type="warning" size="mini" @click="toExam(row)" style="margin-right: 10px">提交审核</el-link>
+                <el-link :underline="false" type="primary" size="mini" @click="toEdit(row)" style="margin-right: 10px">修改</el-link>
+                <el-link :underline="false" type="danger" size="mini" @click="toDelete(row)"> 删除 </el-link>
+              </template>
+            </el-table-column>
+          </el-table>
         </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="负责人电话" prop="person_phone">
-            <el-input size="large" clearable v-model="form.person_phone" placeholder="请输入负责人电话" />
-          </el-form-item>
+        <el-col :span="24" class="thr">
+          <el-pagination background layout="prev, pager, next" :total="total" :page-size="limit" v-model:current-page="currentPage" @current-change="changePage" @size-change="sizeChange" />
         </el-col>
-        <el-col :span="12">
-          <el-form-item label="是否公开" prop="is_show">
-            <el-radio-group size="large" v-model="form.is_show">
-              <el-radio v-for="i in isUseList" :key="i._id" :label="i.value">{{ i.label }}</el-radio>
-            </el-radio-group>
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="所属行业" prop="industry">
-            <el-select size="large" clearable v-model="form.industry" placeholder="请选择所属行业">
-              <el-option v-for="(item, index) in plateList" :key="index" :label="item.title" :value="item.title" />
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="是否和平台合作标识" prop="cooperate">
-            <el-radio-group v-model="form.cooperate" disabled>
-              <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
-            </el-radio-group>
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="所在地区" prop="area">
-            <el-cascader size="large" v-model="form.area" :props="{ value: 'name', label: 'name' }" :options="cityList" clearable placeholder="请选择所在地区" style="width: 100%" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="地址" prop="address">
-            <el-input size="large" v-model="form.address" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" placeholder="请输入地址" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-col :span="24">
-        <el-form-item label="简介" prop="brief">
-          <WangEditor v-model="form.brief" />
-        </el-form-item>
-      </el-col>
-      <el-col :span="24" class="button">
-        <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
-      </el-col>
-    </el-form>
+      </el-tab-pane>
+    </el-tabs>
   </div>
+  <el-dialog v-model="dialog.show" :title="dialog.title" :destroy-on-close="false" @close="toClose">
+    <el-row>
+      <el-col :span="24" v-if="dialog.type == '1'">
+        <custom-form v-model="yearForm" :fields="formFields" :rules="yearRules" @save="toSave" @draftSave="toDraftSave">
+          <template #is_use>
+            <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
+          </template>
+          <template #year>
+            <el-option v-for="i in yearList" :key="i.id" :label="i.label" :value="i.label"></el-option>
+          </template>
+        </custom-form>
+      </el-col>
+    </el-row>
+  </el-dialog>
 </template>
 <script setup>
 // 基础
+import moment from 'moment'
+import { cloneDeep, get } from 'lodash-es'
 const $checkRes = inject('$checkRes')
-const cloneDeep = inject('cloneDeep')
 // 用户信息
 import { UserStore } from '@/store/user'
 const userStore = UserStore()
 const user = computed(() => userStore.user)
 // 表单
 const ruleFormRef = ref()
+const activeName = ref('first')
 // 字典表
 const isUseList = inject('isUseList')
-const plateList = inject('plateList')
+const statusList = inject('statusList')
+const yearList = inject('yearList')
 const cityList = inject('cityList')
 // 接口
 import { IncubatorStore } from '@/store/api/user/incubator'
+import { IncubatorYearStore } from '@/store/api/user/incubatorYear'
 const incubatorStore = IncubatorStore()
+const yearStore = IncubatorYearStore()
 const form = ref({ logo: [] })
 const rules = reactive({
   // nick_name: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
@@ -97,6 +266,29 @@ const rules = reactive({
   // password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
   // refpassword: [{ required: true, validator: validatePassword, trigger: 'blur' }]
 })
+const yearForm = ref({})
+const dialog = ref({ type: '1', show: false, title: '发布年度信息' })
+const formFields = ref([
+  { label: '年度', model: 'year', type: 'select' },
+  { label: '活动总数', model: 'act_num', type: 'number' },
+  { label: '企业实现收入(万元)', model: 'income_money', type: 'number' },
+  { label: '企业利润(万元)', model: 'profit_money', type: 'number' },
+  { label: '企业税金(万元)', model: 'tax_money', type: 'number' },
+  { label: '企业预计收入(万元)', model: 'esincome_money', type: 'number' },
+  { label: '企业预计利润(万元)', model: 'esprofit_money', type: 'number' },
+  { label: '企业预计税金(万元)', model: 'estax_money', type: 'number' },
+  { label: '获得荣誉情况', model: 'content', type: 'textarea' },
+  { label: '是否使用', model: 'is_use', type: 'radio', mark: 'dict', code: 'isUse' }
+])
+const yearRules = reactive({ year: [{ required: true, message: '请选择年度', trigger: 'blur' }] })
+// 列表
+const list = ref([])
+let skip = 0
+let limit = inject('limit')
+const total = ref(0)
+const currentPage = ref(1)
+const searchForm = ref({})
+
 // 上传图片
 const onUpload = (e) => {
   const { model, value } = e
@@ -124,6 +316,9 @@ const submitForm = async (formEl) => {
 onMounted(async () => {
   await search()
 })
+const handleClick = async (event) => {
+  if (event == 'second') await searchYear({ skip, limit })
+}
 const search = async () => {
   if (user.value.id) {
     let res = await incubatorStore.query({ user: user.value.id })
@@ -133,11 +328,122 @@ const search = async () => {
     }
   }
 }
+const searchYear = async (query = { skip, limit }) => {
+  skip = query.skip
+  limit = query.limit
+  const info = {
+    skip: query.skip,
+    limit: query.limit,
+    incubator: form.value.id,
+    ...searchForm.value
+  }
+  if (form.value.id) {
+    const res = await yearStore.query(info)
+    if (res.errcode == '0') {
+      list.value = res.data
+      total.value = res.total
+    }
+  }
+}
+// 字典数据转换
+const getDict = (data, model) => {
+  if (data) {
+    let res
+    if (model == 'status') res = statusList.value.find((f) => f.value == data)
+    else if (model == 'is_use') res = isUseList.value.find((f) => f.value == data)
+    return get(res, 'label')
+  }
+}
+// 添加
+const toAdd = () => {
+  dialog.value = { type: '1', show: true, title: '发布年度信息' }
+}
+// 修改
+const toEdit = (data) => {
+  yearForm.value = data
+  dialog.value = { type: '1', show: true, title: '修改年度信息' }
+}
+// 删除
+const toDelete = (data) => {
+  ElMessageBox.confirm(`您确认删除该数据?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
+    .then(async () => {
+      const res = await yearStore.del(data.id)
+      if ($checkRes(res, true)) {
+        searchYear({ skip, limit })
+      }
+    })
+    .catch(() => {})
+}
+const toSave = async () => {
+  const data = cloneDeep(yearForm.value)
+  const other = { status: '0', user: user.value.id, incubator: form.value.id, time: moment().format('YYYY-MM-DD') }
+  let res
+  if (get(data, 'id')) res = await yearStore.update({ ...data, ...other })
+  else res = await yearStore.create({ ...data, ...other })
+  if ($checkRes(res, true)) {
+    await searchYear({ skip, limit })
+    await toClose()
+  }
+}
+const toDraftSave = async () => {
+  const data = cloneDeep(yearForm.value)
+  const other = { status: '-2', user: user.value.id, incubator: form.value.id, time: moment().format('YYYY-MM-DD') }
+  let res
+  if (get(data, 'id')) res = await yearStore.update({ ...data, ...other })
+  else res = await yearStore.create({ ...data, ...other })
+  if ($checkRes(res, true)) {
+    await searchYear({ skip, limit })
+    await toClose()
+  }
+}
+// 审核保存
+const toExam = async (row) => {
+  ElMessageBox.confirm(`您确认保存并提交审核该数据?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
+    .then(async () => {
+      const data = cloneDeep(row)
+      let res = await yearStore.update({ id: data.id, status: '0', user: user.value.id, incubator: form.value.id, time: moment().format('YYYY-MM-DD') })
+      if ($checkRes(res, true)) {
+        await searchYear({ skip, limit })
+        await toClose()
+      }
+    })
+    .catch(() => {})
+}
+const toClose = () => {
+  yearForm.value = {}
+  dialog.value = { show: false }
+}
 </script>
 <style scoped lang="scss">
 .index {
   .button {
     text-align: center;
   }
+  .one {
+    height: 50px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin: 0 0 10px 0;
+    .one_left {
+      display: flex;
+      font-size: 16px;
+      .button {
+        background: #1875df;
+        padding: 0 10px;
+        height: 30px;
+        color: #fff;
+        line-height: 30px;
+        text-align: center;
+        cursor: default;
+        margin: 0 10px 0 0;
+      }
+    }
+  }
+  .thr {
+    display: flex;
+    justify-content: center;
+    margin: 20px 0 0 0;
+  }
 }
 </style>

+ 56 - 11
src/views/center/project.vue

@@ -5,9 +5,8 @@
         <el-col :span="24" class="one">
           <div class="one_left">
             <div class="button" @click="toAdd">发布项目</div>
-            <div class="button" @click="toTemplate">下载导出模板</div>
-            <el-upload class="button" action="/files/web/cxyy_import/upload" :show-file-list="false" :on-success="onSuccess" accept=".xlsx"> 选择excel模板文件 </el-upload>
-            <div class="button" @click="toDownload">下载Excel</div>
+            <div class="button" @click="toExpert">导入数据</div>
+            <div class="button" @click="toDownload">导出数据</div>
           </div>
           <div class="one_right">
             <el-input v-model="searchForm.name" style="width: 250px" size="large" placeholder="搜索" @change="search" :suffix-icon="Search" />
@@ -115,6 +114,31 @@
             <el-button type="primary" size="mini" @click="toFile()">导出</el-button>
           </el-col>
         </el-col>
+        <el-col :span="24" class="dialog_four" v-if="dialog.type == '4'">
+          <el-row justify="center">
+            <el-col :span="16">
+              <el-steps style="max-width: 600px" :active="importActive" align-center>
+                <el-step title="下载导入模板">
+                  <template #description v-if="importActive == 0">
+                    <el-button type="primary" size="mini" @click="toTemplate">下载导入模板</el-button>
+                  </template>
+                </el-step>
+                <el-step title="上传导入模板" description="上传导入模板">
+                  <template #description v-if="importActive == 1">
+                    <el-upload action="/files/web/cxyy_import/upload" :show-file-list="false" :on-success="onSuccess" accept=".xlsx">
+                      <el-button type="primary" size="mini">上传导入文件</el-button>
+                    </el-upload>
+                  </template>
+                </el-step>
+                <el-step title="确定导入" description="确定导入">
+                  <template #description v-if="importActive == 2">
+                    <el-button type="primary" size="mini" @click="onImport">确定</el-button>
+                  </template>
+                </el-step>
+              </el-steps>
+            </el-col>
+          </el-row>
+        </el-col>
       </el-row>
     </el-dialog>
   </div>
@@ -205,6 +229,9 @@ const rules = reactive({ name: [{ required: true, message: '请输入项目名
 const checkAll = ref(false)
 const checkedExport = ref([])
 const isIndeterminate = ref(true)
+// 导入文件
+const importActive = ref(0)
+const url = ref('')
 // 请求
 onMounted(async () => {
   loading.value = true
@@ -357,6 +384,8 @@ const getArea = (data) => {
   else return '暂无地区'
 }
 const toClose = () => {
+  importActive.value = 0
+  url.value = ''
   checkedExport.value = []
   checkAll.value = false
   form.value = { time: [] }
@@ -374,15 +403,31 @@ const checkedExportChange = (value) => {
   checkAll.value = checkedCount === formFields.value.length
   isIndeterminate.value = checkedCount > 0 && checkedCount < formFields.value.length
 }
-// 下载导出模板
+// 导入数据
+const toExpert = () => {
+  dialog.value = { type: '4', show: true, title: '导入数据' }
+}
+// 导出数据
+const toDownload = () => {
+  dialog.value = { type: '3', show: true, title: '导出数据' }
+}
+
+// 下载导入模板
 const toTemplate = () => {
+  importActive.value = importActive.value + 1
   window.open('/cxyyWeb/产学研用项目模板.xlsx')
 }
+
 // 上传Excel
 const onSuccess = async (response, file) => {
+  importActive.value = importActive.value + 1
+  url.value = response.uri
+}
+// 确定导出
+const onImport = async () => {
   const msgbox = ElMessage({ message: '正在导入中,请稍后...', center: true, duration: 0 })
   try {
-    const res = await utilStore.toImport({ url: response.uri })
+    const res = await utilStore.toImport({ url: url.value })
     if (res.errcode == '0') {
       if (res.data[0].errorList) {
         ElMessageBox.alert(res.data[0].errorList, '错误提示', {
@@ -391,7 +436,8 @@ const onSuccess = async (response, file) => {
       } else {
         ElMessage({ message: '导入成功', type: 'success' })
       }
-      search({ skip, limit })
+      await search({ skip, limit })
+      await toClose()
     }
   } catch (error) {
     console.error(error)
@@ -399,12 +445,8 @@ const onSuccess = async (response, file) => {
     msgbox.close()
   }
 }
-// 下载Excel
-const toDownload = () => {
-  dialog.value = { type: '3', show: true, title: '下载Excel' }
-}
 
-// 导出Excel
+// 导出数据
 const toFile = async () => {
   if (checkedExport.value.length > 0) {
     const reqData = { table: 'project', config: checkedExport.value, user: user.value.id }
@@ -559,4 +601,7 @@ const sizeChange = (limits) => {
     margin: 20px 0 0 0;
   }
 }
+.dialog_four {
+  padding: 20px;
+}
 </style>

+ 54 - 11
src/views/center/supply.vue

@@ -5,9 +5,8 @@
         <el-col :span="24" class="one">
           <div class="one_left">
             <div class="button" @click="toAdd">发布供给</div>
-            <div class="button" @click="toTemplate">下载导出模板</div>
-            <el-upload class="button" action="/files/web/cxyy_import/upload" :show-file-list="false" :on-success="onSuccess" accept=".xlsx"> 选择excel模板文件 </el-upload>
-            <div class="button" @click="toDownload">下载Excel</div>
+            <div class="button" @click="toExpert">导入数据</div>
+            <div class="button" @click="toDownload">导出数据</div>
           </div>
           <div class="one_right">
             <el-input v-model="searchForm.name" style="width: 250px" size="large" placeholder="搜索" @change="search" :suffix-icon="Search" />
@@ -107,6 +106,31 @@
             <el-button type="primary" size="mini" @click="toFile()">导出</el-button>
           </el-col>
         </el-col>
+        <el-col :span="24" class="dialog_four" v-if="dialog.type == '4'">
+          <el-row justify="center">
+            <el-col :span="16">
+              <el-steps style="max-width: 600px" :active="importActive" align-center>
+                <el-step title="下载导入模板">
+                  <template #description v-if="importActive == 0">
+                    <el-button type="primary" size="mini" @click="toTemplate">下载导入模板</el-button>
+                  </template>
+                </el-step>
+                <el-step title="上传导入模板" description="上传导入模板">
+                  <template #description v-if="importActive == 1">
+                    <el-upload action="/files/web/cxyy_import/upload" :show-file-list="false" :on-success="onSuccess" accept=".xlsx">
+                      <el-button type="primary" size="mini">上传导入文件</el-button>
+                    </el-upload>
+                  </template>
+                </el-step>
+                <el-step title="确定导入" description="确定导入">
+                  <template #description v-if="importActive == 2">
+                    <el-button type="primary" size="mini" @click="onImport">确定</el-button>
+                  </template>
+                </el-step>
+              </el-steps>
+            </el-col>
+          </el-row>
+        </el-col>
       </el-row>
     </el-dialog>
   </div>
@@ -191,6 +215,9 @@ const rules = reactive({ name: [{ required: true, message: '请输入供给名
 const checkAll = ref(false)
 const checkedExport = ref([])
 const isIndeterminate = ref(true)
+// 导入文件
+const importActive = ref(0)
+const url = ref('')
 // 请求
 onMounted(async () => {
   loading.value = true
@@ -364,15 +391,31 @@ const checkedExportChange = (value) => {
   checkAll.value = checkedCount === formFields.value.length
   isIndeterminate.value = checkedCount > 0 && checkedCount < formFields.value.length
 }
-// 下载导出模板
+// 导入数据
+const toExpert = () => {
+  dialog.value = { type: '4', show: true, title: '导入数据' }
+}
+// 导出数据
+const toDownload = () => {
+  dialog.value = { type: '3', show: true, title: '导出数据' }
+}
+
+// 下载导入模板
 const toTemplate = () => {
+  importActive.value = importActive.value + 1
   window.open('/cxyyWeb/产学研用供给模板.xlsx')
 }
+
 // 上传Excel
 const onSuccess = async (response, file) => {
+  importActive.value = importActive.value + 1
+  url.value = response.uri
+}
+// 确定导出
+const onImport = async () => {
   const msgbox = ElMessage({ message: '正在导入中,请稍后...', center: true, duration: 0 })
   try {
-    const res = await utilStore.toImport({ url: response.uri })
+    const res = await utilStore.toImport({ url: url.value })
     if (res.errcode == '0') {
       if (res.data[0].errorList) {
         ElMessageBox.alert(res.data[0].errorList, '错误提示', {
@@ -381,7 +424,8 @@ const onSuccess = async (response, file) => {
       } else {
         ElMessage({ message: '导入成功', type: 'success' })
       }
-      search({ skip, limit })
+      await search({ skip, limit })
+      await toClose()
     }
   } catch (error) {
     console.error(error)
@@ -389,12 +433,8 @@ const onSuccess = async (response, file) => {
     msgbox.close()
   }
 }
-// 下载Excel
-const toDownload = () => {
-  dialog.value = { type: '3', show: true, title: '下载Excel' }
-}
 
-// 导出Excel
+// 导出数据
 const toFile = async () => {
   if (checkedExport.value.length > 0) {
     const reqData = { table: 'supply', config: checkedExport.value, user: user.value.id }
@@ -549,4 +589,7 @@ const sizeChange = (limits) => {
     margin: 20px 0 0 0;
   }
 }
+.dialog_four {
+  padding: 20px;
+}
 </style>

+ 37 - 4
src/views/detail/baseDetail.vue

@@ -60,6 +60,9 @@
                   </template>
                 </el-table-column>
               </el-table>
+              <div class="thr">
+                <el-pagination background layout="prev, pager, next" :total="total" :page-size="limit" v-model:current-page="currentPage" @current-change="changePage" @size-change="sizeChange" />
+              </div>
             </div>
           </div>
           <div class="bottom">
@@ -122,6 +125,10 @@ const route = useRoute()
 const info = ref({})
 // 列表
 const list = ref([])
+let skip = 0
+let limit = inject('limit')
+const total = ref(0)
+const currentPage = ref(1)
 const isUseList = ref([])
 const cirelationList = ref([])
 // 请求
@@ -132,7 +139,7 @@ onMounted(async () => {
   loading.value = false
 })
 const searchOther = async () => {
-  const data = { skip: 0, limit: 3, status: '1', is_show: '0' }
+  const data = { skip: 0, limit: 4, status: '1', is_show: '0' }
   let res
   res = await store.query(data)
   if (res.errcode == '0') list.value = res.data
@@ -145,9 +152,21 @@ const search = async () => {
   if (id) {
     let res = await store.detail(id)
     if (res.errcode == '0') info.value = res.data
-    const data = { skip: 0, limit: 6, incubator: res.data.id, status: '1' }
-    res = await cirelationStore.list(data)
-    if (res.errcode == '0') cirelationList.value = res.data
+    await searchCompany({ skip, limit })
+  }
+}
+const searchCompany = async (query = { skip, limit }) => {
+  skip = query.skip
+  limit = query.limit
+  const data = {
+    skip: query.skip,
+    limit: query.limit,
+    incubator: info.value.id
+  }
+  const res = await cirelationStore.list(data)
+  if (res.errcode == '0') {
+    cirelationList.value = res.data
+    total.value = res.total
   }
 }
 // 查看
@@ -196,6 +215,15 @@ const toCollect = async () => {
     }
   } else ElMessage({ message: '未登录!', type: 'error' })
 }
+// 分页
+const changePage = (page = currentPage.value) => {
+  searchCompany({ skip: (page - 1) * limit, limit: limit })
+}
+const sizeChange = (limits) => {
+  limit = limits
+  currentPage.value = 1
+  searchCompany({ skip: 0, limit: limit })
+}
 </script>
 <style scoped lang="scss">
 .main {
@@ -276,6 +304,11 @@ const toCollect = async () => {
         .content {
           padding: 20px;
           font-size: $global-font-size-16;
+          .thr {
+            display: flex;
+            justify-content: center;
+            margin: 20px 0 0 0;
+          }
         }
       }
       .bottom {

BIN
src/views/elevenHatch copy/font/DS-DIGI.TTF


BIN
src/views/elevenHatch copy/font/DS-DIGIB.TTF


BIN
src/views/elevenHatch copy/font/DS-DIGII.TTF


BIN
src/views/elevenHatch copy/font/DS-DIGIT.TTF


BIN
src/views/elevenHatch copy/images/bg.jpg


BIN
src/views/elevenHatch copy/images/head_bg.png


BIN
src/views/elevenHatch copy/images/jt.png


BIN
src/views/elevenHatch copy/images/lbx.png


BIN
src/views/elevenHatch copy/images/line.png


BIN
src/views/elevenHatch copy/images/loading.gif


BIN
src/views/elevenHatch copy/images/map.png


+ 343 - 0
src/views/elevenHatch copy/index.vue

@@ -0,0 +1,343 @@
+<template>
+  <div class="elevenHatch">
+    <el-row>
+      <el-col :span="24" class="animate__animated animate__backInRight" v-loading="loading">
+        <div class="head">
+          <div class="head_1">孵化基地管理驾驶舱</div>
+          <div class="head_2" id="showTime">{{ formattedTime }}</div>
+        </div>
+        <div class="center">
+          <el-row :gutter="20">
+            <el-col :span="6">
+              <div class="center_1">
+                <div class="boxall">
+                  <div class="alltitle">孵化进度</div>
+                  <echarts3></echarts3>
+                </div>
+                <div class="boxall">
+                  <div class="alltitle">孵化项目列表</div>
+                  <div class="wraptit"><span>项目名称</span><span>金额</span><span>风险概率</span><span>时间</span></div>
+                  <div class="one">
+                    <vue3-seamless-scroll :list="oneList" :hover="true" :step="0.2" :wheel="true" :isWatch="true" class="scroll">
+                      <div class="wrap" v-for="(item, index) in oneList" :key="index">
+                        <div class="other">{{ item.name }}</div>
+                        <div class="other">{{ item.money }}</div>
+                        <div class="other">{{ item.number }}</div>
+                        <div class="other">{{ item.time }}</div>
+                      </div>
+                    </vue3-seamless-scroll>
+                  </div>
+                </div>
+                <div class="boxall">
+                  <div class="alltitle">行业领域占比情况</div>
+                  <echarts1></echarts1>
+                </div>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="center_1">
+                <div class="boxall" style="height: 170px">
+                  <div class="clearfix navboxall" style="height: 100%">
+                    <div class="pulll_left num">
+                      <div class="numbt">总体情况<span>(单位:家)</span></div>
+                      <div class="numtxt">190</div>
+                    </div>
+                    <div class="pulll_right zhibiao">
+                      <div class="zb1">
+                        <span>工研院运营</span>
+                        <echarts5></echarts5>
+                      </div>
+                      <div class="zb2">
+                        <span>参股孵化基地</span>
+                        <echarts6></echarts6>
+                      </div>
+                      <div class="zb3">
+                        <span>合作孵化基地</span>
+                        <echarts7></echarts7>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="boxall">
+                  <div class="alltitle">年度项目完成对比</div>
+                  <echarts2></echarts2>
+                </div>
+                <div class="boxall">
+                  <div class="alltitle">投资收益对比</div>
+                  <echarts4></echarts4>
+                </div>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="center_1">
+                <div class="boxall bottom">
+                  <div class="alltitle">视频监控</div>
+                  <div v-for="(item, index) in twoList" :key="index">
+                    <el-image class="image" :src="item.url" fit="fill" />
+                  </div>
+                </div>
+              </div>
+            </el-col>
+          </el-row>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import echarts1 from './path/echarts1.vue'
+import echarts2 from './path/echarts2.vue'
+import echarts3 from './path/echarts3.vue'
+import echarts4 from './path/echarts4.vue'
+import echarts5 from './path/echarts5.vue'
+import echarts6 from './path/echarts6.vue'
+import echarts7 from './path/echarts7.vue'
+// 加载中
+const loading = ref(false)
+// 时间
+const formattedTime = ref('')
+const oneList = ref([
+  { name: '鱿鱼卤制品的研究', money: '110万', number: '10%', time: '2023-4-22' },
+  { name: '一种快速装置自净系统', money: '190万', number: '20%', time: '2023-6-15' },
+  { name: '玻璃表面清洁技术', money: '90万', number: '33%', time: '2023-5-30' },
+  { name: '网上信息安全处理', money: '180万', number: '14%', time: '2023-7-12' },
+  { name: '视觉检测', money: '119万', number: '10%', time: '2023-5-14' },
+  { name: '无纺布气味去除', money: '120万', number: '20%', time: '2023-6-15' },
+  { name: '功能性色母开发', money: '160万', number: '10%', time: '2023-5-30' }
+])
+import video_1 from '/images/video_1.jpg'
+import video_2 from '/images/video_2.jpg'
+import video_3 from '/images/video_3.jpg'
+import video_4 from '/images/video_4.jpg'
+const twoList = ref([{ url: video_1 }, { url: video_2 }, { url: video_3 }, { url: video_4 }])
+
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await updateTime()
+  loading.value = false
+})
+// 创建一个函数来格式化时间并更新状态
+const updateTime = () => {
+  const now = new Date()
+  const options = {
+    year: 'numeric',
+    month: '2-digit',
+    day: '2-digit',
+    hour: '2-digit',
+    minute: '2-digit',
+    second: '2-digit',
+    hour12: false
+  }
+  formattedTime.value = now.toLocaleString('zh-CN', options)
+}
+
+const timer = setInterval(updateTime, 1000)
+
+onMounted(() => {
+  timer // 开始计时器
+})
+
+onBeforeUnmount(() => {
+  clearInterval(timer) // 组件卸载前清除计时器
+})
+</script>
+<style scoped lang="scss">
+.elevenHatch {
+  width: 100%;
+  position: relative;
+  background: url(/images/bg.jpg);
+  background-size: 100% 100%;
+  padding: 0px;
+  margin: 0px;
+  color: #222;
+  font-family: '微软雅黑';
+  cursor: default; /* 将鼠标样式更改为箭头 */
+  @font-face {
+    font-family: electronicFont;
+    src: url(./font/DS-DIGIT.TTF);
+  }
+  a:hover {
+    color: #06c;
+    text-decoration: none !important;
+  }
+  .head {
+    position: relative;
+    height: 70px;
+    background: url(/images/head_bg.png) no-repeat center center;
+    background-size: 100% 100%;
+    .head_1 {
+      color: #fff;
+      text-align: center;
+      font-size: 38px;
+      line-height: 38px;
+      margin: 20px 0;
+    }
+    .head_2 {
+      position: absolute;
+      right: 10px;
+      top: 5px;
+      line-height: 20px;
+      color: rgba(255, 255, 255, 0.7);
+      font-size: 20px;
+      padding-right: 10px;
+      font-family: electronicFont;
+    }
+  }
+  .center {
+    margin: 0 10px;
+    .center_1 {
+      .navboxall {
+        height: calc(100% - 30px);
+      }
+      .boxall {
+        padding: 15px;
+        background: rgba(0, 0, 0, 0.2);
+        position: relative;
+        margin-bottom: 10px;
+        z-index: 10;
+      }
+      .bottom {
+        margin-bottom: 0;
+      }
+
+      .alltitle {
+        font-size: $global-font-size-20;
+        color: #fff;
+        position: relative;
+        padding-left: 12px;
+        margin-bottom: 10px;
+      }
+
+      .alltitle:before {
+        width: 5px;
+        height: 20px;
+        top: 2px;
+        position: absolute;
+        content: '';
+        background: #49bcf7;
+        border-radius: 20px;
+        left: 0;
+      }
+      .image {
+        width: 100%;
+        height: 187px;
+      }
+      .wraptit span {
+        display: inline-block;
+        font-size: $global-font-size-18;
+        color: rgba(255, 255, 255, 0.6);
+      }
+
+      .wraptit {
+        text-align: center;
+        border-bottom: 1px solid rgba(255, 255, 255, 0.2);
+        padding: 0 0 10px 0;
+        margin-bottom: 10px;
+      }
+      .wraptit span:nth-child(1) {
+        width: 30%;
+      }
+
+      .wraptit span:nth-child(2) {
+        width: 20%;
+      }
+
+      .wraptit span:nth-child(3) {
+        width: 30%;
+      }
+
+      .wraptit span:nth-child(4) {
+        width: 20%;
+      }
+
+      .clearfix {
+        display: flex;
+        align-items: center;
+      }
+      .num,
+      .zhibiao {
+        height: 100%;
+        width: 50%;
+      }
+
+      .zb1,
+      .zb2,
+      .zb3 {
+        float: left;
+        width: 33.3333%;
+        height: 100%;
+      }
+
+      #zb1,
+      #zb2,
+      #zb3 {
+        height: calc(100% - 30px);
+      }
+
+      .zhibiao span {
+        padding-top: 20px;
+        display: block;
+        text-align: center;
+        color: #fff;
+        font-size: $global-font-size-18;
+      }
+
+      .num {
+        padding-right: 20px;
+      }
+
+      .numbt {
+        font-size: $global-font-size-26;
+        color: #fff;
+        padding-top: 14px;
+      }
+
+      .numbt span {
+        font-size: $global-font-size-20;
+        padding-left: 10px;
+        color: #fff;
+      }
+
+      .numtxt {
+        color: #fef000;
+        font-size: 40px;
+        font-family: arial;
+        border-top: 1px solid rgba(255, 255, 255, 0.1);
+        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+        padding: 10px 0;
+        margin: 18px 0;
+        font-weight: bold;
+        letter-spacing: 2px;
+      }
+      .one {
+        height: 72px;
+        overflow: hidden;
+        .scroll {
+          width: 100%;
+          .wrap {
+            display: flex;
+            justify-content: space-between;
+            border: 1px solid rgba(25, 186, 139, 0.17);
+            padding: 10px;
+            margin: 0 0 10px 0;
+            .other:first-child {
+              width: 40%;
+            }
+            .other {
+              width: 30%;
+              color: rgba(255, 255, 255, 0.6);
+              text-align: center;
+              text-overflow: ellipsis;
+              white-space: nowrap;
+              overflow: hidden;
+              font-size: 16px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 103310 - 0
src/views/elevenHatch copy/json/china.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 25715 - 0
src/views/elevenHatch copy/json/jilin.json


+ 106 - 0
src/views/elevenHatch copy/path/echarts1.vue

@@ -0,0 +1,106 @@
+<template>
+  <div ref="echarts1" class="echarts1"></div>
+</template>
+<style scoped lang="scss">
+.echarts1 {
+  height: 250px;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+const echarts1 = ref()
+onMounted(() => {
+  echarts1View()
+})
+function echarts1View() {
+  const myChart1 = echarts.init(echarts1.value)
+  const option1 = {
+    tooltip: {
+      trigger: 'item',
+      formatter: '{b} : {c} ({d}%)'
+    },
+    legend: {
+      right: 0,
+      top: 20,
+      height: 160,
+      itemWidth: 10,
+      itemHeight: 10,
+      itemGap: 10,
+      textStyle: {
+        color: 'rgba(255,255,255,.6)',
+        fontSize: 12
+      },
+      orient: 'vertical',
+      data: ['制造业', '服务业', '农业', '金融行业', '电子商务行业']
+    },
+    calculable: true,
+    series: [
+      {
+        name: ' ',
+        color: [
+          '#62c98d',
+          '#2f89cf',
+          '#4cb9cf',
+          '#53b666',
+          '#62c98d',
+          '#205acf',
+          '#c9c862',
+          '#c98b62',
+          '#c962b9',
+          '#7562c9',
+          '#c96262',
+          '#c25775',
+          '#00b7be'
+        ],
+        type: 'pie',
+        radius: [30, 70],
+        center: ['35%', '50%'],
+        roseType: 'radius',
+        label: {
+          normal: {
+            show: true
+          },
+          emphasis: {
+            show: true
+          }
+        },
+        lableLine: {
+          normal: {
+            show: true
+          },
+          emphasis: {
+            show: true
+          }
+        },
+        data: [
+          {
+            value: 10,
+            name: '制造业'
+          },
+          {
+            value: 5,
+            name: '服务业'
+          },
+          {
+            value: 15,
+            name: '农业'
+          },
+          {
+            value: 25,
+            name: '金融行业'
+          },
+          {
+            value: 20,
+            name: '电子商务行业'
+          }
+        ]
+      }
+    ]
+  }
+  myChart1.setOption(option1)
+  window.addEventListener('resize', function () {
+    myChart1.resize()
+  })
+}
+</script>

+ 197 - 0
src/views/elevenHatch copy/path/echarts2.vue

@@ -0,0 +1,197 @@
+<template>
+  <div>
+    <div ref="echarts2" class="echarts2"></div>
+  </div>
+</template>
+<style scoped>
+.echarts2 {
+  height: 260px;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+const echarts2 = ref()
+onMounted(() => {
+  drawEcharts2()
+})
+function drawEcharts2() {
+  var myChart2 = echarts.init(echarts2.value)
+  var option2 = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        lineStyle: {
+          color: '#57617B'
+        }
+      }
+    },
+    legend: {
+      data: [
+        {
+          name: '省重点'
+        },
+        {
+          name: '市重点'
+        },
+        {
+          name: '完成率'
+        }
+      ],
+      top: '0%',
+      textStyle: {
+        color: 'rgba(255,255,255,0.9)'
+      }
+    },
+    xAxis: [
+      {
+        type: 'category',
+        data: [
+          '1月',
+          '2月',
+          '3月',
+          '4月',
+          '5月',
+          '6月',
+          '7月',
+          '8月',
+          '9月',
+          '10月',
+          '11月',
+          '12月'
+        ],
+        axisLine: {
+          lineStyle: {
+            color: 'rgba(255,255,255,.1)'
+          }
+        },
+        axisLabel: {
+          textStyle: {
+            color: 'rgba(255,255,255,.6)',
+            fontSize: '14'
+          }
+        }
+      }
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        name: '金额',
+        min: 0,
+        max: 50,
+        interval: 10,
+        axisLabel: {
+          show: true
+        },
+        axisLine: {
+          lineStyle: {
+            color: 'rgba(255,255,255,.4)'
+          }
+        }
+      },
+      {
+        type: 'value',
+        name: '完成率',
+        show: true,
+        axisLabel: {
+          show: true
+        },
+        axisLine: {
+          lineStyle: {
+            color: 'rgba(255,255,255,.4)'
+          }
+        },
+        splitLine: {
+          show: true,
+          lineStyle: {
+            color: '#001e94'
+          }
+        }
+      }
+    ],
+    grid: {
+      top: '20%',
+      right: '30',
+      bottom: '30',
+      left: '30'
+    },
+    series: [
+      {
+        name: '省重点',
+        type: 'bar',
+        data: [4, 6, 36, 6, 8, 6, 4, 6, 30, 6, 8, 12],
+        barWidth: 'auto',
+        itemStyle: {
+          normal: {
+            color: {
+              type: 'linear',
+              x: 0,
+              y: 0,
+              x2: 0,
+              y2: 1,
+              colorStops: [
+                {
+                  offset: 0,
+                  color: '#609db8'
+                },
+                {
+                  offset: 1,
+                  color: '#609db8'
+                }
+              ],
+              globalCoord: false
+            }
+          }
+        }
+      },
+      {
+        name: '市重点',
+        type: 'bar',
+        data: [4, 2, 34, 6, 8, 6, 4, 2, 32, 6, 8, 18],
+        barWidth: 'auto',
+        itemStyle: {
+          normal: {
+            color: {
+              type: 'linear',
+              x: 0,
+              y: 0,
+              x2: 0,
+              y2: 1,
+              colorStops: [
+                {
+                  offset: 0,
+                  color: '#66b8a7'
+                },
+                {
+                  offset: 1,
+                  color: '#66b8a7'
+                }
+              ],
+              globalCoord: false
+            }
+          }
+        },
+        barGap: '0'
+      },
+      {
+        name: '完成率',
+        type: 'line',
+        yAxisIndex: 1,
+        data: [100, 50, 80, 30, 90, 40, 70, 33, 100, 40, 80, 20],
+        lineStyle: {
+          normal: {
+            width: 2
+          }
+        },
+        itemStyle: {
+          normal: {
+            color: '#cdba00'
+          }
+        },
+        smooth: true
+      }
+    ]
+  }
+  myChart2.setOption(option2)
+}
+</script>

+ 107 - 0
src/views/elevenHatch copy/path/echarts3.vue

@@ -0,0 +1,107 @@
+<template>
+  <div>
+    <div ref="echarts3" class="echarts3"></div>
+  </div>
+</template>
+<style scoped lang="scss">
+.echarts3 {
+  height: 250px;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+const echarts3 = ref()
+onMounted(() => {
+  echarts3View()
+})
+function echarts3View() {
+  var myChart3 = echarts.init(echarts3.value)
+  var option3 = {
+    tooltip: {
+      show: false
+    },
+    grid: {
+      top: '0%',
+      left: '90',
+      right: '14%',
+      bottom: '0%'
+    },
+    xAxis: {
+      min: 0,
+      max: 100,
+      splitLine: {
+        show: false
+      },
+      axisTick: {
+        show: false
+      },
+      axisLine: {
+        show: false
+      },
+      axisLabel: {
+        show: false
+      }
+    },
+    yAxis: {
+      axisLabel: {
+        color: 'rgba(255,255,255,.6)',
+        fontSize: 14,
+        width: 85, //将内容的宽度固定
+        overflow: 'truncate', //超出的部分截断
+        ellipsis: '...' //截断的部分用...代替
+      },
+      data: [
+        '鱿鱼卤制品的研究',
+        '一种快速装置自净系统',
+        '玻璃表面清洁技术',
+        '网上信息安全处理',
+        '视觉检测',
+        '无纺布气味去除',
+        '功能性色母开发'
+      ],
+      axisTick: {
+        show: false
+      },
+      axisLine: {
+        show: false
+      }
+    },
+    series: [
+      {
+        type: 'bar',
+        label: {
+          show: true,
+          zlevel: 10000,
+          position: 'right',
+          padding: 10,
+          color: '#49bcf7',
+          fontSize: 14,
+          formatter: '{c}%'
+        },
+        itemStyle: {
+          color: '#49bcf7'
+        },
+        barWidth: '15',
+        data: [49, 80, 67, 99, 12, 19, 39, 84],
+        z: 10
+      },
+      {
+        type: 'bar',
+        barGap: '-100%',
+        itemStyle: {
+          color: '#fff',
+          opacity: 0.1
+        },
+        barWidth: '15',
+        data: [100, 100, 100, 100, 100, 100, 100, 100],
+        z: 5
+      }
+    ]
+  }
+  myChart3.setOption(option3)
+  window.addEventListener('resize', function () {
+    myChart3.resize()
+  })
+}
+</script>

+ 189 - 0
src/views/elevenHatch copy/path/echarts4.vue

@@ -0,0 +1,189 @@
+<template>
+  <div>
+    <div ref="echarts4" class="echarts4"></div>
+  </div>
+</template>
+<style scoped>
+.echarts4 {
+  height: 242px;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+const echarts4 = ref()
+onMounted(() => {
+  drawEcharts4()
+})
+function drawEcharts4() {
+  var myChart4 = echarts.init(echarts4.value)
+  var option4 = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        lineStyle: {
+          color: '#57617B'
+        }
+      }
+    },
+    legend: {
+      data: ['销售额', '利润'],
+      top: '0',
+      textStyle: {
+        color: '#fff'
+      },
+      itemGap: 20
+    },
+    grid: {
+      left: '0',
+      right: '20',
+      top: '10',
+      bottom: '20',
+      containLabel: true
+    },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: false,
+        axisLabel: {
+          show: true,
+          textStyle: {
+            color: 'rgba(255,255,255,.6)'
+          }
+        },
+        axisLine: {
+          lineStyle: {
+            color: 'rgba(255,255,255,.1)'
+          }
+        },
+        data: [
+          '1月',
+          '2月',
+          '3月',
+          '4月',
+          '5月',
+          '6月',
+          '7月',
+          '8月',
+          '9月',
+          '10月',
+          '11月',
+          '12月'
+        ]
+      },
+      {}
+    ],
+    yAxis: [
+      {
+        axisLabel: {
+          show: true,
+          textStyle: {
+            color: 'rgba(255,255,255,.6)'
+          }
+        },
+        axisLine: {
+          lineStyle: {
+            color: 'rgba(255,255,255,.1)'
+          }
+        },
+        splitLine: {
+          lineStyle: {
+            color: 'rgba(255,255,255,.1)'
+          }
+        }
+      }
+    ],
+    series: [
+      {
+        name: '销售额',
+        type: 'line',
+        smooth: true,
+        symbol: 'circle',
+        symbolSize: 5,
+        showSymbol: false,
+        lineStyle: {
+          normal: {
+            width: 2
+          }
+        },
+        areaStyle: {
+          normal: {
+            color: new echarts.graphic.LinearGradient(
+              0,
+              0,
+              0,
+              1,
+              [
+                {
+                  offset: 0,
+                  color: 'rgba(24, 163, 64, 0.3)'
+                },
+                {
+                  offset: 0.8,
+                  color: 'rgba(24, 163, 64, 0)'
+                }
+              ],
+              false
+            ),
+            shadowColor: 'rgba(0, 0, 0, 0.1)',
+            shadowBlur: 10
+          }
+        },
+        itemStyle: {
+          normal: {
+            color: '#cdba00',
+            borderColor: 'rgba(137,189,2,0.27)',
+            borderWidth: 12
+          }
+        },
+        data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
+      },
+      {
+        name: '利润',
+        type: 'line',
+        smooth: true,
+        symbol: 'circle',
+        symbolSize: 5,
+        showSymbol: false,
+        lineStyle: {
+          normal: {
+            width: 2
+          }
+        },
+        areaStyle: {
+          normal: {
+            color: new echarts.graphic.LinearGradient(
+              0,
+              0,
+              0,
+              1,
+              [
+                {
+                  offset: 0,
+                  color: 'rgba(39, 122,206, 0.3)'
+                },
+                {
+                  offset: 0.8,
+                  color: 'rgba(39, 122,206, 0)'
+                }
+              ],
+              false
+            ),
+            shadowColor: 'rgba(0, 0, 0, 0.1)',
+            shadowBlur: 10
+          }
+        },
+        itemStyle: {
+          normal: {
+            color: '#277ace',
+            borderColor: 'rgba(0,136,212,0.2)',
+            borderWidth: 12
+          }
+        },
+        data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
+      }
+    ]
+  }
+  myChart4.setOption(option4)
+}
+</script>

+ 77 - 0
src/views/elevenHatch copy/path/echarts5.vue

@@ -0,0 +1,77 @@
+<template>
+  <div>
+    <div ref="echarts5" class="echarts5"></div>
+  </div>
+</template>
+<style scoped>
+.echarts5 {
+  height: 110px;
+  width: 150px;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+const echarts5 = ref()
+onMounted(() => {
+  drawEcharts5()
+})
+function drawEcharts5() {
+  var myChart5 = echarts.init(echarts5.value)
+  var b = 298
+  var c = 523
+  var d = b + c
+  var option5 = {
+    series: [
+      {
+        type: 'pie',
+        radius: ['60%', '70%'],
+        color: '#49bcf7',
+        label: {
+          normal: {
+            position: 'center'
+          }
+        },
+        data: [
+          {
+            value: c,
+            name: '女消费',
+            label: {
+              normal: {
+                formatter: c + '',
+                textStyle: {
+                  fontSize: 20,
+                  color: '#fff'
+                }
+              }
+            }
+          },
+          {
+            value: b,
+            name: '男消费',
+            label: {
+              normal: {
+                formatter: function () {
+                  return '占比' + Math.round((c / d) * 100) + '%'
+                },
+                textStyle: {
+                  color: '#aaa',
+                  fontSize: 12
+                }
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: 'rgba(255,255,255,.2)'
+              },
+              emphasis: {
+                color: '#fff'
+              }
+            }
+          }
+        ]
+      }
+    ]
+  }
+  myChart5.setOption(option5)
+}
+</script>

+ 77 - 0
src/views/elevenHatch copy/path/echarts6.vue

@@ -0,0 +1,77 @@
+<template>
+  <div>
+    <div ref="echarts6" class="echarts6"></div>
+  </div>
+</template>
+<style scoped>
+.echarts6 {
+  height: 110px;
+  width: 150px;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+const echarts6 = ref()
+onMounted(() => {
+  drawEcharts6()
+})
+function drawEcharts6() {
+  var myChart6 = echarts.init(echarts6.value)
+  var b = 298
+  var c = 523
+  var d = b + c
+  var option6 = {
+    series: [
+      {
+        type: 'pie',
+        radius: ['60%', '70%'],
+        color: '#cdba00',
+        label: {
+          normal: {
+            position: 'center'
+          }
+        },
+        data: [
+          {
+            value: b,
+            name: '男消费',
+            label: {
+              normal: {
+                formatter: b + '',
+                textStyle: {
+                  fontSize: 20,
+                  color: '#fff'
+                }
+              }
+            }
+          },
+          {
+            value: c,
+            name: '女消费',
+            label: {
+              normal: {
+                formatter: function () {
+                  return '占比' + Math.round((b / d) * 100) + '%'
+                },
+                textStyle: {
+                  color: '#aaa',
+                  fontSize: 12
+                }
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: 'rgba(255,255,255,.2)'
+              },
+              emphasis: {
+                color: '#fff'
+              }
+            }
+          }
+        ]
+      }
+    ]
+  }
+  myChart6.setOption(option6)
+}
+</script>

+ 77 - 0
src/views/elevenHatch copy/path/echarts7.vue

@@ -0,0 +1,77 @@
+<template>
+  <div>
+    <div ref="echarts7" class="echarts7"></div>
+  </div>
+</template>
+<style scoped>
+.echarts7 {
+  height: 110px;
+  width: 150px;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+const echarts7 = ref()
+onMounted(() => {
+  drawEcharts7()
+})
+function drawEcharts7() {
+  var myChart7 = echarts.init(echarts7.value)
+  var b = 298
+  var c = 523
+  var d = b + c
+  var option7 = {
+    series: [
+      {
+        type: 'pie',
+        radius: ['60%', '70%'],
+        color: '#62c98d',
+        label: {
+          normal: {
+            position: 'center'
+          }
+        },
+        data: [
+          {
+            value: c,
+            name: '女消费',
+            label: {
+              normal: {
+                formatter: c + '',
+                textStyle: {
+                  fontSize: 20,
+                  color: '#fff'
+                }
+              }
+            }
+          },
+          {
+            value: b,
+            name: '男消费',
+            label: {
+              normal: {
+                formatter: function () {
+                  return '占比' + Math.round((c / d) * 100) + '%'
+                },
+                textStyle: {
+                  color: '#aaa',
+                  fontSize: 12
+                }
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: 'rgba(255,255,255,.2)'
+              },
+              emphasis: {
+                color: '#fff'
+              }
+            }
+          }
+        ]
+      }
+    ]
+  }
+  myChart7.setOption(option7)
+}
+</script>

BIN
src/views/elevenHatch/images/img1.png


BIN
src/views/elevenHatch/images/img2.png


+ 109 - 26
src/views/elevenHatch/index.vue

@@ -3,7 +3,7 @@
     <el-row>
       <el-col :span="24" class="animate__animated animate__backInRight" v-loading="loading">
         <div class="head">
-          <div class="head_1">孵化基地管理驾驶舱</div>
+          <div class="head_1">{{ info.name || '孵化基地' }}管理驾驶舱</div>
           <div class="head_2" id="showTime">{{ formattedTime }}</div>
         </div>
         <div class="center">
@@ -11,21 +11,12 @@
             <el-col :span="6">
               <div class="center_1">
                 <div class="boxall">
-                  <div class="alltitle">孵化进度</div>
-                  <echarts3></echarts3>
-                </div>
-                <div class="boxall">
-                  <div class="alltitle">孵化项目列表</div>
-                  <div class="wraptit"><span>项目名称</span><span>金额</span><span>风险概率</span><span>时间</span></div>
-                  <div class="one">
-                    <vue3-seamless-scroll :list="oneList" :hover="true" :step="0.2" :wheel="true" :isWatch="true" class="scroll">
-                      <div class="wrap" v-for="(item, index) in oneList" :key="index">
-                        <div class="other">{{ item.name }}</div>
-                        <div class="other">{{ item.money }}</div>
-                        <div class="other">{{ item.number }}</div>
-                        <div class="other">{{ item.time }}</div>
-                      </div>
-                    </vue3-seamless-scroll>
+                  <div class="alltitle">孵化基地汇总</div>
+                  <!-- <echarts3></echarts3> -->
+                  <div class="center_list">
+                    <div class="list_num" v-for="(item, index) in thrList" :key="index">
+                      {{ item.num }}<span>{{ item.name }}</span>
+                    </div>
                   </div>
                 </div>
                 <div class="boxall">
@@ -36,7 +27,7 @@
             </el-col>
             <el-col :span="12">
               <div class="center_1">
-                <div class="boxall" style="height: 170px">
+                <div class="boxall" style="height: 175px">
                   <div class="clearfix navboxall" style="height: 100%">
                     <div class="pulll_left num">
                       <div class="numbt">总体情况<span>(单位:家)</span></div>
@@ -44,36 +35,36 @@
                     </div>
                     <div class="pulll_right zhibiao">
                       <div class="zb1">
-                        <span>工研院运营</span>
+                        <span>从业人员</span>
                         <echarts5></echarts5>
                       </div>
                       <div class="zb2">
-                        <span>参股孵化基地</span>
+                        <span>高新技术企业</span>
                         <echarts6></echarts6>
                       </div>
                       <div class="zb3">
-                        <span>合作孵化基地</span>
+                        <span>专精特新企业</span>
                         <echarts7></echarts7>
                       </div>
                     </div>
                   </div>
                 </div>
                 <div class="boxall">
-                  <div class="alltitle">年度项目完成对比</div>
-                  <echarts2></echarts2>
+                  <div class="alltitle">孵化基地荣誉</div>
+                  <echarts4></echarts4>
                 </div>
                 <div class="boxall">
-                  <div class="alltitle">投资收益对比</div>
-                  <echarts4></echarts4>
+                  <div class="alltitle">孵化基地企业产业占比</div>
+                  <echarts2></echarts2>
                 </div>
               </div>
             </el-col>
             <el-col :span="6">
               <div class="center_1">
                 <div class="boxall bottom">
-                  <div class="alltitle">视频监控</div>
+                  <div class="alltitle">孵化基地风采</div>
                   <div v-for="(item, index) in twoList" :key="index">
-                    <el-image class="image" :src="item.url" fit="fill" />
+                    <el-image class="image" :src="getUrl(item.uri)" fit="fill" />
                   </div>
                 </div>
               </div>
@@ -86,6 +77,15 @@
 </template>
 
 <script setup>
+// 用户信息
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 接口
+import { IncubatorStore } from '@/store/api/user/incubator'
+import { IncubatorYearStore } from '@/store/api/user/incubatorYear'
+const incubatorStore = IncubatorStore()
+const yearStore = IncubatorYearStore()
 import echarts1 from './path/echarts1.vue'
 import echarts2 from './path/echarts2.vue'
 import echarts3 from './path/echarts3.vue'
@@ -112,12 +112,34 @@ import video_3 from '/images/video_3.jpg'
 import video_4 from '/images/video_4.jpg'
 const twoList = ref([{ url: video_1 }, { url: video_2 }, { url: video_3 }, { url: video_4 }])
 
+const thrList = ref([
+  { num: 266, name: '中试场地' },
+  { num: 266, name: '单位人数' },
+  { num: 266, name: '省级导师数' },
+  { num: 266, name: '开展活动总数' },
+  { num: 266, name: '参加活动人次' },
+  { num: 266, name: '合作孵化基地' },
+  { num: 266, name: '开展活动总数' },
+  { num: 266, name: '参加活动人次' },
+  { num: 266, name: '合作孵化基地' }
+])
+const info = ref({})
 // 请求
 onMounted(async () => {
   loading.value = true
+  await search()
   await updateTime()
   loading.value = false
 })
+const search = async () => {
+  if (user.value.id) {
+    let res = await incubatorStore.query({ user: user.value.id })
+    if (res.errcode == '0') {
+      info.value = res.data[0]
+      if (res.data[0].file && res.data[0].file.length > 0) twoList.value = res.data[0].file
+    }
+  }
+}
 // 创建一个函数来格式化时间并更新状态
 const updateTime = () => {
   const now = new Date()
@@ -142,6 +164,9 @@ onMounted(() => {
 onBeforeUnmount(() => {
   clearInterval(timer) // 组件卸载前清除计时器
 })
+const getUrl = (item) => {
+  if (item) return `${import.meta.env.VITE_APP_HOST}${item}`
+}
 </script>
 <style scoped lang="scss">
 .elevenHatch {
@@ -197,6 +222,64 @@ onBeforeUnmount(() => {
         position: relative;
         margin-bottom: 10px;
         z-index: 10;
+        .center_list {
+          display: flex;
+          flex-wrap: wrap;
+          .list_num {
+            position: relative;
+            width: 120px;
+            height: 120px;
+            line-height: 100%;
+            margin: 5px auto;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            flex-direction: column;
+            font-size: 32px;
+            font-family: electronicFont;
+            color: #fef000;
+            span {
+              color: #fff !important;
+              font-size: 16px !important;
+            }
+          }
+          .list_num:before {
+            position: absolute;
+            width: 100%;
+            height: 100%;
+            content: '';
+            background: url(../elevenHatch/images/img1.png) center center;
+            border-radius: 100px;
+            background-size: 100% 100%;
+            opacity: 0.1;
+            left: 0;
+            top: 0;
+            animation: myfirst2 15s infinite linear;
+          }
+          .list_num:after {
+            position: absolute;
+            width: 86%;
+            background: url(../elevenHatch/images/img2.png) center center;
+            border-radius: 100px;
+            background-size: 100% 100%;
+            opacity: 0.1;
+            height: 86%;
+            content: '';
+            left: 7%;
+            top: 7%;
+            animation: myfirst 15s infinite linear;
+          }
+          @keyframes myfirst {
+            to {
+              transform: rotate(-360deg);
+            }
+          }
+          @keyframes myfirst2 {
+            to {
+              transform: rotate(360deg);
+            }
+          }
+        }
       }
       .bottom {
         margin-bottom: 0;

+ 13 - 23
src/views/elevenHatch/path/echarts1.vue

@@ -3,7 +3,7 @@
 </template>
 <style scoped lang="scss">
 .echarts1 {
-  height: 250px;
+  height: 296px;
   width: 100%;
 }
 </style>
@@ -23,7 +23,7 @@ function echarts1View() {
     legend: {
       right: 0,
       top: 20,
-      height: 160,
+      height: 180,
       itemWidth: 10,
       itemHeight: 10,
       itemGap: 10,
@@ -32,27 +32,13 @@ function echarts1View() {
         fontSize: 12
       },
       orient: 'vertical',
-      data: ['制造业', '服务业', '农业', '金融行业', '电子商务行业']
+      data: ['生物医药', '化工新材料', '先进装备制造', '高端服务', '光电子', '电子信息']
     },
     calculable: true,
     series: [
       {
         name: ' ',
-        color: [
-          '#62c98d',
-          '#2f89cf',
-          '#4cb9cf',
-          '#53b666',
-          '#62c98d',
-          '#205acf',
-          '#c9c862',
-          '#c98b62',
-          '#c962b9',
-          '#7562c9',
-          '#c96262',
-          '#c25775',
-          '#00b7be'
-        ],
+        color: ['#62c98d', '#2f89cf', '#4cb9cf', '#53b666', '#62c98d', '#205acf', '#c9c862', '#c98b62', '#c962b9', '#7562c9', '#c96262', '#c25775', '#00b7be'],
         type: 'pie',
         radius: [30, 70],
         center: ['35%', '50%'],
@@ -76,23 +62,27 @@ function echarts1View() {
         data: [
           {
             value: 10,
-            name: '制造业'
+            name: '生物医药'
           },
           {
             value: 5,
-            name: '服务业'
+            name: '化工新材料'
           },
           {
             value: 15,
-            name: '农业'
+            name: '先进装备制造'
           },
           {
             value: 25,
-            name: '金融行业'
+            name: '高端服务'
           },
           {
             value: 20,
-            name: '电子商务行业'
+            name: '光电子'
+          },
+          {
+            value: 20,
+            name: '电子信息'
           }
         ]
       }

+ 76 - 149
src/views/elevenHatch/path/echarts2.vue

@@ -17,180 +17,107 @@ onMounted(() => {
 })
 function drawEcharts2() {
   var myChart2 = echarts.init(echarts2.value)
+  var vdata = [
+    [4, 3, 5, 9, 3, 8, 3, 7, 2, 4, 6, 4],
+    [5, 5, 7, 3, 6, 8, 9, 4, 3, 7, 2, 2],
+    [4, 3, 5, 9, 5, 8, 3, 7, 2, 4, 6, 4]
+  ]
+  var xdata = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
+  var ydata = [
+    { color1: '#8bd46e', color2: '#09bcb7', name: '预计营业收入' },
+    { color1: '#248ff7', color2: '#6851f1', name: '预计收入' },
+    { color1: '#fccb05', color2: '#f5804d', name: '预计税金收入' }
+  ]
+  var series = []
+  vdata.forEach((value, index) => {
+    var series_option = {
+      name: ydata[index].name,
+      type: 'bar',
+      itemStyle: {
+        normal: {
+          barBorderRadius: 15,
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            {
+              offset: 0,
+              color: ydata[index].color1
+            },
+            {
+              offset: 1,
+              color: ydata[index].color2
+            }
+          ])
+        }
+      },
+      barWidth: '20',
+      data: value
+    }
+    series.push(series_option)
+  })
   var option2 = {
+    legend: {
+      data: ydata,
+      type: 'scroll',
+      textStyle: { color: '#fff' },
+      top: '0'
+    },
     tooltip: {
       trigger: 'axis',
       axisPointer: {
-        lineStyle: {
-          color: '#57617B'
-        }
+        type: 'shadow'
       }
     },
-    legend: {
-      data: [
-        {
-          name: '省重点'
-        },
-        {
-          name: '市重点'
-        },
-        {
-          name: '完成率'
-        }
-      ],
-      top: '0%',
-      textStyle: {
-        color: 'rgba(255,255,255,0.9)'
-      }
+    color: ['#62c98d', '#2f89cf', '#f5804d'],
+    grid: {
+      top: '14%',
+      left: '15',
+      right: '35',
+      bottom: '12%',
+      containLabel: true
     },
+
     xAxis: [
       {
         type: 'category',
-        data: [
-          '1月',
-          '2月',
-          '3月',
-          '4月',
-          '5月',
-          '6月',
-          '7月',
-          '8月',
-          '9月',
-          '10月',
-          '11月',
-          '12月'
-        ],
-        axisLine: {
-          lineStyle: {
-            color: 'rgba(255,255,255,.1)'
-          }
-        },
-        axisLabel: {
-          textStyle: {
-            color: 'rgba(255,255,255,.6)',
-            fontSize: '14'
-          }
-        }
+        axisLabel: { textStyle: { color: 'rgba(255,255,255,.6)' } },
+        axisLine: { lineStyle: { color: 'rgba(255,255,255,.1)' } },
+        data: xdata
       }
     ],
     yAxis: [
       {
+        name: '',
         type: 'value',
-        name: '金额',
-        min: 0,
-        max: 50,
-        interval: 10,
-        axisLabel: {
-          show: true
-        },
-        axisLine: {
-          lineStyle: {
-            color: 'rgba(255,255,255,.4)'
-          }
-        }
-      },
-      {
-        type: 'value',
-        name: '完成率',
-        show: true,
-        axisLabel: {
-          show: true
-        },
-        axisLine: {
-          lineStyle: {
-            color: 'rgba(255,255,255,.4)'
-          }
-        },
+        axisTick: { show: false },
         splitLine: {
           show: true,
           lineStyle: {
-            color: '#001e94'
+            color: '#2f2a7a'
           }
-        }
+        }, //x轴线
+        axisLabel: { textStyle: { color: 'rgba(255,255,255,.6)' } },
+        axisLine: { lineStyle: { color: 'rgba(255,255,255,.1)' } }
       }
     ],
-    grid: {
-      top: '20%',
-      right: '30',
-      bottom: '30',
-      left: '30'
-    },
-    series: [
+    dataZoom: [
       {
-        name: '省重点',
-        type: 'bar',
-        data: [4, 6, 36, 6, 8, 6, 4, 6, 30, 6, 8, 12],
-        barWidth: 'auto',
-        itemStyle: {
-          normal: {
-            color: {
-              type: 'linear',
-              x: 0,
-              y: 0,
-              x2: 0,
-              y2: 1,
-              colorStops: [
-                {
-                  offset: 0,
-                  color: '#609db8'
-                },
-                {
-                  offset: 1,
-                  color: '#609db8'
-                }
-              ],
-              globalCoord: false
-            }
-          }
-        }
-      },
-      {
-        name: '市重点',
-        type: 'bar',
-        data: [4, 2, 34, 6, 8, 6, 4, 2, 32, 6, 8, 18],
-        barWidth: 'auto',
-        itemStyle: {
-          normal: {
-            color: {
-              type: 'linear',
-              x: 0,
-              y: 0,
-              x2: 0,
-              y2: 1,
-              colorStops: [
-                {
-                  offset: 0,
-                  color: '#66b8a7'
-                },
-                {
-                  offset: 1,
-                  color: '#66b8a7'
-                }
-              ],
-              globalCoord: false
-            }
-          }
-        },
-        barGap: '0'
-      },
-      {
-        name: '完成率',
-        type: 'line',
-        yAxisIndex: 1,
-        data: [100, 50, 80, 30, 90, 40, 70, 33, 100, 40, 80, 20],
-        lineStyle: {
-          normal: {
-            width: 2
-          }
+        show: true,
+        height: 12,
+        xAxisIndex: [0],
+        bottom: 5,
+        start: 10,
+        end: 80,
+        handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
+        handleSize: '110%',
+        handleStyle: {
+          color: '#d3dee5'
         },
-        itemStyle: {
-          normal: {
-            color: '#cdba00'
-          }
+        textStyle: {
+          color: '#fff'
         },
-        smooth: true
+        borderColor: 'rgba(255,255,255,.3)'
       }
-    ]
+    ],
+    series: series
   }
   myChart2.setOption(option2)
 }

+ 6 - 1
src/views/five/index.vue

@@ -71,7 +71,11 @@
         </div>
         <el-col :span="24" class="two_2">
           <div class="list" v-for="(item, index) in list" :key="index">
-            <el-image class="image" :src="getUrl(item.file)" fit="cover"> </el-image>
+            <el-image class="image" :src="getUrl(item.file)" fit="cover">
+              <template v-slot:error>
+                <el-image class="image" :src="match_3" fit="fill" />
+              </template>
+            </el-image>
             <div class="name">{{ item.name || '暂无' }}</div>
             <div class="other">
               <div class="time">
@@ -92,6 +96,7 @@
 
 <script setup>
 // 图片引入
+import match_3 from '/images/match_3.jpg'
 import lists from '/images/bg-act-list.jpg'
 import time1 from '/images/time-dary.png'
 const $checkRes = inject('$checkRes')