更新操作栏

development
飘泊客 9 months ago
parent a90f0bd897
commit cbfd5bbbcd

@ -9,14 +9,12 @@ ENV = 'development'
# 接口地址 http://8.130.96.163:8899
# 线上
VUE_APP_BASE_API = 'https://baiyee.vip'
# 测试
# VUE_APP_BASE_API = 'http://39.100.77.21:8899'
# VUE_APP_BASE_API = 'http://172.18.0.225:8899'//xy
VUE_APP_BASE_API = 'http://39.100.77.21:8899'
# ts
# VUE_APP_BASE_API = 'http://172.18.0.228:8899'
#VUE_APP_BASE_API = 'http://172.18.1.8:8899jt'
VUE_APP_BASE_IMG = 'https://baiyee.vip'
# 测试
# VUE_APP_BASE_IMG = 'http://39.100.77.21:8899'
VUE_APP_WS_API = 'wss://baiyee.vip'

@ -1137,7 +1137,7 @@ export function activityListUploadFiles(data) {
// 预测式外呼账号配置
export function addAccount(userName, passWord) {
return request({
url: baseObj.url + '/api/account/conf',
url: baseObj.url + 'api/account/conf',
method: 'get',
params: {
userName,
@ -1169,4 +1169,19 @@ export function editActivity(data) {
data
})
}
// 广告模型上传
export function modeUploadFiles(data) {
return request({
url: baseObj.url + 'api/mode/record/upload/files',
method: 'post',
data
})
}
// 广告模型-建模
export function recordBuild(params) {
return request({
url: baseObj.url + 'api/mode/record/build',
method: 'get',
params
})
}

@ -1,52 +1,52 @@
<!--
* @Description:
* @Autor: 飘泊客
* @Date: 2021-12-02 16:54:53
* @LastEditors: 飘泊客
* @LastEditTime: 2022-11-02 10:52:06
-->
<script>
import { DatePicker, DatePickerOptions } from 'element-ui'
import { calendarShortcuts } from '@/utils/shortcuts'
export default {
name: 'DateRangePicker',
mixins: [DatePicker],
props: {
type: {
type: String,
default: 'daterange'
},
valueFormat: {
type: String,
default: 'yyyy-MM-dd HH:mm:ss'
},
defaultTime: {
type: Array,
default: _ => ['00:00:00', '23:59:59']
},
pickerOptions: {
type: DatePickerOptions,
default: _ => {
return { shortcuts: calendarShortcuts }
}
},
size: {
type: String,
default: 'small'
},
rangeSeparator: {
type: String,
default: ':'
},
startPlaceholder: {
type: String,
default: '开始日期'
},
endPlaceholder: {
type: String,
default: '结束日期'
}
}
}
</script>
<!--
* @Description:
* @Autor: 飘泊客
* @Date: 2021-12-02 16:54:53
* @LastEditors: 飘泊客
* @LastEditTime: 2022-11-02 10:52:06
-->
<script>
import { DatePicker, DatePickerOptions } from 'element-ui'
import { calendarShortcuts } from '@/utils/shortcuts'
export default {
name: 'DateRangePicker',
mixins: [DatePicker],
props: {
type: {
type: String,
default: 'daterange'
},
valueFormat: {
type: String,
default: 'yyyy-MM-dd HH:mm:ss'
},
defaultTime: {
type: Array,
default: _ => ['00:00:00', '23:59:59']
},
pickerOptions: {
type: DatePickerOptions,
default: _ => {
return { shortcuts: calendarShortcuts }
}
},
size: {
type: String,
default: 'small'
},
rangeSeparator: {
type: String,
default: ':'
},
startPlaceholder: {
type: String,
default: '开始日期'
},
endPlaceholder: {
type: String,
default: '结束日期'
}
}
}
</script>

@ -1,122 +1,134 @@
<template>
<div class="chart" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
// const animationDuration = 3000
export default {
props: {
// seriesValueDefault: {
// type: Array,
// default: function() { return [] }
// },
// seriesValueReality: {
// type: Array,
// default: function() { return [] }
// },
seriesValue: {
type: Object,
default: function() { return {} }
}
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart(this.seriesValue)
this.__resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
},
beforeDestroy() {
if (!this.chart) {
return
}
window.removeEventListener('resize', this.__resizeHandler)
this.chart.dispose()
this.chart = null
},
methods: {
initChart(data) {
this.chart = echarts.init(this.$el, 'macarons', { width: '560px', height: '312px' })
this.chart.setOption({
// title: {
// text: 'Basic Radar Chart',
// // top: '5%',
// // left: '3%'
// x: 'center' //
// },
legend: {
data: ['平均质量分', '您的质量分'],
x: 'center', //
y: 'bottom' //
// top: '85%', //
// left: '60%' //
},
radar: {
// shape: 'circle',
indicator: [
// { name: '', max: 6000 },
// { name: '', max: 6000 },
// { name: '', max: 6000 },
// { name: '', max: 6000 },
// { name: '', max: 6000 }
{ name: '广告展示量', max: 6000 },
{ name: '广告点击量', max: 6000 },
{ name: '广告到达率', max: 6000 },
{ name: '广告二跳率', max: 6000 },
{ name: '广告转化率', max: 6000 }
],
//
radius: 120
// ()
// name: {
// formatter: '{value}',
// textStyle: {
// fontSize: 15,
// color: '#000'
// }
// },
// [ default: 15 ]
// nameGap: 15
},
series: [
{
name: 'Budget vs spending',
type: 'radar',
data: [
{
value: data.reality,
// value: [4200, 3000, 20000, 35000, 50000, 18000],
name: '您的质量分'
},
{
value: data.default,
// value: [5000, 14000, 28000, 26000, 42000, 21000],
name: '平均质量分'
}
]
}
]
})
}
}
}
</script>
<style lang="scss" scoped>
.chart{
padding: 20px;
}
</style>
<template>
<div class="chart" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
// const animationDuration = 3000
export default {
props: {
// seriesValueDefault: {
// type: Array,
// default: function() { return [] }
// },
// seriesValueReality: {
// type: Array,
// default: function() { return [] }
// },
seriesValue: {
type: Object,
default: function() { return {} }
}
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart(this.seriesValue)
this.__resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
},
beforeDestroy() {
if (!this.chart) {
return
}
window.removeEventListener('resize', this.__resizeHandler)
this.chart.dispose()
this.chart = null
},
methods: {
resettingChart() {
},
initChart(data) {
this.chart = echarts.init(this.$el, 'macarons', { width: '560px', height: '312px' })
this.chart.setOption({
// title: {
// text: 'Basic Radar Chart',
// // top: '5%',
// // left: '3%'
// x: 'center' //
// },
// toolbox: {
// feature: {
// restore: {
// onclick: () => {
// console.log('00000')
// this.resettingChart()
// }
// }
// }
// },
legend: {
data: ['平均质量分', '您的质量分'],
x: 'center', //
y: 'bottom' //
// top: '85%', //
// left: '60%' //
},
radar: {
// shape: 'circle',
indicator: [
// { name: '', max: 6000 },
// { name: '', max: 6000 },
// { name: '', max: 6000 },
// { name: '', max: 6000 },
// { name: '', max: 6000 }
{ name: '广告展示量', max: 6000 },
{ name: '广告点击量', max: 6000 },
{ name: '广告到达率', max: 6000 },
{ name: '广告二跳率', max: 6000 },
{ name: '广告转化率', max: 6000 }
],
//
radius: 120
// ()
// name: {
// formatter: '{value}',
// textStyle: {
// fontSize: 15,
// color: '#000'
// }
// },
// [ default: 15 ]
// nameGap: 15
},
series: [
{
name: 'Budget vs spending',
type: 'radar',
data: [
{
value: data.reality,
// value: [4200, 3000, 20000, 35000, 50000, 18000],
name: '您的质量分'
},
{
value: data.default,
// value: [5000, 14000, 28000, 26000, 42000, 21000],
name: '平均质量分'
}
]
}
]
})
}
}
}
</script>
<style lang="scss" scoped>
.chart{
padding: 20px;
}
</style>

@ -1,120 +1,120 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
const animationDuration = 3000
export default {
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
},
beforeDestroy() {
if (!this.chart) {
return
}
window.removeEventListener('resize', this.__resizeHandler)
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
radar: {
radius: '66%',
center: ['50%', '42%'],
splitNumber: 8,
splitArea: {
areaStyle: {
color: 'rgba(127,95,132,.3)',
opacity: 1,
shadowBlur: 45,
shadowColor: 'rgba(0,0,0,.5)',
shadowOffsetX: 0,
shadowOffsetY: 15
}
},
indicator: [
{ name: 'Sales', max: 10000 },
{ name: 'Administration', max: 20000 },
{ name: 'Information Techology', max: 20000 },
{ name: 'Customer Support', max: 20000 },
{ name: 'Development', max: 20000 },
{ name: 'Marketing', max: 20000 }
]
},
legend: {
left: 'center',
bottom: '10',
data: ['Allocated Budget', 'Expected Spending', 'Actual Spending']
},
series: [{
type: 'radar',
symbolSize: 0,
areaStyle: {
normal: {
shadowBlur: 13,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1
}
},
data: [
{
value: [5000, 7000, 12000, 11000, 15000, 14000],
name: 'Allocated Budget'
},
{
value: [4000, 9000, 15000, 15000, 13000, 11000],
name: 'Expected Spending'
},
{
value: [5500, 11000, 12000, 15000, 12000, 12000],
name: 'Actual Spending'
}
],
animationDuration: animationDuration
}]
})
}
}
}
</script>
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
const animationDuration = 3000
export default {
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
},
beforeDestroy() {
if (!this.chart) {
return
}
window.removeEventListener('resize', this.__resizeHandler)
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
radar: {
radius: '66%',
center: ['50%', '42%'],
splitNumber: 8,
splitArea: {
areaStyle: {
color: 'rgba(127,95,132,.3)',
opacity: 1,
shadowBlur: 45,
shadowColor: 'rgba(0,0,0,.5)',
shadowOffsetX: 0,
shadowOffsetY: 15
}
},
indicator: [
{ name: 'Sales', max: 10000 },
{ name: 'Administration', max: 20000 },
{ name: 'Information Techology', max: 20000 },
{ name: 'Customer Support', max: 20000 },
{ name: 'Development', max: 20000 },
{ name: 'Marketing', max: 20000 }
]
},
legend: {
left: 'center',
bottom: '10',
data: ['Allocated Budget', 'Expected Spending', 'Actual Spending']
},
series: [{
type: 'radar',
symbolSize: 0,
areaStyle: {
normal: {
shadowBlur: 13,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1
}
},
data: [
{
value: [5000, 7000, 12000, 11000, 15000, 14000],
name: 'Allocated Budget'
},
{
value: [4000, 9000, 15000, 15000, 13000, 11000],
name: 'Expected Spending'
},
{
value: [5500, 11000, 12000, 15000, 12000, 12000],
name: 'Actual Spending'
}
],
animationDuration: animationDuration
}]
})
}
}
}
</script>

@ -1,46 +1,45 @@
/*
* @Description:
* @Autor: 飘泊客
* @Date: 2021-12-03 11:10:17
* @LastEditors: 飘泊客
* @LastEditTime: 2022-03-17 13:40:48
*/
const baseUrl = process.env.VUE_APP_BASE_API
const baseImgUrl = process.env.VUE_APP_BASE_IMG
console.log('vuex==', baseImgUrl)
const api = {
state: {
// 部署包上传
deployUploadApi: baseUrl + '/api/deploy/upload',
// SQL脚本上传
databaseUploadApi: baseUrl + '/api/database/upload',
// 任务导入
fileUpload: baseUrl + '/api/task/fileUpload',
// 用户批量导入
importUsers: baseUrl + '/api-management/api/users/importUsers',
// 实时控制台
socketApi: baseUrl + '/websocket?token=kl',
// 图片上传
imagesUploadApi: baseUrl + '/api-management/api/pictures',
// 修改头像
updateAvatarApi: baseUrl + '/api-management/api/users/updateAvatar',
// 上传证件照
picturesUpload: baseUrl + '/api-management/api/pictures/upload',
// 上传文件到七牛云
qiNiuUploadApi: baseUrl + '/api/qiNiuContent',
// Sql 监控
sqlApi: baseUrl + '/druid/index.html',
// swagger
swaggerApi: baseUrl + '/swagger-ui.html',
// 文件上传
fileUploadApi: baseUrl + '/api/localStorage',
// baseUrl
baseApi: baseUrl,
// 图片专用
baseImgUrl: baseImgUrl,
// 任务导入-公海
taskFileUpload: 'api-source/source/uploadFile/taskFileUpload'
}
}
export default api
/*
* @Description:
* @Autor: 飘泊客
* @Date: 2021-12-03 11:10:17
* @LastEditors: 飘泊客
* @LastEditTime: 2022-03-17 13:40:48
*/
const baseUrl = process.env.VUE_APP_BASE_API
const baseImgUrl = process.env.VUE_APP_BASE_IMG
const api = {
state: {
// 部署包上传
deployUploadApi: baseUrl + '/api/deploy/upload',
// SQL脚本上传
databaseUploadApi: baseUrl + '/api/database/upload',
// 任务导入
fileUpload: baseUrl + '/api/task/fileUpload',
// 用户批量导入
importUsers: baseUrl + '/api-management/api/users/importUsers',
// 实时控制台
socketApi: baseUrl + '/websocket?token=kl',
// 图片上传
imagesUploadApi: baseUrl + '/api-management/api/pictures',
// 修改头像
updateAvatarApi: baseUrl + '/api-management/api/users/updateAvatar',
// 上传证件照
picturesUpload: baseUrl + '/api-management/api/pictures/upload',
// 上传文件到七牛云
qiNiuUploadApi: baseUrl + '/api/qiNiuContent',
// Sql 监控
sqlApi: baseUrl + '/druid/index.html',
// swagger
swaggerApi: baseUrl + '/swagger-ui.html',
// 文件上传
fileUploadApi: baseUrl + '/api/localStorage',
// baseUrl
baseApi: baseUrl,
// 图片专用
baseImgUrl: baseImgUrl,
// 任务导入-公海
taskFileUpload: 'api-source/source/uploadFile/taskFileUpload'
}
}
export default api

