仪表盘界面新增文章/用户/银行账户新增信息列表功能

This commit is contained in:
ronger 2022-03-13 23:09:34 +08:00
parent 13e8ca9832
commit 81e304b122
6 changed files with 563 additions and 143 deletions

View File

@ -59,14 +59,14 @@ export default {
title: '文章管理', title: '文章管理',
name: 'admin-articles', name: 'admin-articles',
path: '/admin/articles', path: '/admin/articles',
icon: 'el-icon-s-custom', icon: 'el-icon-tickets',
closable: true closable: true
}, },
{ {
title: '评论管理', title: '评论管理',
name: 'admin-comments', name: 'admin-comments',
path: '/admin/comments', path: '/admin/comments',
icon: 'el-icon-s-custom', icon: 'el-icon-chat-line-square',
closable: true closable: true
}, },
{ {
@ -110,6 +110,13 @@ export default {
path: '/admin/bank-accounts', path: '/admin/bank-accounts',
icon: 'el-icon-bank-card', icon: 'el-icon-bank-card',
closable: true closable: true
},
{
title: '货币规则',
name: 'admin-currency-rules',
path: '/admin/currency-rules',
icon: 'el-icon-document',
closable: true
} }
] ]
} }

View File

@ -152,7 +152,7 @@ export default {
toggleStatus() {}, toggleStatus() {},
setPreference(index, idArticle) { setPreference(index, idArticle) {
let _ts = this; let _ts = this;
_ts.$axios.$patch("/api/article/update-perfect", { _ts.$axios.$patch("/api/admin/article/update-perfect", {
idArticle: idArticle, idArticle: idArticle,
articlePerfect: '1' articlePerfect: '1'
}).then(function (res) { }).then(function (res) {

View File

@ -90,13 +90,13 @@ export default {
fetch({store, params, error}) { fetch({store, params, error}) {
return Promise.all([ return Promise.all([
store store
.dispatch('bank/fetchList', params) .dispatch('currency-rule/fetchList', params)
.catch(err => error({statusCode: 404})) .catch(err => error({statusCode: 404}))
]) ])
}, },
computed: { computed: {
...mapState({ ...mapState({
banks: state => state.bank.list.data.banks, banks: state => state["currency-rule"].list.data.banks,
pagination: state => state.bank.list.data.pagination pagination: state => state.bank.list.data.pagination
}) })
}, },

View File

@ -36,160 +36,493 @@
<el-col class="mt-2rem">今日浏览量</el-col> <el-col class="mt-2rem">今日浏览量</el-col>
</el-card> </el-card>
</el-col> </el-col>
<el-col :span="24">
<div style="width: 100%;">
<el-col :span="24">
<el-col :span="24" style="text-align: left;">
<h3>新增文章列表</h3>
</el-col>
<el-table
:data="articles.articles"
style="width: 100%">
<el-table-column
label="#"
width="60"
prop="idArticle">
</el-table-column>
<el-table-column
label="标题"
prop="articleTitle">
<template slot-scope="scope">
<el-button type="text" @click="openLink(scope.row.articlePermalink)">{{ scope.row.articleTitle }}</el-button>
</template>
</el-table-column>
<el-table-column
label="标签"
prop="articleTitle">
<template slot-scope="scope">
<el-tag
style="margin-left: 0.5rem;"
v-for="tag in scope.row.tags"
:key="tag.idTag"
size="mini"
effect="plain">
# {{ tag.tagTitle }}
</el-tag>
</template>
</el-table-column>
<el-table-column
label="最后更新时间"
width="180"
prop="updatedTime">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button v-if="scope.row.articlePerfect === '1'" size="mini" @click="cancelPreference(scope.$index, scope.row.idArticle)" plain>取消优选</el-button>
<el-button v-else size="mini" @click="setPreference(scope.$index, scope.row.idArticle)" plain>设为优选</el-button>
<el-button size="mini" type="primary"
@click="updateTags(scope.$index, scope.row)" plain>编辑标签
</el-button>
<el-button v-if="scope.row.articleStatus === '0'" size="mini" type="danger"
@click="toggleStatus(scope.$index, scope.row)" plain>下架
</el-button>
<el-button v-else size="mini" type="success"
@click="toggleStatus(scope.$index, scope.row)" plain>上架
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
<el-col>
<el-pagination
:hide-on-single-page="true"
@size-change="handleArticleSizeChange"
@current-change="handleArticleCurrentChange"
:current-page="articles.pagination.currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="articles.pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="articles.pagination.total">
</el-pagination>
</el-col>
<el-col :span="24">
<el-col :span="24" style="text-align: left;">
<h3>新增用户列表</h3>
</el-col>
<el-table :data="users.users"
style="width: 100%">
<el-table-column
label="#"
width="40"
prop="idUser">
</el-table-column>
<el-table-column
label="头像"
width="60"
prop="avatarUrl">
<template slot-scope="scope">
<el-avatar v-if="scope.row.avatarUrl" size="medium" :src="scope.row.avatarUrl"></el-avatar>
<el-avatar v-else size="medium" src="https://rymcu.com/article/1578475481946.png"></el-avatar>
</template>
</el-table-column>
<el-table-column
label="昵称"
width="140"
prop="nickname">
<template slot-scope="scope">
<el-link type="primary" :href="getUserPath(scope.row.account)" :underline="false">
{{ scope.row.nickname }}
</el-link>
</template>
</el-table-column>
<el-table-column
label="注册时间"
width="180"
prop="createdTime">
</el-table-column>
</el-table>
</el-col>
<el-col>
<el-pagination
:hide-on-single-page="true"
@size-change="handleUserSizeChange"
@current-change="handleUserCurrentChange"
:current-page="users.pagination.currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="users.pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="users.pagination.total">
</el-pagination>
</el-col>
<el-col :span="24">
<el-col :span="24" style="text-align: left;">
<h3>新增账户列表</h3>
</el-col>
<el-table :data="bankAccounts.bankAccounts"
style="width: 100%">
<el-table-column
label="#"
width="40"
prop="idBank">
</el-table-column>
<el-table-column
label="银行账户"
width="180"
prop="bankAccount">
</el-table-column>
<el-table-column
label="账户所有者"
width="180"
prop="accountOwnerName">
</el-table-column>
<el-table-column
label="账户余额 (巴旦木)"
width="180"
prop="accountBalance">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="mini" @click="showTransfer(scope.$index, scope.row)" plain>发放新手奖励</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
<el-col>
<el-pagination
:hide-on-single-page="true"
@size-change="handleBankAccountSizeChange"
@current-change="handleBankAccountCurrentChange"
:current-page="bankAccounts.pagination.currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="bankAccounts.pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="bankAccounts.pagination.total">
</el-pagination>
</el-col>
</div>
</el-col>
<el-col class="mt-2rem"> <el-col class="mt-2rem">
<div id="lastThirtyDays" style="width: 100%;height: 500px;"></div> <div id="lastThirtyDays" style="width: 100%;height: 500px;"></div>
</el-col> </el-col>
<el-col class="mt-2rem"> <el-col class="mt-2rem">
<div id="history" style="width: 100%;height: 500px;"></div> <div id="history" style="width: 100%;height: 500px;"></div>
</el-col> </el-col>
<el-col>
<el-dialog :visible.sync="dialogVisible" title="发放新手奖励">
<el-form label-width="180px">
<el-form-item label="收款账户">
<el-input v-model="toBankAccount" style="width: 300px;"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button v-if="toBankAccount" type="primary" @click="transfer"> </el-button>
<el-button v-else type="primary" :disabled="true"> </el-button>
</div>
</el-dialog>
</el-col>
<el-col>
<el-dialog :visible.sync="tagsDialogVisible">
<edit-tags
:idArticle="idArticle"
:tags="articleTags"
@closeDialog="closeTagsDialog">
</edit-tags>
</el-dialog>
</el-col>
</el-row> </el-row>
</template> </template>
<script> <script>
import Vue from 'vue'; import Vue from 'vue';
import {mapState} from 'vuex'; import {mapState} from 'vuex';
import echarts from 'echarts'; import echarts from 'echarts';
import EditTags from '~/components/widget/tags';
Vue.prototype.$echarts = echarts; Vue.prototype.$echarts = echarts;
export default { export default {
name: "Dashboard", name: "Dashboard",
fetch({store, params, error}) { components: {
return Promise.all([ EditTags
store },
.dispatch('dashboard/fetchDashboard', params) fetch({store, params, error}) {
.catch(err => error({statusCode: 404})), return Promise.all([
store.dispatch("dashboard/fetchLastThirtyDays"), store
store.dispatch("dashboard/fetchHistory") .dispatch('dashboard/fetchDashboard', params)
]) .catch(err => error({statusCode: 404})),
store.dispatch("dashboard/fetchLastThirtyDays"),
store.dispatch("dashboard/fetchHistory"),
store.dispatch("dashboard/fetchNewUsers"),
store.dispatch("dashboard/fetchNewBankAccounts"),
store.dispatch("dashboard/fetchNewArticles")
])
},
computed: {
...mapState({
dashboard: state => state.dashboard.data,
lastThirtyDays: state => state.dashboard.lastThirtyDays,
history: state => state.dashboard.history,
users: state => state.dashboard.users,
bankAccounts: state => state.dashboard.bankAccounts,
articles: state => state.dashboard.articles,
})
},
data() {
return {
toBankAccount: '',
dialogVisible: false,
tagsDialogVisible: false,
index: Number,
idArticle: Number,
articleTags: ''
}
},
methods: {
initLastThirtyDaysCharts(data) {
let myChart = this.$echarts.init(document.getElementById('lastThirtyDays'));
//
let option = {
title: {
text: '最近 30 天'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ["文章", "用户", "浏览量"]
},
xAxis: {
type: 'category',
data: data.dates
},
yAxis: {
type: 'value'
},
series: [{
name: '文章',
data: data.articles,
type: 'line',
smooth: true,
areaStyle: {}
},
{
name: '用户',
data: data.users,
type: 'line',
smooth: true,
areaStyle: {}
},
{
name: '浏览量',
data: data.visits,
type: 'line',
smooth: true,
areaStyle: {}
}]
};
// 使
myChart.setOption(option);
}, },
computed: { initHistoryCharts(data) {
...mapState({ let myChart = this.$echarts.init(document.getElementById('history'));
dashboard: state => state.dashboard.data, //
lastThirtyDays: state => state.dashboard.lastThirtyDays, let option = {
history: state => state.dashboard.history, title: {
text: '历史'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ["文章", "用户", "浏览量"]
},
xAxis: {
type: 'category',
data: data.dates
},
yAxis: {
type: 'value'
},
series: [{
name: '文章',
data: data.articles,
type: 'line',
smooth: true,
areaStyle: {}
},
{
name: '用户',
data: data.users,
type: 'line',
smooth: true,
areaStyle: {}
},
{
name: '浏览量',
data: data.visits,
type: 'line',
smooth: true,
areaStyle: {}
}]
};
// 使
myChart.setOption(option);
},
getUserPath(nickname) {
return `/user/${nickname}`
},
showTransfer(index, bank) {
let _ts = this;
_ts.$set(_ts, 'toBankAccount', bank.bankAccount);
_ts.$set(_ts, 'dialogVisible', true);
},
transfer() {
let _ts = this;
_ts.$axios.$post("/api/transaction/newbie-rewards", {
toBankAccount: _ts.toBankAccount
}).then(function (res) {
if (res) {
if (res.idTransactionRecord) {
_ts.$message({
type: 'success',
message: '划转成功!'
});
_ts.$set(_ts, 'dialogVisible', false);
} else {
_ts.$message({
type: 'error',
message: '请勿重复发放奖励!'
});
}
}
}) })
}, },
methods: { openLink(link) {
initLastThirtyDaysCharts(data) { window.open(link);
let myChart = this.$echarts.init(document.getElementById('lastThirtyDays'));
//
let option = {
title: {
text: '最近 30 天'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ["文章", "用户", "浏览量"]
},
xAxis: {
type: 'category',
data: data.dates
},
yAxis: {
type: 'value'
},
series: [{
name: '文章',
data: data.articles,
type: 'line',
smooth: true,
areaStyle: {}
},
{
name: '用户',
data: data.users,
type: 'line',
smooth: true,
areaStyle: {}
},
{
name: '浏览量',
data: data.visits,
type: 'line',
smooth: true,
areaStyle: {}
}]
};
// 使
myChart.setOption(option);
},
initHistoryCharts(data) {
let myChart = this.$echarts.init(document.getElementById('history'));
//
let option = {
title: {
text: '历史'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ["文章", "用户", "浏览量"]
},
xAxis: {
type: 'category',
data: data.dates
},
yAxis: {
type: 'value'
},
series: [{
name: '文章',
data: data.articles,
type: 'line',
smooth: true,
areaStyle: {}
},
{
name: '用户',
data: data.users,
type: 'line',
smooth: true,
areaStyle: {}
},
{
name: '浏览量',
data: data.visits,
type: 'line',
smooth: true,
areaStyle: {}
}]
};
// 使
myChart.setOption(option);
}
}, },
mounted() { setPreference(index, idArticle) {
this.$store.commit("setActiveMenu", "admin-dashboard"); let _ts = this;
this.initLastThirtyDaysCharts(this.lastThirtyDays) _ts.$axios.$patch("/api/admin/article/update-perfect", {
this.initHistoryCharts(this.history) idArticle: idArticle,
} articlePerfect: '1'
}).then(function (res) {
if (res) {
if (res.success) {
_ts.$store.commit('admin/updateArticlePreference', {
index: index,
idArticle: idArticle,
articlePerfect: '1'
})
_ts.$message.success("设置成功!");
} else {
_ts.$message.error(_ts.message);
}
}
})
},
cancelPreference(index, idArticle) {
let _ts = this;
_ts.$axios.$patch("/api/article/update-perfect", {
idArticle: idArticle,
articlePerfect: '0'
}).then(function (res) {
if (res) {
if (res.success) {
_ts.$store.commit('admin/updateArticlePreference', {
index: index,
idArticle: idArticle,
articlePerfect: '0'
})
_ts.$message.success("取消成功!");
} else {
_ts.$message.error(_ts.message);
}
}
})
},
updateTags(index, article) {
let _ts = this
_ts.$set(_ts, 'index', index);
_ts.$set(_ts, 'idArticle', article.idArticle);
_ts.$set(_ts, 'articleTags', article.articleTags);
_ts.$set(_ts, 'tagsDialogVisible', true);
},
toggleStatus() {},
closeTagsDialog() {
this.$set(this, 'tagsDialogVisible', false);
},
handleArticleSizeChange(pageSize) {
let _ts = this;
_ts.$store.dispatch('dashboard/fetchNewArticles', {
page: _ts.pagination.currentPage,
rows: pageSize
})
},
handleArticleCurrentChange(page) {
let _ts = this;
_ts.$store.dispatch('dashboard/fetchNewArticles', {
page: page,
rows: _ts.pagination.pageSize
})
},
handleUserSizeChange(pageSize) {
let _ts = this;
_ts.$store.dispatch('dashboard/fetchNewUsers', {
page: _ts.pagination.currentPage,
rows: pageSize
})
},
handleUserCurrentChange(page) {
let _ts = this;
_ts.$store.dispatch('dashboard/fetchNewUsers', {
page: page,
rows: _ts.pagination.pageSize
})
},
handleBankAccountSizeChange(pageSize) {
let _ts = this;
_ts.$store.dispatch('dashboard/fetchNewBankAccounts', {
page: _ts.pagination.currentPage,
rows: pageSize
})
},
handleBankAccountCurrentChange(page) {
let _ts = this;
_ts.$store.dispatch('dashboard/fetchNewBankAccounts', {
page: page,
rows: _ts.pagination.pageSize
})
},
},
mounted() {
this.$store.commit("setActiveMenu", "admin-dashboard");
this.initLastThirtyDaysCharts(this.lastThirtyDays)
this.initHistoryCharts(this.history)
} }
}
</script> </script>
<style scoped> <style scoped>
.mt-2rem { .mt-2rem {
margin: 2rem auto; margin: 2rem auto;
} }
.dashboard-number { .dashboard-number {
font-weight: bold; font-weight: bold;
font-size: 2em; font-size: 2em;
} }
</style> </style>

View File

@ -140,7 +140,6 @@ export default {
const isPNG = file.type === 'image/png'; const isPNG = file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2; const isLt2M = file.size / 1024 / 1024 < 2;
if (!(isJPG || isPNG)) { if (!(isJPG || isPNG)) {
this.$message.error('上传头像只能是 JPG 或者 PNG 格式!'); this.$message.error('上传头像只能是 JPG 或者 PNG 格式!');
return false; return false;
} }

View File

@ -15,12 +15,36 @@ const getDefaultLastThirtyDaysData = () => {
} }
} }
const getDefaultNewUserData = () => {
return {
users: [],
pagination: {}
}
}
const getDefaultNewBankAccountData = () => {
return {
bankAccounts: [],
pagination: {}
}
}
const getDefaultNewArticleData = () => {
return {
articles: [],
pagination: {}
}
}
export const state = () => { export const state = () => {
return { return {
fetching: false, fetching: false,
data: getDefaultDashboardData(), data: getDefaultDashboardData(),
lastThirtyDays: getDefaultLastThirtyDaysData(), lastThirtyDays: getDefaultLastThirtyDaysData(),
history: getDefaultLastThirtyDaysData() history: getDefaultLastThirtyDaysData(),
users: getDefaultNewUserData(),
bankAccounts: getDefaultNewBankAccountData(),
articles: getDefaultNewArticleData()
} }
} }
@ -36,6 +60,15 @@ export const mutations = {
}, },
updateHistoryData(state, action) { updateHistoryData(state, action) {
state.history = action state.history = action
},
updateNewUsersData(state, action) {
state.users = action
},
updateNewBankAccountsData(state, action) {
state.bankAccounts = action
},
updateNewArticlesData(state, action) {
state.articles = action
} }
} }
@ -87,5 +120,53 @@ export const actions = {
console.log(error); console.log(error);
commit('updateDashboardFetching', false); commit('updateDashboardFetching', false);
}); });
},
fetchNewUsers({commit}, params = {}) {
// 清空已有数据
commit('updateNewUsersData', getDefaultNewUserData())
commit('updateDashboardFetching', true)
return this.$axios
.$get(`${DASHBOARD_API_PATH}/new-users`)
.then(response => {
commit('updateDashboardFetching', false);
commit('updateNewUsersData', response);
})
.catch(error => {
console.log(error);
commit('updateDashboardFetching', false);
});
},
fetchNewBankAccounts({commit}, params = {}) {
// 清空已有数据
commit('updateNewBankAccountsData', getDefaultNewBankAccountData())
commit('updateDashboardFetching', true)
return this.$axios
.$get(`${DASHBOARD_API_PATH}/new-bank-accounts`)
.then(response => {
commit('updateDashboardFetching', false);
commit('updateNewBankAccountsData', response);
})
.catch(error => {
console.log(error);
commit('updateDashboardFetching', false);
});
},
fetchNewArticles({commit}, params = {}) {
// 清空已有数据
commit('updateNewArticlesData', getDefaultNewBankAccountData())
commit('updateDashboardFetching', true)
return this.$axios
.$get(`${DASHBOARD_API_PATH}/new-articles`)
.then(response => {
commit('updateDashboardFetching', false);
commit('updateNewArticlesData', response);
})
.catch(error => {
console.log(error);
commit('updateDashboardFetching', false);
});
} }
} }