地球页面静态资源提交

This commit is contained in:
zhulongchuan 2025-09-23 18:33:18 +08:00
parent 1afa25da70
commit 6b4cb11ead
28 changed files with 3721 additions and 996 deletions

View File

@ -26,6 +26,7 @@
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.28.1",
"cesium": "^1.105.0",
"clipboard": "2.0.8",
"core-js": "^3.37.1",
"echarts": "5.4.0",
@ -47,7 +48,11 @@
"vue-cropper": "0.5.5",
"vue-router": "3.4.9",
"vuedraggable": "2.24.3",
"vuex": "3.6.0"
"vuex": "3.6.0",
"uuid": "^9.0.0",
"yarn": "^1.22.22",
"qrcode": "^1.5.3",
"qrcodejs2-fix": "^0.0.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.6",

226
public/geojson/config.json Normal file
View File

@ -0,0 +1,226 @@
{
"map3d": {
"scene": {
"center": {
"lat": 29.566644,
"lng": 106.54664,
"alt": 15800,
"heading": 360,
"pitch": -90
},
"scene3DOnly": false,
"shadows": false,
"removeDblClick": true,
"sceneMode": 3,
"showSun": true,
"showMoon": true,
"showSkyBox": true,
"showSkyAtmosphere": true,
"fog": true,
"fxaa": true,
"requestRenderMode": true,
"globe": {
"depthTestAgainstTerrain": false,
"baseColor": "#546a53",
"showGroundAtmosphere": true,
"enableLighting": false
},
"cameraController": {
"zoomFactor": 3.0,
"minimumZoomDistance": 1,
"maximumZoomDistance": 50000000,
"enableRotate": true,
"enableTranslate": true,
"enableTilt": true,
"enableZoom": true,
"enableCollisionDetection": true,
"minimumCollisionTerrainHeight": 15000
}
},
"control": {
"sanweiLayerShow": true,
"mapLayerShow": true,
"toolLayerShow": true,
"homeButton": true,
"baseLayerPicker": true,
"sceneModePicker": true,
"vrButton": false,
"fullscreenButton": false,
"navigationHelpButton": true,
"animation": true,
"timeline": true,
"infoBox": false,
"selectionIndicator": false,
"selectRenderLoopErrors": false,
"geocoder": "gaode",
"geocoderConfig": {
"key": [
"6afde914782b66f0a171b596523d2f9f",
"ae29a37307840c7ae4a785ac905927e0"
]
},
"defaultContextMenu": true,
"contextmenu": { "hasDefault": true },
"mouseDownView": true,
"zoom": { "insertIndex": 1 },
"compass": { "bottom": "325px", "left": "5px" },
"distanceLegend": { "left": "180px", "bottom": "28px" },
"locationBar": {
"fps": true,
"crs": "CGCS2000_GK_Zone_3",
"crsDecimal": 0,
"template": "<div>经度:{lng}</div> <div>纬度:{lat}</div> <div class='hide1000'>横{crsx} 纵{crsy}</div> <div>海拔:{alt}米</div> <div class='hide700'>层级:{level}</div><div>方向:{heading}°</div> <div>俯仰角:{pitch}°</div><div class='hide700'>视高:{cameraHeight}米</div>"
}
},
"templateValues": {
"dataServer": "//data.mars3d.cn",
"gltfServerUrl": "//data.mars3d.cn/gltf"
},
"terrain": {
"url": "//data.mars3d.cn/terrain",
"show": true
},
"basemaps": [
{ "id": 10, "name": "地图底图", "type": "group" },
{
"id": 2021,
"pid": 10,
"name": "天地图影像",
"icon": "/img/basemaps/tdt_img.png",
"type": "group",
"layers": [
{ "name": "底图", "type": "tdt", "layer": "img_d" },
{ "name": "注记", "type": "tdt", "layer": "img_z" }
],
"show": true
},
{
"pid": 10,
"name": "天地图电子",
"icon": "/img/basemaps/tdt_vec.png",
"type": "group",
"layers": [
{ "name": "底图", "type": "tdt", "layer": "vec_d" },
{ "name": "注记", "type": "tdt", "layer": "vec_z" }
]
},
{
"pid": 10,
"name": "高德影像",
"type": "group",
"icon": "/img/basemaps/gaode_img.png",
"layers": [
{ "name": "底图", "type": "gaode", "layer": "img_d" },
{ "name": "注记", "type": "gaode", "layer": "img_z" }
]
},
{
"pid": 10,
"name": "高德电子",
"type": "gaode",
"icon": "/img/basemaps/gaode_vec.png",
"layer": "vec"
},
{
"pid": 10,
"name": "百度影像",
"type": "group",
"icon": "/img/basemaps/bd-img.png",
"layers": [
{ "name": "底图", "type": "baidu", "layer": "img_d" },
{ "name": "注记", "type": "baidu", "layer": "img_z" }
]
},
{
"pid": 10,
"name": "百度电子",
"icon": "/img/basemaps/bd-vec.png",
"type": "baidu",
"layer": "vec"
},
{
"pid": 10,
"name": "腾讯影像",
"icon": "/img/basemaps/tencent_img.png",
"type": "group",
"layers": [
{ "name": "底图", "type": "tencent", "layer": "img_d" },
{ "name": "注记", "type": "tencent", "layer": "img_z" }
]
},
{
"pid": 10,
"name": "腾讯电子",
"icon": "/img/basemaps/tencent_vec.png",
"type": "tencent",
"layer": "vec"
},
{
"pid": 10,
"name": "ArcGIS影像",
"icon": "/img/basemaps/esriWorldImagery.png",
"type": "xyz",
"url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
"enablePickFeatures": false
},
{
"pid": 10,
"name": "微软影像",
"icon": "/img/basemaps/bingAerial.png",
"type": "bing",
"layer": "Aerial"
},
{
"pid": 10,
"name": "OSM地图",
"type": "xyz",
"icon": "/img/basemaps/osm.png",
"url": "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
"subdomains": "abc"
},
{
"id": 2017,
"pid": 10,
"name": "暗色底图",
"type": "gaode",
"icon": "/img/basemaps/blackMarble.png",
"layer": "vec",
"invertColor": true,
"filterColor": "#4e70a6",
"brightness": 0.6,
"contrast": 1.8,
"gamma": 0.3,
"hue": 1,
"saturation": 0
},
{
"pid": 10,
"name": "蓝色底图",
"icon": "/img/basemaps/bd-c-midnight.png",
"type": "xyz",
"url": "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
"chinaCRS": "GCJ02",
"enablePickFeatures": false
},
{
"pid": 10,
"name": "黑色底图",
"icon": "/img/basemaps/bd-c-dark.png",
"type": "tencent",
"layer": "custom",
"style": "4"
}
],
"layers": [
{
"pid": 50,
"name": "行政区划界线",
"type": "tdt",
"url": "https://t{s}.tianditu.gov.cn/DataServer?T=ibo_w&x={x}&y={y}&l={z}",
"maximumLevel": 10,
"mapSplit": false
},
{ "id": 99, "name": "数据图层", "type": "group" }
]
}
}

