批量开通课程

This commit is contained in:
liuyuan
2025-04-02 09:52:19 +08:00
parent aea244c5f8
commit b0d0c65352
7 changed files with 601 additions and 129 deletions

View File

@@ -46,6 +46,7 @@ const mainRoutes = {
{ path: '/buyorder-print', component: _import('modules/order/buyorder-print'), name: 'buyorder-print', meta: { title: '打印面单', isTab: true } },
{ path: '/activity-list', component: _import('modules/activity/activityList'), name: 'activity-list', meta: { title: '活动列表', isTab: true } },
{ path: '/user-point-memery', component: _import('modules/user/user-point-memery'), name: 'user-point-memery', meta: { title: '充/扣记录', isTab: true } },
{ path: '/user-add-course', component: _import('modules/user/user-add-course'), name: 'user-add-course', meta: { title: '开通课程', isTab: true } },
{ path: '/order-epay', component: _import('modules/order/order-errorpay'), name: 'order-epay', meta: { title: '充值异常列表', isTab: true } },
{ path: '/xieyi_list', component: _import('modules/xieyi/xieyi'), name: 'xieyi_list', meta: { title: '协议管理', isTab: true } },
{ path: '/book-comments', component: _import('modules/book/bookComments'), name: 'book-comments', meta: { title: '书评管理', isTab: true } },

View File

@@ -0,0 +1,330 @@
<template>
<div class="add-course" v-loading="dataListLoading">
<div class="add-course-left">
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()"
label-width="120px">
<el-form-item label="课程名称" prop="course">
<el-input v-model="dataForm.course" placeholder="请输入课程名称" clearable @input="handleSearch"></el-input>
<div class="data-list" v-if="showList">
<span v-for="(v,i) in dataList" :key="i" @click="checkTitle(v)">{{ v.title }}</span>
</div>
</el-form-item>
<el-form-item label="课程分部" v-if="cataloguesList.length>0" prop="catalogues">
<el-checkbox-group v-model="dataForm.catalogues">
<el-checkbox v-for="(v,i) in cataloguesList" :key="i" :label="v.id">
{{ v.title }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="开课时长" class="day_block" prop="days">
<el-input v-model="dataForm.days"></el-input>&nbsp&nbsp天
</el-form-item>
<el-form-item label="文件上传" prop="file">
<el-upload class="upload-demo"
:action="baseUrl + '/oss/fileoss'"
:on-preview="handlePreview"
:on-remove="handleRemoveNovel"
:before-remove="beforeRemove"
:on-success="handleNovelSuccess"
multiple
:limit="1"
:on-exceed="handleExceed"
:file-list="fileList" accept=".xlsx">
<el-button size="small" type="primary">选择文件</el-button>
</el-upload>
</el-form-item>
<el-form-item label="解析结果" class="remark_block" v-if="resultStatus">
解析成功{{resultData.has.length}}
<span style=" color: #f56c6c;">解析失败{{resultData.no.length}}</span>
<span style=" color: #17B3A3; text-decoration: underline; cursor: pointer; padding-left: 20px;" v-if="resultData.no.length>0" @click="showFail">查看</span>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="dataFormSubmit()">提交</el-button>
</div>
<div class="resultCon" v-if="resultStatus2">
上传成功{{ resultData2.successList.length }}
<span style=" color: #f56c6c;">上传失败{{failList.length}}</span>
<span style=" color: #17B3A3; text-decoration: underline; cursor: pointer; padding-left: 20px;" v-if="failList.length>0" @click="showFail2">查看</span>
</div>
</div>
<div class="add-course-right">
<div class="result_fail" v-if="showFailStatus" :style="!showFailStatus2?'width: 100%':''">
<p>解析失败数据</p>
<el-table :data="resultData.no" border>
<el-table-column prop="name" header-align="center" align="center" label="姓名">
</el-table-column>
<el-table-column prop="phone" header-align="center" align="center" label="手机号">
</el-table-column>
</el-table>
</div>
<div class="result_fail" v-if="showFailStatus2" :style="!showFailStatus?'width: 100%':''">
<p>上传失败数据</p>
<el-table :data="failList" border>
<el-table-column prop="name" header-align="center" align="center" label="姓名">
</el-table-column>
<el-table-column prop="tel" header-align="center" align="center" label="手机号">
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import global from '../../common/common.vue' //引入共用组间
export default {
data() {
return {
baseUrl: global.baseUrl,
dataForm: {
id: 0,
course: '',
file: '',
days: '',
catalogues: [],
},
dataRule: {
course: [{
required: true,
message: '课程名称不能为空',
trigger: 'blur'
}],
catalogues: [{
required: true,
message: '课程分部不能为空',
trigger: 'blur'
}],
days: [{
required: true,
message: '开课时长不能为空',
trigger: 'blur'
}],
file: [{
required: true,
message: '文件不能为空',
trigger: 'blur'
}]
},
showList: false, //显示模糊数据
dataList: [],
fileList: [],
resultStatus: false,
dataListLoading: false,
resultData: {}, //文件解析结果数据
showFailStatus: false,
showFailStatus2: false,
cataloguesList: [], //分部数据
resultData2: {}, //上传结果数据
failList: [], //失败数据
}
},
methods: {
//模糊查询
handleSearch(val){
if(val){
this.$http({
url: this.$http.adornUrl("/master/course/searchCourse"),
method: "post",
data: this.$http.adornData({
keywords: val
})
}).then(({ data }) => {
if (data && data.code === 0) {
if(data.List&&data.List.length>0){
this.dataList = data.List;
this.showList = true;
}else{
this.dataList = [];
this.showList = false;
}
}
});
}
},
//选中模糊值
checkTitle(v){
this.dataForm.course = v.title;
this.showList = false;
this.getCourseCatalogues(v.id);
},
//获取课程分部数据
getCourseCatalogues(id){
this.$http({
url: this.$http.adornUrl("/master/course/getCourseCatalogues"),
method: "post",
data: this.$http.adornData({
id: id
})
}).then(({ data }) => {
if (data && data.code === 0) {
if(data.catalogues&&data.catalogues.length>0){
this.cataloguesList = data.catalogues;
}
}
});
},
//上传文件
handlePreview(file) {
console.log(file);
},
//上传成功
handleNovelSuccess(file) {
this.dataForm.file = file.url;
this.readExcel(this.dataForm.file);
},
//限制提示
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件`);
},
//删除提醒
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${ file.name }`);
},
//删除文件
handleRemoveNovel(){
this.dataForm.file = '';
this.resultStatus = false;
this.showFailStatus = false;
this.resultData = {};
this.resultStatus2 = false;
this.showFailStatus2 = false;
this.failList = [];
},
//访问接口,解析结果
readExcel(){
this.dataListLoading = true;
this.$http({
url: this.$http.adornUrl("/master/userCourseBuy/readExcelForAddCourse"),
method: "post",
data: this.$http.adornData({
file: this.dataForm.file
})
}).then(({ data }) => {
if (data && data.code === 0) {
if(data.result&&data.result.has.length>0){
this.resultStatus = true;
this.resultData = data.result;
this.dataListLoading = false;
}
}else{
this.$message.error('文件解析有误');
this.dataListLoading = false;
}
});
},
//点击查看
showFail(){
this.showFailStatus = true;
},
//点击查看
showFail2(){
this.showFailStatus2 = true;
},
//表单提交
dataFormSubmit() {
if(this.dataForm.file==''){
this.$message.error('请先上传文件');
return
}
this.$refs["dataForm"].validate(valid => {
if (valid) {
this.dataListLoading = true;
this.$http({
url: this.$http.adornUrl("/master/userCourseBuy/AddCourses"),
method: "post",
data: this.$http.adornData({
catalogue_id: this.dataForm.catalogues.join(','),
days: Number(this.dataForm.days),
list: this.resultData.has
})
}).then(({ data }) => {
if (data && data.code === 0) {
if(data.result&&data.result.failList.length>0){
this.resultStatus2 = true;
this.resultData2 = data.result;
this.dataListLoading = false;
this.failList = data.result.failList;
this.$message.success("已成功开通!");
}
}else{
this.$message.error('文件上传有误');
this.dataListLoading = false;
}
});
}
})
}
}
}
</script>
<style lang="less" scoped>
.add-course{
margin-top: 30px;
display: flex;
.add-course-left{
width: 50%;
.data-list{
width: 100%;
border: 1px solid #dcdfe6;
border-top: none;
border-radius: 4px;
background: #fff;
position: absolute;
z-index: 99;
top: 40px;
left: 0;
padding: 0 10px;
cursor: pointer;
max-height: 280px;
overflow-y: scroll;
span{
color: #606266;
line-height: 40px;
font-size: 12px;
display: block;
border-bottom: 1px solid rgb(224, 224, 224);
}
span:last-child{
border-bottom: none;
}
}
}
.add-course-right{
width: 40%;
margin-left: 5%;
display: flex;
justify-content: space-between;
.result_fail{
width: 49%;
/deep/.el-table{
max-height: 720px;
overflow-y: scroll;
}
}
}
.dialog-footer{
text-align: center;
}
}
.day_block{
/deep/.el-input{
width: 200px;
}
}
.resultCon{
text-align: center;
margin-top: 30px;
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<el-dialog :title="!dataForm.id ? '新增' : '修改'" :close-on-click-modal="false" :visible.sync="visible"
<el-dialog :title="!dataForm.id ? '新增用户' : '修改用户'" :close-on-click-modal="false" :visible.sync="visible"
@close="handlereset">
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()"
label-width="120px">

View File

@@ -0,0 +1,192 @@
<template>
<el-dialog title="开通VIP" :close-on-click-modal="false" :visible.sync="visible"
@close="handlereset">
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()"
label-width="120px">
<el-form-item label="用户">
{{dataForm.tel }}<span v-if="dataForm.name&&dataForm.name != ''">({{ dataForm.name }})</span>
</el-form-item>
<el-form-item label="账户余额">
天医币&nbsp<em style="font-style: normal; font-size: 16px; color: #17B3A3;" >{{ dataForm.peanutCoin }}</em>
&nbsp &nbsp积分&nbsp<em style="font-style: normal; font-size: 16px; color: #17B3A3;" >{{ dataForm.peanutCoin }}</em>
</el-form-item>
<el-form-item label="VIP类型" prop="type" class="type_block">
<el-radio-group v-model="dataForm.type" size="mini">
<el-radio
v-for="(option,index) in typeList"
:key="index"
:label="option.value"
>
{{ option.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="VIP年限" prop="year" class="year_block">
<el-radio-group v-model="dataForm.year" size="mini">
<el-radio
v-for="(option,index) in yearList"
:key="index"
:label="option.value"
>
{{ option.label }}
</el-radio>
</el-radio-group>
<span class="qita">其他<el-input v-model="dataForm.day"></el-input>&nbsp&nbsp天</span>
</el-form-item>
<el-form-item label="预计费用" class="price_block">
<span style=" color: #f56c6c;">{{ dataForm.price }}</span>
</el-form-item>
<el-form-item label="抵扣方式" class="coin_block" v-if="peanutCoin==0">
</el-form-item>
<el-form-item label="付费说明">
<el-input
type="textarea"
rows="5"
v-model="dataForm.remark"
placeholder="付费说明"
>
</el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="handlereset">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</span>
</el-dialog>
</template>
<script>
import global from '../../common/common.vue' //引入共用组间
export default {
data() {
return {
baseUrl: global.baseUrl,
visible: false,
dataForm: {
id: 0,
name: '',
tel: '',
email: '',
peanutCoin: '',
type: '', //vip类型
year: '',
day: '',
remark: '',
price: '0',
},
peanutCoin: 0, //天医币和积分总和判断是否为0
dataRule: {
type: [{
required: true,
message: '类型不能为空',
trigger: 'blur'
}],
year: [{
required: true,
message: '年限不能为空',
trigger: 'blur'
}]
},
typeList: [
{ value: '1', label: '医学超v' },
{ value: '4', label: '中医学' },
{ value: '9', label: '中西汇通学' },
{ value: '5', label: '针灸学' },
{ value: '6', label: '肿瘤学' },
{ value: '2', label: '国学与心理学超v' },
{ value: '7', label: '国学' },
{ value: '8', label: '心理学' },
],
yearList: [
{value: '1', label: '1年'},
{value: '3', label: '3年'},
{value: '4', label: '4年'}
]
}
},
methods: {
init(data) {
this.visible = true;
this.dataForm.name = data.name;
this.dataForm.tel = data.tel;
this.dataForm.email = data.email;
this.dataForm.peanutCoin = data.peanutCoin;
},
//表单提交
dataFormSubmit() {
},
//取消
handlereset() {
this.visible = false
},
}
}
</script>
<style lang="less" scoped>
.year_block{
/deep/.el-form-item__content{
display: flex;
align-items: center;
}
/deep/.el-radio{
margin-left: 0;
margin-right: 0;
}
/deep/.el-radio__label{
padding-left: 3px;
padding-right: 30px;
}
.qita{
display: flex;
align-items: center;
font-size: 12px;
/deep/.el-input{
width: 60px;
.el-input__inner{
height: 30px;
line-height: 30px;
}
}
}
}
.price_block{
/deep/.el-form-item__content{
display: flex;
align-items: center;
}
/deep/.el-checkbox-group{
margin-left: 30px;
}
/deep/.el-checkbox{
padding-top: 5px;
margin-left: 20px;
margin-right: 10px;
}
/deep/.el-input{
width: 130px;
}
}
.type_block{
/deep/.el-radio{
margin-left: 0;
margin-right: 0;
}
/deep/.el-radio__label{
padding-left: 3px;
padding-right: 25px;
}
}
</style>

View File

@@ -18,10 +18,6 @@
<el-option label="肿瘤VIP" value=6></el-option>
<el-option label="国学VIP" value=7></el-option>
<el-option label="心理学VIP" value=8></el-option>
</el-select>
</el-form-item>
<el-form-item>
@@ -36,10 +32,13 @@
v-if="isAuth('book:user:save')"
type="primary"
@click="addOrUpdateHandle()"
>新增</el-button
>新增用户</el-button
>
<el-button type="primary" @click="addOrUpdateHandle()"
<!-- <el-button type="primary" @click="addOrUpdateHandle()"
>合并账号</el-button
> -->
<el-button type="primary" @click="addOpenCourse()"
>批量开通课程</el-button
>
<!-- <el-button v-if="isAuth('book:user:delete')" type="danger" @click="deleteHandle()"
:disabled="dataListSelections.length <= 0">批量删除</el-button> -->
@@ -141,24 +140,6 @@
label="邮箱"
>
</el-table-column>
<!-- <el-table-column
prop="password"
header-align="center"
align="center"
label="密码">
</el-table-column> -->
<!-- <el-table-column prop="vip" header-align="center" align="center" label="会员类型">
<template slot-scope="scope">
<span v-if="scope.row.vip == '1'">VIP</span>
<span v-if="scope.row.vip == '0'">普通会员</span>
</template>
</el-table-column> -->
<!-- <el-table-column
prop="vipValidtime"
header-align="center"
align="center"
label="vip 有效期">
</el-table-column> -->
<el-table-column
prop="peanutCoin"
header-align="center"
@@ -166,53 +147,6 @@
label="天医币"
>
</el-table-column>
<!-- <el-table-column
prop="peanutCoin"
header-align="center"
align="center"
label="VIP 办理"
>
<template slot-scope="scope">
<el-popover
placement="right"
width="300"
trigger="click"
@show="getVipMoney(scope.row)"
>
<el-table :data="vipList">
<el-table-column
width="150"
property="title"
label="VIP名称"
></el-table-column>
<el-table-column
width="100"
property="lastFee"
label="开通金额"
></el-table-column>
</el-table>
<el-button slot="reference" size="small">办理金额</el-button>
</el-popover>
</template>
</el-table-column> -->
<!-- <el-table-column
prop="readTime"
header-align="center"
align="center"
label="阅读时间">
</el-table-column> -->
<!-- <el-table-column prop="lastLoginTime" header-align="center" align="center" label="最后登录时间">
</el-table-column>
<el-table-column prop="createTime" header-align="center" align="center" label="创建时间">
</el-table-column> -->
<!-- <el-table-column prop="updateTime" header-align="center" align="center" label="更新时间">
</el-table-column> -->
<!-- <el-table-column
prop="delFlag"
header-align="center"
align="center"
label="删除标记">
</el-table-column> -->
<el-table-column
fixed="right"
header-align="center"
@@ -290,7 +224,11 @@
</el-button>
</router-link>
</el-dropdown-item>
<!-- <el-dropdown-item divided>蚵仔煎</el-dropdown-item> -->
<!-- <el-dropdown-item>
<el-button type="text" size="small" @click="openVip(scope.row)">
开通VIP
</el-button>
</el-dropdown-item> -->
</el-dropdown-menu>
</el-dropdown>
</template>
@@ -312,6 +250,10 @@
ref="addOrUpdate"
@refreshDataList="getDataList"
></add-or-update>
<!-- 开通VIP -->
<open-vip v-if="openVipVisible" ref="openVip">
</open-vip>
<el-dialog
title="充/扣天医币"
:close-on-click-modal="false"
@@ -388,6 +330,7 @@
<script>
import userCouponList from "../coupon/userCouponList";
import OpenVip from "./user-open-vip"
import AddOrUpdate from "./user-add-or-update";
export default {
data() {
@@ -434,17 +377,32 @@ export default {
youVisible: false,
youForm: {},
courperList: [],
courperHistList: []
courperHistList: [],
//开通vip
openVipVisible: false,
};
},
components: {
AddOrUpdate,
userCouponList
userCouponList,
OpenVip
},
activated() {
this.getDataList();
},
methods: {
//批量开通课程
addOpenCourse(){
this.$router.push('/user-add-course');
},
//开通vip
openVip(row){
this.openVipVisible = true;
this.$nextTick(()=>{
this.$refs.openVip.init(row);
})
},
computedVipType(userVips) {
if (!userVips || userVips.length === 0) return '';
@@ -492,26 +450,15 @@ export default {
});
return tags.join(' ');
}
,
},
getVipMoney(data) {
console.log("data at line 420:", data.id);
this.$http({
// url: this.$http.adornUrl('/book/user/list'),
url: this.$http.adornUrl("/master/userVip/getVipProductForUser"),
method: "post",
data: this.$http.adornData({
uid: data.id
})
// params: this.$http.adornParams({
// 'page': 1,
// 'limit': this.pageSize,
// 'key': this.dataForm.key
// })
}).then(({ data }) => {
if (data && data.code === 0) {
var list=[]

View File

@@ -7,6 +7,7 @@
// api接口请求地址
window.SITE_CONFIG['baseUrl'] = 'https://api.nuttyreading.com';
//window.SITE_CONFIG['baseUrl'] = 'http://192.168.110.100:9200/pb';
//window.SITE_CONFIG['baseUrl'] = 'http://192.168.110.110:9200/pb';
// cdn地址 = 域名 + 版本号
window.SITE_CONFIG['domain'] = './'; // 域名

View File

@@ -6,7 +6,8 @@
// api接口请求地址
window.SITE_CONFIG['baseUrl'] = 'https://api.nuttyreading.com'; // 线上正式环境
//window.SITE_CONFIG['baseUrl'] = 'http://192.168.110.100:9200/pb'; //本地
//window.SITE_CONFIG['baseUrl'] = 'http://192.168.110.100:9200/pb'; //
//window.SITE_CONFIG['baseUrl'] = 'http://192.168.110.110:9200/pb'; //本地
// cdn地址 = 域名 + 版本号
window.SITE_CONFIG['domain'] = './'; // 域名