commit e5757c61e7a1808acd7b3d1c6d221b8a8288a8ed Author: qubiaobiao <3294694717@qq.com> Date: Fri Mar 27 17:38:42 2026 +0800 北斗短报文应用服务系统入口页面 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ee54e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo diff --git a/README.md b/README.md new file mode 100644 index 0000000..511a442 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# open-map-assistant + +This template should help get you started developing with Vue 3 in Vite. + +## Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). + +## Customize configuration + +See [Vite Configuration Reference](https://vitejs.dev/config/). + +## Project Setup + +```sh +npm install +``` + +### Compile and Hot-Reload for Development + +```sh +npm run dev +``` + +### Compile and Minify for Production + +```sh +npm run build +``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..3f59822 --- /dev/null +++ b/index.html @@ -0,0 +1,49 @@ + + + + + + + 北斗短报文应用服务系统 + + + +
+ + + \ No newline at end of file diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..5a1f2d2 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "paths": { + "@/*": ["./src/*"] + } + }, + "exclude": ["node_modules", "dist"] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..21041d1 --- /dev/null +++ b/package.json @@ -0,0 +1,42 @@ +{ + "name": "bd-short-message-platform-home", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite --port=7018", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@element-plus/icons-vue": "^2.3.1", + "axios": "^1.6.8", + "cesium": "^1.117.0", + "core-js": "^3.37.0", + "crypto-js": "^4.2.0", + "echarts": "^5.5.0", + "element-plus": "^2.7.2", + "esbuild": "^0.21.5", + "file-saver": "^2.0.5", + "fingerprintjs2": "^2.1.4", + "ol": "^9.1.0", + "pinia": "^2.1.7", + "pinia-plugin-persist": "^1.0.0", + "vue": "^3.4.21", + "vue-cesium": "^v3.2.7", + "vue-echarts": "^6.7.2", + "vue-i18n": "^9.13.1", + "vue-router": "^4.3.0", + "vue3-openlayers": "^8.1.0", + "zipson": "^0.2.12" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "autoprefixer": "^10.4.19", + "postcss": "^8.4.38", + "tailwindcss": "^3.4.3", + "unplugin-auto-import": "^0.17.5", + "unplugin-vue-components": "^0.27.0", + "vite": "^5.2.8" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..6ef5c58 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +} \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..1b51f8f Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..dac3700 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/src/api/index.js b/src/api/index.js new file mode 100644 index 0000000..cee3db0 --- /dev/null +++ b/src/api/index.js @@ -0,0 +1,113 @@ +import axios from "axios"; +import $url from "./url"; +import router from "../router"; +import { encrypt } from "../utils/aes"; + +// 添加请求拦截器 +axios.interceptors.request.use(function (config) { + // 在发送请求之前做些什么 + if (config.headers) { + config.headers.uid = localStorage.data; + if (localStorage.access_token && localStorage.access_token !== "" && localStorage.access_token !== null && localStorage.access_token !== undefined && localStorage.access_token !== NaN) { + config.headers.authorization = localStorage.access_token; + } + } + return config; +}, function (error) { + // 对请求错误做些什么 + return Promise.reject(error); +}); + +// 转到登录页面 +const toLogin = () => { + localStorage.clear(); + const data = { origin_url: window.location.href }; + axios.post($url.toLogin, data).then((res) => { + if (res.data.code === 200) { + window.location.href = res.data.redirect; + } else { + router.push({ path: '/404page' }); + } + }); +}; + +// 添加响应拦截器 +let result = true; +axios.interceptors.response.use(function (response) { + // 2xx 范围内的状态码都会触发该函数。 + // 对响应数据做点什么 + if (response.data.code === 200) { + if ("access_token" in response.data) { + localStorage.setItem("access_token", response.data.access_token); + } + if ("refresh_token" in response.data) { + localStorage.setItem("refresh_token", response.data.refresh_token); + } + if ("data" in response.data) { + localStorage.setItem("data", response.data.data); + } + } + if(response.data.code === 401 && result) { + result = false; + setTimeout(() => { + result = true; + }, 1000); + let getCode = window.location.href.indexOf('?'); + if (getCode != '-1') { + let code = window.location.href.substring(getCode + 1); + const data = { + code: code, + type: encrypt('code') + }; + axios.post($url.getToken, data).then((res) => { + if (res.data.code === 200) { + localStorage.setItem("data", res.data.data); + localStorage.setItem("access_token", res.data.access_token); + localStorage.setItem("refresh_token", res.data.refresh_token); + window.location.href = res.data.redirect; + } else { + toLogin(); + } + }); + } else if (localStorage.refresh_token && localStorage.refresh_token !== "" && localStorage.refresh_token !== null && localStorage.refresh_token !== undefined && localStorage.refresh_token !== NaN) { + const data = { + code: localStorage.refresh_token, + type: localStorage.data + }; + axios.post($url.getToken, data).then((res) => { + if (res.data.code === 200) { + localStorage.setItem("data", res.data.data); + localStorage.setItem("access_token", res.data.access_token); + localStorage.setItem("refresh_token", res.data.refresh_token); + window.location.reload(); + } else { + toLogin(); + } + }); + } else { + toLogin(); + } + } + return response; +}, function (error) { + // 超出 2xx 范围的状态码都会触发该函数。 + // 对响应错误做点什么 + return Promise.reject(error); +}); + +export default { + get(url, query = {}) { + return axios.get(url, { + params: query + }); + }, + post(url, body) { + return axios.post(url, body); + }, + put(url, body) { + return axios.put(url, body); + }, + del(url) { + return axios.delete(url); + }, +} \ No newline at end of file diff --git a/src/api/url.js b/src/api/url.js new file mode 100644 index 0000000..18ec01c --- /dev/null +++ b/src/api/url.js @@ -0,0 +1,16 @@ +export default { + // 用于确认哪个网页在进行登录 + toLogin: "/authentication/toLogin", + // 退出登录 + unLogin: "/authentication/unLogin", + // 用于获取token + getToken: "/authentication/getToken", + // 用于验证token + verify: "/authentication/verify", + // 获取用户基本信息 + getUser: "/authentication/getUser", + // 修改用户基本信息 + editUser: "/authentication/editUser", + // 修改密码 + changePassword: "/authentication/changePassword", +} \ No newline at end of file diff --git a/src/assets/bdjyLogo.png b/src/assets/bdjyLogo.png new file mode 100644 index 0000000..f437e49 Binary files /dev/null and b/src/assets/bdjyLogo.png differ diff --git a/src/assets/bdqhLogo.png b/src/assets/bdqhLogo.png new file mode 100644 index 0000000..ee9c6bd Binary files /dev/null and b/src/assets/bdqhLogo.png differ diff --git a/src/assets/bg.jpg b/src/assets/bg.jpg new file mode 100644 index 0000000..a0c96e4 Binary files /dev/null and b/src/assets/bg.jpg differ diff --git a/src/assets/favicon.ico b/src/assets/favicon.ico new file mode 100644 index 0000000..1b51f8f Binary files /dev/null and b/src/assets/favicon.ico differ diff --git a/src/assets/main.css b/src/assets/main.css new file mode 100644 index 0000000..2c350cf --- /dev/null +++ b/src/assets/main.css @@ -0,0 +1,9 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer components { + .w-h-full { + @apply w-full h-full m-0 p-0 overflow-hidden; + } +} \ No newline at end of file diff --git a/src/components/changePassword.vue b/src/components/changePassword.vue new file mode 100644 index 0000000..3cbd196 --- /dev/null +++ b/src/components/changePassword.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/components/footer.vue b/src/components/footer.vue new file mode 100644 index 0000000..3e654af --- /dev/null +++ b/src/components/footer.vue @@ -0,0 +1,12 @@ + + + + + diff --git a/src/components/header.vue b/src/components/header.vue new file mode 100644 index 0000000..0114d93 --- /dev/null +++ b/src/components/header.vue @@ -0,0 +1,187 @@ + + + + + diff --git a/src/components/main.vue b/src/components/main.vue new file mode 100644 index 0000000..b31d725 --- /dev/null +++ b/src/components/main.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/src/components/userManager.vue b/src/components/userManager.vue new file mode 100644 index 0000000..2656013 --- /dev/null +++ b/src/components/userManager.vue @@ -0,0 +1,284 @@ + + + + + diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..434d7b1 --- /dev/null +++ b/src/main.js @@ -0,0 +1,17 @@ +import './assets/main.css' + +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' + +import App from './App.vue' +import router from './router' + +const app = createApp(App) + +app.use(createPinia()) +app.use(ElementPlus) +app.use(router) + +app.mount('#app') diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..7ddbe60 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,31 @@ +import { createRouter, createWebHistory } from 'vue-router' + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/bdhome', + name: 'bdhome', + component: () => import('../views/bdHome.vue') + }, + { + path: '/404page', + name: '404', + component: () => import('../views/404page.vue') + } + ] +}) + +router.beforeEach((to, from, next) => { + if (to.matched.length === 0) { + if (to.path == "/") { + router.push({ path: '/bdHome' }); + } else { + router.push({ path: '/404page' }); + } + } else { + next(); + } +}) + +export default router diff --git a/src/stores/counter.js b/src/stores/counter.js new file mode 100644 index 0000000..b6757ba --- /dev/null +++ b/src/stores/counter.js @@ -0,0 +1,12 @@ +import { ref, computed } from 'vue' +import { defineStore } from 'pinia' + +export const useCounterStore = defineStore('counter', () => { + const count = ref(0) + const doubleCount = computed(() => count.value * 2) + function increment() { + count.value++ + } + + return { count, doubleCount, increment } +}) diff --git a/src/stores/userManager.js b/src/stores/userManager.js new file mode 100644 index 0000000..300fa33 --- /dev/null +++ b/src/stores/userManager.js @@ -0,0 +1,35 @@ +import { defineStore } from 'pinia'; +import { parse, stringify } from 'zipson'; + +const userManagerActiveStore = defineStore('userManager', { + state: () => ({ + // 持久化数据 + dialogVisible: false, + ruleForm: { + account_name: "", + user_name: "", + phone: "", + gender: "", + age: "", + email: "", + address: "", + post_code: "", + }, + }), + persist: { + enabled: true, // Store 中数据持久化生效 + strategies: [ + { + key: 'userManagerActive', // 存储的 key + storage: localStorage, // 存储位置 + paths: ["dialogVisible", "ruleForm"], // 需要持久化的字段 + serializer: { + deserialize: parse, + serialize: stringify, + }, + } + ] + }, +}) + +export default userManagerActiveStore \ No newline at end of file diff --git a/src/utils/aes.js b/src/utils/aes.js new file mode 100644 index 0000000..17489a5 --- /dev/null +++ b/src/utils/aes.js @@ -0,0 +1,21 @@ +import CryptoJS from 'crypto-js' + +const KEY = CryptoJS.enc.Utf8.parse('BDQH'); + +export const encrypt = (plaintext) => { + if(plaintext !== null && plaintext !== undefined && plaintext !== "") { + return CryptoJS.AES.encrypt(plaintext, KEY, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }).toString(); + } +} + +export const decrypt = (plaintext) => { + if(plaintext !== null && plaintext !== undefined && !plaintext == "") { + return CryptoJS.AES.decrypt(plaintext, KEY, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }).toString(CryptoJS.enc.Utf8); + } +} \ No newline at end of file diff --git a/src/views/404page.vue b/src/views/404page.vue new file mode 100644 index 0000000..a90090c --- /dev/null +++ b/src/views/404page.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/src/views/bdHome.vue b/src/views/bdHome.vue new file mode 100644 index 0000000..0d01346 --- /dev/null +++ b/src/views/bdHome.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..b8f5ac3 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,18 @@ +/** @type {import('tailwindcss').Config} */ +export default { + purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], + darkMode: false, // or 'media' or 'class' + content: [], + theme: { + extend: { + colors: { + 'graywhite': '#f5f5f5', + 'grayblue': '#0da3e2', + }, + }, + }, + variants: { + extend: {}, + }, + plugins: [], +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..38b455d --- /dev/null +++ b/vite.config.js @@ -0,0 +1,38 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import AutoImport from 'unplugin-auto-import/vite' +import Components from 'unplugin-vue-components/vite' +import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' + +// https://vitejs.dev/config/ +export default defineConfig({ + publicPath: './', + plugins: [ + vue(), + AutoImport({ + resolvers: [ElementPlusResolver()], + }), + Components({ + resolvers: [ElementPlusResolver()], + }), + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + } + }, + server: { + //用来配置跨域 + host: '127.0.0.1', + port: 7008, + proxy: { + '/authentication': { + target: 'http://127.0.0.1:8011',//目标服务器地址 + changeOrigin: true, + rewrite: (path) => path.replace(/^\/authentication/, '') + }, + } + } +})