update 增加用户个人信息管理的功能
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
"vue": "^2.6.11",
|
||||
"vue-awesome-swiper": "^4.1.1",
|
||||
"vue-color": "^2.8.1",
|
||||
"vue-cropper": "^0.5.6",
|
||||
"vue-highlight.js": "^3.1.0",
|
||||
"vue-router": "^3.5.1"
|
||||
},
|
||||
|
||||
@@ -1,10 +1,39 @@
|
||||
@import (reference) '~@/assets/style/extend.less';
|
||||
@container-width: 1400px;
|
||||
.container {
|
||||
width: @container-width;
|
||||
.container-base {
|
||||
margin: 0 auto;
|
||||
padding: 0 @padding-md;
|
||||
}
|
||||
.container-fluid {
|
||||
padding: 0 @padding-md;
|
||||
.container {
|
||||
width: @container-width;
|
||||
|
||||
.container-base();
|
||||
}
|
||||
@media (max-width: 1400px) {
|
||||
.container {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
.container-md {
|
||||
width: @container-width - 200px;
|
||||
|
||||
.container-base();
|
||||
}
|
||||
.container-sm {
|
||||
width: @container-width - 400px;
|
||||
|
||||
.container-base();
|
||||
}
|
||||
.container-xs {
|
||||
width: @container-width - 600px;
|
||||
|
||||
.container-base();
|
||||
}
|
||||
.container-xxs {
|
||||
width: @container-width - 700px;
|
||||
|
||||
.container-base();
|
||||
}
|
||||
.container-fluid {
|
||||
.container-base();
|
||||
}
|
||||
|
||||
@@ -136,6 +136,13 @@
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.yo-form--short {
|
||||
.ant-form-item-control-wrapper {
|
||||
flex: 0 0 38.2%;
|
||||
|
||||
width: 38.2%;
|
||||
}
|
||||
}
|
||||
.ant-form-explain {
|
||||
font-size: @font-size-base - 1px;
|
||||
|
||||
|
||||
@@ -1,23 +1,9 @@
|
||||
import { api } from '@/common/api'
|
||||
import { token } from '@/common/token'
|
||||
import { GLOBAL_INFO_KEY } from '@/common/storage'
|
||||
import { encryptByDES, decryptByDES } from '@/util/des'
|
||||
import { removeGlobal } from '@/util/global'
|
||||
import app from '@/main'
|
||||
|
||||
const setGlobal = (info) => {
|
||||
app.$set(app.global, 'info', info)
|
||||
window.sessionStorage.setItem(GLOBAL_INFO_KEY, encryptByDES(JSON.stringify(info)))
|
||||
}
|
||||
|
||||
const removeGlobal = () => {
|
||||
app.$set(app.global, 'info', undefined)
|
||||
window.sessionStorage.removeItem(GLOBAL_INFO_KEY)
|
||||
}
|
||||
|
||||
const getGlobal = () => {
|
||||
return JSON.parse(decryptByDES(window.sessionStorage.getItem(GLOBAL_INFO_KEY)))
|
||||
}
|
||||
|
||||
const doLogin = (args) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
api.login(args).then(({ success, data, message }) => {
|
||||
@@ -72,7 +58,4 @@ const doLogout = () => {
|
||||
export {
|
||||
doLogin,
|
||||
doLogout,
|
||||
|
||||
setGlobal,
|
||||
getGlobal
|
||||
}
|
||||
@@ -17,13 +17,27 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
watch: {
|
||||
async id() {
|
||||
this.src = await this.getSrc()
|
||||
}
|
||||
},
|
||||
|
||||
async created() {
|
||||
if (this.id) {
|
||||
this.$api.sysFileInfoPreview({ id: this.id }).then(async ({ data }) => {
|
||||
this.src = await this.getSrc()
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
getSrc() {
|
||||
return this.$api.sysFileInfoPreview({ id: this.id }).then(async ({ data }) => {
|
||||
const base64 = await ArrayBufferToBase64(data)
|
||||
this.src = base64
|
||||
return base64
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
render() {
|
||||
|
||||
35
Web/src/pages/account/index.vue
Normal file
35
Web/src/pages/account/index.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<container>
|
||||
<br />
|
||||
<a-anchor
|
||||
:get-container="()=> $el.parentNode"
|
||||
:offset-top="16"
|
||||
:wrapper-style="{ backgroundColor: 'transparent' }"
|
||||
>
|
||||
<a-anchor-link
|
||||
:href="`#account-${key}`"
|
||||
:key="key"
|
||||
:title="nav.title"
|
||||
v-for="(nav, key) in navs"
|
||||
/>
|
||||
</a-anchor>
|
||||
|
||||
<section :id="`account-${key}`" :key="key" v-for="(nav, key) in navs">
|
||||
<component :is="nav.component" v-if="nav.component" />
|
||||
</section>
|
||||
</container>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
navs: {
|
||||
0: {
|
||||
title: '我的信息',
|
||||
component: () => import('./setting/info'),
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
254
Web/src/pages/account/setting/info.vue
Normal file
254
Web/src/pages/account/setting/info.vue
Normal file
@@ -0,0 +1,254 @@
|
||||
<template>
|
||||
<container mode="container-xxs">
|
||||
<a-form-model class="yo-form">
|
||||
<h4>我的信息</h4>
|
||||
<div class="yo-avatar-info">
|
||||
<yo-image :id="form.avatar" :size="128" icon="user" type="avatar" />
|
||||
<div @click="avatar.cropper = true" class="yo-avatar-info--cover">
|
||||
<a-icon type="cloud-upload-o" />
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<a-card :key="avatar.key" v-if="avatar.cropper">
|
||||
<a-alert type="error">
|
||||
<template slot="message">上传完成时无法被销毁</template>
|
||||
</a-alert>
|
||||
<br />
|
||||
<a-row :gutter="16" align="middle" type="flex">
|
||||
<a-col :span="12">
|
||||
<div class="yo-avatar-cropper">
|
||||
<vue-cropper
|
||||
:auto-crop-height="avatar.autoWidth"
|
||||
:auto-crop-width="avatar.autoHeight"
|
||||
:img="avatar.img"
|
||||
@real-time="(data) => avatar.preview = data"
|
||||
auto-crop
|
||||
fixed-box
|
||||
info
|
||||
ref="cropper"
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<div class="yo-avatar-preview" v-html="avatar.preview.html"></div>
|
||||
</a-col>
|
||||
<a-col :span="12" class="mt-md text-center">
|
||||
<a-upload
|
||||
:before-upload="onBeforeUpload"
|
||||
:show-upload-list="false"
|
||||
class="mr-xs"
|
||||
name="file"
|
||||
>
|
||||
<a-button icon="picture" type="primary">选择图片</a-button>
|
||||
</a-upload>
|
||||
<a-button-group>
|
||||
<a-button @click="$refs.cropper.changeScale(1)" icon="zoom-in" />
|
||||
<a-button @click="$refs.cropper.changeScale(-1)" icon="zoom-out" />
|
||||
<a-button @click="$refs.cropper.rotateLeft()" icon="undo" />
|
||||
<a-button @click="$refs.cropper.rotateRight()" icon="redo" />
|
||||
</a-button-group>
|
||||
</a-col>
|
||||
<a-col :span="12" class="mt-md text-center">
|
||||
<a-button
|
||||
:loading="avatar.uploading"
|
||||
@click="onAvatarOk"
|
||||
class="mr-xs"
|
||||
icon="check"
|
||||
type="primary"
|
||||
>确认</a-button>
|
||||
<a-button @click="avatar.cropper = false" icon="close">取消</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
|
||||
<div class="yo-form-group yo-form--short">
|
||||
<a-form-model-item label="昵称">
|
||||
<a-input placeholder="请输入昵称" v-model="form.nickName" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="用户名">
|
||||
<span>{{ form.name }}</span>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="生日">
|
||||
<a-date-picker
|
||||
@change="(date) => form.birthday = date ? $moment(date).format('YYYY-MM-DD') : null"
|
||||
class="w-100-p"
|
||||
placeholder="请选择生日"
|
||||
v-model="form.birthday"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="性别" prop="sex">
|
||||
<a-radio-group v-model="form.sex">
|
||||
<a-radio-button :value="0">
|
||||
<a-icon type="stop" />
|
||||
<span>保密</span>
|
||||
</a-radio-button>
|
||||
<a-radio-button :value="1">
|
||||
<a-icon :style="{ color: '#1890ff' }" type="man" />
|
||||
<span>男</span>
|
||||
</a-radio-button>
|
||||
<a-radio-button :value="2">
|
||||
<a-icon :style="{ color: '#eb2f96' }" type="woman" />
|
||||
<span>女</span>
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="电话" prop="tel">
|
||||
<a-input placeholder="请输入电话" v-model="form.tel" />
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
|
||||
<a-button :loading="saving" @click="onSaveInfo" block>更新个人信息</a-button>
|
||||
</a-form-model>
|
||||
</container>
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
@import (reference) '~@/assets/style/extend.less';
|
||||
.yo-avatar-info {
|
||||
position: relative;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
width: 128px;
|
||||
margin: 0 auto;
|
||||
|
||||
border-radius: 50%;
|
||||
&--cover {
|
||||
font-size: @font-size-lg * 2;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
cursor: pointer;
|
||||
transition: @animation-duration-slow;
|
||||
|
||||
opacity: 0;
|
||||
color: @white;
|
||||
background-color: fade(@black, 50%);
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.yo-avatar-cropper {
|
||||
min-width: 240px;
|
||||
height: 240px;
|
||||
|
||||
widows: 100%;
|
||||
}
|
||||
.yo-avatar-preview {
|
||||
overflow: hidden;
|
||||
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 0 auto;
|
||||
|
||||
border-radius: 50%;
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
import { BlobToFile } from '@/util/file';
|
||||
import { setGlobal } from '@/util/global';
|
||||
|
||||
import { VueCropper } from 'vue-cropper';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VueCropper,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
|
||||
avatar: {
|
||||
key: Date.now(),
|
||||
cropper: false,
|
||||
img: '',
|
||||
autoWidth: 200,
|
||||
autoHeight: 200,
|
||||
|
||||
uploading: false,
|
||||
|
||||
preview: {},
|
||||
file: null,
|
||||
},
|
||||
|
||||
saving: false,
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
'avatar.cropper'(value) {
|
||||
if (value) {
|
||||
this.avatar.key = Date.now();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.form = this.$_.cloneDeep(this.$root.global.info);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onRefreshInfo() {
|
||||
return this.$api.getLoginUser().then(async ({ data }) => {
|
||||
// 去除应用和菜单信息,存储基本信息
|
||||
const info = this.$_.cloneDeep(data);
|
||||
delete info.apps;
|
||||
delete info.menus;
|
||||
setGlobal(info);
|
||||
|
||||
this.form = this.$_.cloneDeep(this.$root.global.info);
|
||||
});
|
||||
},
|
||||
|
||||
onBeforeUpload(file) {
|
||||
this.avatar.file = file;
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
this.avatar.img = reader.result;
|
||||
};
|
||||
return false;
|
||||
},
|
||||
|
||||
onAvatarOk() {
|
||||
this.avatar.uploading = true;
|
||||
this.$refs.cropper.getCropBlob(async (data) => {
|
||||
try {
|
||||
const file = BlobToFile(data, this.avatar.file.name, this.avatar.file.type);
|
||||
const fd = new FormData();
|
||||
fd.append('file', file);
|
||||
const { data: fileId } = await this.$api.sysFileInfoUpload(fd);
|
||||
this.form.avatar = fileId;
|
||||
|
||||
this.avatar.cropper = false;
|
||||
} finally {
|
||||
this.avatar.uploading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async onSaveInfo() {
|
||||
this.saving = true;
|
||||
try {
|
||||
await this.$api.sysUserUpdateInfo(this.form);
|
||||
await this.onRefreshInfo();
|
||||
this.$message.success('更新个人信息成功');
|
||||
} finally {
|
||||
this.saving = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,7 +0,0 @@
|
||||
<template>
|
||||
<container>
|
||||
<a-row :gutter="16">
|
||||
<a-col></a-col>
|
||||
</a-row>
|
||||
</container>
|
||||
</template>
|
||||
@@ -1,79 +0,0 @@
|
||||
<template>
|
||||
<container>
|
||||
<br />
|
||||
|
||||
<a-form-model class="yo-form yo-form--fixed">
|
||||
<h3>输入框</h3>
|
||||
<Input />
|
||||
<h3>数字输入框</h3>
|
||||
<div class="yo-form-group">
|
||||
<a-form-model-item label="数字输入框">
|
||||
<span slot="help">
|
||||
<a-tag color="pink">a-input-number</a-tag>可以输入和选择数字
|
||||
</span>
|
||||
<a-input-number autocomplete="off" placeholder="请输入数字" />
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
<h3>文本域</h3>
|
||||
<div class="yo-form-group">
|
||||
<a-form-model-item label="文本域">
|
||||
<a-textarea autocomplete="off" placeholder="请输入文字" />
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
<h3>提及</h3>
|
||||
<div class="yo-form-group">
|
||||
<a-form-model-item label="提及">
|
||||
<a-mentions placeholder="请输入'@'进行提及">
|
||||
<a-mentions-option value="史莱姆">史莱姆</a-mentions-option>
|
||||
<a-mentions-option value="哥布林">哥布林</a-mentions-option>
|
||||
<a-mentions-option value="牛头人">牛头人</a-mentions-option>
|
||||
</a-mentions>
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
<h3>单选框</h3>
|
||||
<div class="yo-form-group">
|
||||
<a-form-model-item label="单选框">
|
||||
<span slot="help">
|
||||
<a-tag color="pink">a-radio-group > a-radio</a-tag>横排的单选框。请注意,因为控件区域宽度的限制,在这里无法使用单选框按钮
|
||||
</span>
|
||||
<a-radio-group>
|
||||
<a-radio value="1">攻击</a-radio>
|
||||
<a-radio value="2">防御</a-radio>
|
||||
<a-radio value="3">剑技</a-radio>
|
||||
<a-radio value="4">魔法</a-radio>
|
||||
<a-radio value="5">回复</a-radio>
|
||||
<a-radio value="6">虐杀</a-radio>
|
||||
<a-radio value="7">踩在脚下</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item class="yo-form--vertical yo-form--vertical-radio" label="垂直单选框">
|
||||
<span slot="help">
|
||||
垂直单选框,需要在垂直布局控件的基础上,添加类
|
||||
<a-tag color="pink">.yo-form--vertical-radio</a-tag>
|
||||
</span>
|
||||
<a-radio-group>
|
||||
<a-radio value="1">攻击</a-radio>
|
||||
<a-radio value="2">防御</a-radio>
|
||||
<a-radio value="3">剑技</a-radio>
|
||||
<a-radio value="4">魔法</a-radio>
|
||||
<a-radio value="5">回复</a-radio>
|
||||
<a-radio value="6">虐杀</a-radio>
|
||||
<a-radio value="7">踩在脚下</a-radio>
|
||||
<a-radio value="8">
|
||||
<a-input />
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
</a-form-model>
|
||||
</container>
|
||||
</template>
|
||||
<script>
|
||||
import Input from './yo/Input';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Input,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<div class="yo-form-group">
|
||||
<a-form-model-item label="输入框">
|
||||
<a-input autocomplete="off" placeholder="请输入文字" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="只读输入框">
|
||||
<a-input autocomplete="off" placeholder="请输入文字" readonly />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="前缀和后缀">
|
||||
<a-input addon-after="后缀" addon-before="前缀" autocomplete="off" placeholder="请输入文字" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="输入框组">
|
||||
<a-input-group compact>
|
||||
<a-input style="width: 40%" />
|
||||
<a-input style="width: 60%" />
|
||||
</a-input-group>
|
||||
<a-input-group>
|
||||
<a-row :gutter="8">
|
||||
<a-col :span="10">
|
||||
<a-input />
|
||||
</a-col>
|
||||
<a-col :span="14">
|
||||
<a-input />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-input-group>
|
||||
<a-input-group>
|
||||
<a-row type="flex">
|
||||
<a-col flex="120px">
|
||||
<a-select default-value="Zhejiang">
|
||||
<a-select-option value="Zhejiang">Zhejiang</a-select-option>
|
||||
<a-select-option value="Jiangsu">Jiangsu</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
<a-col flex="auto">
|
||||
<a-input default-value="Xihu District, Hangzhou" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-input-group>
|
||||
<a-input-group compact>
|
||||
<a-select default-value="1">
|
||||
<a-select-option value="1">Between</a-select-option>
|
||||
<a-select-option value="2">Except</a-select-option>
|
||||
</a-select>
|
||||
<a-input placeholder="Minimum" style=" width: 100px; text-align: center" />
|
||||
<a-input
|
||||
disabled
|
||||
placeholder="~"
|
||||
style=" width: 30px; border-left: 0; pointer-events: none; backgroundColor: transparent"
|
||||
/>
|
||||
<a-input placeholder="Maximum" style=" width: 100px; text-align: center; border-left: 0" />
|
||||
</a-input-group>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item class="yo-form--vertical" label="上下布局">
|
||||
<span slot="help">
|
||||
上下布局,请在
|
||||
<a-tag color="pink">a-form-model-item</a-tag>上添加类
|
||||
<a-tag color="pink">.yo-form--vertical</a-tag>
|
||||
</span>
|
||||
<a-input autocomplete="off" placeholder="请输入文字" />
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,146 +0,0 @@
|
||||
<template>
|
||||
<container>
|
||||
<br />
|
||||
<a-card :bordered="false">
|
||||
<div class="yo-query-bar">
|
||||
<a-form-model :model="query" layout="inline">
|
||||
<a-form-model-item label="区域">
|
||||
<a-select :style="{ width: '100px' }" v-model="query.area">
|
||||
<a-select-option value="宁波市">宁波市</a-select-option>
|
||||
</a-select>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="年份">
|
||||
<a-select :style="{ width: '100px' }" v-model="query.year">
|
||||
<a-select-option value="2020">2020</a-select-option>
|
||||
<a-select-option value="2021">2021</a-select-option>
|
||||
</a-select>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item>
|
||||
<a-button html-type="submit" type="primary">查询</a-button>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</div>
|
||||
|
||||
<a-table
|
||||
:bordered="true"
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
:pagination="{ pageSize: 20}"
|
||||
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
|
||||
>
|
||||
<div class="yo-action-bar" slot="title">
|
||||
<div class="yo-action-bar--actions">
|
||||
<a-button>Button</a-button>
|
||||
<a-button>Button</a-button>
|
||||
<a-button :disabled="true">Button</a-button>
|
||||
<a-button>Button</a-button>
|
||||
<a-button-group>
|
||||
<a-button>Button</a-button>
|
||||
<a-button>Button</a-button>
|
||||
<a-button>Button</a-button>
|
||||
</a-button-group>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1">1st item</a-menu-item>
|
||||
<a-menu-item key="2">2nd item</a-menu-item>
|
||||
<a-menu-item key="3">3rd item</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
Actions
|
||||
<a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-dropdown-button>
|
||||
Dropdown
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1">
|
||||
<a-icon type="user" />1st menu item
|
||||
</a-menu-item>
|
||||
<a-menu-item key="2">
|
||||
<a-icon type="user" />2nd menu item
|
||||
</a-menu-item>
|
||||
<a-menu-item key="3">
|
||||
<a-icon type="user" />3rd item
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-table>
|
||||
</a-card>
|
||||
<br />
|
||||
</container>
|
||||
</template>
|
||||
<script>
|
||||
const _data = [
|
||||
{
|
||||
area: '海曙区',
|
||||
title: '曙光电影院地块',
|
||||
count: 13,
|
||||
date: '2021-01-01',
|
||||
},
|
||||
{
|
||||
area: '江北区',
|
||||
title: '大庆新村地块旧城区改建项目',
|
||||
count: 322,
|
||||
date: '2021-01-01',
|
||||
},
|
||||
{
|
||||
area: '宁海县',
|
||||
title: '桥头胡街道旧城区改造华驰文教地块',
|
||||
count: 1,
|
||||
date: '2021-01-01',
|
||||
},
|
||||
{
|
||||
area: '慈溪市',
|
||||
title: '七二三南延道路工程',
|
||||
count: 1,
|
||||
date: '2021-01-01',
|
||||
},
|
||||
{
|
||||
area: '北仑区',
|
||||
title: '原粮食局宿舍楼1号、2号楼(太河路北延工程)',
|
||||
count: 32,
|
||||
date: '2021-01-01',
|
||||
},
|
||||
];
|
||||
|
||||
const data = Object.assign([], _data, _data, _data);
|
||||
data.map((p, i) => (p.key = 'abcdefghijklmnopqrstuvwxyz'[i]));
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
area: '宁波市',
|
||||
year: '2021',
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: '区域',
|
||||
dataIndex: 'area',
|
||||
},
|
||||
{
|
||||
title: '项目名称',
|
||||
dataIndex: 'title',
|
||||
},
|
||||
{
|
||||
title: '户数',
|
||||
dataIndex: 'count',
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'date',
|
||||
},
|
||||
],
|
||||
data,
|
||||
selectedRowKeys: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSelectChange(selectedRowKeys) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,6 +1,54 @@
|
||||
<template>
|
||||
<a-card :bordered="false" class="mb-none">
|
||||
<container>
|
||||
<a-row :gutter="16" align="middle" class="text-center mb-lg" justify="center" type="flex">
|
||||
<a-col :span="4" class="mt-lg mb-lg">
|
||||
<a href="https://dotnet.microsoft.com/" target="_blank">
|
||||
<img
|
||||
src="https://dotnet.microsoft.com/static/images/redesign/downloads-dot-net-core.svg?v=p6MWQNHwEtnnx0MWJ-i7vCMt-sZmoBf6h-7XmdSs5RE"
|
||||
width="128"
|
||||
/>
|
||||
</a>
|
||||
</a-col>
|
||||
<a-col :span="4" class="mt-lg mb-lg">
|
||||
<a href="https://dotnetchina.gitee.io/furion/" target="_blank">
|
||||
<img src="https://dotnetchina.gitee.io/furion/img/furionlogo.png" width="128" />
|
||||
</a>
|
||||
</a-col>
|
||||
<a-col :span="4" class="mt-lg mb-lg">
|
||||
<a href="https://cn.vuejs.org/index.html" target="_blank">
|
||||
<img src="https://cn.vuejs.org/images/logo.png" width="128" />
|
||||
</a>
|
||||
</a-col>
|
||||
<a-col :span="4" class="mt-lg mb-lg">
|
||||
<a href="https://www.antdv.com/docs/vue/introduce" target="_blank">
|
||||
<img src="https://pro.antdv.com/logo.png" width="128" />
|
||||
</a>
|
||||
</a-col>
|
||||
<a-col :span="4" class="mt-lg mb-lg">
|
||||
<a href="https://echarts.apache.org/zh/index.html" target="_blank">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/zh/images/favicon.png"
|
||||
width="128"
|
||||
/>
|
||||
</a>
|
||||
</a-col>
|
||||
<a-col :span="4" class="mt-lg mb-lg">
|
||||
<a href="http://lesscss.cn/" target="_blank">
|
||||
<img src="http://s.nodejs.cn/less/img/logo.png" width="128" />
|
||||
</a>
|
||||
</a-col>
|
||||
<a-col :span="4" class="mt-lg mb-lg">
|
||||
<a href="https://www.lodashjs.com/" target="_blank">
|
||||
<img src="https://www.lodashjs.com/img/lodash.png" width="128" />
|
||||
</a>
|
||||
</a-col>
|
||||
<a-col :span="4" class="mt-lg mb-lg">
|
||||
<a href="http://www.axios-js.com/zh-cn/" target="_blank">
|
||||
<img src="http://www.axios-js.com/logo.svg" width="128" />
|
||||
</a>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" type="flex">
|
||||
<a-col flex="auto">
|
||||
<container
|
||||
|
||||
@@ -8,3 +8,22 @@ export const EMPTY_ID = '00000000-0000-0000-0000-000000000000'
|
||||
*/
|
||||
import { urls } from '@/common/api'
|
||||
export const PERVIEW_URL = process.env.VUE_APP_BASE_URL + urls.sysFileInfoPreview[0]
|
||||
|
||||
|
||||
/**
|
||||
* 全局信息设置
|
||||
*/
|
||||
import app from '@/main'
|
||||
import { GLOBAL_INFO_KEY } from '@/common/storage'
|
||||
import { encryptByDES, decryptByDES } from '@/util/des'
|
||||
export const setGlobal = (info) => {
|
||||
app.$set(app.global, 'info', info)
|
||||
window.sessionStorage.setItem(GLOBAL_INFO_KEY, encryptByDES(JSON.stringify(info)))
|
||||
}
|
||||
export const removeGlobal = () => {
|
||||
app.$set(app.global, 'info', undefined)
|
||||
window.sessionStorage.removeItem(GLOBAL_INFO_KEY)
|
||||
}
|
||||
export const getGlobal = () => {
|
||||
return JSON.parse(decryptByDES(window.sessionStorage.getItem(GLOBAL_INFO_KEY)))
|
||||
}
|
||||
@@ -35,7 +35,13 @@
|
||||
>关闭右侧标签页</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown>
|
||||
<component :is="pane.component" :key="pane.key" :param="pane.param" v-if="pane.loaded" />
|
||||
<component
|
||||
:is="pane.component"
|
||||
:key="pane.key"
|
||||
:param="pane.param"
|
||||
ref="panes"
|
||||
v-if="pane.loaded"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-content>
|
||||
@@ -75,6 +81,14 @@ export default {
|
||||
onLoadContentWindow(key) {
|
||||
NProgress.start();
|
||||
const pane = this.panes.find((p) => p.key === key);
|
||||
|
||||
// 打开之前先销毁
|
||||
const index = this.panes.indexOf(pane);
|
||||
const component = this.$refs.panes && this.$refs.panes[index];
|
||||
if (component) {
|
||||
component.$destroy();
|
||||
}
|
||||
|
||||
const i = import(`@/pages${pane.path}`);
|
||||
pane.component = () => i;
|
||||
pane.loaded = false;
|
||||
|
||||
@@ -34,6 +34,15 @@ export default {
|
||||
}, 300)
|
||||
},
|
||||
|
||||
onAccountSetting() {
|
||||
this.openContentWindow({
|
||||
key: 'account-home',
|
||||
title: '个人中心',
|
||||
icon: 'user',
|
||||
path: '/account'
|
||||
})
|
||||
},
|
||||
|
||||
onLogout() {
|
||||
this.$confirm({
|
||||
title: '提示',
|
||||
@@ -64,6 +73,10 @@ export default {
|
||||
</div>
|
||||
<div class="user--dropdown" ref="dropdown" style={{ height: `${this.dropdownHeight}px` }}>
|
||||
<ul class="ant-dropdown-menu ant-dropdown-menu-vertical">
|
||||
<li class="ant-dropdown-menu-item" onClick={this.onAccountSetting}>
|
||||
<a-icon type="user" />
|
||||
个人中心
|
||||
</li>
|
||||
<li class="ant-dropdown-menu-item-divider"></li>
|
||||
<li class="ant-dropdown-menu-item" onClick={this.onLogout}>
|
||||
<a-icon type="logout" />
|
||||
|
||||
@@ -35,9 +35,7 @@ import Content from './_layout/content';
|
||||
|
||||
import Setting from './setting';
|
||||
|
||||
import { setGlobal } from '@/common/login';
|
||||
|
||||
import { EMPTY_ID } from '@/util/global';
|
||||
import { EMPTY_ID, setGlobal } from '@/util/global';
|
||||
|
||||
const getNewID = () => {
|
||||
return Math.random().toString(16).slice(2);
|
||||
|
||||
@@ -8518,6 +8518,11 @@ vue-color@^2.8.1:
|
||||
material-colors "^1.0.0"
|
||||
tinycolor2 "^1.1.2"
|
||||
|
||||
vue-cropper@^0.5.6:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.npm.taobao.org/vue-cropper/download/vue-cropper-0.5.6.tgz?cache=0&sync_timestamp=1608604834259&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-cropper%2Fdownload%2Fvue-cropper-0.5.6.tgz#a38c98d402da1421bd5e7535e16b9723f103cafd"
|
||||
integrity sha1-o4yY1ALaFCG9XnU14WuXI/EDyv0=
|
||||
|
||||
vue-eslint-parser@^7.0.0:
|
||||
version "7.6.0"
|
||||
resolved "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-7.6.0.tgz#01ea1a2932f581ff244336565d712801f8f72561"
|
||||
|
||||
Reference in New Issue
Block a user