add && refine

This commit is contained in:
Pan 2017-04-20 20:31:40 +08:00
parent 1e90bc560b
commit 33e384ee95
17 changed files with 324 additions and 563 deletions

View file

@ -22,6 +22,10 @@
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/uploadAvatar.gif)
#### 错误统计
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/errorlog.png)
#### 富文本(整合七牛 打水印等个性化功能)
![enter image description here](https://github.com/PanJiaChen/vue-element-admin/blob/master/gifs/editor.gif)

BIN
documentImg/code1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
gifs/errorlog.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 KiB

View file

@ -16,12 +16,12 @@
"codemirror": "5.22.0",
"dropzone": "4.3.0",
"echarts": "3.4.0",
"element-ui": "1.2.7",
"element-ui": "1.2.9",
"file-saver": "1.3.3",
"jquery": "3.1.1",
"js-cookie": "2.1.3",
"jsonlint": "1.6.2",
"mockjs": "^1.0.1-beta3",
"mockjs": "1.0.1-beta3",
"normalize.css": "3.0.2",
"nprogress": "0.2.0",
"showdown": "1.6.4",
@ -58,7 +58,7 @@
"express": "4.14.1",
"extract-text-webpack-plugin": "2.0.0",
"file-loader": "0.10.0",
"friendly-errors-webpack-plugin": "^1.1.3",
"friendly-errors-webpack-plugin": "1.1.3",
"function-bind": "1.1.0",
"html-webpack-plugin": "2.28.0",
"http-proxy-middleware": "0.17.3",

View file

@ -1,6 +1,12 @@
;(function(window) {
var svgSprite = '<svg>' +
'' +
'<symbol id="icon-bug" viewBox="0 0 1024 1024">' +
'' +
'<path d="M969.142857 548.571429q0 14.848-10.861714 25.709714t-25.709714 10.861714l-128 0q0 97.718857-38.290286 165.705143l118.857143 119.442286q10.861714 10.861714 10.861714 25.709714t-10.861714 25.709714q-10.276571 10.861714-25.709714 10.861714t-25.709714-10.861714l-113.152-112.566857q-2.852571 2.852571-8.557714 7.424t-23.990857 16.274286-37.156571 20.845714-46.848 16.566857-55.442286 7.424l0-512-73.142857 0 0 512q-29.147429 0-58.002286-7.716571t-49.700571-18.870857-37.705143-22.272-24.868571-18.578286l-8.557714-8.009143-104.557714 118.272q-11.446857 11.995429-27.428571 11.995429-13.714286 0-24.576-9.142857-10.861714-10.276571-11.702857-25.417143t8.850286-26.587429l115.419429-129.718857q-33.133714-65.133714-33.133714-156.562286l-128 0q-14.848 0-25.709714-10.861714t-10.861714-25.709714 10.861714-25.709714 25.709714-10.861714l128 0 0-168.009143-98.852571-98.852571q-10.861714-10.861714-10.861714-25.709714t10.861714-25.709714 25.709714-10.861714 25.709714 10.861714l98.852571 98.852571 482.304 0 98.852571-98.852571q10.861714-10.861714 25.709714-10.861714t25.709714 10.861714 10.861714 25.709714-10.861714 25.709714l-98.852571 98.852571 0 168.009143 128 0q14.848 0 25.709714 10.861714t10.861714 25.709714zM694.857143 219.428571l-365.714286 0q0-75.995429 53.430857-129.426286t129.426286-53.430857 129.426286 53.430857 53.430857 129.426286z" ></path>' +
'' +
'</symbol>' +
'' +
'<symbol id="icon-tubiaoleixingzhengchang" viewBox="0 0 1024 1024">' +
'' +
@ -8,6 +14,20 @@
'' +
'</symbol>' +
'' +
'<symbol id="icon-404" viewBox="0 0 1024 1024">' +
'' +
'<path d="M931.6 585.6l0 79c28.6-60.2 44.8-127.4 44.8-198.4C976.4 211 769.4 4 514.2 4S52 211 52 466.2c0 3.2 0.2 6.4 0.2 9.6l166-206 96.4 0L171.8 485.6l46.4 0 0-54.8 99.2-154.6 0 209.4 0 100 0 82.4-99.2 0 0-82.4L67.6 585.6c43 161 170.6 287.4 332.4 328.6-10.4 26.2-40.6 89.4-90.8 100.6-62.2 14 168.8 3.4 333.6-104.6 126.6-36.6 230.8-125.8 287.4-242.2l-97.6 0 0-82.4-166.2 0 0-87.2 0-12.8L666.4 476l166.2-206.2 94 0-140.4 215.8 46.4 0 0-59 99.2-154 0 213.2L931.8 585.6zM366.2 608c-4.8-11.2-7.2-23.2-7.2-36L359 357.6c0-12.8 2.4-24.8 7.2-36 4.8-11.2 11.4-21 19.6-29.2 8.2-8.2 18-14.8 29.2-19.6 11.2-4.8 23.2-7.2 36-7.2l81.6 0c12.8 0 24.8 2.4 36 7.2 11 4.8 20.6 11.2 28.8 19.2l-88.6 129.4 0-23c0-4.8-1.6-8.8-4.8-12-3.2-3.2-7.2-4.8-12-4.8-4.8 0-8.8 1.6-12 4.8-3.2 3.2-4.8 7.2-4.8 12l0 72L372.6 620C370.2 616.2 368 612.2 366.2 608zM624.4 572c0 12.8-2.4 24.8-7.2 36-4.8 11.2-11.4 21-19.6 29.2-8.2 8.2-18 14.8-29.2 19.6-11.2 4.8-23.2 7.2-36 7.2l-81.6 0c-12.8 0-24.8-2.4-36-7.2-11.2-4.8-21-11.4-29.2-19.6-3.6-3.6-7-7.8-10-12l99.2-144.6 0 50.6c0 4.8 1.6 8.8 4.8 12 3.2 3.2 7.2 4.8 12 4.8 4.8 0 8.8-1.6 12-4.8 3.2-3.2 4.8-7.2 4.8-12l0-99.6 92.6-135.2c6.6 7.4 12 15.8 16 25.2 4.8 11.2 7.2 23.2 7.2 36L624.2 572z" ></path>' +
'' +
'</symbol>' +
'' +
'<symbol id="icon-EXCEL" viewBox="0 0 1024 1024">' +
'' +
'<path d="M625.664 132.608V199.68h309.76v43.008h-309.76V312.32h309.76v43.008h-309.76v68.608h309.76v43.008h-309.76v68.608h309.76v43.008h-309.76v68.608h309.76v43.008h-309.76v68.096h309.76v43.008h-309.76v89.088H1024v-757.76h-398.336zM0 914.944L577.024 1024V0L0 109.056" ></path>' +
'' +
'<path d="M229.376 660.48H139.776l118.272-187.904-112.64-180.736h92.16l65.536 119.808L370.688 291.84h89.088l-112.64 177.664L466.944 660.48H373.248l-70.144-125.44L229.376 660.48z" ></path>' +
'' +
'</symbol>' +
'' +
'<symbol id="icon-zujian" viewBox="0 0 1024 1024">' +
'' +
'<path d="M568.6 0h454.9v454.9H568.6V0z m0 568.6h454.9v454.9H568.6V568.6zM0 568.6h454.9v454.9H0V568.6zM0 0h454.9v454.9H0V0z" fill="" ></path>' +

View file

@ -2,7 +2,7 @@
<div>
<el-badge :is-dot="true" style="line-height: 30px;" @click.native="dialogTableVisible=true">
<el-button size="small" type="primary">
<wscn-icon-svg icon-class="bug" class="meta-item__icon"/>
<svg t="1492682037685" class="bug-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1863" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M969.142857 548.571429q0 14.848-10.861714 25.709714t-25.709714 10.861714l-128 0q0 97.718857-38.290286 165.705143l118.857143 119.442286q10.861714 10.861714 10.861714 25.709714t-10.861714 25.709714q-10.276571 10.861714-25.709714 10.861714t-25.709714-10.861714l-113.152-112.566857q-2.852571 2.852571-8.557714 7.424t-23.990857 16.274286-37.156571 20.845714-46.848 16.566857-55.442286 7.424l0-512-73.142857 0 0 512q-29.147429 0-58.002286-7.716571t-49.700571-18.870857-37.705143-22.272-24.868571-18.578286l-8.557714-8.009143-104.557714 118.272q-11.446857 11.995429-27.428571 11.995429-13.714286 0-24.576-9.142857-10.861714-10.276571-11.702857-25.417143t8.850286-26.587429l115.419429-129.718857q-33.133714-65.133714-33.133714-156.562286l-128 0q-14.848 0-25.709714-10.861714t-10.861714-25.709714 10.861714-25.709714 25.709714-10.861714l128 0 0-168.009143-98.852571-98.852571q-10.861714-10.861714-10.861714-25.709714t10.861714-25.709714 25.709714-10.861714 25.709714 10.861714l98.852571 98.852571 482.304 0 98.852571-98.852571q10.861714-10.861714 25.709714-10.861714t25.709714 10.861714 10.861714 25.709714-10.861714 25.709714l-98.852571 98.852571 0 168.009143 128 0q14.848 0 25.709714 10.861714t10.861714 25.709714zM694.857143 219.428571l-365.714286 0q0-75.995429 53.430857-129.426286t129.426286-53.430857 129.426286 53.430857 53.430857 129.426286z" p-id="1864"></path></svg>
</el-button>
</el-badge>
<el-dialog title="bug日志" v-model="dialogTableVisible">
@ -37,7 +37,15 @@
return {
dialogTableVisible: false
}
},
methods: {}
}
}
</script>
<style scoped>
.bug-svg {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>

View file

@ -73,12 +73,6 @@ router.afterEach(() => {
NProgress.done();
});
// 异步组件
// Vue.component('async-Editor', function (resolve) {
// require(['components/Editor'], resolve)
// });
// window.onunhandledrejection = e => {
// console.log('unhandled', e.reason, e.promise);
// e.preventDefault()

View file

@ -27,6 +27,8 @@ const AvatarUpload = resolve => require(['../views/components/avatarupload'], re
const Dropzone = resolve => require(['../views/components/dropzone'], resolve);
const Sticky = resolve => require(['../views/components/sticky'], resolve);
const SplitPane = resolve => require(['../views/components/splitpane'], resolve);
const CountTo = resolve => require(['../views/components/countto'], resolve);
const Mixin = resolve => require(['../views/components/mixin'], resolve);
/* charts*/
@ -35,11 +37,15 @@ const KeyboardChart2 = resolve => require(['../views/charts/keyboard2'], resolve
const LineMarker = resolve => require(['../views/charts/line'], resolve);
const MixChart = resolve => require(['../views/charts/mixchart'], resolve);
/* excel*/
const ErrorLog = resolve => require(['../views/errlog/index'], resolve);
/* excel*/
const ExcelDownload = resolve => require(['../views/excel/index'], resolve);
/* admin*/
// const AdminCreateUser = resolve => require(['../views/admin/createUser'], resolve);
// const QuicklyCreateUser = resolve => require(['../views/admin/quicklycreate'], resolve);
@ -85,7 +91,9 @@ export default new Router({
{ path: 'splitpane', component: SplitPane, name: 'SplitPane' },
{ path: 'avatarupload', component: AvatarUpload, name: '头像上传' },
{ path: 'dropzone', component: Dropzone, name: 'Dropzone' },
{ path: 'sticky', component: Sticky, name: 'Sticky' }
{ path: 'sticky', component: Sticky, name: 'Sticky' },
{ path: 'countto', component: CountTo, name: 'CountTo' },
{ path: 'mixin', component: Mixin, name: '小组件' }
]
},
{
@ -106,18 +114,29 @@ export default new Router({
component: Layout,
redirect: 'noredirect',
name: '错误页面',
icon: 'tubiaoleixingzhengchang',
icon: '404',
children: [
{ path: '401', component: Err401, name: '401' },
{ path: '404', component: Err404, name: '404' }
]
},
{
path: '/errlog',
component: Layout,
redirect: 'noredirect',
name: 'errlog',
icon: 'bug',
noDropdown: true,
children: [
{ path: 'log', component: ErrorLog, name: '错误日志' }
]
},
{
path: '/excel',
component: Layout,
redirect: 'noredirect',
name: 'excel',
icon: 'tubiaoleixingzhengchang',
icon: 'EXCEL',
noDropdown: true,
children: [
{ path: 'download', component: ExcelDownload, name: '导出excel' }

View file

@ -0,0 +1,187 @@
<template>
<div class="components-container">
<code>countTo 组件 <a href='https://github.com/PanJiaChen/vue-countTo' target='_blank'>线上地址</a></code>
<count-to ref='example' class='example' :start-val='_startVal' :end-val='_endVal' :duration='_duration' :decimals='_decimals'
:separator='_separator' :prefix='_prefix' :suffix='_suffix' :autoplay='false' />
<div style='margin-left: 25%;margin-top: 40px;'>
<label class="label" for="startValInput">startVal: <input type="number" v-model.number='setStartVal' name='startValInput' /></label>
<label class="label" for="endValInput">endVal: <input type="number" v-model.number='setEndVal' name='endVaInput' /></label>
<label class="label" for="durationInput">duration: <input type="number" v-model.number='setDuration' name='durationInput' /></label>
<div class="startBtn example-btn" @click='start'>开始</div>
<div class="pause-resume-btn example-btn" @click='pauseResume'>暂停/恢复</div>
<br/>
<label class="label" for="decimalsInput">decimals: <input type="number" v-model.number='setDecimals' name='decimalsInput' /></label>
<label class="label" for="separatorInput">separator: <input v-model='setSeparator' name='separatorInput' /></label>
<label class="label" for="prefixInput">prefix: <input v-model='setPrefix' name='prefixInput' /></label>
<label class="label" for="suffixInput">suffix: <input v-model='setSuffix' name='suffixInput' /></label>
</div>
<code>&lt;count-to :start-val=&#x27;{{_startVal}}&#x27; :end-val=&#x27;{{_endVal}}&#x27; :duration=&#x27;{{_duration}}&#x27; :decimals=&#x27;{{_decimals}}&#x27;
:separator=&#x27;{{_separator}}&#x27; :prefix=&#x27;{{_prefix}}&#x27; :suffix=&#x27;{{_suffix}}&#x27; :autoplay=false&gt;</code>
</div>
</template>
<script>
import countTo from 'vue-count-to';
export default {
components: { countTo },
data() {
return {
setStartVal: 0,
setEndVal: 2017,
setDuration: 4000,
setDecimals: 0,
setSeparator: ',',
setSuffix: ' rmb',
setPrefix: '¥ '
}
},
computed: {
_startVal() {
if (this.setStartVal) {
return this.setStartVal
} else {
return 0
}
},
_endVal() {
if (this.setEndVal) {
return this.setEndVal
} else {
return 0
}
},
_duration() {
if (this.setDuration) {
return this.setDuration
} else {
return 100
}
},
_decimals() {
if (this.setDecimals) {
if (this.setDecimals < 0 || this.setDecimals > 20) {
alert('digits argument must be between 0 and 20')
return 0
}
return this.setDecimals
} else {
return 0
}
},
_separator() {
return this.setSeparator
},
_suffix() {
return this.setSuffix
},
_prefix() {
return this.setPrefix
}
},
methods: {
start() {
this.$refs.example.start();
},
pauseResume() {
this.$refs.example.pauseResume();
}
}
};
</script>
<style scoped>
.example-btn {
display: inline-block;
margin-bottom: 0;
font-weight: 500;
text-align: center;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
white-space: nowrap;
line-height: 1.5;
padding: 4px 15px;
font-size: 12px;
border-radius: 4px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transition: all .3s cubic-bezier(.645, .045, .355, 1);
transition: all .3s cubic-bezier(.645, .045, .355, 1);
position: relative;
color: rgba(0, 0, 0, .65);
background-color: #fff;
border-color: #d9d9d9;
}
.example-btn:hover {
color: #4AB7BD;
background-color: #fff;
border-color: #4AB7BD;
}
.example {
font-size: 50px;
color: #F6416C;
display: block;
margin: 10px 0;
text-align: center;
font-size: 80px;
font-weight: 500;
}
.label {
color: #2f4f4f;
font-size: 16px;
display: inline-block;
margin: 15px 30px 15px 0;
}
input {
position: relative;
display: inline-block;
padding: 4px 7px;
width: 70px;
height: 28px;
cursor: text;
font-size: 12px;
line-height: 1.5;
color: rgba(0, 0, 0, .65);
background-color: #fff;
background-image: none;
border: 1px solid #d9d9d9;
border-radius: 4px;
-webkit-transition: all .3s;
transition: all .3s;
}
.startBtn {
margin-left: 20px;
font-size: 20px;
color: #30B08F;
background-color: #fff;
}
.startBtn:hover {
background-color: #30B08F;
color: #fff;
border-color: #30B08F;
}
.pause-resume-btn {
font-size: 20px;
color: #E65D6E;
background-color: #fff;
}
.pause-resume-btn:hover {
background-color: #E65D6E;
color: #fff;
border-color: #E65D6E;
}
</style>

View file

@ -0,0 +1,39 @@
<template>
<div class="components-container">
<div class='component-item'>
<MDinput name="name" v-model="title" required :maxlength="100">
标题
</MDinput>
<code class='code-part'>Material Design 的input</code>
</div>
<div class='component-item'>
<PanThumb image='https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191'>
上海花裤衩
</PanThumb>
<code class='code-part'>图片hover效果</code>
</div>
</div>
</template>
<script>
import MDinput from 'components/MDinput';
import PanThumb from 'components/PanThumb';
export default {
components: { MDinput, PanThumb },
data() {
return {
title: ''
}
}
};
</script>
<style scoped>
.component-item{
margin-top: 100px;
}
.code-part{
margin-top: 20px;
}
</style>

View file

@ -0,0 +1,7 @@
<template>
<div>
<!--error code-->
{{a.a}}
<!--error code-->
</div>
</template>

View file

@ -0,0 +1,31 @@
<template>
<div class="errPage-container">
<!--error code-->
<err-code/>
<!--error code-->
<h3>请点击右上角bug小图表</h3>
<code>
现在的管理后台基本都是spa的形式了它增强了用户体验但同时也会怎增加页面出问题的可能性可能一个小小的疏忽就导致整个页面的死锁好在Vue官网提供了一个方法来捕获处理异常
</code>
<a href="#"><img src='../../../documentImg/code1.png'></a>
</div>
</template>
<script>
import errCode from './errcode';
// import code1Img from
export default {
components: { errCode },
data() {
return {
}
},
methods: {
back() {
this.$router.go(-1)
}
}
};
</script>

View file

@ -1,102 +0,0 @@
<template>
<div class="app-container mediaUpload-container">
<el-upload
class="upload-container"
action="https://upload.qbox.me"
:data="dataObj"
drag
:multiple="true"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleSuccess"
:before-upload="beforeUpload">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
</el-upload>
<template v-if='fileList.length!=0'>
<el-table
:data="fileList"
border
style="width: 100%">
<el-table-column label="名字">
<template scope="scope">
{{scope.row.name}}
</template>
</el-table-column>
<el-table-column label="url">
<template scope="scope">
{{scope.row.url}}
</template>
</el-table-column>
</el-table>
</template>
</div>
</template>
<script>
import { getToken } from 'api/qiniu';
export default{
data() {
return {
image_uri: [],
dataObj: { token: '', key: '' },
fileList: []
}
},
computed: {
token() {
return this.$store.getters.token
}
},
methods: {
beforeUpload() {
const _self = this;
return new Promise((resolve, reject) => {
getToken(this.token).then(response => {
const key = response.data.qiniu_key;
const token = response.data.qiniu_token;
this.addFile(key, response.data.qiniu_url);
_self._data.dataObj.token = token;
_self._data.dataObj.key = key;
resolve(true);
}).catch(err => {
console.log(err)
reject(false)
});
});
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
handleSuccess(response, file) {
const key = response.key;
for (let i = this.fileList.length; i--;) {
const item = this.fileList[i];
if (item.key === key) {
this.fileList[i].name = file.name;
return
}
}
},
addFile(key, url) {
this.fileList.push({
key,
url,
name: ''
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.mediaUpload-container {
.upload-container {
margin: 30px;
}
}
</style>

View file

@ -1,20 +0,0 @@
<template>
<section class="app-main" style="min-height: 100%">
<transition name="fade" mode="out-in">
<router-view :key="key"></router-view>
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
key() {
return this.$route.name !== undefined
? this.$route.name
: this.$route
}
}
}
</script>

View file

@ -1,118 +0,0 @@
<template>
<div class="fedUser-info-container">
<el-button type="success" v-if="hasPermission" style='position: absolute; top: 20px;left: 50%'
@click="updateForm">更新
</el-button>
<el-form style="margin:0 50px;width: 400px" label-position="left"
label-width="100px">
<el-form-item label="昵称">
<el-input v-model="form.base_info.display_name"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="form.base_info.new_password"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="form.base_info.email"></el-input>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="form.base_info.mobile"></el-input>
</el-form-item>
<el-form-item label="真实姓名">
<el-input v-model="form.extented_info.real_name"></el-input>
</el-form-item>
<el-form-item label="生日">
<el-input v-model="form.extented_info.birthday"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-select v-model="form.base_info.gender" placeholder="请选择">
<el-option
v-for="item in genderOptions"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="教育背景">
<el-select v-model="form.extented_info.education" placeholder="请选择">
<el-option
v-for="item in educationOptions"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="收入">
<el-select v-model="form.extented_info.income" placeholder="请选择">
<el-option
v-for="item in incomeOptions"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="自我介绍">
<el-input
type="textarea"
:autosize="{ minRows: 4}"
placeholder="请输入内容"
v-model=" form.extented_info.introduction">
</el-input>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { updateUserInfo } from 'api/user';
export default {
name: 'fedUser-info',
props: ['info'],
data() {
return {
genderOptions: ['male', 'female', 'other'],
educationOptions: ['high_school', 'bachelor', 'master', 'Ph.D.', 'other'],
incomeOptions: ['3000', '5000', '8000', 'other']
}
},
computed: {
form() {
return this.info
},
hasPermission() {
return ~this.$store.getters.roles.indexOf('admin')
}
},
methods: {
updateForm() {
updateUserInfo(this.form).then(() => {
this.$notify({
title: '成功',
message: '更新成功',
type: 'success'
});
}).catch(err => {
console.log(err);
});
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.fedUser-detail-container {
}
</style>

View file

@ -1,125 +0,0 @@
<template>
<div class="fedUser-detail-container" v-loading="!fetchSuccess">
<div v-if="fetchSuccess" class="top-container clearfix">
<el-col :span="5">
<img class="info-avatar" :src="userInfo.base_info.image">
</el-col>
<el-col :span="16" :offset="2">
<div class="info-item">
<span class="info-label">用户名</span>
<span class="info-text">{{userInfo.base_info.username}}</span>
</div>
<div class="info-item">
<span class="info-label">昵称</span>
<span class="info-text">{{userInfo.base_info.display_name}}</span>
</div>
<div class="info-item">
<span class="info-label">手机号</span>
<span class="info-text">{{userInfo.base_info.mobile}}</span>
</div>
<div class="info-item">
<span class="info-label">余额</span>
<span class="info-text">{{userInfo.banance}}</span>
</div>
<div class="info-item">
<span class="info-label">ios余额</span>
<span class="info-text">{{userInfo.ios_banance}}</span>
</div>
<div class="info-item">
<span class="info-label">注册日期</span>
<span class="info-text">{{userInfo.created_at | parseTime('{y}-{m}-{d} {h}:{i}')}} 注册渠道:{{userInfo.signup_method}}</span>
</div>
<div class="info-item">
<span class="info-label">最后登录</span>
<span class="info-text">{{userInfo.last_signin_time | parseTime('{y}-{m}-{d} {h}:{i}')}}</span>
</div>
</el-col>
</div>
<el-tabs v-if="fetchSuccess" v-model="activeTab">
<el-tab-pane label="基本信息" name="info">
<Info :info="userInfo"></Info>
</el-tab-pane>
<el-tab-pane label="评论记录" name="information">
<Comment :user_id="userInfo.uid"></Comment>
</el-tab-pane>
<!--<el-tab-pane label="消费记录" name="stream">
</el-tab-pane>-->
</el-tabs>
</div>
</template>
<script>
import { userInfo } from 'api/user';
import Info from './components/info';
import Comment from '../comment/commentsList'
export default {
name: 'fedUser-detail',
components: { Info, Comment },
data() {
return {
userInfo: {},
activeTab: 'info',
fetchSuccess: false
}
},
created() {
this.fetchData();
},
methods: {
fetchData() {
userInfo(this.$route.params.id).then(response => {
this.userInfo = response.data;
this.fetchSuccess = true;
}).catch(err => {
this.fetchSuccess = true;
console.log(err);
});
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.fedUser-detail-container {
padding: 30px;
.top-container {
margin-bottom: 30px;
.info-item {
line-height: 14px;
padding-bottom: 18px;
.info-label {
display: inline-block;
color: #1f2f3d;
font-size: 16px;
position: absolute;
}
.info-text {
margin-left: 120px;
font-size: 14px;
color: #5e6d82;
}
}
}
.info-avatar {
width: 200px;
height: 200px;
border-radius: 100%;
}
}
</style>

View file

@ -1,183 +0,0 @@
<template>
<div class="app-container topic-list-container">
<div class="filter-container">
<el-input
style="width:200px"
@keyup.enter.native="handleFilter"
class="filter-item"
placeholder="display_name"
v-model="display_name">
</el-input>
<el-input
style="width:200px"
@keyup.enter.native="handleFilter"
class="filter-item"
placeholder="username"
v-model="username">
</el-input>
<el-select v-model="status" placeholder="状态" >
<el-option
v-for="item in statusOptions"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-button class="filter-item" style="margin-left: 30px;" type="primary" icon="search"
@click="handleFilter">搜索
</el-button>
</div>
<el-table :data="list" v-loading.body="listLoading" border fit highlight-current-row>
<el-table-column header prop="id" label="uid" width="160">
<template scope="scope">
<span style="margin-left: 10px">{{scope.row.uid}}</span>
</template>
</el-table-column>
<el-table-column label="display_name" show-overflow-tooltip>
<template scope="scope">
<router-link class="link-type" :to="'/user/'+scope.row.uid">
{{scope.row.display_name}}
</router-link>
</template>
</el-table-column>
<el-table-column label="username" show-overflow-tooltip>
<template scope="scope">
<router-link class="link-type" :to="'/user/'+scope.row.uid">
{{scope.row.username}}
</router-link>
</template>
</el-table-column>
<el-table-column label="手机号" width="150">
<template scope="scope">
<span>{{scope.row.mobile}}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="120" align='center'>
<template scope="scope">
<el-button v-if='condition.status==""' size="small" type="warning" @click="handleModifyUserStatus('frozen',scope.row)">
注销用户
</el-button>
<el-button v-else type="info" size="small" @click="handleModifyUserStatus('',scope.row)">解禁用户
</el-button>
</template>
</el-table-column>
</el-table>
<div v-show="!listLoading" class="pagination-container">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="listQuery.page"
:page-sizes="[10,20,30, 50]"
:page-size="listQuery.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</div>
</template>
<script>
import { usersList, modifyStatus } from 'api/user';
export default {
name: 'fedUserList',
data() {
return {
list: null,
total: null,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
app_type: 'wscn',
condition: ''
},
display_name: undefined,
username: undefined,
status: '',
statusOptions: [{ label: '正常', value: '' }, { label: '已删除', value: 'frozen' }],
condition: {
status: ''
}
}
},
created() {
this.fetchList();
},
watch: {
display_name(value) {
if (!value) return;
this.condition = {
display_name: value
};
this.username = '';
},
username(value) {
if (!value) return;
this.condition = {
username: value
};
this.display_name = '';
}
},
methods: {
fetchList() {
this.condition.status = this.status;
this.listQuery.condition = JSON.stringify(this.condition);
usersList(this.listQuery).then(response => {
const data = response.data;
this.list = data.items;
this.total = data.total_count;
this.listLoading = false;
})
},
handleSizeChange(val) {
this.listQuery.limit = val;
this.fetchList();
},
handleCurrentChange(val) {
this.listQuery.page = val;
this.fetchList();
},
handleFilter() {
this.fetchList();
},
handleModifyUserStatus(status, row) {
const msg = status === 'frozen' ? '注销' : '恢复';
this.$confirm('是否确' + msg + '用户:' + row.display_name || row.username, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
modifyStatus(status, [row.uid]).then(() => {
this.$notify({
title: '成功',
message: msg + '成功',
type: 'success',
duration: 1600
});
for (const i of this.list) {
if (i.uid === row.uid) {
const index = this.list.indexOf(i);
this.list.splice(index, 1);
break;
}
}
done();
}).catch(() => {
done();
});
} else {
done();
}
}
})
}
}
}
</script>