187
public/geojson/fly.json Normal file
View File

@ -0,0 +1,187 @@
[
{
"id": "1",
"positions": [
[117.220904, 31.833797, 43.75],
[117.220356, 31.833959, 43.67],
[117.220361, 31.835111, 44.36],
[117.213242, 31.835863, 42.31],
[117.211926, 31.835738, 42.14],
[117.183103, 31.833906, 47.17],
[117.183136, 31.833586, 47.39],
[117.183968, 31.833637, 47.05],
[117.184038, 31.833134, 47.39],
[117.184364, 31.833142, 47.26],
[117.184519, 31.833375, 47.04]
],
"style": { "color": "#ffff00", "width": 3 },
"attr": {
"name": "步行贴地路线",
"model": "model_man",
"clampToGround": true,
"interpolation": false,
"showGroundHeight": false,
"showLabel": false,
"showLine": false,
"showShadow": false,
"shadowType": "wall",
"cameraType": "gs",
"followedX": 50,
"followedZ": 10,
"clockLoop": false,
"speed": [50, 50, 50, 50, 50, 50, 50, 50, 50, 50]
}
},
{
"id": "2",
"positions": [
[116.043233, 30.845286, 392.48],
[116.046833, 30.846863, 411.33],
[116.052137, 30.848801, 439.45],
[116.060838, 30.850918, 442.91],
[116.069013, 30.852035, 435.14],
[116.18739, 30.854441, 244.53],
[116.205214, 30.859332, 300.96]
],
"style": { "color": "#ffff00", "width": 3 },
"attr": {
"name": "驾车贴地路线",
"model": "model_car",
"clampToGround": true,
"showGroundHeight": false,
"showLabel": false,
"showLine": true,
"showShadow": false,
"shadowType": "wall",
"cameraType": "gs",
"followedX": 50,
"followedZ": 50,
"clockLoop": false,
"speed": 160
}
},
{
"id": "3",
"positions": [
[117.245989, 31.852285, 100],
[117.246347, 31.834418, 300],
[117.246703, 31.816635, 500]
],
"style": { "color": "#ffff00", "width": 3 },
"attr": {
"name": "飞机飞行投影",
"point": "model_zhanji",
"showLabel": false,
"showLine": true,
"showSection": true,
"cameraType": "gs",
"followedX": 50,
"followedZ": 10,
"remark": "测试",
"showHeightWarn": true,
"warnHeight": 300,
"showShadow": true,
"showGroundHeight": false,
"shadowType": "wall",
"model": "model_zhanji",
"speed": 100
}
},
{
"id": "4",
"positions": [
[117.128256, 31.852721, 600],
[117.163191, 31.853176, 600],
[117.181754, 31.854023, 600]
],
"style": { "color": "#ffff00", "width": 3 },
"attr": {
"name": "飞机飞行投影2",
"model": "model_air",
"showGroundHeight": true,
"showLabel": false,
"showLine": true,
"showShadow": true,
"shadowType": "cylinder",
"cameraType": "gs",
"followedX": 50,
"followedZ": 10,
"clockLoop": false
}
},
{
"id": "5",
"positions": [
[116.025851, 30.848967, 1311.6],
[116.098851, 30.833606, 1916.2],
[116.154079, 30.86119, 1693.3],
[116.171732, 30.927008, 1588.6],
[116.142015, 30.980604, 1963.6],
[116.080821, 31.001745, 2078.7],
[116.022691, 30.965067, 1756.5],
[116.016616, 30.904896, 1573.4]
],
"style": { "color": "#ffff00", "width": 3 },
"attr": {
"name": "山区漫游",
"showLabel": false,
"showLine": false,
"showShadow": false,
"showHeightWarn": false,
"warnHeight": 500,
"cameraType": "dy",
"followedX": 50,
"followedZ": 10,
"speed": 300
}
},
{
"id": "6",
"positions": [
[106.714474, 26.838533, 1303.3],
[106.714448, 26.839618, 1309.4],
[106.714389, 26.840687, 1310.8],
[106.714685, 26.842783, 1295],
[106.715975, 26.846232, 1279.7],
[106.718505, 26.852513, 1278.6]
],
"style": { "color": "#ffff00", "width": 3 },
"attr": {
"name": "园区漫游",
"point": "point",
"showLabel": false,
"showLine": false,
"showShadow": false,
"showHeightWarn": false,
"warnHeight": 500,
"cameraType": "dy",
"followedX": 200,
"followedZ": 50
}
},
{
"id": "7",
"name": "卫星轨道",
"positions": [
[122.167639, 47.692783, 100000],
[110.846366, 36.040396, 100000],
[102.61946, 23.716881, 100000]
],
"style": { "color": "#ffff00", "width": 3 },
"attr": {
"name": "卫星轨道",
"point": "model_weixin",
"showLabel": false,
"showLine": true,
"showShadow": false,
"showHeightWarn": false,
"warnHeight": 500,
"cameraType": "gs",
"followedX": 50,
"followedZ": 10,
"clockLoop": true,
"model": "model_weixin",
"speed": 2000
}
}
]