@ -1,469 +1,469 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<!--工具栏-->
<div class="head-container">
<div>
<!-- 搜索 -->
<label class="y-label">QA名称</label>
<el-input
v-model="query.scriptOrganizeName"
clearable
size="small"
placeholder="请输入"
style="width: 170px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<!-- <label class="y-label">话术分组</label>
<el-select
v-model="query.type"
size="small"
placeholder="请选择"
style="width: 170px"
class="filter-item"
@change="crud.toQuery"
>
<el-option
v-for="item in formulaList"
:key="item.id"
:label="item.scriptOrganizeName"
:value="item.id"
/>
</el-select> -->
<label class="y-label">启用状态</label>
<el-select
v-model="query.status"
clearable
size="small"
placeholder="请选择"
class="filter-item"
style="width: 170px"
@change="crud.toQuery"
>
<el-option :key="true" label="启用" :value="true" />
<el-option :key="false" label="禁用" :value="false" />
</el-select>
<rrOperation />
</div>
<div class="crud-opts">
<span class="crud-opts-left">
<el-button
class="filter-item"
size="mini"
type="primary"
icon="el-icon-plus"
@click="operationFun({type: 'add'})"
>
新增
</el-button>
</span>
</div>
<div>
<div v-if="!inputshow" class="content-end">
<div><span style="color: rgb(64, 158, 255);">置顶话术</span><span :class="{ 'c-red': topScript == '' }">{{ topScript ? topScript : '尚未设置置顶话术' }}</span></div>
<el-button size="mini" type="text" @click="showTopScript"></el-button>
</div>
<div v-else>
<el-input
v-model="topInputScript"
type="textarea"
:autosize="{ minRows: 3, maxRows: 6}"
maxlength="250"
show-word-limit
class="textarea"
placeholder="请输入置顶话术内容"
/>
<div class="mt-5">
<el-button
size="mini"
type="primary"
@click="addTopScript"
>
提交
</el-button>
<el-button
size="mini"
@click="inputshow = false"
>
取消
</el-button>
</div>
</div>
</div>
</div>
<!--表格渲染-->
<el-table ref="tables" v-loading="crud.loading" :data="crud.data.content" :header-cell-style="{'text-align':'left'}" style="width: 100%;">
<el-table-column type="expand">
<template slot-scope="props">
<el-table :data="props.row.scriptTemplateList" :header-cell-style="{'text-align':'center'}" :cell-style="{'text-align':'center'}">
<el-table-column :show-overflow-tooltip="true" prop="question" label="问题" />
<el-table-column :show-overflow-tooltip="true" prop="answer" label="解答" />
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="135" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="100"
fixed="right"
>
<template slot-scope="scope">
<el-button
class="filter-item"
size="mini"
type="text"
@click.stop="operationFun({type: 'editChild', data: scope.row})"
>
修改
</el-button>
<el-button
class="filter-item"
size="mini"
type="text"
@click.stop="delformula(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="scriptOrganizeName" label="QA问题分类" />
<el-table-column label="启用状态" width="150px">
<template slot-scope="scope">
<el-switch v-model="scope.row.status" active-color="#409EFF" inactive-color="#F56C6C" @change="changeEnabled(scope.row, scope.row.status)" />
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="135" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="100"
fixed="right"
>
<template slot-scope="scope">
<el-button
class="filter-item"
size="mini"
type="text"
@click.stop="operationFun({type: 'edit', data: scope.row})"
>
修改
</el-button>
<!-- <el-button
class="filter-item"
size="mini"
type="text"
@click.stop="operationFun({type: 'del', data: scope.row})"
>
删除
</el-button> -->
</template>
</el-table-column>
<template #empty>
<div style="width: 100%; height: 450px;display: flex; flex-direction: column; justify-content: center;align-items: center">
<img src="@/assets/images/zanwu.png" alt="">
<div>暂无数据</div>
</div>
</template>
</el-table>
<!--分页组件-->
<pagination />
</el-row>
<el-dialog :visible.sync="formulaProp" append-to-body :close-on-click-modal="false" :title="propTitle" width="520px" @close="beforeClose">
<el-form ref="formulaRefForm" :inline="true" :model="formulaForm" size="small" label-width="85px">
<el-form-item v-if="operation !== 'editChild'" label="QA分类" prop="scriptOrganizeName" :rules="{ required: true, message: '请选择或新建分类' }">
<el-select
v-if="operation != 'edit'"
v-model="formulaForm.scriptOrganizeName"
filterable
allow-create
default-first-option
clearable
placeholder="请选择或新建分类"
>
<el-option
v-for="item in formulaList"
:key="item.id"
:label="item.scriptOrganizeName"
:value="item.id"
/>
</el-select>
<el-input v-else v-model="formulaForm.scriptOrganizeName" placeholder="请输入分组名" />
</el-form-item>
<div v-show="operation !== 'edit'">
<div v-for="(item, index) in formulaForm.scriptTemplateList" :key="index">
<div class="group-item">话术{{ index + 1 }}</div>
<el-form-item :prop="`scriptTemplateList[${index}].question`" :rules="{ required: true, message: '请输入QA问题' }">
<span slot="label">QA问题</span>
<el-input v-model="item.question" placeholder="请输入QA问题" style="width: 340px" />
</el-form-item>
<el-form-item :prop="`scriptTemplateList[${index}].answer`" :rules="{ required: true, message: '请输入问题解答' }">
<span slot="label">问题解答</span>
<el-input v-model="item.answer" type="textarea" :autosize="{ minRows: 3, maxRows: 6}" placeholder="请输入问题解答" maxlength="250" style="width: 340px" />
<el-button v-show="index != 0" type="danger" icon="el-icon-delete" circle class="ml-5" @click="delGroup(index)" />
</el-form-item>
</div>
</div>
</el-form>
<div slot="footer" class="dialog-footer u-flex u-flex-between">
<div>
<el-button v-if="operation == 'add'" type="primary" icon="el-icon-plus" @click="addGroup">QA</el-button>
</div>
<div>
<el-button type="text" @click="formulaProp = false">取消</el-button>
<el-button
:loading="subloading"
type="primary"
@click="hankShiftSave"
>确认</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { setScriptAdd, getQueryOrganize, setScriptUpdate, setScriptDel, setScriptOrganizeUpdate, addTopScript } from '@/api/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
const defaultForm = { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 'false', roles: [], jobs: [], dept: { id: null }, phone: null }
export default {
name: 'FormulaIndex',
components: { rrOperation, pagination },
cruds() {
return CRUD({ title: '话术管理', url: 'api-management/api/script/organize/queryAll' })
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
height: document.documentElement.clientHeight - 180 + 'px;',
formulaList: [],
formulaProp: false,
operation: 'add',
subloading: false,
formulaForm: {
scriptOrganizeName: '',
scriptTemplateList: [
{
question: '',
answer: ''
}
]
},
inputshow: false,
propTitle: '新增话术',
topScript: '',
topInputScript: ''
}
},
computed: {
...mapGetters([
'user'
])
},
watch: {
'crud.data': {
handler(newVal, oldV) {
this.topScript = newVal.top.answer
},
deep: true
}
},
created() {},
mounted: function() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 180 + 'px;'
}
},
methods: {
changevisible(v) {
this.userKey = Math.ceil(Math.random() * 100)
},
operationFun(obj = {}) {
const { type = '', data = {}} = obj
switch (type) {
case 'add':
this.propTitle = '新增话术'
break
case 'edit':
case 'editChild':
this.propTitle = '编辑话术'
break
}
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
getQueryOrganize({ userId: this.user.id }).then(res => {
this.formulaList = res.data.organize
this.operation = type
this.formulaProp = true
loading.close()
if (type === 'edit') {
this.formulaForm = Object.assign({}, data)
} else if (type === 'editChild') {
this.formulaForm.scriptTemplateList = [Object.assign({}, data)]
}
}).catch(() => {
loading.close()
})
},
//
addGroup() {
this.formulaForm.scriptTemplateList.push({
title: '',
answer: ''
})
},
delGroup(index) {
this.formulaForm.scriptTemplateList.splice(index, 1)
},
showTopScript() {
this.topInputScript = this.topScript
this.inputshow = true
},
addTopScript() {
addTopScript({ answer: this.topInputScript }).then(res => {
this.topScript = this.topInputScript
this.$message.success('设置成功')
this.inputshow = false
})
},
//
changeEnabled(data, val) {
this.$confirm('此操作将修改' + data.scriptOrganizeName + '的状态, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
setScriptOrganizeUpdate({ status: val, id: data.id }).then(res => {
this.crud.notify('成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(() => {
data.status = !data.status
})
}).catch(() => {
data.status = !data.status
})
},
hankShiftSave() {
this.$refs.formulaRefForm.validate(async(valid) => {
if (valid) {
const data = Object.assign({}, this.formulaForm)
if (this.operation === 'add') {
data.scriptOrganizeId = ''
if (typeof data.scriptOrganizeName === 'number') {
data.id = data.scriptOrganizeName
data.scriptOrganizeName = ''
}
setScriptAdd(data).then(res => {
if (res.status === 0) {
this.crud.toQuery()
}
this.formulaProp = false
})
}
if (this.operation === 'edit') {
const res = await setScriptOrganizeUpdate(data)
this.formulaProp = false
if (res.status === 0) {
this.crud.toQuery()
}
}
if (this.operation === 'editChild') {
const res = await setScriptUpdate(data.scriptTemplateList[0])
this.formulaProp = false
if (res.status === 0) {
this.crud.toQuery()
}
}
}
})
},
//
delformula(id) {
this.$confirm('请确定要删除话术吗', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
setScriptDel(id).then(res => {
this.crud.notify('删除成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.crud.toQuery()
})
})
.catch(() => {})
},
beforeClose() {
this.$refs.formulaRefForm.resetFields()
const data = {
scriptOrganizeName: '',
scriptTemplateList: [
{
question: '',
answer: ''
}
]
}
this.formulaForm = data
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.group-item {
width: 80px;
line-height: 32px;
float: none;
display: inline-block;
color: #FFAA00;
text-align: left;
vertical-align: middle;
padding: 0 12px 0 0;
font-weight: bold;
position: relative;
&::before {
content: "";
border-left: 3px solid #FFAA00;
margin-right: 4px;
border-radius: 10px;
}
}
.c-red {
color: rgb(245, 108, 108);
}
.content-end {
display: inline-block;
min-width: 350px;
max-width: 600px;
padding: 7px 5px 0px;
background: #fafafa!important;
border: 1px solid #f0f0f0;
border-radius: 4px;
font-style: normal;
font-weight: 500;
font-size: 12px;
color: #333;
word-wrap: break-word
// display: flex;
// justify-content: space-between;
// align-items: center;
// flex-wrap: wrap;
}
.textarea{
max-width: 600px;
}
</style>
<template>
<div class="app-container">
<el-row :gutter="20">
<!--工具栏-->
<div class="head-container">
<div>
<!-- 搜索 -->
<label class="y-label">QA名称</label>
<el-input
v-model="query.scriptOrganizeName"
clearable
size="small"
placeholder="请输入"
style="width: 170px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<!-- <label class="y-label">话术分组</label>
<el-select
v-model="query.type"
size="small"
placeholder="请选择"
style="width: 170px"
class="filter-item"
@change="crud.toQuery"
>
<el-option
v-for="item in formulaList"
:key="item.id"
:label="item.scriptOrganizeName"
:value="item.id"
/>
</el-select> -->
<label class="y-label">启用状态</label>
<el-select
v-model="query.status"
clearable
size="small"
placeholder="请选择"
class="filter-item"
style="width: 170px"
@change="crud.toQuery"
>
<el-option :key="true" label="启用" :value="true" />
<el-option :key="false" label="禁用" :value="false" />
</el-select>
<rrOperation />
</div>
<div class="crud-opts">
<span class="crud-opts-left">
<el-button
class="filter-item"
size="mini"
type="primary"
icon="el-icon-plus"
@click="operationFun({type: 'add'})"
>
新增
</el-button>
</span>
</div>
<div>
<div v-if="!inputshow" class="content-end">
<div><span style="color: rgb(64, 158, 255);">置顶话术</span><span :class="{ 'c-red': topScript == '' }">{{ topScript ? topScript : '尚未设置置顶话术' }}</span></div>
<el-button size="mini" type="text" @click="showTopScript"></el-button>
</div>
<div v-else>
<el-input
v-model="topInputScript"
type="textarea"
:autosize="{ minRows: 3, maxRows: 6}"
maxlength="250"
show-word-limit
class="textarea"
placeholder="请输入置顶话术内容"
/>
<div class="mt-5">
<el-button
size="mini"
type="primary"
@click="addTopScript"
>
提交
</el-button>
<el-button
size="mini"
@click="inputshow = false"
>
取消
</el-button>
</div>
</div>
</div>
</div>
<!--表格渲染-->
<el-table ref="tables" v-loading="crud.loading" :data="crud.data.content" :header-cell-style="{'text-align':'left'}" style="width: 100%;">
<el-table-column type="expand">
<template slot-scope="props">
<el-table :data="props.row.scriptTemplateList" :header-cell-style="{'text-align':'center'}" :cell-style="{'text-align':'center'}">
<el-table-column :show-overflow-tooltip="true" prop="question" label="问题" />
<el-table-column :show-overflow-tooltip="true" prop="answer" label="解答" />
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="135" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="100"
fixed="right"
>
<template slot-scope="scope">
<el-button
class="filter-item"
size="mini"
type="text"
@click.stop="operationFun({type: 'editChild', data: scope.row})"
>
修改
</el-button>
<el-button
class="filter-item"
size="mini"
type="text"
@click.stop="delformula(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="scriptOrganizeName" label="QA问题分类" />
<el-table-column label="启用状态" width="150px">
<template slot-scope="scope">
<el-switch v-model="scope.row.status" active-color="#409EFF" inactive-color="#F56C6C" @change="changeEnabled(scope.row, scope.row.status)" />
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="135" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="75"
fixed="right"
>
<template slot-scope="scope">
<el-button
class="filter-item"
size="mini"
type="text"
@click.stop="operationFun({type: 'edit', data: scope.row})"
>
修改
</el-button>
<!-- <el-button
class="filter-item"
size="mini"
type="text"
@click.stop="operationFun({type: 'del', data: scope.row})"
>
删除
</el-button> -->
</template>
</el-table-column>
<template #empty>
<div style="width: 100%; height: 450px;display: flex; flex-direction: column; justify-content: center;align-items: center">
<img src="@/assets/images/zanwu.png" alt="">
<div>暂无数据</div>
</div>
</template>
</el-table>
<!--分页组件-->
<pagination />
</el-row>
<el-dialog :visible.sync="formulaProp" append-to-body :close-on-click-modal="false" :title="propTitle" width="520px" @close="beforeClose">
<el-form ref="formulaRefForm" :inline="true" :model="formulaForm" size="small" label-width="85px">
<el-form-item v-if="operation !== 'editChild'" label="QA分类" prop="scriptOrganizeName" :rules="{ required: true, message: '请选择或新建分类' }">
<el-select
v-if="operation != 'edit'"
v-model="formulaForm.scriptOrganizeName"
filterable
allow-create
default-first-option
clearable
placeholder="请选择或新建分类"
>
<el-option
v-for="item in formulaList"
:key="item.id"
:label="item.scriptOrganizeName"
:value="item.id"
/>
</el-select>
<el-input v-else v-model="formulaForm.scriptOrganizeName" placeholder="请输入分组名" />
</el-form-item>
<div v-show="operation !== 'edit'">
<div v-for="(item, index) in formulaForm.scriptTemplateList" :key="index">
<div class="group-item">话术{{ index + 1 }}</div>
<el-form-item :prop="`scriptTemplateList[${index}].question`" :rules="{ required: true, message: '请输入QA问题' }">
<span slot="label">QA问题</span>
<el-input v-model="item.question" placeholder="请输入QA问题" style="width: 340px" />
</el-form-item>
<el-form-item :prop="`scriptTemplateList[${index}].answer`" :rules="{ required: true, message: '请输入问题解答' }">
<span slot="label">问题解答</span>
<el-input v-model="item.answer" type="textarea" :autosize="{ minRows: 3, maxRows: 6}" placeholder="请输入问题解答" maxlength="250" style="width: 340px" />
<el-button v-show="index != 0" type="danger" icon="el-icon-delete" circle class="ml-5" @click="delGroup(index)" />
</el-form-item>
</div>
</div>
</el-form>
<div slot="footer" class="dialog-footer u-flex u-flex-between">
<div>
<el-button v-if="operation == 'add'" type="primary" icon="el-icon-plus" @click="addGroup">QA</el-button>
</div>
<div>
<el-button type="text" @click="formulaProp = false">取消</el-button>
<el-button
:loading="subloading"
type="primary"
@click="hankShiftSave"
>确认</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { setScriptAdd, getQueryOrganize, setScriptUpdate, setScriptDel, setScriptOrganizeUpdate, addTopScript } from '@/api/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
const defaultForm = { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 'false', roles: [], jobs: [], dept: { id: null }, phone: null }
export default {
name: 'FormulaIndex',
components: { rrOperation, pagination },
cruds() {
return CRUD({ title: '话术管理', url: 'api-management/api/script/organize/queryAll' })
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
height: document.documentElement.clientHeight - 180 + 'px;',
formulaList: [],
formulaProp: false,
operation: 'add',
subloading: false,
formulaForm: {
scriptOrganizeName: '',
scriptTemplateList: [
{
question: '',
answer: ''
}
]
},
inputshow: false,
propTitle: '新增话术',
topScript: '',
topInputScript: ''
}
},
computed: {
...mapGetters([
'user'
])
},
watch: {
'crud.data': {
handler(newVal, oldV) {
this.topScript = newVal.top.answer
},
deep: true
}
},
created() {},
mounted: function() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 180 + 'px;'
}
},
methods: {
changevisible(v) {
this.userKey = Math.ceil(Math.random() * 100)
},
operationFun(obj = {}) {
const { type = '', data = {}} = obj
switch (type) {
case 'add':
this.propTitle = '新增话术'
break
case 'edit':
case 'editChild':
this.propTitle = '编辑话术'
break
}
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
getQueryOrganize({ userId: this.user.id }).then(res => {
this.formulaList = res.data.organize
this.operation = type
this.formulaProp = true
loading.close()
if (type === 'edit') {
this.formulaForm = Object.assign({}, data)
} else if (type === 'editChild') {
this.formulaForm.scriptTemplateList = [Object.assign({}, data)]
}
}).catch(() => {
loading.close()
})
},
//
addGroup() {
this.formulaForm.scriptTemplateList.push({
title: '',
answer: ''
})
},
delGroup(index) {
this.formulaForm.scriptTemplateList.splice(index, 1)
},
showTopScript() {
this.topInputScript = this.topScript
this.inputshow = true
},
addTopScript() {
addTopScript({ answer: this.topInputScript }).then(res => {
this.topScript = this.topInputScript
this.$message.success('设置成功')
this.inputshow = false
})
},
//
changeEnabled(data, val) {
this.$confirm('此操作将修改' + data.scriptOrganizeName + '的状态, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
setScriptOrganizeUpdate({ status: val, id: data.id }).then(res => {
this.crud.notify('成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(() => {
data.status = !data.status
})
}).catch(() => {
data.status = !data.status
})
},
hankShiftSave() {
this.$refs.formulaRefForm.validate(async(valid) => {
if (valid) {
const data = Object.assign({}, this.formulaForm)
if (this.operation === 'add') {
data.scriptOrganizeId = ''
if (typeof data.scriptOrganizeName === 'number') {
data.id = data.scriptOrganizeName
data.scriptOrganizeName = ''
}
setScriptAdd(data).then(res => {
if (res.status === 0) {
this.crud.toQuery()
}
this.formulaProp = false
})
}
if (this.operation === 'edit') {
const res = await setScriptOrganizeUpdate(data)
this.formulaProp = false
if (res.status === 0) {
this.crud.toQuery()
}
}
if (this.operation === 'editChild') {
const res = await setScriptUpdate(data.scriptTemplateList[0])
this.formulaProp = false
if (res.status === 0) {
this.crud.toQuery()
}
}
}
})
},
//
delformula(id) {
this.$confirm('请确定要删除话术吗', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
setScriptDel(id).then(res => {
this.crud.notify('删除成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.crud.toQuery()
})
})
.catch(() => {})
},
beforeClose() {
this.$refs.formulaRefForm.resetFields()
const data = {
scriptOrganizeName: '',
scriptTemplateList: [
{
question: '',
answer: ''
}
]
}
this.formulaForm = data
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.group-item {
width: 80px;
line-height: 32px;
float: none;
display: inline-block;
color: #FFAA00;
text-align: left;
vertical-align: middle;
padding: 0 12px 0 0;
font-weight: bold;
position: relative;
&::before {
content: "";
border-left: 3px solid #FFAA00;
margin-right: 4px;
border-radius: 10px;
}
}
.c-red {
color: rgb(245, 108, 108);
}
.content-end {
display: inline-block;
min-width: 350px;
max-width: 600px;
padding: 7px 5px 0px;
background: #fafafa!important;
border: 1px solid #f0f0f0;
border-radius: 4px;
font-style: normal;
font-weight: 500;
font-size: 12px;
color: #333;
word-wrap: break-word
// display: flex;
// justify-content: space-between;
// align-items: center;
// flex-wrap: wrap;
}
.textarea{
max-width: 600px;
}
</style>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,368 @@
<template>
<div>
<div class="u-flex" style="align-items: normal">
<div class="app-container flex-1" style="margin-bottom: 0;margin-right: 10px;">
<div class="margin-auto">
<el-upload
ref="updaatefilesTo"
accept=".xls,.xlsx"
drag
:action="fileUpload"
multiple
:limit="5"
:file-list="fileList"
:auto-upload="false"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:http-request="updtaFils"
>
<i class="el-icon-upload" />
<div class="el-upload__text">
将文件拖到此处<em>点击上传</em>
</div>
<div slot="tip" class="el-upload__tip">
只能上传.xls.xlsx文件且不超过100M
</div>
</el-upload>
<div class="line-text">
<div class="mb-10 u-flex">
<label>任务名称</label>
<div class="u-flex">
<el-input v-model="taskValue" clearable />
</div>
</div>
<div class="mb-10 u-flex">
<label>方式类型</label>
<el-select v-model="uploadType" size="small" class="filter-item" clearable placeholder="请选择状态">
<el-option v-for="(item, index) in uploadTypeList" :key="index" :label="item.key" :value="item.value" />
</el-select>
</div>
</div>
<div>
<el-button
type="primary"
class="mt-10"
:loading="uploading"
@click="submitUpload({ ref: 'updaatefilesTo' })"
>上传资源</el-button>
<el-button
type="text"
class="mt-10"
@click="resettingUpdate"
>重置</el-button>
</div>
</div>
</div>
<div class="app-container flex-1" style="margin-bottom: 0;margin-left: 10px;">
<a href="https://business.oceanengine.com" target="_blank">跳转巨量平台<i class="el-icon-s-promotion" /></a>
<advertisingQualityscore v-if="JSON.stringify(advertisingQualityScoreData) !== '{}'" :series-value="advertisingQualityScoreData" />
</div>
</div>
<div class="app-container">
<el-row :gutter="20">
<!--工具栏-->
<div class="head-container">
<!-- 搜索 -->
<date-range-picker v-model="query.createTime" class="date-item" />
<el-input
v-model="query.taskName"
clearable
size="small"
placeholder="输入任务名"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<el-select v-model="query.recordStatus" size="small" class="filter-item" style="width: 130px" clearable placeholder="请选择状态" @change="crud.toQuery">
<el-option v-for="(item, index) in statusList" :key="index" :label="item.key" :value="item.value" />
</el-select>
<rrOperation />
</div>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
:header-cell-style="{ 'text-align': 'left' }"
style="width: 100%;"
>
<el-table-column :show-overflow-tooltip="true" prop="id" label="ID" width="35" />
<el-table-column
:show-overflow-tooltip="true"
prop="taskName"
label="任务名"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="uploadNum"
label="上传数量"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="analysisNum"
label="解析数量"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="payTime"
width="135"
label="上传时间"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="payTime"
width="110"
label="发送类型"
>
<template slot-scope="scope">
<span>{{ statecCmparison('uploadTypeList', scope.row.recordType) }}</span>
</template>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="recordStatus"
width="110"
label="状态"
>
<template slot-scope="scope">
<span>{{ statecCmparison('statusList', scope.row.recordStatus) }}</span>
</template>
</el-table-column>
<template #empty>
<div style="width: 100%; height: 450px;display: flex; flex-direction: column; justify-content: center;align-items: center">
<img src="@/assets/images/zanwu.png" alt="">
<div>暂无数据</div>
</div>
</template>
</el-table>
<!--分页组件-->
<pagination />
</el-row>
</div>
</div>
</template>
<script>
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import DateRangePicker from '@/components/DateRangePicker'
import { getAdvertisingQualityScore } from '@/api/login.js'
import advertisingQualityscore from '@/components/Echarts/Radar'
import {
modeUploadFiles
} from '@/api/index'
import { mapGetters } from 'vuex'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
const defaultForm = {}
export default {
name: 'AdvertisementList',
components: { rrOperation, pagination, DateRangePicker, advertisingQualityscore },
cruds() {
return CRUD({
title: '广告建模',
url: '/api-management/api/mode/record',
crudMethod: {}
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
height: document.documentElement.clientHeight - 180 + 'px;',
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del'],
download: ['admin', 'user:download']
},
fileList: [], // files
taskValue: '',
uploadType: '',
uploading: false,
uploadTypeList: [
{
key: '方式一',
value: '0'
},
{
key: '方式二',
value: '1'
},
{
key: '方式三',
value: '2'
}
],
statusList: [
{
key: '上传失败',
value: '-1'
},
{
key: '上传中',
value: '0'
},
{
key: '上传成功',
value: '1'
},
{
key: '建模中',
value: '2'
},
{
key: '建模成功',
value: '3'
}
],
advertisingQualityScoreData: {} //
}
},
computed: {
...mapGetters(['user', 'fileUpload'])
},
created() {
this.getAdvertisingQualityScoreData()
},
mounted: function() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 180 + 'px;'
}
},
methods: {
// 广
async getAdvertisingQualityScoreData() {
const res = await getAdvertisingQualityScore()
if (res.status === 0) {
this.advertisingQualityScoreData = res.data
} else {
this.$message.error(res.msg)
}
},
//
updtaFils(file) {
this.fileData.append('file', file.file)
},
//
handleRemove(file, fileList) {
this.fileList = fileList
},
//
handleExceed(files, fileList) {
this.$message.warning(
`当前限制选择 5 个文件,本次选择了 ${
files.length
} 个文件共选择了 ${files.length + fileList.length} 个文件`
)
},
submitUpload({ ref }) {
if (this.taskValue === '') {
this.$message({
message: '请输入任务名',
type: 'warning'
})
} else if (this.uploadType === '') {
this.$message({
message: '请选择方式类型',
type: 'warning'
})
} else {
const isLt100M = this.fileList.every(
file => file.size / 1024 / 1024 < 100
)
if (!isLt100M) {
this.$message.warning('请检查上传文件大小不能超过100MB!')
} else {
this.fileData = new FormData() // new formData
this.$refs[ref].submit()
if (!this.fileData.get('file')) {
this.$message({
message: '请先选择文件',
type: 'warning'
})
return false
}
this.fileData.append('taskName', this.taskValue)
this.fileData.append('uploadType', this.uploadType)
this.uploading = true
modeUploadFiles(this.fileData)
.then(res => {
if (res.status === 0) {
this.$message({
message: '操作成功,文件上传中...',
type: 'success'
})
this.crud.resetQuery()
this.resettingUpdate()
} else {
this.$message({
message: res.data.desc,
type: 'error'
})
}
this.uploading = false
})
.catch(() => {
this.uploading = false
})
}
}
},
resettingUpdate() {
this.fileList = []
this.taskValue = ''
this.uploadType = ''
},
//
downFilex({ type }) {
// downLoadTemplate({ downLoadType: type }).then(res => {
// window.location.href = res
// })
},
statecCmparison(name, val) {
return this[name].filter(item => { return Number(item.value) === val })[0].key
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .vue-treeselect__control,
::v-deep .vue-treeselect__placeholder,
::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
::v-deep .el-dialog__body {
padding: 20px;
}
.date-item {
width: 230px !important;
}
//label
::v-deep .y-label {
vertical-align: unset;
min-width: unset;
}
//
.el-pagination {
text-align: right;
}
.line-text {
font-size: 14px;
color: #606266;
line-height: 21px;
margin-top: 10px;
}
.chart {
padding: 0px;
}
a {
color: #246fdc;
}
</style>

@ -0,0 +1,235 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<!--工具栏-->
<div class="head-container">
<div>
<!-- 搜索 -->
<date-range-picker v-model="query.createTime" class="date-item" />
<el-input
v-model="query.taskName"
clearable
size="small"
placeholder="输入任务名"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<!-- <el-select v-model="value" size="small" class="filter-item" style="width: 110px" clearable placeholder="请选择状态" @change="crud.toQuery">
<el-option :value="0">等待建模</el-option>
<el-option :value="1">建模成功</el-option>
</el-select> -->
<rrOperation />
</div>
</div>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
:header-cell-style="{ 'text-align': 'left' }"
style="width: 100%;"
>
<el-table-column :show-overflow-tooltip="true" prop="id" label="ID" width="35" />
<el-table-column
:show-overflow-tooltip="true"
prop="taskName"
label="任务名"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="uploadNum"
label="上传数量"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="analysisNum"
label="解析数量"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="payTime"
width="135"
label="上传时间"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="payTime"
width="110"
label="发送类型"
>
<template slot-scope="scope">
<span>{{ statecCmparison('uploadTypeList', scope.row.recordType) }}</span>
</template>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="recordStatus"
width="110"
label="状态"
>
<template slot-scope="scope">
<span>{{ statecCmparison('statusList', scope.row.recordStatus) }}</span>
</template>
</el-table-column>
<el-table-column
width="75"
label="操作"
>
<template slot-scope="scope">
<el-button
slot="reference"
size="mini"
type="text"
:disabled="scope.row.recordStatus !== 1"
@click="openModeling(scope.row.id)"
>建模</el-button>
</template>
</el-table-column>
<template #empty>
<div style="width: 100%; height: 450px;display: flex; flex-direction: column; justify-content: center;align-items: center">
<img src="@/assets/images/zanwu.png" alt="">
<div>暂无数据</div>
</div>
</template>
</el-table>
<!--分页组件-->
<pagination />
</el-row>
<el-dialog title="建模创建" :visible.sync="dialogFormVisible" width="420px" @close="closeDialog">
<el-form ref="refForm" :model="modelingForm">
<el-form-item label="活动ID" prop="actId" :rules="[{ required: true, message: '请输入活动id'}]">
<el-input v-model="modelingForm.actId" autocomplete="off" />
</el-form-item>
<el-form-item label="活动名称" prop="actName" :rules="[{ required: true, message: '请输入活动名称'}]">
<el-input v-model="modelingForm.actName" autocomplete="off" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="dialogFormVisible = false"> </el-button>
<el-button type="primary" @click="recordBuildFun"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import DateRangePicker from '@/components/DateRangePicker'
import {
recordBuild
} from '@/api/index'
import { mapGetters } from 'vuex'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
const defaultForm = {}
export default {
name: 'ManageIndex',
components: { rrOperation, pagination, DateRangePicker },
cruds() {
return CRUD({
title: '建模管理',
url: 'api-management/api/mode/record',
crudMethod: {}
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
height: document.documentElement.clientHeight - 180 + 'px;',
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del'],
download: ['admin', 'user:download']
},
dialogFormVisible: false,
modelingForm: {
id: '',
actId: '',
actName: ''
},
uploadTypeList: [
{
key: '方式一',
value: '0'
},
{
key: '方式二',
value: '1'
},
{
key: '方式三',
value: '2'
}
],
statusList: [
{
key: '上传失败',
value: '-1'
},
{
key: '上传中',
value: '0'
},
{
key: '上传成功',
value: '1'
},
{
key: '建模中',
value: '2'
},
{
key: '建模成功',
value: '3'
}
]
}
},
computed: {
...mapGetters(['user'])
},
created() {
},
mounted: function() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 180 + 'px;'
}
},
methods: {
openModeling(id) {
this.modelingForm.id = id
this.dialogFormVisible = true
},
closeDialog() {
this.$refs.refForm.resetFields()
},
recordBuildFun() {
this.$refs.refForm.validate((valid) => {
if (valid) {
recordBuild(this.modelingForm).then(res => {
this.$message('操作成功')
this.dialogFormVisible = false
})
}
})
},
statecCmparison(name, val) {
return this[name].filter(item => { return Number(item.value) === val })[0].key
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-dialog__body {
padding: 20px;
}
</style>

File diff suppressed because it is too large Load Diff

@ -570,17 +570,17 @@
label="dmp投量"
/>
<el-table-column label="操作" width="240" fixed="right">
<el-table-column label="操作" width="140" fixed="right">
<template slot-scope="scope">
<div style="display: flex; align-items: center">
<span style="color: #246fdc; margin-right: 5px">|</span>
<!-- <span style="color: #246fdc; margin-right: 5px">|</span> -->
<el-button
slot="reference"
class="popover-item"
type="text"
@click="allotmentQuantity(scope.row)"
>配量</el-button>
<span style="color: #246fdc; margin: 0 5px">|</span>
<!-- <span style="color: #246fdc; margin: 0 5px">|</span> -->
<el-button
slot="reference"
class="popover-item"
@ -589,7 +589,7 @@
@click="generateLink(scope.row)"
>
生链</el-button>
<span style="color: #246fdc; margin-left: 5px">|</span>
<!-- <span style="color: #246fdc; margin-left: 5px">|</span> -->
<el-button
slot="reference"
class="popover-item"
@ -598,7 +598,7 @@
@click="modifyDeliveryQuantity(scope.row)"
>
改量</el-button>
<span style="color: #246fdc; margin-left: 5px">|</span>
<!-- <span style="color: #246fdc; margin-left: 5px">|</span> -->
</div>
</template>
</el-table-column>

File diff suppressed because it is too large Load Diff

@ -1,322 +1,322 @@
<!--
* @Description: 标签管理
* @Autor: 飘泊客
* @Date: 2022-05-23 15:20:02
* @LastEditors: 飘泊客
* @LastEditTime: 2023-05-16 16:53:42
-->
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div>
<!-- 搜索 -->
<label class="y-label">标签组名</label>
<el-input
v-model="query.name"
clearable
size="small"
placeholder="请输入"
style="width: 170px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<rrOperation />
</div>
<crudOperation show="" :permission="permission" />
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" :header-cell-style="{'text-align':'left'}" @selection-change="crud.selectionChangeHandler">
<el-table-column type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" prop="name" label="标签组名" />
<el-table-column :show-overflow-tooltip="true" prop="labelList" label="标签">
<template slot-scope="scope">
<div class="u-flex">
<div v-for="item in scope.row.labelList" :key="item.id" class="mr-5">
<el-tag>{{ item.labelName }}</el-tag>
</div>
</div>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="isEnable" label="是否开启">
<template slot-scope="scope">
<el-switch v-model="scope.row.isEnable" active-color="#246fdc" :active-value="1" :inactive-value="0" @change="quickUpdate(scope.row)" />
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="135" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="140"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
@customEdit="editLabel"
/>
</template>
</el-table-column>
<template #empty>
<div style="width: 100%; height: 450px;display: flex; flex-direction: column; justify-content: center;align-items: center">
<img src="@/assets/images/zanwu.png" alt="">
<div>暂无数据</div>
</div>
</template>
</el-table>
<!--分页组件-->
<pagination />
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="cancelCU"
:visible.sync="crud.status.cu > 0"
title="标签管理"
width="520px"
>
<el-form
ref="form"
:inline="true"
:rules="rules"
:model="form"
size="small"
label-width="80px"
>
<el-form-item label="标签组名" prop="name">
<el-input v-model="form.name" style="width: 340px" />
</el-form-item>
<el-form-item label="是否开启">
<el-switch v-model="form.isEnable" active-color="#246fdc" :active-value="1" :inactive-value="0" />
</el-form-item>
<div class="u-flex mb-15">
<div class="label">
标签
</div>
<div class="u-flex labelGroup">
<div>
<el-tag
v-for="(tag, index) in form.labelList"
:key="index"
closable
:disable-transitions="false"
class="mr-5 mb-5"
@close="handleClose(index)"
>
{{ tag.labelName }}
</el-tag>
<el-input
v-if="inputVisible"
ref="saveTagInput"
v-model="inputValue"
class="input-new-tag"
size="small"
@keyup.enter.native="handleInputConfirm"
@blur="handleInputConfirm"
/>
<el-button v-else class="button-new-tag" size="small" @click="showInput"></el-button>
</div>
</div>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="cancelCU"></el-button>
<el-button
:loading="subloading"
type="primary"
@click="submitTlabel"
>确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import udOperation from '@crud/UD.operation'
import { labelOrganizeAdd, labelOrganizeDel, labelOrganizeUpdate } from '@/api/index'
const defaultForm = {}
export default {
name: 'LabelManagement',
components: {
rrOperation,
pagination,
udOperation,
crudOperation
},
cruds() {
return CRUD({
title: '标签管理',
url: 'api-management/api/labelOrganize/queryAll',
optShow: {
add: true,
edit: false,
del: true,
download: false,
reset: true
},
crudMethod: { del: labelOrganizeDel }
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del'],
download: ['admin', 'user:download'],
recharge: false,
labelDel: true
},
inputVisible: false,
inputValue: '',
subloading: false,
labelDialog: false,
delArr: [], // ID
form: {
name: '',
isEnable: 0,
labelList: []
},
rules: {
name: [
{ required: true, message: '请输入标签组名', trigger: 'blur' }
]
}
}
},
mounted() {
},
methods: {
submitTlabel() {
this.$refs.form.validate((valide) => {
if (valide) {
this.subloading = true
const obj = Object.assign({}, this.form)
// const arr = []
// obj.labelList.length > 0 && obj.labelList.forEach(element => {
// arr.push({ labelName: element })
// })
// obj.labelList = arr
// delete obj.labelList
if (this.crud.status.add === 1) {
labelOrganizeAdd(obj).then(res => {
this.$message({
type: 'success',
message: '操作成功!',
showClose: true
})
this.subloading = false
this.cancelCU()
this.crud.toQuery()
}).catch(() => {
this.subloading = false
})
} else if (this.crud.status.edit === 1) {
obj.id = this.form.id
obj.delLabelId = this.delArr
labelOrganizeUpdate(obj).then(res => {
this.$message({
type: 'success',
message: '操作成功!',
showClose: true
})
this.subloading = false
this.cancelCU()
this.crud.toQuery()
}).catch(() => {
this.subloading = false
})
}
this.delArr = []
this.form = {
name: '',
isEnable: 0,
labelList: []
}
}
})
},
quickUpdate(data) {
labelOrganizeUpdate(data).then(res => {
this.crud.toQuery()
}).catch(() => {
})
},
editLabel(data) {
this.crud.status.edit = 1
this.crud.getDataStatus(this.crud.getDataId(data)).edit = 1
const todata = JSON.stringify(data)
this.form = JSON.parse(todata)
},
handleClose(index) {
if (this.form.labelList[index].id != null) this.delArr.push(this.form.labelList[index].id)
this.form.labelList.splice(index, 1)
},
showInput() {
this.inputVisible = true
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus()
})
},
cancelCU() {
if (this.crud.status.edit === 1) {
this.crud.status.edit = 0
}
if (this.crud.status.add === 1) {
this.crud.status.add = 0
}
this.form.name = ''
this.form.isEnable = 0
this.form.labelList = []
this.$refs['form'].clearValidate()
},
handleInputConfirm() {
const inputValue = this.inputValue
if (inputValue) {
this.form.labelList.push({ labelName: inputValue, id: null })
}
this.inputVisible = false
this.inputValue = ''
}
}
}
</script>
<style lang="scss">
.label{
min-width: 80px;
line-height: 32px;
float: none;
display: inline-block;
font-size: 14px;
color: #606266;
text-align: right;
vertical-align: middle;
font-weight: 700;
padding: 0 12px 0 20px;
}
.labelGroup {
flex-wrap: wrap;
div{
margin-right: 6px;
}
}
.input-new-tag {
width: 90px;
margin-left: 10px;
vertical-align: bottom;
}
.button-new-tag {
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
</style>
<!--
* @Description: 标签管理
* @Autor: 飘泊客
* @Date: 2022-05-23 15:20:02
* @LastEditors: 飘泊客
* @LastEditTime: 2023-05-16 16:53:42
-->
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div>
<!-- 搜索 -->
<label class="y-label">标签组名</label>
<el-input
v-model="query.name"
clearable
size="small"
placeholder="请输入"
style="width: 170px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<rrOperation />
</div>
<crudOperation show="" :permission="permission" />
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" :header-cell-style="{'text-align':'left'}" @selection-change="crud.selectionChangeHandler">
<el-table-column type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" prop="name" label="标签组名" />
<el-table-column :show-overflow-tooltip="true" prop="labelList" label="标签">
<template slot-scope="scope">
<div class="u-flex">
<div v-for="item in scope.row.labelList" :key="item.id" class="mr-5">
<el-tag>{{ item.labelName }}</el-tag>
</div>
</div>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="isEnable" label="是否开启">
<template slot-scope="scope">
<el-switch v-model="scope.row.isEnable" active-color="#246fdc" :active-value="1" :inactive-value="0" @change="quickUpdate(scope.row)" />
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="135" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="100"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
@customEdit="editLabel"
/>
</template>
</el-table-column>
<template #empty>
<div style="width: 100%; height: 450px;display: flex; flex-direction: column; justify-content: center;align-items: center">
<img src="@/assets/images/zanwu.png" alt="">
<div>暂无数据</div>
</div>
</template>
</el-table>
<!--分页组件-->
<pagination />
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="cancelCU"
:visible.sync="crud.status.cu > 0"
title="标签管理"
width="520px"
>
<el-form
ref="form"
:inline="true"
:rules="rules"
:model="form"
size="small"
label-width="80px"
>
<el-form-item label="标签组名" prop="name">
<el-input v-model="form.name" style="width: 340px" />
</el-form-item>
<el-form-item label="是否开启">
<el-switch v-model="form.isEnable" active-color="#246fdc" :active-value="1" :inactive-value="0" />
</el-form-item>
<div class="u-flex mb-15">
<div class="label">
标签
</div>
<div class="u-flex labelGroup">
<div>
<el-tag
v-for="(tag, index) in form.labelList"
:key="index"
closable
:disable-transitions="false"
class="mr-5 mb-5"
@close="handleClose(index)"
>
{{ tag.labelName }}
</el-tag>
<el-input
v-if="inputVisible"
ref="saveTagInput"
v-model="inputValue"
class="input-new-tag"
size="small"
@keyup.enter.native="handleInputConfirm"
@blur="handleInputConfirm"
/>
<el-button v-else class="button-new-tag" size="small" @click="showInput"></el-button>
</div>
</div>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="cancelCU"></el-button>
<el-button
:loading="subloading"
type="primary"
@click="submitTlabel"
>确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import udOperation from '@crud/UD.operation'
import { labelOrganizeAdd, labelOrganizeDel, labelOrganizeUpdate } from '@/api/index'
const defaultForm = {}
export default {
name: 'LabelManagement',
components: {
rrOperation,
pagination,
udOperation,
crudOperation
},
cruds() {
return CRUD({
title: '标签管理',
url: 'api-management/api/labelOrganize/queryAll',
optShow: {
add: true,
edit: false,
del: true,
download: false,
reset: true
},
crudMethod: { del: labelOrganizeDel }
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del'],
download: ['admin', 'user:download'],
recharge: false,
labelDel: true
},
inputVisible: false,
inputValue: '',
subloading: false,
labelDialog: false,
delArr: [], // ID
form: {
name: '',
isEnable: 0,
labelList: []
},
rules: {
name: [
{ required: true, message: '请输入标签组名', trigger: 'blur' }
]
}
}
},
mounted() {
},
methods: {
submitTlabel() {
this.$refs.form.validate((valide) => {
if (valide) {
this.subloading = true
const obj = Object.assign({}, this.form)
// const arr = []
// obj.labelList.length > 0 && obj.labelList.forEach(element => {
// arr.push({ labelName: element })
// })
// obj.labelList = arr
// delete obj.labelList
if (this.crud.status.add === 1) {
labelOrganizeAdd(obj).then(res => {
this.$message({
type: 'success',
message: '操作成功!',
showClose: true
})
this.subloading = false
this.cancelCU()
this.crud.toQuery()
}).catch(() => {
this.subloading = false
})
} else if (this.crud.status.edit === 1) {
obj.id = this.form.id
obj.delLabelId = this.delArr
labelOrganizeUpdate(obj).then(res => {
this.$message({
type: 'success',
message: '操作成功!',
showClose: true
})
this.subloading = false
this.cancelCU()
this.crud.toQuery()
}).catch(() => {
this.subloading = false
})
}
this.delArr = []
this.form = {
name: '',
isEnable: 0,
labelList: []
}
}
})
},
quickUpdate(data) {
labelOrganizeUpdate(data).then(res => {
this.crud.toQuery()
}).catch(() => {
})
},
editLabel(data) {
this.crud.status.edit = 1
this.crud.getDataStatus(this.crud.getDataId(data)).edit = 1
const todata = JSON.stringify(data)
this.form = JSON.parse(todata)
},
handleClose(index) {
if (this.form.labelList[index].id != null) this.delArr.push(this.form.labelList[index].id)
this.form.labelList.splice(index, 1)
},
showInput() {
this.inputVisible = true
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus()
})
},
cancelCU() {
if (this.crud.status.edit === 1) {
this.crud.status.edit = 0
}
if (this.crud.status.add === 1) {
this.crud.status.add = 0
}
this.form.name = ''
this.form.isEnable = 0
this.form.labelList = []
this.$refs['form'].clearValidate()
},
handleInputConfirm() {
const inputValue = this.inputValue
if (inputValue) {
this.form.labelList.push({ labelName: inputValue, id: null })
}
this.inputVisible = false
this.inputValue = ''
}
}
}
</script>
<style lang="scss">
.label{
min-width: 80px;
line-height: 32px;
float: none;
display: inline-block;
font-size: 14px;
color: #606266;
text-align: right;
vertical-align: middle;
font-weight: 700;
padding: 0 12px 0 20px;
}
.labelGroup {
flex-wrap: wrap;
div{
margin-right: 6px;
}
}
.input-new-tag {
width: 90px;
margin-left: 10px;
vertical-align: bottom;
}
.button-new-tag {
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -53,8 +53,7 @@
</el-table-column>
<el-table-column
label="操作"
width="100"
align="left"
width="75"
fixed="right"
>
<template slot-scope="scope">

@ -1,395 +1,395 @@
<!--
* @Description: 充值页
* @Autor: 飘泊客
* @Date: 2022-03-11 13:48:26
* @LastEditors: 飘泊客
* @LastEditTime: 2023-06-21 15:41:15
-->
<template>
<div class="app-container">
<div class="subject">
<el-row :gutter="20">
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<el-card class="box-card overflow">
<div class="card-item">
<div class="u-flex">
<img src="@/assets/images/qianbao-icon.png" class="qianbao-icon">
<div class="item-left">
<div class="title">可用额度</div>
<div class="text-item">
<span class="line-price">{{ user.userBalance || 0 }}</span>
<el-button size="mini" class="ml-15" type="primary" @click="rechargePay"></el-button>
</div>
</div>
</div>
<img src="@/assets/images/qianbao-bj.png" class="qianbao-bj">
</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<el-card class="box-card overflow">
<div class="card-item">
<div class="u-flex">
<img src="@/assets/images/qianbao-icon.png" class="qianbao-icon">
<div class="item-left">
<div class="title">现金余额</div>
<div class="text-item">
<span class="line-price">{{ user.userBalance || 0 }}</span>
</div>
</div>
</div>
<img src="@/assets/images/qianbao-bj.png" class="qianbao-bj">
</div>
</el-card>
</el-col>
</el-row>
<div class="upper-bottom">
<el-card class="box-card exhibitionBlock">
<div class="block-title">月账单概览</div>
<el-table
:data="monthBillList"
stripe
:header-cell-style="{'text-align': 'left'}"
style="width: 100%"
>
<el-table-column prop="callMonth" label="账期" width="160" />
<el-table-column prop="billDate" label="出账日期" width="160" />
<el-table-column prop="total" label="消费金额">
<template slot-scope="scope">
{{ scope.row.total }}
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button type="text" @click.stop="doDetail(scope.row.callMonth)">查看详情</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<el-dialog
append-to-body
:close-on-click-modal="false"
:visible.sync="detailDialog"
title="月账单详情"
width="730px"
:show-close="false"
class="monthlyDialog"
@close="closeDialog"
>
<div class="u-flex u-flex-between">
<span class="dia-title">账单基本信息</span>
<el-button type="text" size="mini" :disabled="!monthBillDetail.content" @click="deductDownload"></el-button>
</div>
<div class="mt-15">
<label class="label">客户名称</label>
<span>{{ monthBillDetail.companyName }}</span>
</div>
<div class="mt-10">
<label class="label">账期</label>
<span>{{ monthBillDetail.chargeBill }}</span>
</div>
<div class="mt-15 mb-10">
<span class="dia-title">账单消费汇总</span>
</div>
<el-table
:data="monthBillDetail.content"
stripe
:header-cell-style="{'text-align':'left'}"
style="width: 100%"
>
<el-table-column prop="username" label="账号名称" width="200" />
<el-table-column label="账号属性">子账号</el-table-column>
<el-table-column prop="type" label="费用类型">
<template slot-scope="scope">
{{ scope.row.type == 1 ? '日结费' : '套餐费' }}
</template>
</el-table-column>
<el-table-column prop="deductAmount" label="费用金额" />
<el-table-column prop="deductDuration" label="扣减时间" width="150">
<template slot-scope="scope">
{{ scope.row.deductDuration }}分钟
</template>
</el-table-column>
<el-table-column prop="status" label="扣减状态">
<template slot-scope="scope">
{{ scope.row.status ? '扣减成功' : '扣减失败' }}
</template>
</el-table-column>
<el-table-column prop="comboType" label="套餐类型" />
</el-table>
<el-pagination
background
:page-size.sync="page.size"
:total="page.total"
:current-page.sync="page.page"
style="margin-top: 8px;"
layout="total, prev, pager, next, sizes"
@size-change="sizeChangeHandler($event)"
@current-change="pageChangeHandler"
/>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="detailDialog = false">关闭</el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { getDeductList, getDeductMonthList, downloadDeduct } from '@/api/index'
import { downloadFile } from '@/utils/index'
export default {
name: 'BillList',
data() {
return {
payType: 1,
rechargeAmount: '',
detailDialog: false,
monthBillList: [], //
page: {
page: 1,
size: 10,
total: 0
},
monthBillDetail: '', //
month: null
}
},
computed: {
...mapGetters([
'user'
])
},
mounted() {
this.init()
},
methods: {
init() {
getDeductList().then(res => {
this.monthBillList = res.content
})
},
//
doDetail(month) {
if (month) this.month = month
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
getDeductMonthList({ queryTime: this.month, page: this.page.page - 1, size: this.page.size }).then(res => {
this.monthBillDetail = res
this.page.total = res.totalElements
console.log(this.page.total)
this.detailDialog = true
loading.close()
}).catch(() => {
loading.close()
})
},
pageChangeHandler(e) {
this.page.page = e
this.doDetail()
},
sizeChangeHandler(e) {
this.page.size = e
this.page.page = 1
this.doDetail()
},
// excel
deductDownload() {
downloadDeduct({ queryTime: this.monthBillDetail.chargeBill }).then(res => {
downloadFile(res, '任务统计数据', 'xlsx')
})
},
rechargePay() {
this.$router.push({ path: '/recharge/recharge' })
},
closeDialog() {
this.page.page = 1
this.page.size = 10
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-radio__label{
display: flex;
align-items: center;
}
::v-deep .el-radio__input.is-checked+.el-radio__label {
color: #1890ff;
}
::v-deep .el-radio__input.is-checked .el-radio__inner {
border-color: #1890ff;
background: #1890ff;
}
.monthlyDialog ::v-deep .el-dialog__body {
padding-top: 0;
}
.app-container {
background: #f0f2f5;
padding: 0;
padding-top: 20px;
}
.card-item {
display: flex;
justify-content: space-between;
position: relative;
.item-left {
margin-left: 15px;
line-height: 30px;
}
.title {
font-size: 16px;
font-weight: 500;
color: rgba(0,0,0,0.65);
}
.line-price {
font-weight: 600;
color: #F86E21;
font-size: 20px;
}
.qianbao-icon {
width: 40px;
height: 40px;
}
.qianbao-bj {
width: 68px;
height: 68px;
position: absolute;
right: 0px;
top: 15px;
}
}
.monthlyDialog {
.dia-title {
font-size: 15px;
font-weight: 600;
color: #181818;
}
.label {
font-weight: 500;
display: inline-block;
width: 100px;
text-align: right;
}
}
.toptitle {
padding: 12px 0;
// border-bottom: 1px solid #d4d3d3;
margin: 0 0 12px;
height: auto;
line-height: normal;
span:nth-child(1) {
color: #181818;
font-size: 14px;
height: 24px;
line-height: 24px;
vertical-align: middle;
}
span:nth-child(2) {
display: block;
color: #909399;
font-size: 13px;
margin-top: 12px;
}
}
.upper-bottom {
// background: #F0F0F0;
// width: 100%;
// min-height: calc(100vh - 170px);
}
.overflow {
position: relative;
top: -20px;
}
.block-title {
font-size: 16px;
font-weight: 600;
color: #000000;
margin-bottom: 20px;
}
.exhibitionBlock {
margin: auto;
.horndiv {
width: 100%;
transform-origin: center top;
z-index: 2074;
background: #F0F0F0;
height: 60px;
margin: auto;
margin-top: 15px;
padding: 15px;
span:nth-child(1) {
margin-bottom: 5px;
}
span {
color: #606266;
font-size: 14px;
}
}
}
.subject {
width: 100%;
position: relative;
box-sizing: border-box;
}
.c-title {
font-size: 14px;
color: black;
font-size: 14px;
img {
width: 30px;
height: 30px;;
border-radius: 50%;
margin-right: 5px;
}
}
.line-price {
color: #FF9C00;
font-size: 19px;
font-weight: 600;
vertical-align: middle;
}
.line-price:before {
content: '¥';
font-size: 19px;
}
.topinput {
line-height: 30px;
}
.text-item {
font-size: 17px;
color: #181818;
}
.radio-content {
width: 80%;
}
.yellow{
color: rgb(238, 103, 35);
}
.backicon:hover{
cursor: pointer;
}
.red{
color: red;
}
.lin-title {
font-size: 14px;
box-sizing: border-box;
margin-right: 10px;
margin-left: 2px;
color:#999999
}
.lin-text {
font-size: 12px;
color: red;
padding-left: 170px;
margin-top: 6px
}
</style>
<!--
* @Description: 充值页
* @Autor: 飘泊客
* @Date: 2022-03-11 13:48:26
* @LastEditors: 飘泊客
* @LastEditTime: 2023-06-21 15:41:15
-->
<template>
<div class="app-container">
<div class="subject">
<el-row :gutter="20">
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<el-card class="box-card overflow">
<div class="card-item">
<div class="u-flex">
<img src="@/assets/images/qianbao-icon.png" class="qianbao-icon">
<div class="item-left">
<div class="title">可用额度</div>
<div class="text-item">
<span class="line-price">{{ user.userBalance || 0 }}</span>
<el-button size="mini" class="ml-15" type="primary" @click="rechargePay"></el-button>
</div>
</div>
</div>
<img src="@/assets/images/qianbao-bj.png" class="qianbao-bj">
</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<el-card class="box-card overflow">
<div class="card-item">
<div class="u-flex">
<img src="@/assets/images/qianbao-icon.png" class="qianbao-icon">
<div class="item-left">
<div class="title">现金余额</div>
<div class="text-item">
<span class="line-price">{{ user.userBalance || 0 }}</span>
</div>
</div>
</div>
<img src="@/assets/images/qianbao-bj.png" class="qianbao-bj">
</div>
</el-card>
</el-col>
</el-row>
<div class="upper-bottom">
<el-card class="box-card exhibitionBlock">
<div class="block-title">月账单概览</div>
<el-table
:data="monthBillList"
stripe
:header-cell-style="{'text-align': 'left'}"
style="width: 100%"
>
<el-table-column prop="callMonth" label="账期" width="160" />
<el-table-column prop="billDate" label="出账日期" width="160" />
<el-table-column prop="total" label="消费金额">
<template slot-scope="scope">
{{ scope.row.total }}
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button type="text" @click.stop="doDetail(scope.row.callMonth)">查看详情</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<el-dialog
append-to-body
:close-on-click-modal="false"
:visible.sync="detailDialog"
title="月账单详情"
width="730px"
:show-close="false"
class="monthlyDialog"
@close="closeDialog"
>
<div class="u-flex u-flex-between">
<span class="dia-title">账单基本信息</span>
<el-button type="text" size="mini" :disabled="!monthBillDetail.content" @click="deductDownload"></el-button>
</div>
<div class="mt-15">
<label class="label">客户名称</label>
<span>{{ monthBillDetail.companyName }}</span>
</div>
<div class="mt-10">
<label class="label">账期</label>
<span>{{ monthBillDetail.chargeBill }}</span>
</div>
<div class="mt-15 mb-10">
<span class="dia-title">账单消费汇总</span>
</div>
<el-table
:data="monthBillDetail.content"
stripe
:header-cell-style="{'text-align':'left'}"
style="width: 100%"
>
<el-table-column prop="username" label="账号名称" width="200" />
<el-table-column label="账号属性">子账号</el-table-column>
<el-table-column prop="type" label="费用类型">
<template slot-scope="scope">
{{ scope.row.type == 1 ? '日结费' : '套餐费' }}
</template>
</el-table-column>
<el-table-column prop="deductAmount" label="费用金额" />
<el-table-column prop="deductDuration" label="扣减时间" width="150">
<template slot-scope="scope">
{{ scope.row.deductDuration }}分钟
</template>
</el-table-column>
<el-table-column prop="status" label="扣减状态">
<template slot-scope="scope">
{{ scope.row.status ? '扣减成功' : '扣减失败' }}
</template>
</el-table-column>
<el-table-column prop="comboType" label="套餐类型" />
</el-table>
<el-pagination
background
:page-size.sync="page.size"
:total="page.total"
:current-page.sync="page.page"
style="margin-top: 8px;"
layout="total, prev, pager, next, sizes"
@size-change="sizeChangeHandler($event)"
@current-change="pageChangeHandler"
/>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="detailDialog = false">关闭</el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { getDeductList, getDeductMonthList, downloadDeduct } from '@/api/index'
import { downloadFile } from '@/utils/index'
export default {
name: 'BillList',
data() {
return {
payType: 1,
rechargeAmount: '',
detailDialog: false,
monthBillList: [], //
page: {
page: 1,
size: 10,
total: 0
},
monthBillDetail: '', //
month: null
}
},
computed: {
...mapGetters([
'user'
])
},
mounted() {
this.init()
},
methods: {
init() {
getDeductList().then(res => {
this.monthBillList = res.content
})
},
//
doDetail(month) {
if (month) this.month = month
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
getDeductMonthList({ queryTime: this.month, page: this.page.page - 1, size: this.page.size }).then(res => {
this.monthBillDetail = res
this.page.total = res.totalElements
console.log(this.page.total)
this.detailDialog = true
loading.close()
}).catch(() => {
loading.close()
})
},
pageChangeHandler(e) {
this.page.page = e
this.doDetail()
},
sizeChangeHandler(e) {
this.page.size = e
this.page.page = 1
this.doDetail()
},
// excel
deductDownload() {
downloadDeduct({ queryTime: this.monthBillDetail.chargeBill }).then(res => {
downloadFile(res, '任务统计数据', 'xlsx')
})
},
rechargePay() {
this.$router.push({ path: '/recharge/recharge' })
},
closeDialog() {
this.page.page = 1
this.page.size = 10
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-radio__label{
display: flex;
align-items: center;
}
::v-deep .el-radio__input.is-checked+.el-radio__label {
color: #1890ff;
}
::v-deep .el-radio__input.is-checked .el-radio__inner {
border-color: #1890ff;
background: #1890ff;
}
.monthlyDialog ::v-deep .el-dialog__body {
padding-top: 0;
}
.app-container {
background: #f0f2f5;
padding: 0;
padding-top: 20px;
}
.card-item {
display: flex;
justify-content: space-between;
position: relative;
.item-left {
margin-left: 15px;
line-height: 30px;
}
.title {
font-size: 16px;
font-weight: 500;
color: rgba(0,0,0,0.65);
}
.line-price {
font-weight: 600;
color: #F86E21;
font-size: 20px;
}
.qianbao-icon {
width: 40px;
height: 40px;
}
.qianbao-bj {
width: 68px;
height: 68px;
position: absolute;
right: 0px;
top: 15px;
}
}
.monthlyDialog {
.dia-title {
font-size: 15px;
font-weight: 600;
color: #181818;
}
.label {
font-weight: 500;
display: inline-block;
width: 100px;
text-align: right;
}
}
.toptitle {
padding: 12px 0;
// border-bottom: 1px solid #d4d3d3;
margin: 0 0 12px;
height: auto;
line-height: normal;
span:nth-child(1) {
color: #181818;
font-size: 14px;
height: 24px;
line-height: 24px;
vertical-align: middle;
}
span:nth-child(2) {
display: block;
color: #909399;
font-size: 13px;
margin-top: 12px;
}
}
.upper-bottom {
// background: #F0F0F0;
// width: 100%;
// min-height: calc(100vh - 170px);
}
.overflow {
position: relative;
top: -20px;
}
.block-title {
font-size: 16px;
font-weight: 600;
color: #000000;
margin-bottom: 20px;
}
.exhibitionBlock {
margin: auto;
.horndiv {
width: 100%;
transform-origin: center top;
z-index: 2074;
background: #F0F0F0;
height: 60px;
margin: auto;
margin-top: 15px;
padding: 15px;
span:nth-child(1) {
margin-bottom: 5px;
}
span {
color: #606266;
font-size: 14px;
}
}
}
.subject {
width: 100%;
position: relative;
box-sizing: border-box;
}
.c-title {
font-size: 14px;
color: black;
font-size: 14px;
img {
width: 30px;
height: 30px;;
border-radius: 50%;
margin-right: 5px;
}
}
.line-price {
color: #FF9C00;
font-size: 19px;
font-weight: 600;
vertical-align: middle;
}
.line-price:before {
content: '¥';
font-size: 19px;
}
.topinput {
line-height: 30px;
}
.text-item {
font-size: 17px;
color: #181818;
}
.radio-content {
width: 80%;
}
.yellow{
color: rgb(238, 103, 35);
}
.backicon:hover{
cursor: pointer;
}
.red{
color: red;
}
.lin-title {
font-size: 14px;
box-sizing: border-box;
margin-right: 10px;
margin-left: 2px;
color:#999999
}
.lin-text {
font-size: 12px;
color: red;
padding-left: 170px;
margin-top: 6px
}
</style>

File diff suppressed because it is too large Load Diff

@ -1,293 +1,293 @@
<!--
* @Description:
* @Autor: 飘泊客
* @Date: 2022-04-19 15:52:12
* @LastEditors: 飘泊客
* @LastEditTime: 2023-05-06 14:25:58
-->
<template>
<div class="app-container">
<el-row :gutter="20">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input
v-model="query.phone"
clearable
size="small"
placeholder="输入手机号码搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<!-- <date-range-picker v-model="query.createTime" class="date-item" /> -->
<!-- <el-select
v-model="query.enabled"
clearable
size="small"
placeholder="状态"
class="filter-item"
style="width: 90px"
@change="crud.toQuery"
>
<el-option
v-for="item in enabledTypeOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select> -->
<rrOperation />
</div>
<!-- <crudOperation show="" :permission="permission" @onRechargeArr="onRecharges">
<template v-slot:right>
<div class="rig-btn filter-item">
<el-upload
class="upload-demo"
:action="importUsers"
:show-file-list="false"
:headers="headers"
accept=".xlsx,.xls"
multiple
:limit="1"
:on-success="onsucess"
:on-error="onerror"
>
<el-button size="mini" type="primary">批量上传</el-button>
</el-upload>
<el-link type="primary" :underline="false" @click="downLink">()</el-link>
</div>
</template>
</crudOperation> -->
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" :header-cell-style="{'text-align':'left'}" @selection-change="crud.selectionChangeHandler">
<el-table-column :show-overflow-tooltip="true" prop="phone" label="用户名" />
<el-table-column prop="invitationNums" label="邀请数量" width="80" />
<el-table-column :show-overflow-tooltip="true" width="135" prop="qrCodePath" label="分销二维码">
<template slot-scope="scope">
<el-image
style="width: 100px; height: 100px"
:src=" baseImgUrl + scope.row.qrCodePath"
fit="contain"
:preview-src-list="previewImg(baseImgUrl + scope.row.qrCodePath)"
/>
</template>
</el-table-column>
<el-table-column label="状态" align="center" width="100" prop="status">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
:disabled="user.id === scope.row.id"
active-color="#409EFF"
inactive-color="#F56C6C"
@change="changeEnabled(scope.row, scope.row.status)"
/>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="lastLoginTime" label="最后登录时间">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.lastLoginTime) }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
v-permission="['admin','user:edit','user:del']"
label="操作"
width="140"
fixed="right"
>
<template slot-scope="scope">
<el-button slot="reference" type="primary" size="mini" @click="openDetail(scope.row.id)"></el-button>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</el-row>
<el-dialog append-to-body :close-on-click-modal="false" :visible.sync="recordProp" title="分销人员" width="850px">
<!-- <div class="mb-10">
<date-range-picker v-model="childrenQuery.createTime" class="date-item" />
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery"></el-button>
</div> -->
<el-table ref="table" v-loading="detail.loading" :data="detail.data" :header-cell-style="{'text-align':'left'}" style="width: 100%;">
<el-table-column :show-overflow-tooltip="true" prop="name" label="姓名" width="80" />
<el-table-column prop="nid" label="电话" width="120" />
<el-table-column :show-overflow-tooltip="true" prop="debtType" label="债务类别">
<template slot-scope="scope">
<span>{{ (scope.row.debtType == 0 ? '信用卡' : scope.row.debtType == 1 ? '网贷' : '信用卡+网贷') }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="quota" label="额度">
<template slot-scope="scope">
<span>{{ (scope.row.quota == 0 ? '5-10万' : scope.row.quota == 1 ? '10-20万' : scope.row.quota == 2 ? '20-30万' : scope.row.quota == 3 ? '30-50万' : '50万以上') }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<el-pagination
:page-size.sync="page.size"
:total="page.total"
:current-page.sync="page.page"
style="margin-top: 8px;"
layout="total, prev, pager, next"
@current-change="pageChangeHandler"
/>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="recordProp = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import crudUser from '@/api/system/user'
import { getToken } from '@/utils/auth'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
import { updateUserStatus, debtqueryAll } from '@/api/index'
const defaultForm = { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 'false', roles: [], jobs: [], dept: { id: null }, phone: null }
//
export default {
name: 'Distributor',
components: { rrOperation, pagination },
cruds() {
return CRUD({ title: '分销商', url: 'api-management/api/form/user/queryAll', crudMethod: { ...crudUser }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
//
dicts: ['user_status'],
data() {
return {
height: document.documentElement.clientHeight - 180 + 'px;',
deptName: '', depts: [], deptDatas: [], jobs: [], level: 3, roles: [],
jobDatas: [], roleDatas: '', // 使
defaultProps: { children: 'children', label: 'name', isLeaf: 'leaf' },
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del'],
download: ['admin', 'user:download'],
copy: true,
more: true,
recharge: true
},
enabledTypeOptions: [
{ key: 'true', display_name: '激活' },
{ key: 'false', display_name: '锁定' }
],
headers: {
Authorization: 'Bearer ' + getToken()
},
page: {
page: 1,
size: 10,
total: 0
},
childrenQuery: {
createTime: ''
},
detail: {
data: [],
loading: false
},
recordProp: false,
detailId: null // id
}
},
computed: {
...mapGetters([
'user',
'importUsers',
'baseImgUrl'
])
},
created() {},
mounted: function() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 180 + 'px;'
}
setTimeout(() => {
console.log(this.crud.data)
}, 6000)
},
methods: {
//
changeEnabled(data, val) {
this.$confirm('此操作将 "' + this.dict.label.user_status[val] + '" ' + data.phone + ', 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
updateUserStatus({ status: data.status, id: data.id }).then(res => {
this.crud.notify(this.dict.label.user_status[val] + '成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(() => {
data.status = !data.status
})
}).catch(() => {
data.status = !data.status
})
},
//
previewImg(img) {
return [img]
},
//
pageChangeHandler(option) {
this.page.page = option
this.searchDetail()
},
openDetail(id) {
this.detailId = id
this.page.page = 1
this.searchDetail()
},
//
toQuery() {
this.page.page = 1
this.searchDetail()
},
searchDetail() {
this.detail.loading = true
this.recordProp = true
debtqueryAll({ userId: this.detailId, createTime: this.childrenQuery.createTime, page: this.page.page - 1, size: this.page.size }).then(res => {
this.page.total = res.totalElements
this.detail.data = res.content
this.detail.loading = false
}).catch(() => {
this.detail.loading = false
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
.rig-btn {
width: 180px;
display: flex!important;
}
.upload-demo {
margin-left: 7px;
}
.head-container ::v-deep .crud-opts-left {
display: inherit!important;
}
</style>
<!--
* @Description:
* @Autor: 飘泊客
* @Date: 2022-04-19 15:52:12
* @LastEditors: 飘泊客
* @LastEditTime: 2023-05-06 14:25:58
-->
<template>
<div class="app-container">
<el-row :gutter="20">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input
v-model="query.phone"
clearable
size="small"
placeholder="输入手机号码搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<!-- <date-range-picker v-model="query.createTime" class="date-item" /> -->
<!-- <el-select
v-model="query.enabled"
clearable
size="small"
placeholder="状态"
class="filter-item"
style="width: 90px"
@change="crud.toQuery"
>
<el-option
v-for="item in enabledTypeOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select> -->
<rrOperation />
</div>
<!-- <crudOperation show="" :permission="permission" @onRechargeArr="onRecharges">
<template v-slot:right>
<div class="rig-btn filter-item">
<el-upload
class="upload-demo"
:action="importUsers"
:show-file-list="false"
:headers="headers"
accept=".xlsx,.xls"
multiple
:limit="1"
:on-success="onsucess"
:on-error="onerror"
>
<el-button size="mini" type="primary">批量上传</el-button>
</el-upload>
<el-link type="primary" :underline="false" @click="downLink">()</el-link>
</div>
</template>
</crudOperation> -->
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" :header-cell-style="{'text-align':'left'}" @selection-change="crud.selectionChangeHandler">
<el-table-column :show-overflow-tooltip="true" prop="phone" label="用户名" />
<el-table-column prop="invitationNums" label="邀请数量" width="80" />
<el-table-column :show-overflow-tooltip="true" width="135" prop="qrCodePath" label="分销二维码">
<template slot-scope="scope">
<el-image
style="width: 100px; height: 100px"
:src=" baseImgUrl + scope.row.qrCodePath"
fit="contain"
:preview-src-list="previewImg(baseImgUrl + scope.row.qrCodePath)"
/>
</template>
</el-table-column>
<el-table-column label="状态" align="center" width="100" prop="status">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
:disabled="user.id === scope.row.id"
active-color="#409EFF"
inactive-color="#F56C6C"
@change="changeEnabled(scope.row, scope.row.status)"
/>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="lastLoginTime" label="最后登录时间">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.lastLoginTime) }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
v-permission="['admin','user:edit','user:del']"
label="操作"
width="75"
fixed="right"
>
<template slot-scope="scope">
<el-button slot="reference" type="primary" size="mini" @click="openDetail(scope.row.id)"></el-button>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</el-row>
<el-dialog append-to-body :close-on-click-modal="false" :visible.sync="recordProp" title="分销人员" width="850px">
<!-- <div class="mb-10">
<date-range-picker v-model="childrenQuery.createTime" class="date-item" />
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery"></el-button>
</div> -->
<el-table ref="table" v-loading="detail.loading" :data="detail.data" :header-cell-style="{'text-align':'left'}" style="width: 100%;">
<el-table-column :show-overflow-tooltip="true" prop="name" label="姓名" width="80" />
<el-table-column prop="nid" label="电话" width="120" />
<el-table-column :show-overflow-tooltip="true" prop="debtType" label="债务类别">
<template slot-scope="scope">
<span>{{ (scope.row.debtType == 0 ? '信用卡' : scope.row.debtType == 1 ? '网贷' : '信用卡+网贷') }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="quota" label="额度">
<template slot-scope="scope">
<span>{{ (scope.row.quota == 0 ? '5-10万' : scope.row.quota == 1 ? '10-20万' : scope.row.quota == 2 ? '20-30万' : scope.row.quota == 3 ? '30-50万' : '50万以上') }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<el-pagination
:page-size.sync="page.size"
:total="page.total"
:current-page.sync="page.page"
style="margin-top: 8px;"
layout="total, prev, pager, next"
@current-change="pageChangeHandler"
/>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="recordProp = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import crudUser from '@/api/system/user'
import { getToken } from '@/utils/auth'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
import { updateUserStatus, debtqueryAll } from '@/api/index'
const defaultForm = { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 'false', roles: [], jobs: [], dept: { id: null }, phone: null }
//
export default {
name: 'Distributor',
components: { rrOperation, pagination },
cruds() {
return CRUD({ title: '分销商', url: 'api-management/api/form/user/queryAll', crudMethod: { ...crudUser }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
//
dicts: ['user_status'],
data() {
return {
height: document.documentElement.clientHeight - 180 + 'px;',
deptName: '', depts: [], deptDatas: [], jobs: [], level: 3, roles: [],
jobDatas: [], roleDatas: '', // 使
defaultProps: { children: 'children', label: 'name', isLeaf: 'leaf' },
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del'],
download: ['admin', 'user:download'],
copy: true,
more: true,
recharge: true
},
enabledTypeOptions: [
{ key: 'true', display_name: '激活' },
{ key: 'false', display_name: '锁定' }
],
headers: {
Authorization: 'Bearer ' + getToken()
},
page: {
page: 1,
size: 10,
total: 0
},
childrenQuery: {
createTime: ''
},
detail: {
data: [],
loading: false
},
recordProp: false,
detailId: null // id
}
},
computed: {
...mapGetters([
'user',
'importUsers',
'baseImgUrl'
])
},
created() {},
mounted: function() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 180 + 'px;'
}
setTimeout(() => {
console.log(this.crud.data)
}, 6000)
},
methods: {
//
changeEnabled(data, val) {
this.$confirm('此操作将 "' + this.dict.label.user_status[val] + '" ' + data.phone + ', 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
updateUserStatus({ status: data.status, id: data.id }).then(res => {
this.crud.notify(this.dict.label.user_status[val] + '成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(() => {
data.status = !data.status
})
}).catch(() => {
data.status = !data.status
})
},
//
previewImg(img) {
return [img]
},
//
pageChangeHandler(option) {
this.page.page = option
this.searchDetail()
},
openDetail(id) {
this.detailId = id
this.page.page = 1
this.searchDetail()
},
//
toQuery() {
this.page.page = 1
this.searchDetail()
},
searchDetail() {
this.detail.loading = true
this.recordProp = true
debtqueryAll({ userId: this.detailId, createTime: this.childrenQuery.createTime, page: this.page.page - 1, size: this.page.size }).then(res => {
this.page.total = res.totalElements
this.detail.data = res.content
this.detail.loading = false
}).catch(() => {
this.detail.loading = false
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
.rig-btn {
width: 180px;
display: flex!important;
}
.upload-demo {
margin-left: 7px;
}
.head-container ::v-deep .crud-opts-left {
display: inherit!important;
}
</style>

@ -41,14 +41,14 @@
</el-table-column> -->
<el-table-column
label="操作"
width="300"
width="160"
align="center"
fixed="right"
>
<template slot-scope="scope">
<el-button v-if="scope.row.type === 1 && scope.row.clueNum >= 100" @click="sendEmail(scope.row.id)"></el-button>
<el-button v-if="scope.row.status === 1" type="primary" @click="downloadUrl('email', scope.row)"></el-button>
<el-button v-if="scope.row.type === 2 || (scope.row.type === 1 && scope.row.clueNum < 100)" type="success" @click="downloadUrl('excel', scope.row)">excel</el-button>
<el-button v-if="scope.row.type === 1 && scope.row.clueNum >= 100" type="text" @click="sendEmail(scope.row.id)"></el-button>
<el-button v-if="scope.row.status === 1" type="text" @click="downloadUrl('email', scope.row)"></el-button>
<el-button v-if="scope.row.type === 2 || (scope.row.type === 1 && scope.row.clueNum < 100)" type="text" @click="downloadUrl('excel', scope.row)">excel</el-button>
</template>
</el-table-column>
</el-table>

@ -34,12 +34,10 @@
</el-table-column> -->
<el-table-column
label="操作"
width="140"
align="center"
fixed="right"
width="100"
>
<template slot-scope="scope">
<el-button v-if="scope.row.status === 1" type="primary" @click="downloadUrl('email', scope.row)"></el-button>
<el-button v-if="scope.row.status === 1" type="text" @click="downloadUrl('email', scope.row)"></el-button>
</template>
</el-table-column>
</el-table>

@ -267,8 +267,7 @@
<el-table-column
v-if="checkPer(['admin', 'menu:edit', 'menu:del'])"
label="操作"
width="130px"
align="center"
width="100px"
fixed="right"
>
<template slot-scope="scope">

@ -98,8 +98,8 @@
</template>
</el-table-column> -->
<el-table-column
:show-overflow-tooltip="true"
prop="amount"
width="100"
label="详情"
>
<template slot-scope="scope">

@ -1,360 +1,360 @@
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.blurry" size="small" clearable placeholder="输入名称或者描述搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<crudOperation :permission="permission" />
</div>
<!-- 表单渲染 -->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="520px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" style="width: 380px;" />
</el-form-item>
<el-form-item label="角色级别" prop="level">
<el-input-number v-model.number="form.level" :min="1" controls-position="right" style="width: 145px;" />
</el-form-item>
<el-form-item label="数据范围" prop="dataScope">
<el-select v-model="form.dataScope" style="width: 140px" placeholder="请选择数据范围" @change="changeScope">
<el-option
v-for="item in dateScopes"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item v-if="form.dataScope === '自定义'" label="数据权限" prop="depts">
<treeselect
v-model="deptDatas"
:load-options="loadDepts"
:options="depts"
multiple
style="width: 380px"
placeholder="请选择"
/>
</el-form-item>
<el-form-item label="描述信息" prop="description">
<el-input v-model="form.description" style="width: 380px;" rows="5" type="textarea" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU"></el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU"></el-button>
</div>
</el-dialog>
<el-row :gutter="15">
<!--角色管理-->
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="17" style="margin-bottom: 10px">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span class="role-span">角色列表</span>
</div>
<el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" :data="crud.data" :header-cell-style="{'text-align':'left'}" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="dataScope" label="数据权限" />
<el-table-column prop="level" label="角色级别" />
<el-table-column :show-overflow-tooltip="true" prop="description" label="描述" />
<el-table-column :show-overflow-tooltip="true" width="135px" prop="createTime" label="创建日期" />
<el-table-column v-if="checkPer(['admin','roles:edit','roles:del'])" label="操作" width="130px" align="center" fixed="right">
<template slot-scope="scope">
<udOperation
v-if="scope.row.level >= level"
:data="scope.row"
:permission="permission"
/>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</el-card>
</el-col>
<!-- 菜单授权 -->
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="7">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top">
<span class="role-span">菜单分配</span>
</el-tooltip>
<el-button
v-permission="['admin','roles:edit']"
:disabled="!showButton"
:loading="menuLoading"
icon="el-icon-check"
size="mini"
style="float: right; padding: 6px 9px"
type="primary"
@click="saveMenu"
>保存</el-button>
</div>
<el-tree
ref="menu"
lazy
:data="menus"
:default-checked-keys="menuIds"
:load="getMenuDatas"
:props="defaultProps"
check-strictly
accordion
show-checkbox
node-key="id"
@check="menuChange"
/>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import crudRoles from '@/api/system/role'
import { getDepts, getDeptSuperior } from '@/api/system/dept'
import { getMenusTree, getChild } from '@/api/system/menu'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import DateRangePicker from '@/components/DateRangePicker'
const defaultForm = { id: null, name: null, depts: [], description: null, dataScope: '全部', level: 3 }
export default {
name: 'Role',
components: { Treeselect, pagination, crudOperation, rrOperation, udOperation, DateRangePicker },
cruds() {
return CRUD({ title: '角色', url: 'api-management/api/roles', sort: 'level,asc', crudMethod: { ...crudRoles }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' },
dateScopes: ['全部', '本级', '自定义'], level: 3,
currentId: 0, menuLoading: false, showButton: false,
menus: [], menuIds: [], depts: [], deptDatas: [], // 使
permission: {
add: ['admin', 'roles:add'],
edit: ['admin', 'roles:edit'],
del: ['admin', 'roles:del']
},
rules: {
name: [
{ required: true, message: '请输入名称', trigger: 'blur' }
],
permission: [
{ required: true, message: '请输入权限', trigger: 'blur' }
]
}
}
},
created() {
crudRoles.getLevel().then(data => {
this.level = data.level
})
},
methods: {
getMenuDatas(node, resolve) {
setTimeout(() => {
getMenusTree(node.data.id ? node.data.id : 0).then(res => {
resolve(res)
})
}, 100)
},
[CRUD.HOOK.afterRefresh]() {
this.$refs.menu.setCheckedKeys([])
},
//
[CRUD.HOOK.beforeToAdd](crud, form) {
this.deptDatas = []
form.menus = null
},
//
[CRUD.HOOK.beforeToEdit](crud, form) {
this.deptDatas = []
if (form.dataScope === '自定义') {
this.getSupDepts(form.depts)
}
const _this = this
form.depts.forEach(function(dept) {
_this.deptDatas.push(dept.id)
})
//
form.menus = null
},
//
[CRUD.HOOK.afterValidateCU](crud) {
if (crud.form.dataScope === '自定义' && this.deptDatas.length === 0) {
this.$message({
message: '自定义数据权限不能为空',
type: 'warning'
})
return false
} else if (crud.form.dataScope === '自定义') {
const depts = []
this.deptDatas.forEach(function(data) {
const dept = { id: data }
depts.push(dept)
})
crud.form.depts = depts
} else {
crud.form.depts = []
}
return true
},
//
handleCurrentChange(val) {
if (val) {
const _this = this
//
this.$refs.menu.setCheckedKeys([])
// id
this.currentId = val.id
// key
this.menuIds = []
val.menus.forEach(function(data) {
_this.menuIds.push(data.id)
})
this.showButton = true
}
},
menuChange(menu) {
// id
getChild(menu.id).then(childIds => {
// menuIds
if (this.menuIds.indexOf(menu.id) !== -1) {
for (let i = 0; i < childIds.length; i++) {
const index = this.menuIds.indexOf(childIds[i])
if (index !== -1) {
this.menuIds.splice(index, 1)
}
}
} else {
for (let i = 0; i < childIds.length; i++) {
const index = this.menuIds.indexOf(childIds[i])
if (index === -1) {
this.menuIds.push(childIds[i])
}
}
}
this.$refs.menu.setCheckedKeys(this.menuIds)
})
},
//
saveMenu() {
this.menuLoading = true
const role = { id: this.currentId, menus: [] }
// key
this.menuIds.forEach(function(id) {
const menu = { id: id }
role.menus.push(menu)
})
crudRoles.editMenu(role).then(() => {
this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.menuLoading = false
this.update()
}).catch(err => {
this.menuLoading = false
console.log(err.response.data.message)
})
},
//
update() {
//
crudRoles.get(this.currentId).then(res => {
for (let i = 0; i < this.crud.data.length; i++) {
if (res.id === this.crud.data[i].id) {
this.crud.data[i] = res
break
}
}
})
},
//
getDepts() {
getDepts({ enabled: true }).then(res => {
this.depts = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
})
},
getSupDepts(depts) {
const ids = []
depts.forEach(dept => {
ids.push(dept.id)
})
getDeptSuperior(ids).then(res => {
const date = res.content
this.buildDepts(date)
this.depts = date
})
},
buildDepts(depts) {
depts.forEach(data => {
if (data.children) {
this.buildDepts(data.children)
}
if (data.hasChildren && !data.children) {
data.children = null
}
})
},
//
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
getDepts({ enabled: true, pid: parentNode.id }).then(res => {
parentNode.children = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 200)
})
}
},
//
changeScope() {
if (this.form.dataScope === '自定义') {
this.getDepts()
}
},
checkboxT(row) {
return row.level >= this.level
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.role-span {
font-weight: bold;color: #303133;
font-size: 15px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__multi-value{
margin-bottom: 0;
}
::v-deep .vue-treeselect__multi-value-item{
border: 0;
padding: 0;
}
</style>
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.blurry" size="small" clearable placeholder="输入名称或者描述搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<crudOperation :permission="permission" />
</div>
<!-- 表单渲染 -->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="520px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" style="width: 380px;" />
</el-form-item>
<el-form-item label="角色级别" prop="level">
<el-input-number v-model.number="form.level" :min="1" controls-position="right" style="width: 145px;" />
</el-form-item>
<el-form-item label="数据范围" prop="dataScope">
<el-select v-model="form.dataScope" style="width: 140px" placeholder="请选择数据范围" @change="changeScope">
<el-option
v-for="item in dateScopes"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item v-if="form.dataScope === '自定义'" label="数据权限" prop="depts">
<treeselect
v-model="deptDatas"
:load-options="loadDepts"
:options="depts"
multiple
style="width: 380px"
placeholder="请选择"
/>
</el-form-item>
<el-form-item label="描述信息" prop="description">
<el-input v-model="form.description" style="width: 380px;" rows="5" type="textarea" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU"></el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU"></el-button>
</div>
</el-dialog>
<el-row :gutter="15">
<!--角色管理-->
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="17" style="margin-bottom: 10px">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span class="role-span">角色列表</span>
</div>
<el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" :data="crud.data" :header-cell-style="{'text-align':'left'}" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="dataScope" label="数据权限" />
<el-table-column prop="level" label="角色级别" />
<el-table-column :show-overflow-tooltip="true" prop="description" label="描述" />
<el-table-column :show-overflow-tooltip="true" width="135px" prop="createTime" label="创建日期" />
<el-table-column v-if="checkPer(['admin','roles:edit','roles:del'])" label="操作" width="140px" align="center" fixed="right">
<template slot-scope="scope">
<udOperation
v-if="scope.row.level >= level"
:data="scope.row"
:permission="permission"
/>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</el-card>
</el-col>
<!-- 菜单授权 -->
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="7">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top">
<span class="role-span">菜单分配</span>
</el-tooltip>
<el-button
v-permission="['admin','roles:edit']"
:disabled="!showButton"
:loading="menuLoading"
icon="el-icon-check"
size="mini"
style="float: right; padding: 6px 9px"
type="primary"
@click="saveMenu"
>保存</el-button>
</div>
<el-tree
ref="menu"
lazy
:data="menus"
:default-checked-keys="menuIds"
:load="getMenuDatas"
:props="defaultProps"
check-strictly
accordion
show-checkbox
node-key="id"
@check="menuChange"
/>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import crudRoles from '@/api/system/role'
import { getDepts, getDeptSuperior } from '@/api/system/dept'
import { getMenusTree, getChild } from '@/api/system/menu'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import DateRangePicker from '@/components/DateRangePicker'
const defaultForm = { id: null, name: null, depts: [], description: null, dataScope: '全部', level: 3 }
export default {
name: 'Role',
components: { Treeselect, pagination, crudOperation, rrOperation, udOperation, DateRangePicker },
cruds() {
return CRUD({ title: '角色', url: 'api-management/api/roles', sort: 'level,asc', crudMethod: { ...crudRoles }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' },
dateScopes: ['全部', '本级', '自定义'], level: 3,
currentId: 0, menuLoading: false, showButton: false,
menus: [], menuIds: [], depts: [], deptDatas: [], // 使
permission: {
add: ['admin', 'roles:add'],
edit: ['admin', 'roles:edit'],
del: ['admin', 'roles:del']
},
rules: {
name: [
{ required: true, message: '请输入名称', trigger: 'blur' }
],
permission: [
{ required: true, message: '请输入权限', trigger: 'blur' }
]
}
}
},
created() {
crudRoles.getLevel().then(data => {
this.level = data.level
})
},
methods: {
getMenuDatas(node, resolve) {
setTimeout(() => {
getMenusTree(node.data.id ? node.data.id : 0).then(res => {
resolve(res)
})
}, 100)
},
[CRUD.HOOK.afterRefresh]() {
this.$refs.menu.setCheckedKeys([])
},
//
[CRUD.HOOK.beforeToAdd](crud, form) {
this.deptDatas = []
form.menus = null
},
//
[CRUD.HOOK.beforeToEdit](crud, form) {
this.deptDatas = []
if (form.dataScope === '自定义') {
this.getSupDepts(form.depts)
}
const _this = this
form.depts.forEach(function(dept) {
_this.deptDatas.push(dept.id)
})
//
form.menus = null
},
//
[CRUD.HOOK.afterValidateCU](crud) {
if (crud.form.dataScope === '自定义' && this.deptDatas.length === 0) {
this.$message({
message: '自定义数据权限不能为空',
type: 'warning'
})
return false
} else if (crud.form.dataScope === '自定义') {
const depts = []
this.deptDatas.forEach(function(data) {
const dept = { id: data }
depts.push(dept)
})
crud.form.depts = depts
} else {
crud.form.depts = []
}
return true
},
//
handleCurrentChange(val) {
if (val) {
const _this = this
//
this.$refs.menu.setCheckedKeys([])
// id
this.currentId = val.id
// key
this.menuIds = []
val.menus.forEach(function(data) {
_this.menuIds.push(data.id)
})
this.showButton = true
}
},
menuChange(menu) {
// id
getChild(menu.id).then(childIds => {
// menuIds
if (this.menuIds.indexOf(menu.id) !== -1) {
for (let i = 0; i < childIds.length; i++) {
const index = this.menuIds.indexOf(childIds[i])
if (index !== -1) {
this.menuIds.splice(index, 1)
}
}
} else {
for (let i = 0; i < childIds.length; i++) {
const index = this.menuIds.indexOf(childIds[i])
if (index === -1) {
this.menuIds.push(childIds[i])
}
}
}
this.$refs.menu.setCheckedKeys(this.menuIds)
})
},
//
saveMenu() {
this.menuLoading = true
const role = { id: this.currentId, menus: [] }
// key
this.menuIds.forEach(function(id) {
const menu = { id: id }
role.menus.push(menu)
})
crudRoles.editMenu(role).then(() => {
this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.menuLoading = false
this.update()
}).catch(err => {
this.menuLoading = false
console.log(err.response.data.message)
})
},
//
update() {
//
crudRoles.get(this.currentId).then(res => {
for (let i = 0; i < this.crud.data.length; i++) {
if (res.id === this.crud.data[i].id) {
this.crud.data[i] = res
break
}
}
})
},
//
getDepts() {
getDepts({ enabled: true }).then(res => {
this.depts = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
})
},
getSupDepts(depts) {
const ids = []
depts.forEach(dept => {
ids.push(dept.id)
})
getDeptSuperior(ids).then(res => {
const date = res.content
this.buildDepts(date)
this.depts = date
})
},
buildDepts(depts) {
depts.forEach(data => {
if (data.children) {
this.buildDepts(data.children)
}
if (data.hasChildren && !data.children) {
data.children = null
}
})
},
//
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
getDepts({ enabled: true, pid: parentNode.id }).then(res => {
parentNode.children = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 200)
})
}
},
//
changeScope() {
if (this.form.dataScope === '自定义') {
this.getDepts()
}
},
checkboxT(row) {
return row.level >= this.level
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.role-span {
font-weight: bold;color: #303133;
font-size: 15px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__multi-value{
margin-bottom: 0;
}
::v-deep .vue-treeselect__multi-value-item{
border: 0;
padding: 0;
}
</style>

File diff suppressed because it is too large Load Diff

@ -173,7 +173,7 @@
<el-table-column
v-permission="['admin','user:edit','user:del']"
label="操作"
width="160"
width="140"
fixed="right"
>
<template slot-scope="scope">
@ -246,7 +246,7 @@
/>
<el-table-column
label="操作"
width="100"
width="75"
>
<template slot-scope="scope">
<!-- <el-button
@ -278,7 +278,7 @@
</el-table-column>
<el-table-column
label="操作"
width="140"
width="100"
>
<template slot-scope="scope">
<el-button

@ -91,7 +91,7 @@
<el-table-column
v-permission="['admin']"
label="操作"
width="175"
width="100"
fixed="right"
>
<!-- <template slot-scope="scope">
@ -359,7 +359,7 @@
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="90">
<el-table-column label="操作" width="75">
<template slot-scope="scope">
<el-button @click="dohankClick({ type: 'dyAuthorization', row: scope.row, action: 'url' })">授权</el-button>
</template>

@ -151,7 +151,7 @@
</el-table-column>
<el-table-column
label="操作"
width="200"
width="160"
>
<template slot-scope="scope">
<el-button

@ -164,7 +164,7 @@
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<el-table-column label="操作" width="160">
<template slot-scope="scope">
<el-button
size="mini"
@ -173,7 +173,7 @@
icon="el-icon-phone"
@click="dialTel(scope.row)"
>拨打</el-button>
<el-button size="mini" type="text" @click.stop="rowClick(scope.row)">通话记录</el-button>
<el-button size="mini" type="text" @click.stop="rowClick(scope.row)">详情</el-button>
<el-button
v-if="callMode !== 1"
size="mini"

@ -47,7 +47,7 @@
</el-table-column>
<el-table-column
label="操作"
width="100"
width="75"
fixed="right"
>
<template slot-scope="scope">

@ -197,7 +197,7 @@
</el-table-column>
<el-table-column
label="操作"
width="140"
width="100"
fixed="right"
>
<template slot-scope="scope">

@ -196,7 +196,7 @@
</el-table-column>
<el-table-column
label="操作"
width="140"
width="100"
fixed="right"
>
<template slot-scope="scope">

Loading…
Cancel
Save