提交 8e1b04b5 authored 作者: 翟畅's avatar 翟畅

zc改版图书、资源二维码激活验证、统计、部门等

上级 7dd74001
......@@ -3,8 +3,8 @@ ENV = 'development'
# base api
# VUE_APP_BASE_API = '/dev-api'
# VUE_APP_BASE_API = 'https://www.class.com.cn'
VUE_APP_BASE_API = 'http://test24.zhongdianyun.com:8096'
VUE_APP_BASE_API = 'https://www.class.com.cn'
# VUE_APP_BASE_API = 'http://test24.zhongdianyun.com:8096'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
......
......@@ -3,6 +3,6 @@ ENV = 'production'
# base api
# VUE_APP_BASE_API = '/prod-api'
# VUE_APP_BASE_API = 'https://www.class.com.cn'
VUE_APP_BASE_API = 'http://test24.zhongdianyun.com:8096'
VUE_APP_BASE_API = 'https://www.class.com.cn'
# VUE_APP_BASE_API = 'http://test24.zhongdianyun.com:8096'
import request from '@/utils/request1'
import { requestPath } from '@/utils/global.js'
export function resourceLinkRelativeAPI() { //资源环比统计
return request({
url: `${requestPath.statistics}/api/sta/resource/link/relative`,
method: 'get'
})
}
export function getNumberAPI(params) { //资源量统计
return request({
url: `${requestPath.statistics}/api/sta/resource/get/number`,
method: 'get',
params
})
}
export function getNumberAllAPI(params) { //资源类型占比
return request({
url: `${requestPath.statistics}/api/sta/resource/get/number/all`,
method: 'get',
params
})
}
export function getRegisteredPercentageAPI(params) { //新老用户注册量占比
return request({
url: `${requestPath.statistics}/api/sta/member/registered/percentage`,
method: 'get',
params
})
}
export function getOrderPercentageAPI(params) { //新老用户订单量占比
return request({
url: `${requestPath.statistics}/api/sta/member/order/percentage`,
method: 'get',
params
})
}
export function getResourceTrendAPI(params) { //新老用户注册量占比
return request({
url: `${requestPath.statistics}/api/sta/resource/get/trend`,
method: 'get',
params
})
}
export function getResourceStatusAPI(params) { //资源状态占比
return request({
url: `${requestPath.statistics}/api/sta/resource/get/status/number`,
method: 'get',
params
})
}
export function getHeatSortListAPI(params) { //查询资源热度排行榜
return request({
url: `${requestPath.statistics}/api/sta/resource/get/heat`,
method: 'get',
params
})
}
\ No newline at end of file
import request from '@/utils/request1'
import { requestPath } from '@/utils/global.js'
export function courseTrendAnalysisDataAPI(params) { //课程统计--统计课程学习人数、金额、资源量
return request({
url: `${requestPath.resource}/course/courseEchartsData`,
method: 'get',
params
})
}
export function departmentTrendOrderDataAPI(params) { //部门统计统计--统计课程学习人数、视频、音频、资源量
return request({
url: `${requestPath.resource}/course/detpEchartsData`,
method: 'get',
params
})
}
export function TrendOrderDataAPI(params) { //订单统计
return request({
url: `${requestPath.order}/order/statistic`,
method: 'get',
params
})
}
import request from '@/utils/request1'
import { requestPath } from '@/utils/global.js'
export function getPhysicalCodeAPI(oid) { //一册一码数据统计
return request({
url: `${requestPath.resource}/statistics/physicalCode-statistics?phyId=${oid}`,
method: 'get'
})
}
export function memberRelativeAPI() { //用户数据概览
return request({
url: `${requestPath.statistics}/api/sta/member/relative`,
method: 'get'
})
}
export function trendEchartsDataAPI(params) { //用户趋势统计
return request({
url: `${requestPath.statistics}/api/sta/member/trendEchartsData`,
method: 'get',
params
})
}
export function ageEchartsAPI() { //统计用户年龄分布
return request({
url: `${requestPath.statistics}/api/sta/member/ageEcharts`,
method: 'get'
})
}
export function educationalEchartsAPI() { //统计用户学历
return request({
url: `${requestPath.statistics}/api/sta/member/educationalEcharts`,
method: 'get'
})
}
export function sexEchartsAPI() { //统计用户性别分布
return request({
url: `${requestPath.statistics}/api/sta/member/sexEcharts`,
method: 'get'
})
}
export function memberRegionAPI() { //用户地域占比
return request({
url: `${requestPath.statistics}/api/sta/member/region`,
method: 'get'
})
}
\ No newline at end of file
<template>
<div>
<div ref="echarts" v-show="flag" class="echarts"></div>
<div class="no_data" v-show="!flag">暂无数据</div>
</div>
</template>
<script>
import * as echarts from 'echarts';
export default {
data(){
return {
myChart:null
}
},
props:{
height:{
type:Number/String,
default:300
},
flag:{
type:Boolean,
default:true
}
},
mounted(){
window.addEventListener('resize', () => {
this.myChart.resize();
})
},
methods:{
initEcharth(option){
this.$refs.echarts.style.height=this.height + 'px'
this.myChart = echarts.init(this.$refs.echarts)
option && this.myChart.setOption(option);
},
}
}
</script>
<style scoped lang="scss">
.no_data{
height: 100%;
line-height: 1;
text-align: center;
}
</style>
\ No newline at end of file
......@@ -83,7 +83,7 @@
},
series: [
{
name: '访问来源',
name: '资源数量',
type: 'pie',
radius: '70%',
center: ['50%', '60%'],
......
import Layout from '@/layout'
const statisticsRouter = {
path: '/statistics_manage',
component: Layout,
redirect: '/statistics_manage/course',
name: 'statistics',
// alwaysShow: true,
meta: {
title: '统计分析',
icon: 'marketing'
},
children: [
{
path: 'course',
component: () => import('@/views/statistics_manage/course/index'),
name: 'courseStatistics',
meta: {
title: '课程学习统计分析'
}
},
{
path: 'department',
component: () => import('@/views/statistics_manage/department/index'),
name: 'departmentStatistics',
meta: {
title: '部门工作量统计分析'
},
path: '/statistics_manage',
component: Layout,
redirect: '/statistics_manage/resource_module',
name: 'statistics',
meta: {
title: '统计管理',
},
]
}
children: [
{
path: 'resource_module',
component: () => import('@/views/statistics_manage/resource_module/index'),
name: 'resource_module',
meta: { title: '资源统计'}
},{
path: 'traffic_module',
component: () => import('@/views/statistics_manage/traffic_module/index'),
name: 'traffic_module',
meta: { title: ' 一册一码统计'}
}
]
}
export default statisticsRouter
\ No newline at end of file
export default statisticsRouter
......@@ -53,6 +53,21 @@ export function formatSortQue(arr) {
return formatArr
}
export function formatDepartQue(arr) {
let formatArr = []
function formatFun(arr) {
arr.forEach(item => {
formatArr.push({ code: item.code, label: item.departmentName })
if (item.list.length > 0) {
formatFun(item.list)
}
})
}
formatFun(arr)
return formatArr
}
export function stitchData(allData, data) {
let name = data.showName
......
......@@ -145,4 +145,15 @@ export const invoiceTypeList = { //财务管理-发票管理-发票类型
export const invoiceStatusList = { //财务管理-发票管理-发票状态
'0': '成功',
'1': '失败',
}
\ No newline at end of file
}
export const resourcStaticList=[
{label:'纸质书',value:1},
{label:'电子书',value:2},
{label:'文章',value:3},
{label:'视频',value:5},
{label:'音频',value:6},
{label:'专题',value:7},
{label:'图片',value:9},
{label:'附件',value:12},
]
\ No newline at end of file
......@@ -276,7 +276,7 @@ import searchDia from "@/components/dialog/searchTips";
this.changeUpdata('1', "上架");
},
soldOutBtn: () => {
this.changeUpdata('2', "下架");
this.changeUpdata('0', "下架");
},
createBtn: () => { //新建
this.createdArticle();
......@@ -424,7 +424,7 @@ import searchDia from "@/components/dialog/searchTips";
}
let ids = getSelectionIds(this.chooiceList);
let deleteList = []
if(status == '2'){
if(status == '0'){
deleteList = await deleteCheckAPI({resourceType:3,ids}).then(res => {
if(res.data.code == 0){
return res.data.data
......
......@@ -41,7 +41,7 @@
</template>
</el-table-column>
<el-table-column prop="verifyNum" align="center" label="验证数量" min-width="8%"/>
<el-table-column prop="conversionPlain" label="兑换码明码" min-width="12%" align="center"></el-table-column>
<!-- <el-table-column prop="conversionPlain" label="兑换码明码" min-width="12%" align="center"></el-table-column> -->
<el-table-column label="操作" min-width="15%" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" v-for="(item,index) in lineBtn" @click="handleBtn(item.url,scope.row.id)" :key="index">{{item.name}}</el-button>
......
......@@ -77,6 +77,9 @@
</el-form-item>
<el-form-item label="购买链接:" prop="purchaseAdd">
<el-input v-model="dataForm.purchaseAdd" style="width:85%;"></el-input>
</el-form-item>
<el-form-item label="所属部门:" prop="departmentName" v-if="dataForm.departmentName">
<el-input v-model="dataForm.departmentName" style="width:85%;" disabled></el-input>
</el-form-item>
</div>
</div>
......@@ -183,6 +186,12 @@
<el-radio :label="'2'"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否展示图书二维码:" prop="isQRCode" label-width="160px">
<el-radio-group v-model="dataForm.isQRCode">
<el-radio :label="'1'"></el-radio>
<el-radio :label="'2'"></el-radio>
</el-radio-group>
</el-form-item>
<!-- 0 免费,1收费 , -->
<!-- <el-form-item label="运费:" prop="shippingCostType">
<el-radio-group v-model="dataForm.shippingCostType">
......@@ -297,6 +306,7 @@ export default {
digest: null,
shippingCostType:'0',
activation:'1',
isQRCode:'1'
},
value:null,
rules: {
......
......@@ -32,10 +32,16 @@
<div class="departSearch">
<el-form :model="listQuery" ref="listQuery" label-width="95px">
<el-form-item label="部门检索:">
<el-select v-model="listQuery.departmentCode" clearable placeholder="请选择" @change="searchDepart">
<el-option label="全部" :value="null"></el-option>
<el-option v-for="(item,index) in departList" :key="'depart'+index" :label="item.departmentName" :value="item.code"></el-option>
</el-select>
<el-popover popper-class="category-popover" placement="bottom-start" trigger="click" ref="popover">
<el-tree :data="departList" node-key="code" :props="defaultProps2"
:highlight-current="true" :expand-on-click-node="false"
:current-node-key="typeName" @node-click="handleDepartNodeClick"
style=" max-height: 400px; overflow-y: auto; width:380px;"></el-tree>
<el-select v-model="typeName" style="width:400px" popper-class="hidden-selection" slot="reference">
<el-option :value="null" label="全部"></el-option>
<el-option v-for="item in options" :key="item.code" :label="item.departmentName" :value="item.code"></el-option>
</el-select>
</el-popover>
</el-form-item>
</el-form>
</div>
......@@ -117,7 +123,7 @@
</el-table-column>
<el-table-column label="操作" min-width="18%" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" v-for="(item,index) in lineBtn" @click="handleBtn(item.url,scope.row.id,scope.row.name,scope.row.isbn)" :key="index">
<el-button type="text" size="small" v-for="(item,index) in lineBtn" @click="handleBtn(item.url,scope.row)" :key="index">
<span v-if="item.url == 'removeLine' && scope.row.status == '2'">{{item.name}}</span>
<span v-if="item.url == 'viewLine' && scope.row.status == '1'">{{item.name}}</span>
<span v-if="item.url != 'viewLine' && item.url != 'removeLine'">{{item.name}}</span>
......@@ -185,6 +191,7 @@ import editSort from "@/components/dialog/editSort";
import importDia from "@/components/dialog/importExcel";
import { baseUrl, pcUrl, requestPath } from "@/utils/global";
import { departListAPI } from '@/api/departManage.js'
import { formatDepartQue } from '@/utils/format'
import axios from "axios";
import queryString from "query-string";
export default {
......@@ -224,7 +231,8 @@ import queryString from "query-string";
endTime: null,
option: null,
seriesname: null,
status: ""
status: '',
departmentCode:null,
},
total: null,
listLoading: false,
......@@ -244,6 +252,12 @@ import queryString from "query-string";
priceForm: {},
sending: null,
departList:[],
options:[],
typeName: null,
defaultProps2: {
children: 'list',
label: 'departmentName'
},
}
},
mounted() {
......@@ -266,13 +280,17 @@ import queryString from "query-string";
getDepartList(){
departListAPI().then((res) => {
this.departList = res
this.options = formatDepartQue(this.departList)
this.departList.unshift({departmentName:'全部',code:''})
}).catch((res) => {
this.$message.error(res)
})
},
searchDepart(val){
this.listQuery.departmentCode = val
handleDepartNodeClick(data) {//点击分类--搜索
this.typeName = data.departmentName
this.listQuery.departmentCode = data.code
this.getList(1)
this.$refs.popover.doClose()
},
downLoadTemplate(){
// baseUrl
......@@ -339,7 +357,7 @@ import queryString from "query-string";
this.listQuery.option = type
this.$forceUpdate()
},
handleBtn(btnName, id, name, isbn) {
handleBtn(btnName,item) {
let status = { //按钮事件
importBtn: () => { //导入
// this.dialogImport = true;
......@@ -355,17 +373,17 @@ import queryString from "query-string";
this.createdBook();
},
editLine: () => { //编辑
this.createdBook(id);
this.createdBook(item.id);
},
viewLine: () => { //预览
// this.$message.success("打开pc端详情");
window.open(pcUrl+'/resource/paperBookDetail?id=' + id)
window.open(pcUrl+'/resource/paperBookDetail?id=' + item.id)
},
recommendLine: () => { //推荐内容
this.goRecommend(id);
this.goRecommend(item);
},
removeLine: () => { //删除
this.removeData(id);
this.removeData(item.id);
},
batchRemoveBtn: () => { //批量删除
this.removeData();
......@@ -377,19 +395,26 @@ import queryString from "query-string";
this.changePrice();
},
changeCodeLine: () => { //防伪码
this.goChangeCodePage(id,name)
this.goChangeCodePage(item.id,item.name)
},
resourceCodeLine: () => { //资源码
this.goResourceCodePage(id,name,isbn)
this.goResourceCodePage(item.id,item.name,item.isbn)
},
batchDownloadQRcodeBtn: () => {//批量下载二维码
this.downLoadData();
},
downloadQRcodeLine: () => { //单独下载二维码
this.downLoadData(item.id);
}
};
status[btnName]();
},
goRecommend(id){
this.$router.push({path:'/resource_manage/recommendedContent',query:{id:id,type:1}})
goRecommend(item){
if(item.activation){
this.$router.push({path:'/resource_manage/recommendedContent',query:{id:item.id,type:1,activation:item.activation}})
}else{
this.$router.push({path:'/resource_manage/recommendedContent',query:{id:item.id,type:1}})
}
},
goChangeCodePage(id,name){
this.$router.push({path:'/resource_manage/change_code',query:{id:id,currentBookName:name}})
......@@ -432,9 +457,7 @@ import queryString from "query-string";
getList(num) {
this.listLoading = true;
this.listQuery.pageNum = num ? num : this.listQuery.pageNum
let obj = {}
obj = this.collapse ? this.listQuery : {params:this.listQuery.params,diyTypeCode:this.listQuery.diyTypeCode,pageNum:this.listQuery.pageNum,pageSize:this.listQuery.pageSize,status:this.listQuery.status,orderBy:this.listQuery.orderBy,seriesname:this.listQuery.seriesname}
bookListAPI(obj).then(res => {
bookListAPI(this.listQuery).then(res => {
if (res.data.code === 0) {
this.dataList = res.data.data.list?res.data.data.list:[];
this.total = res.data.data.total?res.data.data.total:0;
......@@ -574,12 +597,10 @@ import queryString from "query-string";
this.$message.warning("请先下架,再删除数据");
}
},
downLoadData() {//下载图书二维码
if (this.isExist(this.chooiceList)) {//至少选中一条
let ids = getSelectionIds(this.chooiceList);
downLoadData(id) {//下载图书二维码
if(id){
let data = {
ids:ids,
isCode:this.downLoadType
ids:[id]
}
let {...params} = data
let tempParams = {}
......@@ -592,7 +613,26 @@ import queryString from "query-string";
confirm.apply(this, ["确定下载选择的图书二维码吗?"]).then(() => {
window.open(`${process.env.VUE_APP_BASE_API}${requestPath.resource}/phy/batch/downloadOneCode?${paramStr}`)
});
}else{
if (this.isExist(this.chooiceList)) {//至少选中一条
let ids = getSelectionIds(this.chooiceList);
let data = {
ids:ids
}
let {...params} = data
let tempParams = {}
for (const key in params) {
if (({}).hasOwnProperty.call(params, key) && params[key]!== null && params[key]!== '' && params[key]!== undefined) {
tempParams[key] = params[key]
}
}
let paramStr = queryString.stringify(tempParams)
confirm.apply(this, ["确定下载选择的图书二维码吗?"]).then(() => {
window.open(`${process.env.VUE_APP_BASE_API}${requestPath.resource}/phy/batch/downloadOneCode?${paramStr}`)
});
}
}
},
selectionChange(val) {
//勾选table
......
......@@ -56,7 +56,7 @@
</el-table-column>
<el-table-column label="操作" min-width="10%" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" v-for="(item,index) in lineBtn" @click="handleBtn(item.url,scope.row.id,scope.row.sort)" v-if="(item.url != 'removeLine' || scope.row.status == 0)" :key="index">{{item.name}}</el-button>
<el-button type="text" size="small" v-for="(item,index) in lineBtn" @click="handleBtn(item.url,scope.row)" v-if="(item.url != 'removeLine' || scope.row.status == 0)" :key="index">{{item.name}}</el-button>
</template>
</el-table-column>
</el-table>
......@@ -87,6 +87,16 @@
<content-dialog :type='listQuery.type' :showDialog.sync="dialogContent" :bookId="$route.query.id" :code="listQuery.code" @close='dialogContent = false' @saveContent="getList"></content-dialog>
<catalogue-dialog :showDialog.sync="dialogCatalogue" :phyId="$route.query.id" @close='moduleClose' @saveContent="getAllModule"></catalogue-dialog>
<!-- 查看二维码弹窗 -->
<el-dialog title="查看二维码" :visible.sync="qrCodeViewDialog" width="450px" :close-on-click-modal="false" @close="closeQrCode">
<div class="codeBox">
<div id="qrCodeUr" ref="qrCodeUrBox"></div>
</div>
<span class="dialog-footer" style="text-align:center;width:100%;display:inline-block">
<el-button @click="qrCodeViewDialog = false">关 闭</el-button>
</span>
</el-dialog>
</el-card>
</div>
</template>
......@@ -101,6 +111,7 @@ import contentDialog from './content_dialog.vue'
import catalogueDialog from './module.vue'
import { baseUrl, pcUrl, requestPath } from "@/utils/global";
import queryString from "query-string";
import QRCode from "qrcodejs2";
export default {
components:{
contentDialog,
......@@ -108,12 +119,13 @@ export default {
},
data() {
return {
baseUrl,
topBtn:[],
lineBtn:[],
specialList,
filterStatus:[
{text:'电子书',value:2},
{text:'纸质书',value:1},
// {text:'电子书',value:2},
// {text:'纸质书',value:1},
// {text:'文章',value:3},
{text:'视频',value:5},
{text:'音频',value:6},
......@@ -163,6 +175,9 @@ export default {
code: 'code'
},
dialogCatalogue:false,
activation:'',
qrCodeViewDialog:false,
currentQrCode:'',
}
},
created() {
......@@ -189,6 +204,7 @@ export default {
},0)
this.listQuery.id = this.$route.query.id
this.listQuery.type = this.$route.query.type == 4 ? 2 : this.$route.query.type
this.activation = this.$route.query.activation?this.$route.query.activation:null
this.getAllModule()
this.getList()
......@@ -242,12 +258,12 @@ export default {
this.listLoading = false
})
},
handleBtn(btnName,id,sort) {
handleBtn(btnName,item) {
let status = {
'editSortLine':()=>{ //修改排序
this.dialogOrder = true;
this.sortId = id;
this.sortForm.sort = sort;
this.sortId = item.id;
this.sortForm.sort = item.sort;
this.$nextTick(()=>{
this.$refs['sortForm'].resetFields();
})
......@@ -263,9 +279,53 @@ export default {
'batchDownloadQRcodeBtn': () => {//批量下载二维码
this.downLoadData();
},
'lookCodeLine': () => {
this.lookCode(item)
}
}
status[btnName]()
},
//查看二维码
lookCode(item){
this.qrCodeViewDialog = true
if(item.resourceType == '5'){
setTimeout(() => {
let qr = new QRCode('qrCodeUr', {
text: this.baseUrl + '/h5/resource/video/index?id=' + item.resourceId + '&activation=' + this.activation + '&phyId=' + this.$route.query.id + '&priceOption=' + item.priceOption + '&isDownload=' + item.isDownload,
width: 200,
height: 200,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
})
},1000)
}else if(item.resourceType == '6'){
setTimeout(() => {
let qr = new QRCode('qrCodeUr', {
text: this.baseUrl + '/h5/resource/audioBook/detail?id=' + item.resourceId + '&activation=' + this.activation + '&phyId=' + this.$route.query.id + '&priceOption=' + item.priceOption + '&isDownload=' + item.isDownload,
width: 200,
height: 200,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
})
},1000)
}else if(item.resourceType == '9'){
setTimeout(() => {
let qr = new QRCode('qrCodeUr', {
text: this.baseUrl + '/h5/resource/picture/detail?id=' + item.resourceId + '&activation=' + this.activation + '&phyId=' + this.$route.query.id + '&priceOption=' + item.priceOption + '&isDownload=' + item.isDownload,
width: 200,
height: 200,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
})
},1000)
}
},
closeQrCode(){
this.$refs.qrCodeUrBox.innerHTML = ''
},
removeData() {//删除数据
if(this.isExist(this.chooiceList)){//至少选中一条
confirm.apply(this,['确定批量取消选择的数据吗?']).then(() => {
......@@ -344,6 +404,17 @@ export default {
}
</script>
<style lang="scss" scoped>
.codeBox{
width: 100%;
height: 220px;
display:flex;
justify-content: center;
align-items: center;
.codeSize{
width:200px;
height: 200px;
}
}
//左侧列表样式
.catalogueOther{
padding-left: 260px;
......
......@@ -11,6 +11,12 @@
<el-input v-model="listQuery[item.name]" @keyup.enter.native="getList(1)"
:placeholder="item.placeholder" clearable></el-input>
</el-form-item>
<el-form-item label="是否需登录:">
<el-radio-group v-model="listQuery.priceOption">
<el-radio :label="'3'"></el-radio>
<el-radio :label="'2'"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList(1)" icon="el-icon-search">检索</el-button>
</el-form-item>
......@@ -20,7 +26,13 @@
<el-table-column type="selection" ref="selectionCheckbox"></el-table-column>
<el-table-column prop="name" label="资源名称" min-width="17%" show-overflow-tooltip></el-table-column>
<el-table-column prop="author" min-width="10%" label="作者" align="center" v-if="listQuery.resourceType != 7 && listQuery.resourceType != 10"></el-table-column>
<el-table-column label="上传时间" min-width="15%" align="center">
<el-table-column label="是否需登陆" min-width="10%" align="center">
<template slot-scope="scope">
<span v-if="scope.row.priceOption == '3'">需登录</span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="上传时间" min-width="12%" align="center">
<template slot-scope="scope">
<span v-if="scope.row.createdTime">{{scope.row.createdTime}}</span>
<span v-else>{{scope.row.uploadTime}}</span>
......@@ -67,14 +79,15 @@ export default {
id:null,
pageSize: 50,
pageNum:1,
resourceType:2,
resourceType:5,
priceOption:null,
type:null
},
openDialog:false,
total: null,
sending: false,
// resourceList:[{id:2,name:'电子书'},{id:1,name:'纸质书'},{id:3,name:'文章'},{id:5,name:'视频'},{id:6,name:'音频'},{id:10,name:'课程'},{id:11,name:'有声书'},{id:7,name:'专题'}],
resourceList:[{id:2,name:'电子书'},{id:1,name:'纸质书'},{id:5,name:'视频'},{id:6,name:'音频'},{id:9,name:'图片'}],
resourceList:[{id:5,name:'视频'},{id:6,name:'音频'},{id:9,name:'图片'}],
}
},
props:['showDialog','bookId','code','type'],
......@@ -89,6 +102,8 @@ export default {
this.listQuery.resourceType = 5
}else if(parseInt(this.type) == 4){
this.listQuery.resourceType = 2
}else if(parseInt(this.type) == 1){
this.listQuery.resourceType = 5
}else{
this.listQuery.resourceType = parseInt(this.type)
}
......
<template>
<div>
<el-popover placement="bottom" :width="width" trigger="click" v-model="flag" style="min-width:146px">
<div class="popover_box">
<div class="left">{{title}}:</div>
<div class="right">
<div class="list" v-for="(item,index) in list" :key="index" :class="selectValue == item.label ? 'check':''" @click="checkList(index,item)">{{item.label}}</div>
</div>
</div>
<div class="select_box" slot="reference">
<div class="select_title">{{title}}:</div>
<div class="select_name">{{selectValue}}</div>
<img src="./xl.png" class="select_xl_img" :class="flag?'show':''">
</div>
</el-popover>
</div>
</template>
<script>
import {resourcStaticList} from '@/utils/static'
export default {
data(){
return{
flag:false,
selectValue:'',
}
},
props:{
title:{
type:String,
default:'资源类型'
},
list:{
type:Array,
default:() => resourcStaticList
},
width:{
type:Number,
default:146
}
},
created(){
this.selectValue = this.list.length > 0 ? this.list[0].label : ''
},
methods:{
checkList(i,e){
if(this.selectValue == this.list[i].label){
return false
}
this.selectValue = this.list[i].label
this.flag = false
this.$emit('change',e)
}
}
}
</script>
<style lang="scss" scoped>
.popover_box{
padding: 10px 0;
box-sizing: border-box;
display: flex;
justify-content: flex-start;
.left{
min-width: 50px;
max-width: 70px;
font-size: 14px;
padding-right: 10px;
box-sizing: border-box;
color: #82899B;
line-height: 32px;
}
.list{
font-size: 14px;
color: #485166;
line-height: 32px;
cursor: pointer;
&.check{
color: #136CFC;
font-weight: bold;
}
}
}
.select_box{
cursor: pointer;
min-width: 146px;
max-width: 150px;
height: 28px;
line-height: 28px;
background: #FFFFFF;
border: 1px solid #B9BFC7;
border-radius: 4px;
display: flex;
box-sizing: border-box;
padding: 0 8px 0 6px;
justify-content: space-between;
align-items: center;
.select_title{
font-size: 14px;
font-weight: 500;
color: #7F8B9C;
min-width: 30px;
max-width: 60px;
}
.select_name{
font-size: 14px;
font-weight: 500;
color: #485166;
min-width:50px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.select_xl_img{
width: 10px;
height: 10px;
transition-duration: 0.3s;
&.show{
transform: rotate(-180deg);
}
}
}
</style>
\ No newline at end of file
<template>
<div>
<el-popover placement="bottom-end" width="280" trigger="click" v-model="flag">
<div class="popover_box">
<div class="tips">提示:至少选择两项</div>
<div>
<el-checkbox-group v-model="checkList" :min="2" class="checkbox_group_box" @change="checkChange">
<el-checkbox :label="item.label" v-for="(item,index) in list" :key="index" class="checkbox_list"></el-checkbox>
</el-checkbox-group>
</div>
</div>
<div class="select_box" slot="reference">
<div class="select_title">{{title}}:</div>
<div class="select_name">{{selectValue}}</div>
<img src="./xl.png" class="select_xl_img" :class="flag?'show':''">
</div>
</el-popover>
</div>
</template>
<script>
import {resourcStaticList} from '@/utils/static'
export default {
data(){
return{
list:resourcStaticList,
checkList:[],
flag:false
}
},
props:{
title:{
type:String,
default:'资源'
}
},
created(){
this.checkList = this.list.map(item => {return item.label})
},
computed:{
selectValue(){
return this.checkList.join(',')
}
},
methods:{
checkChange(e){
this.$emit('change',e)
}
}
}
</script>
<style lang="scss" scoped>
.popover_box{
padding: 10px;
box-sizing: border-box;
.tips{
font-size: 14px;
font-weight: 500;
color: #F89514;
}
.checkbox_group_box{
display: flex;
flex-wrap: wrap;
margin-top: 6px;
.checkbox_list{
width: 50%;
box-sizing: border-box;
padding-left: 10px;
margin: 10px 0 0;
}
}
}
.select_box{
cursor: pointer;
min-width: 162px;
max-width: 200px;
height: 28px;
line-height: 28px;
background: #FFFFFF;
border: 1px solid #B9BFC7;
border-radius: 4px;
display: flex;
box-sizing: border-box;
padding: 0 8px 0 6px;
justify-content: space-between;
align-items: center;
.select_title{
font-size: 14px;
font-weight: 500;
color: #7F8B9C;
min-width: 35px;
}
.select_name{
font-size: 14px;
font-weight: 500;
color: #485166;
width: 94px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.select_xl_img{
width: 10px;
height: 10px;
transition-duration: 0.3s;
&.show{
transform: rotate(-180deg);
}
}
}
</style>
\ No newline at end of file
<template>
<div>
<div class="divBox">
<el-card class="box-card">
<div class="date_box">
<div class="title">数据概览</div>
<div class="date" v-if="updateTime">更新时间:{{updateTime}}</div>
</div>
<div class="box">
<div v-for="(item,index) in list" :key="index" class="list_box">
<div class="name">{{item.name}}</div>
<div class="count">{{item.count}}</div>
<div class="bot_box">
<div class="bot">
<span>较上周</span>
<span :class="item.link > 0?'up':'doun'">
{{Math.abs(item.link).toFixed(2)}}%<i :class="item.link >= 0 ? 'el-icon-caret-top':'el-icon-caret-bottom'"></i>
</span>
</div>
<div class="bot">
<span>较昨日</span>
<span :class="item.link > 0?'up':'doun'">
{{Math.abs(item.thanLastWeek).toFixed(2)}}%<i :class="item.thanLastWeek >= 0 ? 'el-icon-caret-top':'el-icon-caret-bottom'"></i>
</span>
</div>
</div>
</div>
</div>
</el-card>
</div>
</div>
</template>
<script>
export default {
data() {
return {
}
},
props:{
list:{
type:Array,
default:() => []
},
updateTime:{
type:String,
default:''
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.divBox{
padding-bottom:0;
margin-bottom:20px;
}
.date_box{
display: flex;
align-items: center;
padding-left: 16px;
padding-bottom: 4px;
.title{
font-size: 20px;
}
.date{
font-size: 14px;
color: #666;
margin-left: 15px;
}
}
/deep/.el-card__body{
padding: 20px 0 0;
}
.bot_box{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding-top: 15px;
}
.box{
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
padding-left: 30px;
}
.list_box{
flex-shrink: 0;
padding: 12px 14px;
margin-right: 30px;
margin-bottom: 30px;
border: 1px solid #ccc;
border-radius: 10px;
box-sizing: border-box;
width: 280px;
}
.name{
font-size: 16px;
font-weight: 500;
color: #485166;
}
.count{
font-size: 30px;
font-weight: bold;
color: #485166;
margin-top: 10px;
}
.bot{
font-size: 14px;
}
.bot1{
margin-left: 5px;
}
.up, .el-icon-caret-top {
color: #E40000;
font-size: 14px;
opacity: 1 !important;
}
.down, .el-icon-caret-bottom {
color: #0DB771;
font-size: 14px;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="top_box">
<div class="top_title">课程详情</div>
</div>
<top :list="topList"></top>
<div class="divBox">
<el-row :gutter="24">
<el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<div>
<span class="ivu-pl-8">学习情况统计</span>
<span class="date_title">统计日期:</span>
<el-date-picker class="date_box" v-model="dateValue" value-format="yyyy-MM-dd" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
<span v-for="(item,index) in tabList" class="tab_span" :key="index" :class="item.check ? 'check':''" @click="tabChange(index,item)">{{item.name}}</span>
</div>
</div>
</div>
<div class="echarts_box">
<div class="select_box">
<select-box title="渠道" :list="irrigationDitchList" @change="irrigationDitchChange"></select-box>
<select-box title="纬度" :list="dimensionList" class="dimension" @change="dimensionChange"></select-box>
</div>
<echarts1 ref="chart_one" :height="319"></echarts1>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="24" class="el_row_box">
<el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<span class="ivu-pl-8">年龄占比</span>
</div>
</div>
<div class="echarts_box1">
<echarts1 ref="chart_two" :height="319"></echarts1>
</div>
</el-card>
</el-col>
<el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<span class="ivu-pl-8">完学率统计</span>
</div>
</div>
<div class="echarts_box1">
<echarts1 ref="chart_three" :height="319"></echarts1>
</div>
</el-card>
</el-col>
<el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<span class="ivu-pl-8">用户来源占比</span>
</div>
</div>
<div class="echarts_box1">
<echarts1 ref="chart_four" :height="319"></echarts1>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="24" class="el_row_box">
<el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<span class="ivu-pl-8">用户学习详情</span>
</div>
</div>
<div class="table_box">
<table-box></table-box>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import echarts1 from '@/components/echarts/echarts.vue'
import top from '../components/top.vue'
import selectBox from '../components/selectBox.vue'
import tableBox from './detail_table.vue'
export default {
name:'curriculum_detail',
components:{
top,echarts1,tableBox,selectBox
},
data() {
return {
listLoading:false,
dateValue:[],
topList:[],
tableData:[],
dimensionName:'学习时长',
dimensionList:[
{label:'学习时长',value:1},
{label:'学习人数',value:2},
],
irrigationDitchList:[
{label:'全部',value:1},
{label:'PC端',value:2},
{label:'移动端',value:3},
],
tabList:[
{name:'按时',check:false,value:1},
{name:'按日',check:true,value:2},
{name:'按周',check:false,value:3},
{name:'按月',check:false,value:4},
],
}
},
mounted() {
this.topList = [
{name:'学生数量',count:800,link:'-12.14',thanLastWeek:'1.18'},
{name:'课程素材量',count:90,link:'-12.14',thanLastWeek:'1.18'},
{name:'日活跃度',count:9700,link:'-12.14',thanLastWeek:'1.18'},
{name:'周活跃度',count:340,link:'-12.14',thanLastWeek:'1.18'},
{name:'月活跃度',count:48,link:'-12.14',thanLastWeek:'1.18'},
{name:'人均日学习时长',count:'65min',link:'-12.14',thanLastWeek:'1.18'}
]
this.getLearningSituation()
this.getSourceMaterial()
this.getFinish()
this.getSource()
},
methods: {
getLearningSituation(){
let xData = ['10/06','10/07','10/08','10/09','10/10','10/11','10/12']
let yData = [50,100,130,80,65,50,80]
this.echartsOne(xData,yData)
},
echartsOne(list1,list2){
let option = {
tooltip: {
trigger: 'axis',
formatter:'{b}'+this.dimensionName+':{c}'
},
grid:{
bottom:80,
left:50,
right:50
},
xAxis: {
type: 'category',
data: list1,
axisLabel:{
interval:0,
rotate:30
}
},
yAxis: {
type: 'value'
},
series: [
{
data: list2,
color:'#FAC858',
type: 'line'
}
]
}
this.$refs.chart_one.initEcharth(option)
},
getSourceMaterial(){
let data = [
{name:'视频',value:50},
{name:'音频',value:100},
{name:'题库',value:130},
{name:'数字教材',value:80},
{name:'电子书',value:65},
{name:'随书资源',value:105},
]
let option = this.echartsTwo(data)
this.$refs.chart_two.initEcharth(option)
},
getFinish(){
let data = [
{name:'已完成',value:105},
{name:'未完成',value:100}
]
let option = this.echartsTwoOption(data,205,'#FAC858','#EE6666','','总人数','')
this.$refs.chart_three.initEcharth(option)
},
getSource(){
let data = [
{name:'移动端',value:480},
{name:'PC端',value:300},
]
let option = this.echartsTwo(data)
this.$refs.chart_four.initEcharth(option)
},
echartsTwo(data){
let option = {
tooltip: {
trigger: 'item',
formatter:'{b}:{c},{d}%'
},
legend: {
orient: 'horizontal',
y:'bottom'
},
label:{
formatter:'{b}\n {c},{d}%'
},
color:['#FF9900','#B37FEB','#31BFFD','#19BE6B','#EE6666','#FAC858','#1890FF','#fd0000','#5470C6','#4f47c1'],
series: [
{
type: 'pie',
radius: '50%',
data: data
}
]
}
return option
},
echartsTwoOption(data,total,color1,color2,dw,totalContent,labelName){
let str = labelName ? labelName :''
let option = {
tooltip: {
trigger: 'item',
formatter:'{b}{c},\n{d}% ' + dw
},
legend: {
orient: 'vertical',
left: 'left'
},
label:{
formatter:'{b}'+str+'{c},\n{d}%' + dw
},
title: {
text: total + dw + "\n" + totalContent,
left: "center",
top: "center",
padding: [0, 0],
textStyle: {
fontWeight:'500',
color: "#485166",
fontSize: 14,
align: "center",
lineHeight: 20,
},
},
color:[color1,color2],
series: [
{
type: 'pie',
radius: ['40%', '65%'],
data: data,
itemStyle: {
borderColor: '#fff',
borderWidth: 2
},
}
]
}
return option
},
dimensionChange(e){
this.dimensionName = e.label
},
irrigationDitchChange(e){
},
tabChange(i,e){
this.tabList.forEach((item,index) => {
item.check = false
if(index == i){
item.check = true
}
})
// if(this.trendObj.statisticsType != e.value){
// this.trendObj.statisticsType = e.value
// this.getResourceTrend()
// }
},
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/top_common.scss';
.select_box{
display: flex;
justify-content: flex-end;
.dimension{
margin-left: 20px;
}
}
.flex{
display: flex;
justify-content: space-between;
align-items: center;
}
.tab_span{
margin-left: 10px;
cursor: pointer;
font-size: 12px;
font-weight: bold;
color: #7F8B9C;
padding: 5px 9px;
border: 1px solid #B9BFC7;
border-radius: 4px;
&:first-of-type{
margin: 0;
}
}
.check{
color: #0DB771;
background: #E7FAF0;
border: 1px solid #81E5BC;
border-radius: 4px;
}
.divBox{
padding: 0 16px;
}
.ivu-pl-8{
font-size: 16px;
font-weight: bold;
color: #485166;
}
.echarts_box{
box-sizing: border-box;
height: 379px;
width: 100%;
}
.el_row_box{
margin-top: 16px;
}
/deep/.el-table__body{
width: 100% !important;
}
/deep/.el-table__empty-block{
width: 100% !important;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="container">
<el-form inline size="small" :model="listQuery" ref="listQuery">
<el-form-item label="学习天数:">
<el-input v-model="listQuery.num1" clearable class="num"/>
——
<el-input v-model="listQuery.num2" clearable class="num"/>
</el-form-item>
<el-form-item label="">
<el-input v-model="listQuery.name" placeholder="请输入学员姓名" clearable />
</el-form-item>
<el-form-item>
<div class="search_btn" @click="getList(1)">
<img src="@/assets/img/common/ico-sousuo.png" />
检索
</div>
</el-form-item>
<el-form-item label="">
<el-button type="primary">导出数据</el-button>
</el-form-item>
</el-form>
</div>
<el-table ref="table" class="table_box" :border="true" v-loading="listLoading" :data="dataList" highlight-current-row >
<el-table-column type="index" align="center" label="序号" width="60"> </el-table-column>
<el-table-column label="姓名" align="center" prop="name" min-width="15%" show-overflow-tooltip> </el-table-column>
<el-table-column prop="source" align="center" label="来源" min-width="10%"> </el-table-column>
<el-table-column prop="timeLength" align="center" label="学习时长" min-width="10%"></el-table-column>
<el-table-column prop="studyNum" align="center" label="学习天数" min-width="10%"></el-table-column>
<el-table-column prop="viewsNum" align="center" label="浏览次数" min-width="10%"></el-table-column>
<el-table-column prop="averageNum" align="center" label="日均学习时长" min-width="10%"></el-table-column>
<el-table-column prop="accomplish" align="center" label="完成率" min-width="10%"></el-table-column>
</el-table>
<div class="block">
<el-pagination
@size-change="sizeChange"
@current-change="currentChange"
:current-page="listQuery.pageNum"
:page-sizes="[30, 50, 100, 200]"
:page-size="listQuery.pageSize"
layout="total, prev, pager, next, sizes, jumper"
:total="total"
/>
</div>
</div>
</template>
<script>
export default {
data(){
return {
listLoading:false,
dataList:[],
listQuery:{
pageNum: 1,
pageSize: 30,
name: null,
num1:null,
num2:null
},
total:10
}
},
created(){
this.getList()
},
methods:{
getList(){
this.dataList = []
for(var i=0;i<10;i++){
let obj = {
name:'工程原理第一期',
source:i < 5 ? 'PC端' :'移动端',
timeLength:'10小时12分钟45秒',
studyNum:'3天',
viewsNum:15,
averageNum:'1小时12分钟45秒',
accomplish:'30%',
}
this.dataList.push(obj)
}
},
sizeChange(val){
this.listQuery.pageSize = val
this.getList()
},
currentChange(val) {
this.listQuery.pageNum = val
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
.flex{
display: flex;
justify-content: flex-start;
align-items: center;
}
.num{
width: 100px;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="top_box">
<div class="top_title">课程统计</div>
</div>
<top :list="topList"></top>
<div class="divBox">
<el-row :gutter="24">
<el-col :xl="16" :lg="16" :md="16" :sm="16" :xs="16">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle flex">
<span class="ivu-pl-8">各类课程学习时长</span>
<div>
<span v-for="(item,index) in tabList" class="tab_span" :key="index" :class="item.check ? 'check':''" @click="tabChange(index,item)">{{item.name}}</span>
</div>
</div>
</div>
<div class="echarts_box">
<echarts1 ref="chart_one" :height="319"></echarts1>
</div>
</el-card>
</el-col>
<el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<span class="ivu-pl-8">课程分类占比</span>
</div>
</div>
<div class="echarts_box">
<echarts1 ref="chart_two" :height="319"></echarts1>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="24" class="el_row_box">
<el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<span class="ivu-pl-8">课程明细表</span>
</div>
</div>
<div class="table_box">
<table-box></table-box>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import echarts1 from '@/components/echarts/echarts.vue'
import top from '../components/top.vue'
import tableBox from './table.vue'
export default {
name:'curriculum_module',
components:{
top,echarts1,tableBox
},
data() {
return {
topList:[],
tableData:[],
tabList:[
{name:'今日',check:true,value:1},
{name:'本周',check:false,value:2},
{name:'本月',check:false,value:3},
],
}
},
mounted() {
this.topList = [
{name:'课程数量',count:800,link:'-12.14',thanLastWeek:'1.18'},
{name:'课程时长',count:'9h',link:'-12.14',thanLastWeek:'1.18'},
{name:'课程素材量',count:9700,link:'-12.14',thanLastWeek:'1.18'},
{name:'学生数量',count:65,link:'-12.14',thanLastWeek:'1.18'},
{name:'今日浏览量',count:12,link:'-12.14',thanLastWeek:'1.18'},
{name:'今日交易量',count:48,link:'-12.14',thanLastWeek:'1.18'}
]
this.geProportion()
this.getTimeLength()
},
methods: {
getTimeLength(){
let xData = ['分类1','分类2','分类3','分类4','分类5']
let yData = [50,100,130,80,65]
this.echartsOne(xData,yData)
},
echartsOne(xData,yData){
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: {
type: 'category',
data: xData
},
yAxis: {
type: 'value',
boundaryGap: [0, 0.01]
},
barWidth:22,
barGap:'0',
color:['#5470C6','#FAC858','#EE6666'],
series: [
{
name: '总时长',
type: 'bar',
data: yData,
}],
}
this.$refs.chart_one.initEcharth(option)
},
geProportion(){
let data = [
{name:'分类1',value:50},
{name:'分类2',value:100},
{name:'分类3',value:130},
{name:'分类4',value:80},
{name:'分类5',value:65},
]
let option = {
tooltip: {
trigger: 'item',
formatter:'{b}:{c},{d}%'
},
legend: {
orient: 'horizontal',
y:'bottom'
},
label:{
formatter:'{b}\n {c},{d}%'
},
color:['#FF9900','#B37FEB','#31BFFD','#19BE6B','#EE6666','#FAC858','#1890FF','#fd0000','#5470C6','#4f47c1'],
series: [
{
type: 'pie',
radius: '50%',
data: data
}
]
}
this.$refs.chart_two.initEcharth(option)
},
tabChange(i,e){
this.tabList.forEach((item,index) => {
item.check = false
if(index == i){
item.check = true
}
})
// if(this.trendObj.statisticsType != e.value){
// this.trendObj.statisticsType = e.value
// this.getResourceTrend()
// }
},
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/top_common.scss';
.flex{
display: flex;
justify-content: space-between;
align-items: center;
}
.tab_span{
margin-left: 10px;
cursor: pointer;
font-size: 12px;
font-weight: bold;
color: #7F8B9C;
padding: 5px 9px;
border: 1px solid #B9BFC7;
border-radius: 4px;
&:first-of-type{
margin: 0;
}
}
.check{
color: #0DB771;
background: #E7FAF0;
border: 1px solid #81E5BC;
border-radius: 4px;
}
.divBox{
padding: 0 16px;
}
.ivu-pl-8{
font-size: 16px;
font-weight: bold;
color: #485166;
}
.echarts_box{
box-sizing: border-box;
height: 379px;
width: 100%;
}
.el_row_box{
margin-top: 16px;
}
/deep/.el-table__body{
width: 100% !important;
}
/deep/.el-table__empty-block{
width: 100% !important;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="container">
<el-form inline size="small" :model="listQuery" ref="listQuery">
<el-form-item label="">
<el-input v-model="listQuery.name" placeholder="请输入课程名称" clearable class="selWidth"/>
</el-form-item>
<el-form-item>
<div class="search_btn" @click="getList(1)">
<img src="@/assets/img/common/ico-sousuo.png" />
检索
</div>
</el-form-item>
<el-form-item label="排序:">
<div class="flex">
<div class="list" v-for="(item,index) in list" :key="index" @click="sortChange(item,index)">
<div class="list_text">{{item.name}}</div>
<img src="./moren.png" v-if="item.order=='' && item.name != '默认'">
<img src="./desc.png" v-if="item.order=='desc' && item.name != '默认'">
<img src="./asc.png" v-if="item.order=='asc' && item.name != '默认'">
<div class="line" v-show="item.check"></div>
</div>
</div>
</el-form-item>
<el-form-item label="">
<el-button type="primary">导出数据</el-button>
</el-form-item>
</el-form>
</div>
<el-table ref="table" class="table_box" :border="true" v-loading="listLoading" :data="dataList" highlight-current-row :header-cell-style="{fontWeight:'bold'}">
<el-table-column type="index" align="center" label="序号" width="60"> </el-table-column>
<el-table-column label="课程名称" align="center" prop="name" min-width="15%" show-overflow-tooltip> </el-table-column>
<el-table-column prop="views" align="center" label="浏览量" min-width="10%"> </el-table-column>
<el-table-column prop="business" align="center" label="交易量" min-width="10%"></el-table-column>
<el-table-column prop="timeLength" align="center" label="课程时长" min-width="10%"></el-table-column>
<el-table-column prop="material" align="center" label="素材量" min-width="10%"></el-table-column>
<el-table-column prop="stuNum" align="center" label="学生数量" min-width="10%"></el-table-column>
<el-table-column prop="discussNum" align="center" label="讨论数量" min-width="10%"></el-table-column>
<el-table-column prop="updateTime" align="center" label="上架时间" min-width="10%"></el-table-column>
<el-table-column label="操作" min-width="10%" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="goDetail(scope.row.id)">查看详情</el-button>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
@size-change="sizeChange"
@current-change="currentChange"
:current-page="listQuery.pageNum"
:page-sizes="[30, 50, 100, 200]"
:page-size="listQuery.pageSize"
layout="total, prev, pager, next, sizes, jumper"
:total="total"
/>
</div>
</div>
</template>
<script>
export default {
data(){
return {
list:[
{name:'默认',check:true,order:''},
{name:'热度',check:false,order:''},
{name:'时间',check:false,order:''}
],
listLoading:false,
dataList:[],
listQuery:{
pageNum: 1,
pageSize: 30,
name: null
},
total:10
}
},
created(){
this.getList()
},
methods:{
goDetail(id){
this.$router.push({path:'/statistics_manage/curriculum_detail',query:{id}})
},
sortChange(e,i){
this.list.forEach((item,index) => {
if(i == index){
item.check = true
if(index != 0){
item.order = item.order == ''? 'desc':item.order == 'desc' ? 'asc':'desc'
}
}else{
item.check = false
item.order = ''
}
})
this.$emit('sortChange',this.list[i])
},
getList(){
this.dataList = []
let obj = {
name:'工程原理第一期',
views:102,
business:10,
timeLength:'10h',
material:12,
stuNum:15,
discussNum:8,
updateTime:'2023-01-02',
}
for(let i=0;i<10;i++){
this.dataList.push(obj)
}
},
sizeChange(val){
this.listQuery.pageSize = val
this.getList()
},
currentChange(val) {
this.listQuery.pageNum = val
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
.flex{
display: flex;
justify-content: flex-start;
align-items: center;
}
.list{
color: #333333;
height: 100%;
margin-right: 30px;
cursor: pointer;
display: flex;
justify-content: flex-start;
align-items: center;
position: relative;
.list_text{
margin-right: 6px;
}
.line{
position: absolute;
width: 56px;
height: 3px;
background: #FD6C51;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
}
</style>
\ No newline at end of file
差异被折叠。
<template>
<div>
<div class="top_box">
<div class="top_title">成绩详情</div>
</div>
<div class="divBox">
<el-card class="box-card">
<div slot="header">
<div class="acea-row row-middle">
<el-form inline size="small" :model="listQuery" ref="listQuery">
<el-select v-model="listQuery.type" placeholder="选择类型" clearable size="mini">
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
<el-form-item label="">
<el-input v-model="listQuery.name" placeholder="请输入学员姓名" clearable />
</el-form-item>
<el-form-item>
<div class="search_btn" @click="getList(1)">
<img src="@/assets/img/common/ico-sousuo.png" />
检索
</div>
</el-form-item>
</el-form>
</div>
</div>
<div class="flex">
<div class="echarts_box">
<echarts1 ref="chart_one" :height="319"></echarts1>
<div class="span_box">
<span>参与人数:100</span>
<span>平均分:80</span>
<span>最高分:98</span>
<span>最低分:58</span>
</div>
</div>
<div class="right_box">
<el-table ref="table" v-loading="listLoading" :data="dataList" highlight-current-row >
<el-table-column label="得分区间" align="center" prop="limits" min-width="8%"> </el-table-column>
<el-table-column label="人数" align="center" prop="num" min-width="8%" show-overflow-tooltip> </el-table-column>
<el-table-column label="所占比例" align="center" prop="scale" min-width="8%"> </el-table-column>
</el-table>
</div>
</div>
</el-card>
<el-row :gutter="24" class="el_row_box">
<el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<span class="ivu-pl-8">学员详情</span>
</div>
</div>
<div class="table_box">
<table-box></table-box>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import echarts1 from '@/components/echarts/echarts.vue'
import selectBox from '../components/selectBox.vue'
import tableBox from './detail_table.vue'
export default {
name:'result_detail',
components:{
echarts1,tableBox,selectBox
},
data() {
return {
listLoading:false,
typeList:[
{label:'考试',value:1},
{label:'测验',value:2},
{label:'作业',value:3},
],
listQuery:{
name:null,
type:null
},
dataList:[]
}
},
mounted() {
this.getList()
this.getAchievementData()
},
methods: {
getList(){
this.listLoading = false
this.dataList = [
{limits:'未考试',num:0,scale:'0%'},
{limits:'得分(0,60)',num:22,scale:'22%'},
{limits:'得分(60,70)',num:3,scale:'3%'},
{limits:'得分(70,80)',num:30,scale:'30%'},
{limits:'得分(80,90)',num:40,scale:'40%'},
{limits:'得分(90,100)',num:5,scale:'5%'},
]
},
getAchievementData(){
let data = [
{name:'及格',value:78},
{name:'未及格',value:22}
]
let option = this.echartsTwoOption(data,100,'#FAC858','#EE6666','人','及格率','')
this.$refs.chart_one.initEcharth(option)
},
echartsTwoOption(data,total,color1,color2,dw,totalContent,labelName){
let str = labelName ? labelName :''
let option = {
tooltip: {
trigger: 'item',
formatter:'{b}{c},\n{d}% ' + dw
},
label:{
formatter:'{b}'+str+'{c}'
},
title: {
text: totalContent + "\n" + (data[0].value/total*100).toFixed(2)+'%',
left: "center",
top: "center",
padding: [0, 0],
textStyle: {
fontWeight:'500',
color: "#485166",
fontSize: 14,
align: "center",
lineHeight: 20,
},
},
color:[color1,color2],
series: [
{
type: 'pie',
radius: ['50%', '70%'],
data: data,
itemStyle: {
borderColor: '#fff',
borderWidth: 2
},
}
]
}
return option
},
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/top_common.scss';
.right_box{
width: 60%;
}
.flex{
display: flex;
justify-content: space-between;
align-items: center;
}
.span_box{
font-size: 16px;
width: 250px;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
span{
margin-bottom: 15px;
width: 50%;
}
}
.echarts_box{
box-sizing: border-box;
height: 379px;
width: 40%;
}
.el_row_box{
margin-top: 16px;
}
/deep/.el-table__body{
width: 100% !important;
}
/deep/.el-table__empty-block{
width: 100% !important;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="container">
<el-form inline size="small" :model="listQuery" ref="listQuery">
<el-form-item label="得分区间:">
<el-input v-model="listQuery.num1" clearable class="num"/>
——
<el-input v-model="listQuery.num2" clearable class="num"/>
</el-form-item>
<el-form-item label="">
<el-input v-model="listQuery.name" placeholder="请输入学员姓名" clearable />
</el-form-item>
<el-form-item>
<div class="search_btn" @click="getList(1)">
<img src="@/assets/img/common/ico-sousuo.png" />
检索
</div>
</el-form-item>
<el-form-item label="">
<el-button type="primary">导出数据</el-button>
</el-form-item>
</el-form>
</div>
<el-table ref="table" class="table_box" v-loading="listLoading" :data="dataList" highlight-current-row >
<el-table-column label="学号" align="center" prop="studentID" min-width="8%"> </el-table-column>
<el-table-column label="姓名" align="center" prop="name" min-width="8%" show-overflow-tooltip> </el-table-column>
<el-table-column prop="score" align="center" label="得分" min-width="8%"> </el-table-column>
<el-table-column prop="accomplish" align="center" label="完成率" min-width="8%"></el-table-column>
<el-table-column align="center" label="作答时间" min-width="15%">
<template slot-scope="scope">
<span>{{scope.row.startTime}}-{{scope.row.endTime}}</span>
</template>
</el-table-column>
<el-table-column prop="answerTime" align="center" label="作答时长" min-width="10%"></el-table-column>
<el-table-column prop="pass" align="center" label="是否及格" min-width="8%">
<template slot-scope="scope">
<span v-if="scope.row.pass"></span>
<span v-if="!scope.row.pass"></span>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
@size-change="sizeChange"
@current-change="currentChange"
:current-page="listQuery.pageNum"
:page-sizes="[30, 50, 100, 200]"
:page-size="listQuery.pageSize"
layout="total, prev, pager, next, sizes, jumper"
:total="total"
/>
</div>
</div>
</template>
<script>
export default {
data(){
return {
listLoading:false,
dataList:[],
listQuery:{
pageNum: 1,
pageSize: 30,
name: null,
num1:null,
num2:null
},
total:10
}
},
created(){
this.getList()
},
methods:{
getList(){
this.dataList = []
for(var i=0;i<10;i++){
let obj = {
studentID:i < 9 ? '00' + (i+1):'0' + (i+1),
name:'张三',
score:i < 5 ? 80 : 50,
accomplish:'80%',
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
answerTime:'1h10min',
pass:i < 5 ? true : false
}
this.dataList.push(obj)
}
},
sizeChange(val){
this.listQuery.pageSize = val
this.getList()
},
currentChange(val) {
this.listQuery.pageNum = val
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
.flex{
display: flex;
justify-content: flex-start;
align-items: center;
}
.num{
width: 100px;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="top_box">
<div class="top_title">题库统计</div>
</div>
<top :list="topList"></top>
<div class="divBox">
<el-row :gutter="24" class="el_row_box">
<el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
<el-card :bordered="false" dis-hover>
<div slot="header">
<div class="acea-row row-middle">
<span class="ivu-pl-8">题库明细表</span>
</div>
</div>
<div class="table_box">
<table-box></table-box>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import echarts1 from '@/components/echarts/echarts.vue'
import top from '../components/top.vue'
import tableBox from './table.vue'
export default {
name:'question_module',
components:{
top,echarts1,tableBox
},
data() {
return {
topList:[],
}
},
mounted() {
this.topList = [
{name:'作业习题数',count:12800,link:'-12.14',thanLastWeek:'1.18'},
{name:'测验习题数',count:9700,link:'-12.14',thanLastWeek:'1.18'},
{name:'考试习题数',count:800,link:'-12.14',thanLastWeek:'1.18'},
{name:'作业次数',count:4800,link:'-12.14',thanLastWeek:'1.18'},
{name:'测验次数',count:65,link:'-12.14',thanLastWeek:'1.18'},
{name:'考试次数',count:65,link:'-12.14',thanLastWeek:'1.18'}
]
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/top_common.scss';
.flex{
display: flex;
justify-content: space-between;
align-items: center;
}
.divBox{
padding: 0 16px;
}
.el_row_box{
margin-top: 16px;
}
/deep/.el-table__body{
width: 100% !important;
}
/deep/.el-table__empty-block{
width: 100% !important;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="container">
<el-form inline size="small" :model="listQuery" ref="listQuery">
<el-form-item label="所属类型:">
<el-select v-model="listQuery.type" placeholder="请选择" class="table_select" size="mini">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="">
<el-input v-model="listQuery.name" placeholder="请输入名称" clearable />
</el-form-item>
<el-form-item>
<div class="search_btn" @click="getList(1)">
<img src="@/assets/img/common/ico-sousuo.png" />
检索
</div>
</el-form-item>
<el-form-item label="">
<el-button type="primary">导出数据</el-button>
</el-form-item>
</el-form>
</div>
<el-table ref="table" class="table_box" v-loading="listLoading" :data="dataList" highlight-current-row :header-cell-style="{fontWeight:'bold'}">
<el-table-column type="index" align="center" label="序号" width="60"> </el-table-column>
<el-table-column label="名称" align="center" prop="name" min-width="15%" show-overflow-tooltip> </el-table-column>
<el-table-column prop="type" align="center" label="类型" min-width="8%">
<template slot-scope="scope">
<span v-if="scope.row.type == 1">考试</span>
<span v-if="scope.row.type == 2">作业</span>
<span v-if="scope.row.type == 3">测验</span>
</template>
</el-table-column>
<el-table-column prop="questionTotal" align="center" label="习题数量" min-width="8%"></el-table-column>
<el-table-column prop="peopleTotal" align="center" label="参与人数" min-width="8%"></el-table-column>
<el-table-column align="center" label="最高/最低/平均分" min-width="10%">
<template slot-scope="scope">
<span>{{scope.row.highest}}/{{scope.row.lowest}}/{{scope.row.average}}</span>
</template>
</el-table-column>
<el-table-column prop="averageNum" align="center" label="开始/结束时间" min-width="20%">
<template slot-scope="scope">
<span>{{scope.row.startTime}}-{{scope.row.endTime}}</span>
</template>
</el-table-column>
<el-table-column label="操作" min-width="10%" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="goDetail(scope.row.id)">查看详情</el-button>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
@size-change="sizeChange"
@current-change="currentChange"
:current-page="listQuery.pageNum"
:page-sizes="[30, 50, 100, 200]"
:page-size="listQuery.pageSize"
layout="total, prev, pager, next, sizes, jumper"
:total="total"
/>
</div>
</div>
</template>
<script>
export default {
data(){
return {
listLoading:false,
dataList:[],
listQuery:{
pageNum: 1,
pageSize: 30,
name: null,
type:null
},
options:[
{label:'考试',value:1},
{label:'作业',value:2},
{label:'测验',value:3},
],
total:10
}
},
created(){
this.getList()
},
methods:{
goDetail(id){
this.$router.push({path:'/statistics_manage/result_detail',query:{id}})
},
getList(){
let arr = [
{
name:'期末考试',
type:1,
questionTotal:10,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'单元测验',
type:2,
questionTotal:50,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'章节随堂练习',
type:3,
questionTotal:30,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'单元测验',
type:1,
questionTotal:10,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'单元测验',
type:1,
questionTotal:10,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'单元测验',
type:1,
questionTotal:10,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'单元测验',
type:1,
questionTotal:10,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'单元测验',
type:1,
questionTotal:10,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'单元测验',
type:1,
questionTotal:10,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},{
name:'单元测验',
type:1,
questionTotal:10,
peopleTotal:200,
highest:100,
lowest:57,
average:82,
startTime:'2023-03-24 10:00:00',
endTime:'2023-03-24 12:00:00',
},
]
this.dataList = arr
},
sizeChange(val){
this.listQuery.pageSize = val
this.getList()
},
currentChange(val) {
this.listQuery.pageNum = val
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
.flex{
display: flex;
justify-content: flex-start;
align-items: center;
}
.num{
width: 100px;
}
</style>
\ No newline at end of file
<template>
<div>
<el-table ref="table" class="table_box" :border="true" :data="list" highlight-current-row :header-cell-style="{fontWeight:'bold'}">
<el-table-column type="index" align="center" label="序号" width="60"> </el-table-column>
<el-table-column label="商品名称" align="center" prop="name" min-width="15%" show-overflow-tooltip> </el-table-column>
<el-table-column prop="type" label="类型" min-width="7%" align="center">
<template slot-scope="scope">
<span v-if="scope.row.type == 2">电子书</span>
<span v-if="scope.row.type == 1">纸质书</span>
<span v-if="scope.row.type == 3">文章</span>
<span v-if="scope.row.type == 5">视频</span>
<span v-if="scope.row.type == 6">音频</span>
<span v-if="scope.row.type == 7">专题</span>
<span v-if="scope.row.type == 10">课程</span>
<span v-if="scope.row.type == 11">有声书</span>
</template>
</el-table-column>
<el-table-column prop="browseNum" label="浏览量" min-width="7%" align="center"></el-table-column>
<el-table-column prop="salesNum" align="center" label="销量" min-width="10%"></el-table-column>
<el-table-column prop="salesCount" align="center" label="销售金额" min-width="10%"></el-table-column>
<el-table-column prop="conversionRate" align="center" label="浏览-支付转化率" min-width="10%"></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data(){
return {
}
},
props:{
list:{
type:Array,
default: () => []
}
},
methods:{
}
}
</script>
\ No newline at end of file
<template>
<div>
<div class="top_box">
<div class="top_title">一册一码数据统计</div>
</div>
<div class="divBox">
<div class="table_box_wrap">
<div class="searchBox">
<el-form :model="listQuery" ref="listQuery" label-width="95px" :inline="true">
<el-form-item label="图书名称:">
<el-input v-model="listQuery.name" clearable class="selWidth"/>
</el-form-item>
<el-form-item label="ISBN:">
<el-input v-model="listQuery.isbn" clearable class="selWidth"/>
</el-form-item>
<div class="search_btn_box">
<el-button type="primary" icon="ios-search" label="default" class="mr15" size="small" @click="getList()">搜索</el-button>
<!-- <el-button class="mr10" @click="resetFilder" size="small">重置</el-button> -->
</div>
</el-form>
</div>
<el-table ref="table" class="table_box" :data="dataList" style="width: 100%" size="mini" @selection-change="selectionChange" highlight-current-row>
<el-table-column type="selection" align="center" width="50"></el-table-column>
<el-table-column label="图书名称" min-width="15%" align="center">
<template slot-scope="scope">
<div class="name_div">
<img v-if="scope.row.cover" class="cover_img" :src="coverUrl(scope.row.cover)"/>
<img v-else class="cover_img" :src="defaultImg('book')"/>
<span class="name_line">{{scope.row.name }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="isbn" label="ISBN" min-width="10%" align="center"/>
<el-table-column label="操作" min-width="18%" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="goCodeData(scope.row.id)">查看</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="block">
<el-pagination
@size-change="sizeChange"
@current-change="currentChange"
:current-page="listQuery.pageNum"
:page-sizes="[30, 50, 100, 200]"
:page-size="listQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
/>
</div>
</div>
<!-- 激活码使用量弹窗 -->
<el-dialog title="防伪码使用情况" :visible.sync="centerDialogVisible" width="30%">
<div class="dialogTable">
<echarts1 ref="chart_one" width="100%" :height="349"></echarts1>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="centerDialogVisible = false">关 闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getPhysicalCodeAPI } from '@/api/statistics/traffic'
import { bookListAPI } from "@/api/resource/paperbook";
import echarts1 from '@/components/echarts/echarts.vue'
export default {
name:'traffic_module',
components:{
echarts1,
},
data() {
return {
listQuery: {
pageNum: 1,
pageSize: 20,
name:null,
isbn:null,
},
total: null,
dataList:[],
chooiceList:[],
codeDataList:[],
centerDialogVisible:false,
}
},
created(){
},
mounted() {
this.getList();
},
methods: {
getList() {
bookListAPI(this.listQuery).then(res => {
if (res.data.code === 0) {
this.dataList = res.data.data.list?res.data.data.list:[];
this.total = res.data.data.total?res.data.data.total:0;
} else {
this.$message.error("获取数据失败");
}
}).catch(res => {
this.$message.error(res.msg)
});
},
selectionChange(val) {
//勾选table
this.chooiceList = val;
},
sizeChange(val) {
this.listQuery.pageSize = val;
this.getList();
},
currentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
goCodeData(id){
getPhysicalCodeAPI(id).then((res) => {
if(res.data.code == 0){
this.codeDataList = res.data.data
let xData = []
let list1 = []
let list2 = []
if(this.codeDataList && this.codeDataList.length > 0){
this.centerDialogVisible = true
setTimeout(() => {
this.codeDataList.forEach((item,index) => {
xData.push(item.name)
list1.push(item.codeNum)
list2.push(item.verifyNum)
})
this.echartsOne(xData,list1,list2)
},2000)
}else{
this.$message.warning('该图书暂无防伪码使用情况')
}
}else{
this.$message.error(res.data.msg)
}
})
},
echartsOne(xData,list1,list2,list3){
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
orient: 'horizontal',
left: 'center'
},
xAxis: {
type: 'category',
data: xData
},
yAxis: {
type: 'value',
boundaryGap: [0, 0.01]
},
barWidth:22,
barGap:'0',
color:['#5470C6','#FAC858','#EE6666'],
series: [
{
name: '防伪码总数量',
type: 'bar',
data: list1,
},
{
name: '防伪码使用数量',
type: 'bar',
data: list2,
}],
}
this.$refs.chart_one.initEcharth(option)
},
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/top_common.scss';
.cover_img{
width: 28px;
height: 38px;
}
/deep/.top_box{
margin-top:15px;
}
.divBox{
width:98.5%;
height: auto;
margin-left: 15px;
background-color: #fff;
}
.table_box_wrap{
padding: 30px;
box-sizing: border-box;
}
.searchBox{
width:100%;
height:60px;
display:flex;
justify-content: flex-end;
align-items: center;
}
.search_btn_box{
width:180px;
height: 60px;
display: inline-block;
}
.dialogTable{
height:400px;
}
</style>
\ No newline at end of file
......@@ -20,7 +20,7 @@
<el-input v-model="pram.realName" placeholder="管理员姓名" />
</el-form-item>
<el-form-item label="管理员身份" prop="roles">
<el-select v-model="pram.roles" placeholder="身份" clearable multiple style="width: 100%">
<el-select v-model="pram.roles" placeholder="身份" clearable multiple style="width: 100%" @change="chooseRoles">
<el-option
v-for="item,index in roleList.list"
:key="index"
......@@ -30,14 +30,16 @@
</el-select>
</el-form-item>
<el-form-item label="管理员所属部门" prop="departmentId" v-if="!pram.roles.some(x => x == 1)">
<el-select v-model="pram.departmentId" placeholder="请选择部门" style="width: 100%" @change="chooseDepart">
<el-option
v-for="(item,index) in departList"
:key="'depart'+index"
:label="item.departmentName"
:value="item.id"
/>
</el-select>
<el-popover popper-class="category-popover" placement="bottom-start" trigger="click" ref="popover" style="width: 100%">
<el-tree :data="departList" node-key="code" :props="defaultProps2"
:highlight-current="true" :expand-on-click-node="false"
:current-node-key="typeName" @node-click="handleDepartNodeClick"
style=" max-height: 400px; overflow-y: auto; width:380px;"></el-tree>
<el-select v-model="typeName" style="width:100%" popper-class="hidden-selection" slot="reference">
<el-option :value="null" label="全部"></el-option>
<el-option v-for="item in options" :key="item.code" :label="item.departmentName" :value="item.code"></el-option>
</el-select>
</el-popover>
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input type="text" v-model="pram.phone" prefix="ios-contact-outline"
......@@ -58,6 +60,7 @@
import * as roleApi from '@/api/role.js'
import * as systemAdminApi from '@/api/systemadmin.js'
import { departListAPI } from '@/api/departManage.js'
import { formatDepartQue } from '@/utils/format'
export default {
// name: "edit"
components: { },
......@@ -126,7 +129,13 @@ export default {
{ required: true, message: '请填写手机号'},
{ validator: validatePhone, trigger: 'change' }
]
}
},
options:[],
typeName: null,
defaultProps2: {
children: 'list',
label: 'departmentName'
},
}
},
mounted() {
......@@ -141,19 +150,30 @@ export default {
getDepartList(){
departListAPI().then((res) => {
this.departList = res
this.departList.unshift({ id: null, departmentName: '请选择部门' })
this.options = formatDepartQue(this.departList)
this.departList.unshift({departmentName:'请选择部门',id: 0,code:0})
}).catch((res) => {
this.$message.error(res)
})
},
chooseDepart(val){
this.departList.forEach((item,index) => {
if(item.id == val){
this.pram.departmentId = item.id
this.pram.departmentCode = item.code
this.pram.departmentName = item.departmentName
}
})
handleDepartNodeClick(data) {//点击分类--搜索
this.typeName = data.departmentName
this.pram.departmentId = data.id
this.pram.departmentCode = data.code
this.pram.departmentName = data.departmentName
this.$refs.popover.doClose()
},
chooseRoles(val){
let isAdmin = val.some(x => x == 1)
if(isAdmin){
this.pram.departmentId = 0
this.pram.departmentCode = 0
this.pram.departmentName = 0
}else{
this.pram.departmentId = this.editData.id
this.pram.departmentCode = this.editData.code
this.pram.departmentName = this.editData.departmentName
}
},
handleGetRoleList() {
const _pram = {
......@@ -180,6 +200,7 @@ export default {
this.pram.departmentId = departmentId
this.pram.departmentCode = departmentCode
this.pram.departmentName = departmentName
this.typeName = this.pram.departmentName
this.pram.status = status
this.pram.id = id
this.pram.phone = phone
......
......@@ -262,15 +262,10 @@ export default {
})
},
handlerOpenEdit(isCreate, editDate={}) {
editDate.departmentId = 0
editDate.departmentCode = 0
editDate.departmentName = 0
if(isCreate == 1){
this.departList.map((item,index) => {
if(item.departmentName == editDate.departmentName){
editDate.departmentId = item.id
}
})
if(isCreate == 0){
editDate.departmentId = 0
editDate.departmentCode = 0
editDate.departmentName = 0
}
this.editDialogConfig.editData = editDate
this.editDialogConfig.isCreate = isCreate
......
......@@ -8,7 +8,7 @@
<el-input type="textarea" v-model="pram.synopsis" placeholder="请输入部门介绍" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handlerSubmit('pram')" :loading="sureLoading">{{ isCreate===0?'确定':'更新' }}</el-button>
<el-button type="primary" @click="handlerSubmit('pram')" :loading="sureLoading">{{ confirmTxt }}</el-button>
<el-button @click="close">取消</el-button>
</el-form-item>
</el-form>
......@@ -33,6 +33,7 @@ export default {
},
data() {
return {
confirmTxt:'确定',
constants:this.$constants,
departList:[],
pram: {
......@@ -67,13 +68,21 @@ export default {
},
initEditData() {
if (this.isCreate !== 1) return
const { departmentName, synopsis, id, parentId, rules, code } = this.editData
this.pram.departmentName = departmentName
this.pram.synopsis = synopsis
this.pram.id = id
this.pram.parentId = 0
this.pram.rules = rules
this.pram.code = code
if(this.editData.type == 'edit'){
this.confirmTxt = '更新'
const { departmentName, synopsis, id, parentId, rules, code, type } = this.editData
this.pram.departmentName = departmentName
this.pram.synopsis = synopsis
this.pram.id = id
this.pram.parentId = parentId
this.pram.rules = rules
this.pram.code = code
}else{
this.confirmTxt = '编辑'
const { departmentName, synopsis, id, parentId, rules, code, type } = this.editData
this.pram.parentId = id
this.pram.rules = rules
}
},
departNameNorepeat(val){
let dl = this.departList.length
......
......@@ -7,7 +7,7 @@
<el-button size="mini" type="primary" @click="handlerOpenDel()">批量删除</el-button>
</el-form-item>
</el-form>
<el-table :data="departList" size="mini" @selection-change="selectionChange" v-loading="listLoading">
<!-- <el-table :data="departList" size="mini" @selection-change="selectionChange" v-loading="listLoading">
<el-table-column type="selection" min-width="80"/>
<el-table-column label="部门名称" prop="departmentName" min-width="120"/>
<el-table-column label="部门代号" prop="code" min-width="120"/>
......@@ -20,11 +20,26 @@
</template>
</template>
</el-table-column>
</el-table>
</el-table> -->
<el-table :data="departList" style="width:100%;" row-key="id" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @select="handleSelectionChange" :header-cell-style="{ color: '#4F5D73' }" @select-all="changeAll" ref="table" default-expand-all size="mini" class="minHeight580">
<el-table-column type="selection" ref="selectionCheckbox"></el-table-column>
<el-table-column label="部门名称" prop="departmentName" min-width="120"/>
<el-table-column label="部门代号" prop="code" min-width="120"/>
<el-table-column label="描述" prop="synopsis" min-width="120"></el-table-column>
<el-table-column label="操作" min-width="130" fixed="right">
<template slot-scope="scope">
<template>
<el-button type="text" size="mini" @click="handlerOpenEdit(1,scope.row,'create')">新建</el-button>
<el-button type="text" size="mini" @click="handlerOpenEdit(1,scope.row,'edit')">编辑</el-button>
<el-button type="text" size="mini" @click="handlerOpenDel(scope.row.id)">删除</el-button>
</template>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog
:visible.sync="editDialogConfig.visible"
:title="editDialogConfig.isCreate === 0? '创建部门':'编辑部门'"
:title="titleText"
destroy-on-close
:close-on-click-modal="false"
width="700px"
......@@ -50,6 +65,7 @@ export default {
return {
departList:[],
listLoading:false,
titleText:'创建部门',
constants:this.$constants,
listPram: {
name:null,
......@@ -60,6 +76,7 @@ export default {
editData: {}
},
chooiceList:[],
multipleSelection: [],
}
},
mounted() {
......@@ -69,15 +86,62 @@ export default {
getDepartList(){
this.listLoading = true;
departListAPI().then((res) => {
this.departList = res
const originalData = JSON.stringify(res);
this.departList = JSON.parse(originalData.replace(/list/gi, "children"));
this.listLoading = false;
}).catch((res) => {
this.$message.error(res)
this.listLoading = false;
})
},
selectionChange(val) {//勾选table
this.chooiceList = val
// selectionChange(val) {//勾选table
// this.chooiceList = val
// },
handleSelectionChange(selection, row) {
let that = this;
let isAddRow = true;
this.multipleSelection = []; //清空选中数组
selection.map(el => {
//判断节点添加还是删除
isAddRow = selection.some(el => el.code == row.code);
});
if (isAddRow) {
//添加
selection.map(el => {
if (el.children.length > 0) {
//带子集部门
that.$nextTick(function() {
let arr = [];
arr.push(el);
that.addSel(arr, selection);
});
} else {
//只有一级部门
this.multipleSelection.push(el);
}
});
} else {
//删除
if (row.children) {
//删除节点是否有子元素
that.$nextTick(function() {
let arr = [];
arr.push(row);
that.delSel(arr, selection);
});
}
}
},
changeAll(selection) {
let that = this;
if (selection.length == this.departList.length) {
that.addSel(selection);
that.multipleSelection = selection;
} else {
this.$refs.table.clearSelection(); // 删除后清空之前选择的数据
that.multipleSelection = [];
}
this.checkAll = this.multipleSelection.length > 0; //顶部全选控制外部全选按钮
},
//删除部门
handlerOpenDel(id) {
......@@ -85,8 +149,8 @@ export default {
if (id) {//单条删除
arr.push(id);
} else {//批量删除
if (this.isExist(this.chooiceList)) {
arr = getSelectionIds(this.chooiceList);
if (this.isExist(this.multipleSelection)) {
arr = getSelectionIds(this.multipleSelection);
} else {
return;
}
......@@ -98,10 +162,24 @@ export default {
})
})
},
handlerOpenEdit(isCreate, editDate) {
handlerOpenEdit(isCreate, editDate, type) {
this.editDialogConfig.editData = editDate
if(type){
this.editDialogConfig.editData.type = type
}
this.editDialogConfig.isCreate = isCreate
this.editDialogConfig.visible = true
if(this.editDialogConfig.isCreate == 1){
if(type && type == 'create'){
this.titleText = '创建子部门'
this.editDialogConfig.visible = true
}else{
this.titleText = '编辑部门'
this.editDialogConfig.visible = true
}
}else{
this.titleText = '创建部门'
this.editDialogConfig.visible = true
}
},
hideEditDialog() {
this.editDialogConfig.visible = false
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论