1893
public/geojson/hefei.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
{
"三维立体类": [
{
"image": "/img/swsq.png",
"type": "circle",
"show": true,
"style": {
"color": "#FF1900",
"opacity": 0.5,
"diffHeight": 36,
"materialType": "RadarWave",
"radius": 234.39,
"rotationDegree": 0,
"materialOptions": {
"color": "#FF1900",
"speed": 5,
"materialType": "RadarWave"
},
"highlight": {
"type": "click",
"opacity": 0.9
}
},
"drawShow": true
},
{
"image": "/img/yuanzhu.png",
"type": "circle",
"show": true,
"style": {
"color": "#ff0000",
"opacity": 0.5,
"diffHeight": 30,
"materialType": "CircleWave",
"radius": 799.82,
"materialOptions": {
"color": "rgba(255,230,35,1)",
"count": 1,
"gradient": 0.1,
"speed": 5,
"materialType": "CircleWave"
},
"highlight": {
"type": "click",
"opacity": 0.9
}
},
"flyToOptions": {
"scale": 5,
"minHeight": 1500,
"maxHeight": 1500,
"pitch": -30,
"roll": -60
},
"drawShow": true
},
{
"name": "反制圈",
"image": "/img/leida.png",
"type": "ellipsoid",
"show": true,
"style": {
"radii_x": 200,
"radii_y": 200,
"radii_z": 200,
"maximumConeDegree": 90,
"color": "rgba(255,0,0,0.3)",
"outline": false,
"outlineColor": "rgba(255,255,255,0.5)",
"materialType": "EllipsoidElectric",
"materialOptions": {
"color": "#3388ff",
"speed": 10,
"materialType": "EllipsoidElectric"
}
},
"flyToOptions": {
"scale": 5,
"minHeight": 800,
"maxHeight": 3000,
"pitch": -30,
"roll": -60
},
"drawShow": true
}
]
}

