Commit 7d4169d8 authored by 张牧越's avatar 张牧越

初始化

parents
NODE_ENV = "development"
Mock: true
VUE_APP_API_URL = ""
NODE_ENV = "production"
Mock: false
VUE_APP_API_URL = ""
\ No newline at end of file
/node_modules
/dist
\ No newline at end of file
npm install 安装依赖
npm run serve 本地服务
npm run build 打包
node版本14.14.0
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "digital-construction",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"animate.css": "^4.1.1",
"autoprefixer": "^10.4.14",
"axios": "^1.3.4",
"core-js": "^3.8.3",
"element-ui": "2.15.13",
"js-md5": "^0.8.3",
"lib-flexible": "^0.3.2",
"moment": "^2.29.4",
"postcss": "^8.4.38",
"precss": "^4.0.0",
"vue": "^2.6.14",
"vue-router": "^3.5.2",
"vuex": "^3.6.2"
},
"postcss": {
"plugins": {
"autoprefixer": {},
"precss": {}
}
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"file-loader": "^6.2.0",
"less": "^4.1.3",
"less-loader": "^11.1.0",
"postcss-plugin-px2rem": "^0.8.1",
"px2rem-loader": "^0.1.9",
"style-resources-loader": "^1.5.0",
"url-loader": "^4.1.1",
"vue-cli-plugin-style-resources-loader": "^0.1.5",
"vue-template-compiler": "^2.6.14"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {
"vue/multi-word-component-names": "off",
"no-unused-vars": "off",
"no-redeclare": "off",
"no-undef": "off"
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>
</title>
<style>
</style>
</head>
<body style="height: 100vh;">
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
\ No newline at end of file
<template>
<div id="app">
<Index ref="index"></Index>
</div>
</template>
<script>
import md5 from "js-md5";
import { getToken } from "@/api/index";
import Index from "./components/Index.vue";
export default {
components: { Index },
name: "App",
data() {
return {};
},
methods: {},
mounted() {
if (
!this.$route.query.redirectUrl ||
this.$route.query.redirectUrl.indexOf("_") == -1
) {
this.$refs.index.bindText = "url参数错误";
return this.$message.error("url参数错误");
}
getToken({
ticketId: this.$route.query.redirectUrl.split("_")[1],
}).then((res) => {
if (res.status == 200) {
localStorage.setItem(
"Authorization",
`${res.data.token_type} ${res.data.access_token}`
);
this.$refs.index.autoLogin();
}
});
},
};
</script>
<style>
* {
margin: 0;
padding: 0;
}
body {
min-width: 1400px;
margin: 0px;
}
#app {
height: 100%;
}
</style>
import request from "@/utils/request"
import portalRequest from "@/utils/portalRequest"
export async function getToken(params) {
return await request({
url: '/api/access',
method: 'get',
params
})
}
export async function getAuth(data) {
return await request({
url: '/api/sso/auth',
method: 'post',
data
})
}
export async function logout() {
return await portalRequest({
url: '/uc/unifiedLogout',
method: 'get',
})
}
<template>
<div id="index">
<div class="user-dialog">
<div class="user-list" v-if="loginType == 'login'">
<template v-if="ajaxSuccess && userList.length > 1">
<div class="title">选择账号登录</div>
<div
:class="['user', activeUser == index ? 'active' : '']"
v-for="(user, index) in userList"
:key="index"
@click="activeUser = index"
>
<div class="radio" v-if="activeUser != index"></div>
<div class="select-radio" v-if="activeUser == index"></div>
{{ user.op_code }}
</div>
<el-button style="width: 100%" type="primary" @click="selectLogin"
>选择登录</el-button
>
</template>
<template v-else>
<div style="text-align: center">
<img class="bind-img" src="@/assets/common/logging.png" alt="" />
</div>
<div class="bind-text">登录中...</div>
</template>
</div>
<div v-else style="text-align: center">
<img
class="bind-img"
v-if="activeIndex == 0"
src="@/assets/common/logging.png"
alt=""
/>
<img
class="bind-img"
v-else-if="activeIndex == 1"
src="@/assets/common/success.png"
alt=""
/>
<div class="bind-text">
{{ bindText }}
</div>
<div style="text-align: center" v-if="jumpUrl">
<el-button type="primary" @click="jump">返回</el-button>
</div>
</div>
</div>
</div>
</template>
<script>
import { getAuth, logout } from "@/api/index";
export default {
name: "Index",
data() {
return {
loginType:
this.$route.query.redirectUrl &&
this.$route.query.redirectUrl.split("_")[0],
activeIndex: 0,
userList: [],
activeUser: 0,
bindText: "绑定中",
ajaxSuccess: false,
jumpUrl: "",
iframeSrc: "",
};
},
components: {},
computed: {},
methods: {
selectLogin() {
if (this.activeUser === null) {
return this.$message.error("请选择用户登录!");
}
window.location.href = this.userList[this.activeUser].url;
},
autoLogin() {
if (
!this.$route.query.redirectUrl ||
this.$route.query.redirectUrl.indexOf("_") == -1
) {
return this.$message.error("url参数错误!");
}
setTimeout(() => {
getAuth({
ticketId: this.$route.query.ticketId,
sp: this.$route.query.redirectUrl.split("_")[0],
systicketId: this.$route.query.redirectUrl.split("_")[1],
}).then((res) => {
if (res.status == 200) {
this.ajaxSuccess = true;
if (this.$route.query.redirectUrl.split("_")[0] == "login") {
if (res.data.length == 1) {
window.location.href = res.data[0].url;
} else if (res.data.length > 1) {
this.userList = res.data;
}
} else if (this.$route.query.redirectUrl.split("_")[0] == "bind") {
this.activeIndex = 1;
this.bindText = "绑定成功";
}
} else {
if (this.loginType == "login") {
this.loginType = "bind";
}
this.bindText = res.msg;
if (res.data && res.data.length > 0) {
this.jumpUrl = res.data;
}
}
});
}, 1000);
},
jump() {
window.location.href = this.jumpUrl;
},
},
mounted() {},
};
</script>
<style scoped lang="less">
#index {
height: 100%;
}
.title {
padding-left: 12px;
position: relative;
color: #333;
font-size: 18px;
margin-bottom: 32px;
&::before {
content: "";
position: absolute;
left: 0%;
top: 50%;
width: 3px;
height: 20px;
transform: translateY(-50%);
background: #5798eb;
}
}
.user-dialog {
width: 420px;
padding: 30px 0;
margin: 0 auto;
}
.user {
padding: 12px 20px;
border: 1px solid #d2d2d2;
border-radius: 5px;
line-height: 22px;
margin-bottom: 20px;
cursor: pointer;
&.active {
border: 1px solid #5798eb;
.radio {
}
}
.radio {
width: 20px;
height: 20px;
border-radius: 50%;
border: 1px solid #d2d2d2;
display: inline-block;
vertical-align: top;
margin-right: 4px;
}
.select-radio {
width: 20px;
height: 20px;
border-radius: 50%;
position: relative;
border: 1px solid #5798eb;
vertical-align: top;
display: inline-block;
margin-right: 4px;
&::after {
position: absolute;
left: 3px;
top: 3px;
height: 14px;
width: 14px;
background: #5798eb;
content: "";
border-radius: 50%;
}
}
}
img {
width: 200px;
vertical-align: top;
margin: 0 auto;
}
.bind-text {
text-align: center;
font-size: 20px;
}
</style>
\ No newline at end of file
import Vue from 'vue'
import App from './App.vue'
import router from '@/router/index'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import 'lib-flexible'
import "animate.css"
import store from "@/store/index"
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
render: h => h(App),
store,
router
}).$mount('#app')
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from "@/components/Index"
Vue.use(VueRouter)
const router = new VueRouter({
mode: "history",
// routes: [
// {
// path: "/", component: Index, name: "index",
// },
// ]
})
export default router
\ No newline at end of file
import Vue from 'vue'
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
}
})
export default store
import axios from 'axios'
import { Message } from 'element-ui';
function urlTool(url) {
//将url用“?”和“&”分割;
const array = url.split("?").pop().split("&");
//声明一个空对象用来储存分割后的参数;
const data = {};
array.forEach((ele) => {
//将获得到的每个元素用 "="进行分割
let dataArr = ele.split("=");
//将数组的每一个元素遍历到对象中;
data[dataArr[0]] = dataArr[1];
});
return data;
}
const getResponseRequest = axios.create({
withCredentials: false,
responseType: 'blob',
})
getResponseRequest.interceptors.request.use(
config => {
const ticket = urlTool(window.location.href).ticket
if (ticket) {
config.headers['ticket'] = ticket
}
config.headers['X-Requested-With'] = 'XMLHttpRequest'
return config
},
error => {
return Promise.reject(new Error(error).message)
}
)
getResponseRequest.interceptors.response.use(
response => {
return response
},
error => {
Message({
message: '服务器错误',
type: 'error'
})
return Promise.reject(new Error(error).message)
}
)
export default getResponseRequest
import axios from 'axios'
import Vue from 'vue'
import { Message, Loading } from 'element-ui';
// loading框设置局部刷新,且所有请求完成后关闭loading框
let loadingInstance; //loading 实例
let needLoadingRequestCount = 0; //当前正在请求的数量
function showLoading() {
let main = document.querySelector('#app') //获取dom节点
if (main) {
if (needLoadingRequestCount === 0 && !loadingInstance) {
loadingInstance = Loading.service({
target: main, text: '正在加载...', background: 'rgba(0,0,0,0.6)', spinner: 'el-icon-loading'
});
}
needLoadingRequestCount++;
}
}
function closeLoading() {
Vue.nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
needLoadingRequestCount--;
needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); // 保证大于等于0
if (needLoadingRequestCount === 0) {
if (loadingInstance) {
hideLoading()
}
}
});
}
function urlTool(url) {
//将url用“?”和“&”分割;
const array = url.split("?").pop().split("&");
//声明一个空对象用来储存分割后的参数;
const data = {};
array.forEach((ele) => {
//将获得到的每个元素用 "="进行分割
let dataArr = ele.split("=");
//将数组的每一个元素遍历到对象中;
data[dataArr[0]] = dataArr[1];
});
return data;
}
//防抖
var hideLoading = () => {
loadingInstance.close();
loadingInstance = null;
}
const portalRequest = axios.create({
withCredentials: false,
baseURL: "https://portal.zjzwfw.gov.cn/",
})
portalRequest.interceptors.request.use(
config => {
const Authorization = localStorage.getItem('Authorization')
if (Authorization) {
config.headers['Authorization'] = Authorization
}
showLoading()
return config
},
error => {
closeLoading()
return Promise.reject(new Error(error).message)
}
)
portalRequest.interceptors.response.use(
response => {
closeLoading()
if (response.data.status != 200) {
Message({
message: response.data.msg,
type: 'error'
})
}
return response.data
},
error => {
Message({
message: '服务器错误',
type: 'error'
})
closeLoading()
setTimeout(() => {
window.history.back()
}, 1000)
return Promise.reject(new Error(error).message)
}
)
export default portalRequest
import axios from 'axios'
import Vue from 'vue'
import { Message, Loading } from 'element-ui';
// loading框设置局部刷新,且所有请求完成后关闭loading框
let loadingInstance; //loading 实例
let needLoadingRequestCount = 0; //当前正在请求的数量
function showLoading() {
let main = document.querySelector('#app') //获取dom节点
if (main) {
if (needLoadingRequestCount === 0 && !loadingInstance) {
loadingInstance = Loading.service({
target: main, text: '正在加载...', background: 'rgba(0,0,0,0.6)', spinner: 'el-icon-loading'
});
}
needLoadingRequestCount++;
}
}
function closeLoading() {
Vue.nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
needLoadingRequestCount--;
needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); // 保证大于等于0
if (needLoadingRequestCount === 0) {
if (loadingInstance) {
hideLoading()
}
}
});
}
function urlTool(url) {
//将url用“?”和“&”分割;
const array = url.split("?").pop().split("&");
//声明一个空对象用来储存分割后的参数;
const data = {};
array.forEach((ele) => {
//将获得到的每个元素用 "="进行分割
let dataArr = ele.split("=");
//将数组的每一个元素遍历到对象中;
data[dataArr[0]] = dataArr[1];
});
return data;
}
//防抖
var hideLoading = () => {
loadingInstance.close();
loadingInstance = null;
}
const request = axios.create({
withCredentials: false,
baseURL: "https://zjwaterfile.cnjsjd.net:8099/"
// baseURL: "https://watertestapi.vnet1000.net/",
})
request.interceptors.request.use(
config => {
const Authorization = localStorage.getItem('Authorization')
if (Authorization) {
config.headers['Authorization'] = Authorization
}
showLoading()
return config
},
error => {
closeLoading()
return Promise.reject(new Error(error).message)
}
)
request.interceptors.response.use(
response => {
closeLoading()
if (response.data.status != 200) {
Message({
message: response.data.msg,
type: 'error'
})
}
return response.data
},
error => {
Message({
message: '服务器错误',
type: 'error'
})
closeLoading()
setTimeout(() => {
window.history.back()
}, 1000)
return Promise.reject(new Error(error).message)
}
)
export default request
// base64 生成文件
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
}
export function downloadFileByByte(fileByte, fileName) {
let blob = dataURLtoBlob(fileByte)
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
let downloadElement = document.createElement("a");
let href = window.URL.createObjectURL(blob);
downloadElement.href = href;
downloadElement.download = fileName;
document.body.appendChild(downloadElement);
downloadElement.click();
document.body.removeChild(downloadElement);
window.URL.revokeObjectURL(href);
}
}
\ No newline at end of file
'use strict'
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
productionSourceMap: false,
// css: {
// loaderOptions: {
// postcss: {
// postcssOptions: {
// plugins: [
// require('postcss-plugin-px2rem')({
// rootValue: 54,
// mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
// minPixelValue: 1 //设置要替换的最小像素值(3px会被转rem)。 默认 0
// }),
// ]
// }
// }
// }
// },
outputDir: "build",
publicPath: process.env.NODE_ENV == 'production' ? './' : '/',
devServer: {
port: 3000,
proxy: {
'/api': {
target: 'http://192.168.0.171:8035/api',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
},
lintOnSave: true,
pluginOptions: {
"style-resources-loader": {
preProcessor: "less",
patterns: []
}
},
chainWebpack: (config) => {
config.module
.rule('css')
.test(/\.css$/)
.oneOf('vue')
.resourceQuery(/\?vue/)
.use('px2rem')
.loader('px2rem-loader')
.options({
remUnit: 75
})
}
})
File added
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment