Commit 3653ecb9 authored by wanghuan's avatar wanghuan

上传aserver-ui的nojc分支

parents
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
FROM nginx:stable
LABEL maintainer="dengguoqi@archser.com"
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
\ No newline at end of file
# aserver-ui
## 准备
设置私服地址
```
npm config set registry=http://archser.com:8081/repository/npm-group/
```
## 安装项目依赖模块
```
npm install
```
## 开发模式,热加载
```
npm run serve
```
## 产品模式,最小化编译
```
npm run build
```
## 语法检查
```
npm run lint
```
\ No newline at end of file
module.exports = {
presets: [
[
"@vue/app",
{
"useBuiltIns": "entry"
}
]
],
}
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain application/xml application/javascript text/css application/octet-stream;
gzip_vary on;
# websocke 连接需要下面的配置
map $http_upgrade $connection_upgrade {
websocket upgrade;
default $sent_http_connection;
}
server {
listen 80;
#server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location ~ \.(gif|jpg|jpeg|bmp|png|ico|txt|mp3|mp4|swf|css|js|ttf)$ {
root /usr/share/nginx/html;
expires max;
}
location /aserver {
proxy_pass http://aserver:11038/aserver;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# websocke 连接需要下面的配置
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "aserver-ui",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve --port 11028",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@archser/layout-ui": "^0.8.2",
"babel-polyfill": "^6.26.0",
"core-js": "^2.6.10",
"crypto-js": "^4.0.0",
"es6-promise": "^4.2.8",
"iview": "^3.5.4",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"qs": "^6.9.1",
"sm-crypto": "^0.1.0",
"vue": "^2.6.10",
"vue-router": "^3.1.3",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.12.1",
"@vue/cli-plugin-eslint": "^3.12.1",
"@vue/cli-service": "^4.1.2",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.2.3",
"vue-template-compiler": "^2.6.10"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {
"no-unused-vars": "off"
},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"repository": {
"type": "git",
"url": "http://gitlab.archser.com/spb/aserver-ui.git"
},
"license": "MIT",
"browserslist": [
"> 1%",
"last 2 versions"
],
"prettier": {
"semi": false,
"printwidth": 180,
"singleQuote": true
}
}
<!DOCTYPE html>
<html lang="en">
<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">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>aserver-ui</title>
</head>
<body>
<noscript>
<strong>We're sorry but aserver-ui 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>
This diff is collapsed.
<!DOCTYPE html>
<html lang="en">
<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">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>登录</title>
</head>
<body>
<noscript>
<strong>We're sorry but aserver-ui 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>
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
import { axios } from '@archser/layout-ui'
import myaxios from 'axios'
const SERVICE_URL = '/aserver'
//获取操作文件列表
export const getList = (params) => {
return axios.request({
url: SERVICE_URL + '/helper/getList',
params:params,//LiuKexin 20201123 修改传递参数的格式
method: 'post'
})
}
export const edit = (param) => {
return axios.request({
url: SERVICE_URL + '/helper/edit',
data: param,
method: 'post'
})
}
export const remove = (ids) => {
return axios.request({
url: SERVICE_URL + '/helper/remove',
data: {
ids
},
method: 'post'
})
}
export const add = param => {
return myaxios({
url: SERVICE_URL + '/helper/add',
data: param,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
\ No newline at end of file
import { axios } from '@archser/layout-ui'
const SERVICE_URL = '/aserver'
/**
* LiuKexin 20210311 根据用户名获取设置首页
* @param {*} params
* @returns
*/
export const getUserHome = params => {
return axios.request({
url: SERVICE_URL + '/getUserHome',
data: params,
method: 'post'
})
}
//修改密码
export const update = (username, newPwd) => {
return axios.request({
url: SERVICE_URL + '/updatePassword',
data: {
username,
newPwd
},
method: 'post'
})
}
/**
* @description: 验证密码强度
* @Author: ChengYaqing
* @Date: 2020-10-30 10:30:45
*/
export const verifyPassword = params => {
return axios.request({
url: SERVICE_URL + '/verifyPassword',
data: params,
method: 'post'
})
}
/**
* 检查SN
*/
export const snVerify = () => {
return axios.request({
url: SERVICE_URL + '/sn/snVerify',
method: 'post'
})
}
/**
* 注册SN
* @param {*} params
*/
export const registered = params => {
return axios.request({
url: SERVICE_URL + '/sn/registered',
data: params,
method: 'post'
})
}
export const ruleValidate = {
organName: [
{ required: true, message: '机构名不能为空', trigger: 'blur' }
],
uniqueCode: [
{ required: true, message: '注册码不能为空', trigger: 'blur' },
]
}
\ No newline at end of file
import { axios } from '@archser/layout-ui'
const SERVICE_URL = '/aserver/menu'
/**
* 根据SysId获取菜单列表
*/
export const getMenuList = params => {
return axios.request({
url: SERVICE_URL + '/getMenuList',
params: params,
method: 'get'
})
}
/**
* 保存菜单数据
*/
export const saveMenuData = params => {
return axios.request({
url: SERVICE_URL + '/saveMenuData',
params: params,
method: 'post'
})
}
/**
* 删除菜单数据
*/
export const deleteMenu = params => {
return axios.request({
url: SERVICE_URL + '/deleteMenu',
params: params,
method: 'post'
})
}
import { axios } from '@archser/layout-ui'
import myaxios from 'axios'
const SERVICE_URL = '/aserver'
/**
* 获取所有系统
*/
export const getSettings = () => {
return axios.get('/aserver/setting/all')
}
export const add = config => {
return axios.request({
url: SERVICE_URL + '/setting/add',
data: config,
method: 'post'
})
}
export const dele = data => {
return axios.request({
url: SERVICE_URL + '/setting/dele',
data,
method: 'post'
})
}
export const findConfigList = (params) => {
return axios.request({
url: SERVICE_URL + '/setting/findConfigList',
params: params,
method: 'post'
})
}
/**
* Liukexin 20200930 更改系统名称和图标
* @param {*} param
*/
export const changeSetting = param => {
return myaxios({
url: SERVICE_URL + '/setting/changeSetting',
method: 'post',
data: param,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
import { axios } from '@archser/layout-ui'
const SERVICE_URL = '/aserver'
/**
* 获取所有系统
*/
export const getSystems = (params) => {
return axios.request({
url: SERVICE_URL + '/system',
params: params,
method: 'get'
})
}
export const create = () => {
return axios.get(SERVICE_URL + '/key/create')
}
export const addorEdit = params => {
return axios.request({
url: SERVICE_URL + '/system/addorEdit',
data: params,
method: 'post'
})
}
export const dele = params => {
return axios.request({
url: SERVICE_URL + '/system/dele',
data: params,
method: 'post'
})
}
<template>
<div class="searchClass" :style="width?('width: '+(width-37)+'px;'):'width:100%;'">
<iInput
class="searchInputClass"
:placeholder="placeholder"
@on-clear="clear"
@on-enter="search"
@on-change="change"
@on-focus="focus"
@on-blur="blur"
@on-keyup="keyup"
@on-keypress="keypress"
@on-keydown="keydown"
:disabled="disabled"
v-model="inputValue"
clearable/>
<Button type="primary" @click="search" class="searchButtonClass">
<Icon :custom="'fa '+custom+' fa-fw'" aria-hidden="true"/>
</Button>
</div>
</template>
<script>
export default {
name: 'SearchInput',
props: {
custom: {
type: String,
default: 'fa-search'
},
disabled: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: '请输入搜索内容'
},
width: {
type: Number,
default: null
},
value: {
type: String,
default: ''
},
original: {// 是否不处理输入的内容,即:不将单引号转换为两个单引号
type: Boolean,
defalut: false,
}
},
computed: {
},
data() {
return {
inputValue: this.getValue(this.value)
}
},
methods: {
/**
* @description: // CP-1820 替换一个单引号为两个单引号 huwenbin 2020/12/21
* @author: huwenbin
* @Date: 2020/12/21 11:35
*/
getValue(value) {
if (value != null && !this.original) {
return value.replace(/''/g, "'")
}
return value
},
/**
* @description: // CP-1820 替换一个单引号为两个单引号 huwenbin 2020/12/21
* @author: huwenbin
* @Date: 2020/12/21 11:35
*/
convertValue(value) {
if (value != null && !this.original) {
return value.replace(/'/g, "''")
}
return value
},
focus() {
this.$emit('on-focus')
},
blur() {
this.$emit('on-blur')
},
enter() {
this.$emit('on-enter')
},
keyup() {
this.$emit('on-keyup')
},
keypress() {
this.$emit('on-keypress')
},
keydown() {
this.$emit('on-keydown')
},
change() {
this.$emit('update:value', this.convertValue(this.inputValue))
this.$emit('on-change')
},
clear() {
this.$emit('on-clear')
},
search() {
this.$emit('on-click')
}
}
}
</script>
<style>
.searchClass {
display: inline-flex;
border-radius: 5px;
border: 1px solid rgba(200, 200, 200, 0);
}
.searchClass:hover{
border-color: #57a3f3;
-webkit-transition: all .5s;
transition: all .5s;
}
.searchClass:focus-within{
border-color: #57a3f3;
-webkit-box-shadow: 0 0 0 2px rgba(45,140,240,.2);
box-shadow: 0 0 0 2px rgba(45,140,240,.2);
background-position: 0 0%;
-webkit-transition: all .5s;
transition: all .5s;
}
.searchClass .searchButtonClass {
width: 35px;
text-align: center;
padding-left: 7px;
background: #fff;
color: #808695;
border-bottom-left-radius: 0px;
border-top-left-radius: 0px;
border: 1px solid #dcdee2;
border-left: 0px;
}
.searchClass .searchButtonClass:focus {
outline: none;
box-shadow: none;
}
.searchClass .searchInputClass .ivu-input-icon {
right: 0px;
}
.searchClass .searchInputClass input{
border-bottom-right-radius: 0px;
border-top-right-radius: 0px;
border-right: 0px;
}
.searchClass .searchInputClass input:focus{
outline: none;
border: 1px solid #dcdee2;
border-right: 0px;
box-shadow: none;
}
.searchClass .searchInputClass input:hover{
border: 1px solid #dcdee2;
border-right: 0px;
}
</style>
import Vue from 'vue'
import axios from 'axios'
import qs from 'qs'
import Login from './views/login/Login.vue'
let ajax = axios.create({
timeout: 30000,
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
transformRequest: [
function(data) {
return qs.stringify(data)
}
],
paramsSerializer: function(data) {
return qs.stringify(data)
}
})
Vue.config.productionTip = false
Vue.prototype.$http = ajax
new Vue({
render: h => h(Login)
}).$mount('#app')
import { layout } from '@archser/layout-ui'
import 'babel-polyfill'
import Es6Promise from 'es6-promise'
Es6Promise.polyfill()
import '@archser/layout-ui/dist/layout-ui.css'
import router from './router'
layout(router)
\ No newline at end of file
/**
* 路由
*/
export default {
routes: [
{
path: '/',
name: 'login',
meta: {
title: '应用管理'
},
component: () => import('@/views/login/login.vue')
}
]
}
\ No newline at end of file
/**
* 路由
*/
export default {
routes: [
{
path: '/',
name: 'home',
redirect: '/home',
children: [
{
path: 'home',
name: 'home_index',
meta: {
title: '应用管理'
},
component: () => import('@/views/apply/apply.vue')
},
{
path: 'setting',
name: 'setting',
meta: {
title: '配置'
},
component: () => import('@/views/setting/Setting.vue')
},
{
path: 'help',
name: 'help',
meta: {
title: '帮助下载'
},
component: () => import('@/views/helpCenter/help-download.vue')
},
{
path: 'helpManager',
name: 'helpManager',
meta: {
title: '帮助中心管理'
},
component: () => import('@/views/helpCenter/help-Manager.vue')
},
]
}
]
}
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
}
})
This diff is collapsed.
This diff is collapsed.
/**LiuKexin 20201229 更换图标 */
export const iconList = [
'fa fa-file',
'fa fa-mixcloud',
'fa fa-cloud-upload',
'fa fa-cloud-download',
'fa fa-file-archive-o',
'fa fa-archive',
'fa fa-search',
'fa fa-object-group',
'fa fa-trophy',
'fa fa-clipboard',
'fa fa-comments-o',
'fa fa-calendar-o',
'fa fa-heart',
'fa fa-id-card',
'fa fa-bookmark',
'fa fa-external-link',
'fa fa-lightbulb-o',
'fa fa-magic',
'fa fa-hand-pointer-o',
'fa fa-wrench',
'fa fa-area-chart',
'fa fa-bar-chart',
'fa fa-pie-chart',
'fa fa-line-chart',
'fa fa-microchip',
'fa fa-building',
'fa fa-cogs',
'fa fa-calendar',
'fa fa-university',
'fa fa-list-ul',
'fa fa-print',
'fa fa-table',
'fa fa-sitemap',
'fa fa-list-alt',
'fa fa-columns',
'fa fa-handshake-o',
'fa fa-database',
'fa fa-users',
'fa fa-user-secret',
'fa fa-trash',
'fa fa-file-text',
'fa fa-server',
'fa fa-globe',
'fa fa-crosshairs',
'fa fa-warning',
'fa fa-trello',
'fa fa-files-o',
'fa fa-modx',
'fa fa-chain-broken',
'fa fa-book',
'fa fa-folder-open-o',
'fa fa-shield',
'fa fa-newspaper-o',
'fa fa-home',
]
export const columns = [ //LiuKexin 20201225 文本省略号 提示
{
type: 'selection',
width: 50, //LiuKexin 20201216 列宽
align: 'center',
fixed: 'left',
className: 'compact-cell'
},
{
title: '操作',
width: 50,
align: 'center',
slot: 'operate',
fixed: 'left',
className: 'compact-cell'
},
{
title: '名称',
minWidth: 150,
key: 'title',
ellipsis:true,
tooltip:true,
resizable:true
},
{
title: '英文标识',
width: 150,
key: 'name',
ellipsis:true,
tooltip:true,
resizable:true
},
{
title: '访问路径',
width: 200,
key: 'path',
ellipsis:true,
tooltip:true,
resizable:true
},
{
title: '图标',
width: 150,
key: 'icon',
ellipsis:true,
tooltip:true,
resizable:true
},
/**
* 暂时不需要展示该字段 liuyimeng 2020-03-02
* **/
// {
// title: '目标',
// width: 100,
// key: 'target'
// },
{
title: '描述',
width: 250,
key: 'description',
ellipsis:true,
tooltip:true,
resizable:true
},
{
title: '是否隐藏',
width: 100,
key: 'hidden',
render(h, params) {
return h('div', [
params.row.hidden?'是':'否'
])
}
}
]
\ No newline at end of file
import Side from './side.vue'
export default Side
<template>
<transition
:css="false"
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@leave="leave"
>
<div class="side" :style="sideStyle" v-show="visible" v-clickoutside="handleClose" ref="side">
<slot></slot>
</div>
</transition>
</template>
<script>
import Velocity from 'velocity-animate'
export default {
props: {
width: {
type: [Number, String],
required: true
},
value: {
type: Boolean,
default: false
}
},
watch: {
value() {
this.visible = this.value
}
},
data() {
return {
visible: this.show
}
},
computed: {
sideStyle() {
return {
width: typeof this.width == 'string' ? this.width : this.width + 'px',
right: (this.visible ? 0 : -this.width) + 'px'
}
}
},
methods: {
// handleClose() {
// this.visible = false
// this.$emit('input', this.visible)
// },
handleClose(e) {
//处理与其他组件冲突
let s = this.$refs['side'].getBoundingClientRect()
let domX = s.left
let domY = s.bottom
//如果鼠标在窗口内则不触发
if (domX < e.clientX && domY > e.clientY) {
return;
}
this.visible = false
this.$emit('input', this.visible)
},
beforeEnter(el) {
el.style.right = -this.width + 'px'
},
enter(el, done) {
Velocity(el, { right: '0px' }, { duration: 200, complete: done })
},
afterEnter(el) {},
leave(el, done) {
Velocity(
el,
{ right: -this.width + 'px' },
{ duration: 200, complete: done }
)
}
},
created() {
this.visible = this.value
}
}
</script>
<style>
.side {
position: absolute;
height: 100%;
top: 0px;
z-index: 1000;
box-shadow: -2px 0 6px -2px rgba(0, 0, 0, 0.2);
}
</style>
<template>
<div class="apply-app-outer">
<div class="apply-app-container">
<div class="apply-toolbar">
<Row span="24">
<Button @click.stop="addSystem" type="primary" style="padding:0 8px;">
<Icon custom="fa fa-fw fa-plus"></Icon>添加
</Button>
<Button @click="remove" type="text" style="margin-left:8px;padding:0px;">
<Icon custom="fa fa-trash fa-fw" aria-hidden="true" style="color: red"></Icon>删除
</Button>
<Divider type="vertical" />
<SearchInput
:value.sync="searchText"
@on-clear="clearSearch"
@on-click="searchByKeyword"
:width="260"
/>
</Row>
</div>
<div>
<!-- LiuKexin 20210318 调整高度 -->
<Table
border
tooltip="true"
:columns="columns"
:data="list"
:loading="loading"
:height="tableheight-70"
@on-selection-change="onSelect"
>
<template slot-scope="{ row, index }" slot="operate">
<ButtonGroup>
<Button
class="operate-button"
@click.stop="edit(row, index)"
>
<Icon custom="fa fa-fw fa-edit" title="编辑"></Icon>
</Button>
</ButtonGroup>
</template>
</Table>
<Page
style="float:left;padding:10px;width:100%;background-color:#fff"
:total="total"
:current="page_sum"
:page-size="page_size"
:page-size-opts="[10, 20, 50, 100]"
@on-change="handlePage"
@on-page-size-change="handelPageSizeChange"
size="small"
show-elevator
show-total
show-sizer
prev-text="上一页"
next-text="下一页"
/>
</div>
<template>
<!-- LiuKexin 20210318 调整间距和高度 -->
<Side :width="sideComponentWidth" v-model="showSide" style="margin-top:120px;margin-right:25px;background-color:#fff;height:auto;">
<Card :style="'height:' + (tableheight+20) + 'px'">
<span slot="title">
<Icon :custom="'fa fa-' + sideComponentIcon"></Icon>
{{sideComponentTitle}}
</span>
<component
:is="sideComponent"
:paraData="paraData"
@reload="reload"
></component>
</Card>
</Side>
</template>
</div>
</div>
</template>
<script>
import SearchInput from '_c/search-input/searchInput'
import { getList,remove } from '@/api/helper'
import Side from '@/views/components/side/side'
export default {
components: {
Side,
SearchInput
},
data() {
return {
paraData: {},
showSide: false,
sideComponentTitle: '',
sideComponentIcon: '',
sideComponentWidth: 0,
sideComponent: null,
columns: [
{
type: "selection",
width: 60,
align: "center",
},
{
title: "操作",
width: 70,
align: "center",
slot: "operate",
className: "compact-cell",
},
{
title: "名称",
minWidth: 150,
key: "name",
},
{
title: "文档类型",
width: 150,
key: "type_cn",
},
{
title: "描述",
width: 300,
key: "description",
},
],
tableheight: 0,
title: '',
list: [],
loading: false,
modal: false,
selection: [],
searchText: '',
page_size: 20,
page_sum: 1,
total:0,
isIE:false
}
},
methods: {
getTableData(pageSize) {
this.page_size = pageSize
this.getList();
},
reload(){
this.getList()
},
handelPageSizeChange(value) {
this.page_size = value;
this.page_sum = 1
this.getList();
},
handlePage(value) {
this.page_sum = value;
this.getList();
},
/**
* LiuKexin 20201123 修改删除,(1)添加警告框,(2)没有选择数据时给予提示
*/
remove(){
if(this.selection.length == 0){
this.$Notice.warning({title:'警告',desc:'请先选择数据'})
return
}
let content ="删除的数据不可恢复,确定要删除吗?"
this.showConfirmModal(this.selection, content).then(ids => {
remove(ids.join(",")).then(res => {
if (res.data && res.data.state === 'ok') {
this.$Notice.success({ title: '提示', desc: '删除成功!' })
/** LiuKexin 20201123 当前页全部删除后,页码停留在上一页 start*/
if(this.selection.length == this.list.length && this.page_sum > 1){
this.page_sum = this.page_sum - 1
}
if(this.selection.length == this.list.length && this.page_sum == 1){
this.page_sum = 1
}
/** LiuKexin 20201123 当前页全部删除后,页码停留在上一页 end*/
this.getList()
} else {
this.$Notice.error({
title: '提示',
desc:
res.data.msg != null
? res.data.msg
: '未知错误,请联系管理员解决',
})
}
this.$Modal.remove()
})
})
},
/**
* LiuKexin 20201123 删除添加弹出框
*/
showConfirmModal(selection, content) {
return new Promise(resolve => {
this.$Modal.confirm({
title: '警告',
content: content,
loading: true,
onOk: () => {
let ids = selection.map(item => {
return item.id
})
event.stopPropagation()
resolve(ids)
},
onCancel: () => {
event.stopPropagation()
}
})
})
},
clearSearch() {
this.getList()
},
searchByKeyword() {
this.page_sum = 1
this.getList()
},
addSystem(row) {
// this.paraData = {
// tableheight: this.tableheight-43,
// id: row.id
// }
this.sideComponentTitle = '添加帮助'
this.sideComponentIcon = 'pencil-square-o'
this.sideComponentWidth = 1000
this.showSide = true
this.paraData = null
import('./help-edit').then(comp => {
this.sideComponent = comp.default
})
},
edit(row) {
this.sideComponentTitle = '编辑帮助' //LiuKexn 20210315 名称
this.sideComponentIcon = 'edit'
this.sideComponentWidth = 1000
this.showSide = true
this.paraData = Object.assign({}, row)
import('./help-edit').then(comp => {
this.sideComponent = comp.default
})
},
onSelect(selection) {
this.selection = selection
},
getList() {
//LiuKexin 20201123 修改传递参数的格式
let params = {
searchText:this.searchText,
pageSize:this.page_size,
pageNumber:this.page_sum
}
getList(params).then(res => {
if (res.data && res.data.state === 'ok') {
let list = res.data.list.list
list.forEach(help => {
if (help.type == 0){
help["type_cn"] = "标准规范"
} else if (help.type == 1) {
help["type_cn"] = "使用手册"
} else if (help.type == 2) {
help["type_cn"] = "操作视频"
}
});
this.list = list
this.total = res.data.list.totalRow
this.selection = []
}
})
}
},
mounted() {
this.tableheight = document.body.clientHeight - 160
this.getList()
}
}
</script>
<style>
.ivu-card-body {
padding: 0px;
}
.operate-button {
padding: 2px 7px;
}
.compact-cell .ivu-table-cell {
padding-left: 5px;
padding-right: 5px;
}
.apply-app-outer {
height: 100%;
padding: 24px;
}
.apply-app-container {
height: 100%;
text-align: left;
background: #e9e9e9;
}
.apply-toolbar {
padding: 4px;
background-color: #fff;
border: 1px solid #d7dde4;
}
.form-editor {
position: relative;
padding: 16px;
}
.apply-server-search-icon {
width: 32px;
height: 32px;
line-height: 32px;
font-size: 16px;
text-align: center;
color: #808695;
position: absolute;
right: 13%;
z-index: 3;
}
.side-card{
height:800px;
}
</style>
<template>
<div class="apply-app-outer">
<div class="apply-app-container">
<div class="apply-toolbar">
<Row span="24">
<SearchInput
:value.sync="searchText"
@on-clear="clearSearch"
@on-click="searchByKeyword"
:width="260"
/>
</Row>
</div>
<div>
<!-- LiuKexin 20210318 调整高度 -->
<Table
border
tooltip="true"
:columns="columns"
:data="list"
:loading="loading"
:height="tableheight-70"
@on-selection-change="onSelect"
>
<template slot-scope="{ row, index }" slot="operate">
<ButtonGroup>
<Button
class="operate-button"
@click.stop="download(row, index)"
>
<span class="fa fa-download" title="下载文件"></span>
</Button>
</ButtonGroup>
</template>
</Table>
<Page
style="float:left;padding:10px;width:100%;background-color:#fff"
:total="total"
:current="page_sum"
:page-size="page_size"
:page-size-opts="[10, 20, 50, 100]"
@on-change="handlePage"
@on-page-size-change="handelPageSizeChange"
size="small"
show-elevator
show-total
show-sizer
prev-text="上一页"
next-text="下一页"
/>
</div>
</div>
</div>
</template>
<script>
import { getList } from '@/api/helper'
import SearchInput from '_c/search-input/searchInput'
export default {
components: {
SearchInput
},
data() {
return {
paraData: {},
showSide: false,
sideComponentTitle: '',
sideComponentIcon: '',
sideComponentWidth: 0,
sideComponent: null,
columns: [
{
title: '序号',
width: 50,
key: 'index',
type: 'index',
align: 'center',
className: 'compact-cell'
},
{
title: "操作",
width: 70,
align: "center",
slot: "operate",
className: "compact-cell",
},
{
title: "名称",
minWidth: 150,
key: "name",
},
{
title: "文档类型",
width: 150,
key: "type_cn",
},
{
title: "描述",
width: 300,
key: "description",
},
],
tableheight: 0,
title: '',
loading: false,
selection: [],
searchText: null,
list:[],
page_size: 20,
page_sum: 1,
total:0,
isIE:false
}
},
methods: {
getTableData(pageSize) {
this.page_size = pageSize
this.getList();
},
handelPageSizeChange(value) {
this.page_size = value;
this.page_sum = 1
this.getList();
},
handlePage(value) {
this.page_sum = value;
this.getList();
},
getList() {
let params = {
searchText:this.searchText,
pageSize:this.page_size,
pageNumber:this.page_sum
}
getList(params).then(res => {
if (res.data && res.data.state === 'ok') {
let list = res.data.list.list
list.forEach(help => {
if (help.type == 0){
help["type_cn"] = "标准规范"
} else if (help.type == 1) {
help["type_cn"] = "使用手册"
} else if (help.type == 2) {
help["type_cn"] = "操作视频"
}
});
this.list = list
this.total = res.data.list.totalRow
this.selection = []
}
})
},
/**
* Liukexin 20201120 下载操作手册
*/
download(row,index){
location.href = '/aserver/helper/downloadOperation?id=' + row.id
},
clearSearch() {
this.getList()
},
searchByKeyword() {
this.getList()
},
},
mounted() {
this.tableheight = document.body.clientHeight - 160
this.getList()
}
}
</script>
<style>
.ivu-card-body {
padding: 0px;
}
.operate-button {
padding: 2px 7px;
}
.compact-cell .ivu-table-cell {
padding-left: 5px;
padding-right: 5px;
}
.apply-app-outer {
height: 100%;
padding: 24px;
}
.apply-app-container {
height: 100%;
text-align: left;
background: #e9e9e9;
}
.apply-toolbar {
padding: 5px 10px;
background-color: #fff;
border: 1px solid #d7dde4;
}
.form-editor {
position: relative;
padding: 16px;
}
.apply-server-search-icon {
width: 32px;
height: 32px;
line-height: 32px;
font-size: 16px;
text-align: center;
color: #808695;
position: absolute;
right: 13%;
z-index: 3;
}
</style>
<template>
<div>
<template>
<Spin fix v-if="spinShow">
<Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
<div>正在提交中,请稍等片刻...</div>
</Spin>
</template>
<Row class="head-toolbar">
<iCol>
<Button type="primary" style="padding:0 8px;" @click.stop="sub">
<!-- LiuKexin 20201123 修改确定图标 -->
<Icon custom="fa fa-save"></Icon>&nbsp;确定
</Button>
</iCol>
</Row>
<div class="content-toolbar">
<Form ref="helperFrom" :rules="helperValidate" :label-width="80">
<Row>
<iCol span="11">
<FormItem label="文件名称" prop="name" :maxlength="50">
<Input v-model.trim="helper.name" placeholder="请输入文件名称" />
</FormItem>
</iCol>
</Row>
<Row>
<iCol span="11">
<FormItem label="文件类别" prop="type" :maxlength="50">
<!-- <Input v-model.trim="helper.type" placeholder="请输入文件类别" /> -->
<RadioGroup v-model="helper.type">
<Radio :label="1">使用手册</Radio>
<Radio :label="0">标准规范</Radio>
<Radio :label="2">操作视频</Radio>
</RadioGroup>
</FormItem>
</iCol>
</Row>
<Row>
<iCol span="22">
<FormItem label="描述" prop="description">
<Input
v-model.trim="helper.description"
type="textarea"
:autosize="{ minRows: 2, maxRows: 5 }"
placeholder="请输入报表描述"
/>
</FormItem>
</iCol>
</Row>
<template v-if="isAdd">
<Row>
<iCol span="22">
<FormItem label="文件" prop="file">
<Upload
action
:before-upload="handleBeForeUpload"
show-upload-list
>
<Button icon="ios-cloud-upload-outline">{{
fileName == null ? '点击上传文件' : fileName
}}</Button>
</Upload>
</FormItem>
</iCol>
</Row>
</template>
</Form>
</div>
</div>
</template>
<script>
import { add, edit } from '@/api/helper'
export default {
props: {
paraData: Object,
},
data() {
return {
helper: {
file: '',
name: '',
type: 1,
description: '',
},
fileName: null,
helperValidate: {
name: [
{
validator: (rule, value, callback) => {
if (
this.helper.name == null ||
this.helper.name == undefined ||
this.helper.name.length == 0
) {
callback(new Error('文件名称不能为空'))
return
} else if (this.helper.name.length > 20) {
callback(new Error('文件名称不能超过20个字'))
return
}
callback()
},
required: true,
message: '文件名称不能为空',
trigger: 'blur',
},
],
type: [
{
validator: (rule, value, callback) => {
if (
this.helper.type == null ||
this.helper.type == undefined ||
this.helper.type.length == 0
) {
callback(new Error('文件类型不能为空'))
return
}
callback()
},
required: true,
message: '文件类型不能为空',
trigger: 'blur',
},
],
description: [
{
validator: (rule, value, callback) => {
if (this.helper.description.length > 50) {
callback(new Error('备注超出限制'))
return
}
callback()
},
trigger: 'blur',
},
],
file: [
{
validator: (rule, value, callback) => {
if (
this.helper.file == null ||
this.helper.file == undefined ||
this.helper.file == ''
) {
callback(new Error('请选择上传文件'))
return
}
callback()
},
required: true,
trigger: 'blur',
},
],
},
isAdd: true,
spinShow: false
}
},
computed: {},
mounted() {
if (this.paraData) {
this.isAdd = false
this.helper = Object.assign({}, this.paraData)
} else {
this.isAdd = true
this.helper = {
file: '',
name: '',
type: 1,
description: '',
}
}
},
methods: {
handleFormatError(file) {},
handleBeForeUpload(file) {
let size = file.size
if (size > 1024 * 1024 * 150) {
this.$Notice.error({ title: '提示', desc: '上传文件不能大于150M!' })
return false;
}
this.fileName = file.name
let fileFormat = this.fileName.substring(this.fileName.lastIndexOf('.'))
this.helper.file = file
return false
},
sub() {
// LiuKexin 20210315 描述为null
if(this.helper.description == null){
this.helper.description = ''
}
this.$refs.helperFrom.validate((valid) => {
this.backupValue = null
if (valid) {
// //对input框的值去除特殊字符 liuyimeng 20200403
// this.helper.name = this.helper.name.replace(
// /[ `~!@#$%^&*()_\-+=<>?:"{}|,.\\/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g,
// ''
// )
// if (this.helper.description) {
// this.helper.description = this.helper.description.replace(
// /[ `~!@#$%^&*()_\-+=<>?:"{}|,.\\/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g,
// ''
// )
// }
let param = new FormData() // 创建form对象
param.append('file', this.helper.file)
param.append('name', this.helper.name)
param.append('description', this.helper.description)
param.append('type', this.helper.type)
if (this.isAdd) {
this.add(param)
} else {
this.edit(this.helper)
}
}
})
},
edit(param) {
edit(param).then((res) => {
if (res.data && res.data.state === 'ok') {
this.$Notice.success({ title: '提示', desc: '修改成功!' })
this.$emit('reload')
} else {
this.$Notice.error({
title: '提示',
desc:
res.data.msg != null
? res.data.msg
: '未知错误,请联系管理员解决',
})
}
})
},
add(param) {
this.spinShow = true
add(param).then((res) => {
if (res.data && res.data.state === 'ok') {
this.$Notice.success({ title: '提示', desc: '添加成功!' })
//2020年11月23日 解决添加后页面不刷新 yangchengwu
this.helper = {
file: '',
name: '',
type: 1,
description: '',
}
this.fileName = null
this.spinShow = false
this.$emit('reload')
} else {
this.$Notice.error({
title: '提示',
desc:
res.data.msg != null
? res.data.msg
: '未知错误,请联系管理员解决',
})
}
this.$emit('close', true)
})
},
},
watch: {
paraData(newValue) {
if (newValue) {
this.isAdd = false
this.helper = Object.assign({}, newValue)
} else {
this.isAdd = true
this.helper = {
file: '',
name: '',
type: 1,
description: '',
}
}
},
},
}
</script>
<style>
.head-toolbar {
padding-top: 4px;
padding-bottom: 3px;
padding-left: 4px;
border-bottom: 1px solid #d7dde4;
background: #fff;
height: 100%;
}
.ivu-card-body {
padding: 0px;
}
.content-toolbar {
padding: 16px;
}
</style>
This diff is collapsed.
<!--LiuKexin 20210329 生成图片验证码-->
<template>
<div class="s-canvas">
<canvas
id="s-canvas"
:width="contentWidth"
:height="contentHeight"
></canvas>
</div>
</template>
<script>
export default {
name: 'SIdentify',
props: {
identifyCode: {
type: String,
default: 'ASDF',
},
fontSizeMin: {
type: Number,
default: 24,
},
fontSizeMax: {
type: Number,
default: 32,
},
backgroundColorMin: {
type: Number,
default: 180,
},
backgroundColorMax: {
type: Number,
default: 240,
},
colorMin: {
type: Number,
default: 50,
},
colorMax: {
type: Number,
default: 160,
},
lineColorMin: {
type: Number,
default: 100,
},
lineColorMax: {
type: Number,
default: 200,
},
dotColorMin: {
type: Number,
default: 0,
},
dotColorMax: {
type: Number,
default: 255,
},
contentWidth: {
type: Number,
default: 100,
},
contentHeight: {
type: Number,
default: 32,
},
},
methods: {
// 生成一个随机数
randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min)
},
// 生成一个随机的颜色
randomColor(min, max) {
let r = this.randomNum(min, max)
let g = this.randomNum(min, max)
let b = this.randomNum(min, max)
return 'rgb(' + r + ',' + g + ',' + b + ')'
},
transparent() {
return 'rgb(255,255,255)'
},
drawPic() {
let canvas = document.getElementById('s-canvas')
let ctx = canvas.getContext('2d')
ctx.textBaseline = 'bottom'
// 绘制背景
ctx.fillStyle = this.randomColor(
this.backgroundColorMin,
this.backgroundColorMax
) //图形填充颜色设置
ctx.strokeStyle = this.randomColor(
this.backgroundColorMin,
this.backgroundColorMax
) //图形轮廓的颜色设置
ctx.fillRect(0, 0, this.contentWidth, this.contentHeight) //绘制一个填充的矩形 0 0 width height x起点 y起点 宽 高
ctx.strokeRect(0, 0, this.contentWidth, this.contentHeight) // 绘制一个矩形边框 0 0 width height x起点 y起点 宽 高
// 绘制文字
for (let i = 0; i < this.identifyCode.length; i++) {
this.drawText(ctx, this.identifyCode[i], i)
}
this.drawLine(ctx)
this.drawDot(ctx)
},
drawText(ctx, txt, i) {
ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
ctx.font =
this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei border'
let x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1)) -8
let y = this.randomNum(this.fontSizeMax, this.contentHeight+5)
var deg = this.randomNum(-10, 10)
// 修改坐标原点和旋转角度
ctx.translate(x, y)
ctx.rotate((deg * Math.PI) / 180)
ctx.fillText(txt, 0, 0)
// 恢复坐标原点和旋转角度
ctx.rotate((-deg * Math.PI) / 180)
ctx.translate(-x, -y)
},
drawLine(ctx) {
// 绘制干扰线
for (let i = 0; i < 5; i++) {
ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax)
ctx.beginPath()
ctx.moveTo(
this.randomNum(0, this.contentWidth),
this.randomNum(0, this.contentHeight)
)
ctx.lineTo(
this.randomNum(0, this.contentWidth),
this.randomNum(0, this.contentHeight)
)
ctx.stroke()
}
},
drawDot(ctx) {
// 绘制干扰点
for (let i = 0; i < 10; i++) {
ctx.fillStyle = this.randomColor(0, 255)
ctx.beginPath()
ctx.arc(
this.randomNum(0, this.contentWidth),
this.randomNum(0, this.contentHeight),
1,
0,
2 * Math.PI
)
ctx.fill()
}
},
},
watch: {
identifyCode() {
this.drawPic()
},
},
mounted() {
this.drawPic()
},
}
</script>
\ No newline at end of file
<template>
<div>
<!-- Liukexin 20210305 添加标题重置密码 -->
<div class="login-card-productName">重置密码</div>
<div class="login-message-panel">
<div
class="login-message"
:class="{ success: isSuccess, error: isError }"
>
<span>{{ message }}</span>
</div>
</div>
<!-- Liukexin 20210305 调整表单域标签的位置 ,会置于表单域顶部。-->
<Form
label-position="top"
:model="pwdData"
class="fromClass"
:rules="pwdValidate"
ref="userForm"
>
<Row class="login-form-item">
<iCol span="24">
<FormItem label="新密码" prop="newPwd"> <!--LiuKexin 20210305 去除:-->
<iInput
v-model.trim="pwdData.newPwd"
type="password"
placeholder="请输入密码"
style="width: 100%"
></iInput>
</FormItem>
</iCol>
</Row>
<Row class="login-form-item">
<iCol span="24">
<FormItem label="确认密码" prop="confirmPwd"> <!--LiuKexin 20210305 去除:-->
<iInput
v-model.trim="pwdData.confirmPwd"
type="password"
placeholder="请输入确认密码"
style="width: 100%"
></iInput>
</FormItem>
</iCol>
</Row>
<Row class="Savebutton">
<Button type="primary" @click="updatePwd" style="width: 100%"
><Icon custom="fa fa-fw fa-save"></Icon>保存</Button
>
</Row>
</Form>
</div>
</template>
<script>
import { update, verifyPassword } from '@/api/login'
// import { sm2 } from 'sm-crypto'
import 'iview/dist/styles/iview.css'
export default {
name: '',
props: {
formData: {
type: Object,
},
},
data() {
const validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('密码不能为空'))
} else {
verifyPassword({ password: value }).then((res) => {
if (res.data && res.data.state === 'ok') {
callback()
} else {
callback(new Error(res.data.msg))
}
})
}
}
const confirmPwd = (rule, value, callback) => {
if (value === '') {
callback(new Error('确认密码不能为空'))
} else if (this.pwdData.newPwd != value) {
callback(new Error('两次密码不一致'))
} else {
callback()
}
}
return {
message: '',
isSuccess: false,
isError: false,
confirmPwdMsg: false,
confirmMsg: '',
newMsg: '',
pwdData: {
newPwd: '',
confirmPwd: '',
},
pwdValidate: {
newPwd: [
{
required: true,
message: '密码不能为空',
trigger: 'blur',
},
{ validator: validatePass, trigger: 'blur' },
],
confirmPwd: [
{
required: true,
message: '确认密码不能为空',
trigger: 'blur',
},
{
validator: confirmPwd,
trigger: 'blur',
},
],
},
}
},
methods: {
//修改密码
updatePwd() {
this.isSuccess = false
this.isError = false
this.$refs.userForm.validate((valid) => {
if (!valid) {
return false
} else {
update(this.formData.username, this.pwdData.newPwd)
.then((res) => {
if (res.data.state === 'ok') {
let href =
this.formData.callback + '?token=' + this.formData.token
document.location.href = href
this.setSuccess()
} else {
this.setError(res.data.msg ? res.data.msg : '修改失败')
}
})
.catch(() => {
this.setError('修改失败')
})
}
})
},
// encrypt(data) {
// let publicKey =
// '04272a7c8997d9883078acc011f450f88d54fdbbd6ddab950d7856a565182aad7e0b5da415f50e1d4433c2b633752dfa3bc04de879311091361db05584d972ff06'
// return sm2.doEncrypt(data, publicKey, 0)
// },
// encrypt(data) {
// let publicKey =
// '04272a7c8997d9883078acc011f450f88d54fdbbd6ddab950d7856a565182aad7e0b5da415f50e1d4433c2b633752dfa3bc04de879311091361db05584d972ff06'
// return sm2.doEncrypt(data, publicKey, 0)
// },
setSuccess(msg = '修改成功') {
this.message = msg
this.isSuccess = true
this.isError = false
},
setError(msg = '修改失败') {
this.message = msg
this.isSuccess = false
this.isError = true
},
},
}
</script>
<style scoped>
.login-message {
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
}
/**LiuKexin 20210305 '重置密码'样式 */
.login-card-productName {
font-size: 18px;
color: #000000;
text-align: center;
font-family: 'Microsoft YaHei';
}
/**LiuKexin 20210305 设置表单样式 */
.login-form-item{
padding-bottom: 8px;
height: 72px;
}
/**LiuKexin 20210305 保存按钮样式 */
.Savebutton{
height: 32px;
margin-top:48px;
}
</style>
import CryptoJS from 'crypto-js/crypto-js'
// 默认的 KEY 与 iv 如果没有给
const KEY = CryptoJS.enc.Utf8.parse("1234567890123456");
const IV = CryptoJS.enc.Utf8.parse('1234567890123456');
/**
* AES加密 :字符串 key iv 返回base64
*/
export function Encrypt(word, keyStr, ivStr) {
let key = KEY;
let iv = IV;
if (keyStr) {
key = CryptoJS.enc.Utf8.parse(keyStr);
iv = CryptoJS.enc.Utf8.parse(ivStr);
}
let srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
});
return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}
/**
* AES 解密 :字符串 key iv 返回base64
*
* @return {string}
*/
export function Decrypt(word, keyStr, ivStr) {
let key = KEY;
let iv = IV;
if (keyStr) {
key = CryptoJS.enc.Utf8.parse(keyStr);
iv = CryptoJS.enc.Utf8.parse(ivStr);
}
let base64 = CryptoJS.enc.Base64.parse(word);
let src = CryptoJS.enc.Base64.stringify(base64);
let decrypt = CryptoJS.AES.decrypt(src, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
});
let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
This diff is collapsed.
/*
* @Author: dongchaoguang
* @Date: 2021-09-10 12:12:59
* @LastEditors: dongchaoguang
* @LastEditTime: 2021-11-08 11:46:49
* @Description: file content
* @FilePath: \aserver-ui-15-nojc\vue.config.js
*/
const path = require('path')
const resolve = dir => {
return path.join(__dirname, dir)
}
// jc_sqjz/dzjz/aserver
const PUBLIC_PATH = process.env.NODE_ENV === 'production' ? '/' : '/'
module.exports = {
publicPath: PUBLIC_PATH,
// publicPath: '/aserver',
chainWebpack: config => {
config.resolve.alias
.set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components'))
.set('_c', resolve('src/components'))
config.module
.rule('iview')
.test(/iview.src.*?js$/)
.use('babel')
.loader('babel-loader')
.end()
},
transpileDependencies:[
'iview'
],
pages: {
index: {
// page 的入口
entry: 'src/main.js',
// 模板来源
template: 'public/index.html',
// 在 dist/index.html 的输出
filename: 'index.html',
// 当使用 title 选项时,
// template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
title: '基础服务',
// 在这个页面中包含的块,默认情况下会包含
// 提取出来的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
login: {
entry: 'src/main-login.js',
template: 'public/login.html',
filename: 'login.html',
tilte: '登录'
},
},
productionSourceMap: false,
devServer: {
proxy: {
'/aserver': {
target: 'http://localhost:11048/'
}
},
}
}
\ No newline at end of file
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