84
public/geojson/layer.json Normal file
View File

@ -0,0 +1,84 @@
{
"map3d": {
"layers": [
{
"id": "baimo",
"name": "重庆3DTiles",
"type": "3dtiles",
"url": "/shp/chongqing/tileset.json",
"maximumScreenSpaceError": 1,
"maximumMemoryUsage": 1024,
"position": {"alt": -3192.3 },
"show": false
},
{
"id": "guobo",
"name": "重庆国博3DTiles",
"type": "3dtiles",
"url": "/shp/sceneModel/guobo-new/terra_b3dms/tileset.json",
"maximumScreenSpaceError": 1,
"maximumMemoryUsage": 1024,
"position": {"alt": 0 },
"rotation": {
"z": 0.0,
"x": 0.0,
"y": 0.0
},
"scale": 1,
"opacity": 1,
"show": false
},
{
"id": "guobo-old",
"name": "TJ旧国博3DTiles",
"type": "3dtiles",
"url": "/shp/sceneModel/guobo/terra_b3dms/tileset.json",
"maximumScreenSpaceError": 1,
"maximumMemoryUsage": 1024,
"position": {"alt": 0 },
"rotation": {
"z": 0.0,
"x": 0.0,
"y": 0.0
},
"scale": 1,
"opacity": 1,
"show": false
},
{
"id": "tjzd",
"name": "重庆ZDTJ3DTiles",
"type": "3dtiles",
"url": "/shp/sceneModel/tjzd/terra_b3dms/tileset.json",
"maximumScreenSpaceError": 1,
"maximumMemoryUsage": 1024,
"position": {"alt": 0 },
"rotation": {
"z": 0.0,
"x": 0.0,
"y": 0.0
},
"scale": 1,
"opacity": 1,
"show": false
}
,
{
"id": "basket",
"name": "重庆basket3DTiles",
"type": "3dtiles",
"url": "/shp/sceneModel/basket/terra_pnts/tileset.json",
"maximumScreenSpaceError": 1,
"maximumMemoryUsage": 1024,
"position": {"alt": 0 },
"rotation": {
"z": 0.0,
"x": 0.0,
"y": 0.0
},
"scale": 1,
"flyTo": true
}
]
}
}

1237
public/geojson/plotlist.json Normal file

File diff suppressed because it is too large Load Diff

BIN
public/skyBox/nx.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
public/skyBox/ny.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

BIN
public/skyBox/nz.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
public/skyBox/px.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
public/skyBox/py.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
public/skyBox/pz.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
public/skyBoxNear/nx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
public/skyBoxNear/ny.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
public/skyBoxNear/nz.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
public/skyBoxNear/px.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

BIN
public/skyBoxNear/py.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
public/skyBoxNear/pz.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

View File

@ -1,95 +0,0 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="6" :xs="24">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>个人信息</span>
</div>
<div>
<div class="text-center">
<userAvatar />
</div>
<ul class="list-group list-group-striped">
<li class="list-group-item">
<svg-icon icon-class="user" />用户名称
<div class="pull-right">{{ user.userName }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="phone" />手机号码
<div class="pull-right">{{ user.phonenumber }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="email" />用户邮箱
<div class="pull-right">{{ user.email }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="tree" />所属部门
<div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="peoples" />所属角色
<div class="pull-right">{{ roleGroup }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="date" />创建日期
<div class="pull-right">{{ user.createTime }}</div>
</li>
</ul>
</div>
</el-card>
</el-col>
<el-col :span="18" :xs="24">
<el-card>
<div slot="header" class="clearfix">
<span>基本资料</span>
</div>
<el-tabs v-model="selectedTab">
<el-tab-pane label="基本资料" name="userinfo">
<userInfo :user="user" />
</el-tab-pane>
<el-tab-pane label="修改密码" name="resetPwd">
<resetPwd />
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import userAvatar from "./userAvatar"
import userInfo from "./userInfo"
import resetPwd from "./resetPwd"
import { getUserProfile } from "@/api/system/user"
export default {
name: "Profile",
components: { userAvatar, userInfo, resetPwd },
data() {
return {
user: {},
roleGroup: {},
postGroup: {},
selectedTab: "userinfo"
}
},
created() {
const activeTab = this.$route.params && this.$route.params.activeTab
if (activeTab) {
this.selectedTab = activeTab
}
this.getUser()
},
methods: {
getUser() {
getUserProfile().then(response => {
this.user = response.data
this.roleGroup = response.roleGroup
this.postGroup = response.postGroup
})
}
}
}
</script>

View File

@ -1,69 +0,0 @@
<template>
<el-form ref="form" :model="user" :rules="rules" label-width="80px">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="user.oldPassword" placeholder="请输入旧密码" type="password" show-password/>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password/>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="user.confirmPassword" placeholder="请确认新密码" type="password" show-password/>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="submit">保存</el-button>
<el-button type="danger" size="mini" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { updateUserPwd } from "@/api/system/user"
export default {
data() {
const equalToPassword = (rule, value, callback) => {
if (this.user.newPassword !== value) {
callback(new Error("两次输入的密码不一致"))
} else {
callback()
}
}
return {
user: {
oldPassword: undefined,
newPassword: undefined,
confirmPassword: undefined
},
//
rules: {
oldPassword: [
{ required: true, message: "旧密码不能为空", trigger: "blur" }
],
newPassword: [
{ required: true, message: "新密码不能为空", trigger: "blur" },
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
],
confirmPassword: [
{ required: true, message: "确认密码不能为空", trigger: "blur" },
{ required: true, validator: equalToPassword, trigger: "blur" }
]
}
}
},
methods: {
submit() {
this.$refs["form"].validate(valid => {
if (valid) {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
this.$modal.msgSuccess("修改成功")
})
}
})
},
close() {
this.$tab.closePage()
}
}
}
</script>

View File

@ -1,184 +0,0 @@
<template>
<div>
<div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
<el-row>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<vue-cropper
ref="cropper"
:img="options.img"
:info="true"
:autoCrop="options.autoCrop"
:autoCropWidth="options.autoCropWidth"
:autoCropHeight="options.autoCropHeight"
:fixedBox="options.fixedBox"
:outputType="options.outputType"
@realTime="realTime"
v-if="visible"
/>
</el-col>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<div class="avatar-upload-preview">
<img :src="previews.url" :style="previews.img" />
</div>
</el-col>
</el-row>
<br />
<el-row>
<el-col :lg="2" :sm="3" :xs="3">
<el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
<el-button size="small">
选择
<i class="el-icon-upload el-icon--right"></i>
</el-button>
</el-upload>
</el-col>
<el-col :lg="{span: 1, offset: 2}" :sm="2" :xs="2">
<el-button icon="el-icon-plus" size="small" @click="changeScale(1)"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
<el-button icon="el-icon-minus" size="small" @click="changeScale(-1)"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
<el-button icon="el-icon-refresh-left" size="small" @click="rotateLeft()"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
<el-button icon="el-icon-refresh-right" size="small" @click="rotateRight()"></el-button>
</el-col>
<el-col :lg="{span: 2, offset: 6}" :sm="2" :xs="2">
<el-button type="primary" size="small" @click="uploadImg()"> </el-button>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
import store from "@/store"
import { VueCropper } from "vue-cropper"
import { uploadAvatar } from "@/api/system/user"
import { debounce } from '@/utils'
export default {
components: { VueCropper },
data() {
return {
//
open: false,
// cropper
visible: false,
//
title: "修改头像",
options: {
img: store.getters.avatar, //
autoCrop: true, //
autoCropWidth: 200, //
autoCropHeight: 200, //
fixedBox: true, //
outputType:"png", // PNG
filename: 'avatar' //
},
previews: {},
resizeHandler: null
}
},
methods: {
//
editCropper() {
this.open = true
},
//
modalOpened() {
this.visible = true
if (!this.resizeHandler) {
this.resizeHandler = debounce(() => {
this.refresh()
}, 100)
}
window.addEventListener("resize", this.resizeHandler)
},
//
refresh() {
this.$refs.cropper.refresh()
},
//
requestUpload() {
},
//
rotateLeft() {
this.$refs.cropper.rotateLeft()
},
//
rotateRight() {
this.$refs.cropper.rotateRight()
},
//
changeScale(num) {
num = num || 1
this.$refs.cropper.changeScale(num)
},
//
beforeUpload(file) {
if (file.type.indexOf("image/") == -1) {
this.$modal.msgError("文件格式错误,请上传图片类型,如JPGPNG后缀的文件。")
} else {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
this.options.img = reader.result
this.options.filename = file.name
}
}
},
//
uploadImg() {
this.$refs.cropper.getCropBlob(data => {
let formData = new FormData()
formData.append("avatarfile", data, this.options.filename)
uploadAvatar(formData).then(response => {
this.open = false
this.options.img = process.env.VUE_APP_BASE_API + response.imgUrl
store.commit('SET_AVATAR', this.options.img)
this.$modal.msgSuccess("修改成功")
this.visible = false
})
})
},
//
realTime(data) {
this.previews = data
},
//
closeDialog() {
this.options.img = store.getters.avatar
this.visible = false
window.removeEventListener("resize", this.resizeHandler)
}
}
}
</script>
<style scoped lang="scss">
.user-info-head {
position: relative;
display: inline-block;
height: 120px;
}
.user-info-head:hover:after {
content: '+';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
color: #eee;
background: rgba(0, 0, 0, 0.5);
font-size: 24px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
cursor: pointer;
line-height: 110px;
border-radius: 50%;
}
</style>

View File

@ -1,88 +0,0 @@
<template>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" maxlength="30" />
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="form.phonenumber" maxlength="11" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" maxlength="50" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.sex">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="submit">保存</el-button>
<el-button type="danger" size="mini" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { updateUserProfile } from "@/api/system/user"
export default {
props: {
user: {
type: Object
}
},
data() {
return {
form: {},
//
rules: {
nickName: [
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
],
email: [
{ required: true, message: "邮箱地址不能为空", trigger: "blur" },
{
type: "email",
message: "请输入正确的邮箱地址",
trigger: ["blur", "change"]
}
],
phonenumber: [
{ required: true, message: "手机号码不能为空", trigger: "blur" },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
]
}
}
},
watch: {
user: {
handler(user) {
if (user) {
this.form = { nickName: user.nickName, phonenumber: user.phonenumber, email: user.email, sex: user.sex }
}
},
immediate: true
}
},
methods: {
submit() {
this.$refs["form"].validate(valid => {
if (valid) {
updateUserProfile(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.user.phonenumber = this.form.phonenumber
this.user.email = this.form.email
})
}
})
},
close() {
this.$tab.closePage()
}
}
}
</script>

View File

@ -1,123 +0,0 @@
<template>
<div class="app-container">
<h4 class="form-header h4">基本信息</h4>
<el-form ref="form" :model="form" label-width="80px">
<el-row>
<el-col :span="8" :offset="2">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" disabled />
</el-form-item>
</el-col>
<el-col :span="8" :offset="2">
<el-form-item label="登录账号" prop="userName">
<el-input v-model="form.userName" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
<h4 class="form-header h4">角色信息</h4>
<el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="table" @selection-change="handleSelectionChange" :data="roles.slice((pageNum-1)*pageSize,pageNum*pageSize)">
<el-table-column label="序号" type="index" align="center">
<template slot-scope="scope">
<span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column type="selection" :reserve-selection="true" :selectable="checkSelectable" width="55" />
<el-table-column label="角色编号" align="center" prop="roleId" />
<el-table-column label="角色名称" align="center" prop="roleName" />
<el-table-column label="权限字符" align="center" prop="roleKey" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" />
<el-form label-width="100px">
<el-form-item style="text-align: center;margin-left:-120px;margin-top:30px;">
<el-button type="primary" @click="submitForm()">提交</el-button>
<el-button @click="close()">返回</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getAuthRole, updateAuthRole } from "@/api/system/user"
export default {
name: "AuthRole",
data() {
return {
//
loading: true,
//
total: 0,
pageNum: 1,
pageSize: 10,
//
roleIds: [],
//
roles: [],
//
form: {}
}
},
created() {
const userId = this.$route.params && this.$route.params.userId
if (userId) {
this.loading = true
getAuthRole(userId).then((response) => {
this.form = response.user
this.roles = response.roles
this.total = this.roles.length
this.$nextTick(() => {
this.roles.forEach((row) => {
if (row.flag) {
this.$refs.table.toggleRowSelection(row)
}
})
})
this.loading = false
})
}
},
methods: {
/** 单击选中行数据 */
clickRow(row) {
if (this.checkSelectable(row)) {
this.$refs.table.toggleRowSelection(row)
}
},
//
handleSelectionChange(selection) {
this.roleIds = selection.map((item) => item.roleId)
},
//
getRowKey(row) {
return row.roleId
},
//
checkSelectable(row) {
return row.status === "0" ? true : false
},
/** 提交按钮 */
submitForm() {
const userId = this.form.userId
const roleIds = this.roleIds.join(",")
updateAuthRole({ userId: userId, roleIds: roleIds }).then((response) => {
this.$modal.msgSuccess("授权成功")
this.close()
})
},
/** 关闭按钮 */
close() {
const obj = { path: "/system/user" }
this.$tab.closeOpenPage(obj)
}
}
}
</script>

View File

@ -1,95 +0,0 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="6" :xs="24">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>个人信息</span>
</div>
<div>
<div class="text-center">
<userAvatar />
</div>
<ul class="list-group list-group-striped">
<li class="list-group-item">
<svg-icon icon-class="user" />用户名称
<div class="pull-right">{{ user.userName }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="phone" />手机号码
<div class="pull-right">{{ user.phonenumber }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="email" />用户邮箱
<div class="pull-right">{{ user.email }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="tree" />所属部门
<div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="peoples" />所属角色
<div class="pull-right">{{ roleGroup }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="date" />创建日期
<div class="pull-right">{{ user.createTime }}</div>
</li>
</ul>
</div>
</el-card>
</el-col>
<el-col :span="18" :xs="24">
<el-card>
<div slot="header" class="clearfix">
<span>基本资料</span>
</div>
<el-tabs v-model="selectedTab">
<el-tab-pane label="基本资料" name="userinfo">
<userInfo :user="user" />
</el-tab-pane>
<el-tab-pane label="修改密码" name="resetPwd">
<resetPwd />
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import userAvatar from "./userAvatar"
import userInfo from "./userInfo"
import resetPwd from "./resetPwd"
import { getUserProfile } from "@/api/system/user"
export default {
name: "Profile",
components: { userAvatar, userInfo, resetPwd },
data() {
return {
user: {},
roleGroup: {},
postGroup: {},
selectedTab: "userinfo"
}
},
created() {
const activeTab = this.$route.params && this.$route.params.activeTab
if (activeTab) {
this.selectedTab = activeTab
}
this.getUser()
},
methods: {
getUser() {
getUserProfile().then(response => {
this.user = response.data
this.roleGroup = response.roleGroup
this.postGroup = response.postGroup
})
}
}
}
</script>

View File

@ -1,69 +0,0 @@
<template>
<el-form ref="form" :model="user" :rules="rules" label-width="80px">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="user.oldPassword" placeholder="请输入旧密码" type="password" show-password/>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password/>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="user.confirmPassword" placeholder="请确认新密码" type="password" show-password/>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="submit">保存</el-button>
<el-button type="danger" size="mini" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { updateUserPwd } from "@/api/system/user"
export default {
data() {
const equalToPassword = (rule, value, callback) => {
if (this.user.newPassword !== value) {
callback(new Error("两次输入的密码不一致"))
} else {
callback()
}
}
return {
user: {
oldPassword: undefined,
newPassword: undefined,
confirmPassword: undefined
},
//
rules: {
oldPassword: [
{ required: true, message: "旧密码不能为空", trigger: "blur" }
],
newPassword: [
{ required: true, message: "新密码不能为空", trigger: "blur" },
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
],
confirmPassword: [
{ required: true, message: "确认密码不能为空", trigger: "blur" },
{ required: true, validator: equalToPassword, trigger: "blur" }
]
}
}
},
methods: {
submit() {
this.$refs["form"].validate(valid => {
if (valid) {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
this.$modal.msgSuccess("修改成功")
})
}
})
},
close() {
this.$tab.closePage()
}
}
}
</script>

View File

@ -1,184 +0,0 @@
<template>
<div>
<div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
<el-row>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<vue-cropper
ref="cropper"
:img="options.img"
:info="true"
:autoCrop="options.autoCrop"
:autoCropWidth="options.autoCropWidth"
:autoCropHeight="options.autoCropHeight"
:fixedBox="options.fixedBox"
:outputType="options.outputType"
@realTime="realTime"
v-if="visible"
/>
</el-col>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<div class="avatar-upload-preview">
<img :src="previews.url" :style="previews.img" />
</div>
</el-col>
</el-row>
<br />
<el-row>
<el-col :lg="2" :sm="3" :xs="3">
<el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
<el-button size="small">
选择
<i class="el-icon-upload el-icon--right"></i>
</el-button>
</el-upload>
</el-col>
<el-col :lg="{span: 1, offset: 2}" :sm="2" :xs="2">
<el-button icon="el-icon-plus" size="small" @click="changeScale(1)"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
<el-button icon="el-icon-minus" size="small" @click="changeScale(-1)"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
<el-button icon="el-icon-refresh-left" size="small" @click="rotateLeft()"></el-button>
</el-col>
<el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
<el-button icon="el-icon-refresh-right" size="small" @click="rotateRight()"></el-button>
</el-col>
<el-col :lg="{span: 2, offset: 6}" :sm="2" :xs="2">
<el-button type="primary" size="small" @click="uploadImg()"> </el-button>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
import store from "@/store"
import { VueCropper } from "vue-cropper"
import { uploadAvatar } from "@/api/system/user"
import { debounce } from '@/utils'
export default {
components: { VueCropper },
data() {
return {
//
open: false,
// cropper
visible: false,
//
title: "修改头像",
options: {
img: store.getters.avatar, //
autoCrop: true, //
autoCropWidth: 200, //
autoCropHeight: 200, //
fixedBox: true, //
outputType:"png", // PNG
filename: 'avatar' //
},
previews: {},
resizeHandler: null
}
},
methods: {
//
editCropper() {
this.open = true
},
//
modalOpened() {
this.visible = true
if (!this.resizeHandler) {
this.resizeHandler = debounce(() => {
this.refresh()
}, 100)
}
window.addEventListener("resize", this.resizeHandler)
},
//
refresh() {
this.$refs.cropper.refresh()
},
//
requestUpload() {
},
//
rotateLeft() {
this.$refs.cropper.rotateLeft()
},
//
rotateRight() {
this.$refs.cropper.rotateRight()
},
//
changeScale(num) {
num = num || 1
this.$refs.cropper.changeScale(num)
},
//
beforeUpload(file) {
if (file.type.indexOf("image/") == -1) {
this.$modal.msgError("文件格式错误,请上传图片类型,如JPGPNG后缀的文件。")
} else {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
this.options.img = reader.result
this.options.filename = file.name
}
}
},
//
uploadImg() {
this.$refs.cropper.getCropBlob(data => {
let formData = new FormData()
formData.append("avatarfile", data, this.options.filename)
uploadAvatar(formData).then(response => {
this.open = false
this.options.img = process.env.VUE_APP_BASE_API + response.imgUrl
store.commit('SET_AVATAR', this.options.img)
this.$modal.msgSuccess("修改成功")
this.visible = false
})
})
},
//
realTime(data) {
this.previews = data
},
//
closeDialog() {
this.options.img = store.getters.avatar
this.visible = false
window.removeEventListener("resize", this.resizeHandler)
}
}
}
</script>
<style scoped lang="scss">
.user-info-head {
position: relative;
display: inline-block;
height: 120px;
}
.user-info-head:hover:after {
content: '+';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
color: #eee;
background: rgba(0, 0, 0, 0.5);
font-size: 24px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
cursor: pointer;
line-height: 110px;
border-radius: 50%;
}
</style>

View File

@ -1,88 +0,0 @@
<template>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" maxlength="30" />
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="form.phonenumber" maxlength="11" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" maxlength="50" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.sex">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="submit">保存</el-button>
<el-button type="danger" size="mini" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { updateUserProfile } from "@/api/system/user"
export default {
props: {
user: {
type: Object
}
},
data() {
return {
form: {},
//
rules: {
nickName: [
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
],
email: [
{ required: true, message: "邮箱地址不能为空", trigger: "blur" },
{
type: "email",
message: "请输入正确的邮箱地址",
trigger: ["blur", "change"]
}
],
phonenumber: [
{ required: true, message: "手机号码不能为空", trigger: "blur" },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
]
}
}
},
watch: {
user: {
handler(user) {
if (user) {
this.form = { nickName: user.nickName, phonenumber: user.phonenumber, email: user.email, sex: user.sex }
}
},
immediate: true
}
},
methods: {
submit() {
this.$refs["form"].validate(valid => {
if (valid) {
updateUserProfile(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.user.phonenumber = this.form.phonenumber
this.user.email = this.form.email
})
}
})
},
close() {
this.$tab.closePage()
}
}
}
</script>