master
yujialong 6 hours ago
parent 313a1210d9
commit 794e386705
  1. 4
      apis/modules/course.js
  2. 399
      course/addCourse/addCourse.vue
  3. 280
      course/clients/clients.vue
  4. 89
      course/courseDetail/courseDetail.vue
  5. 273
      course/curClient/curClient.vue
  6. 504
      course/editCourse/editCourse.vue
  7. 1201
      course/orderDetail/orderDetail.vue
  8. 285
      course/ordered/ordered.vue
  9. 106
      course/practiceDetail/practiceDetail.vue
  10. 399
      course/products/products.vue
  11. 317
      course/shopCart/shopCart.vue
  12. 34
      libs/util.js
  13. 13
      package-lock.json
  14. 1
      package.json
  15. 43
      pages.json
  16. 2
      pages/achievement/achievement.vue
  17. 2
      pages/index/index.vue
  18. BIN
      static/image/index/1.png
  19. BIN
      static/image/index/2.png
  20. BIN
      static/image/index/3.png
  21. BIN
      static/image/index/4.png
  22. BIN
      static/image/index/5.png
  23. BIN
      static/image/index/6.png
  24. BIN
      static/image/index/7.png
  25. BIN
      static/image/index/8.png
  26. BIN
      static/image/index/9.png
  27. BIN
      static/image/index/banner.png
  28. BIN
      static/image/index/banner1.png
  29. BIN
      static/image/info-bg.jpg
  30. BIN
      static/image/info.png
  31. BIN
      static/image/logo.png
  32. BIN
      static/image/logo1.png
  33. BIN
      static/image/person26.png
  34. BIN
      static/image/person27.png
  35. BIN
      static/image/person5.png
  36. BIN
      static/image/person6.png
  37. BIN
      static/image/person7.png
  38. BIN
      static/image/person8.png
  39. BIN
      static/image/person9.png
  40. BIN
      static/image/phone.png
  41. BIN
      static/image/product.png
  42. BIN
      static/image/product/1.png
  43. BIN
      static/image/product/2.png
  44. BIN
      static/image/product/3.png
  45. BIN
      static/image/product/4.png
  46. BIN
      static/image/product/5.png
  47. BIN
      static/image/product/6.png
  48. BIN
      static/image/product/excel.png
  49. BIN
      static/image/product/pdf.png
  50. BIN
      static/image/product/ppt.png
  51. BIN
      static/image/product/shop-blue.png
  52. BIN
      static/image/product/shop.png
  53. BIN
      static/image/product/word.png
  54. BIN
      static/image/qrcode.png
  55. BIN
      static/image/school.png
  56. BIN
      static/image/study-bg.jpg
  57. BIN
      static/image/tab3-1.png
  58. BIN
      static/image/tab3.png
  59. BIN
      static/image/trash.png
  60. BIN
      static/image/unfold.png
  61. BIN
      static/image/wechat.png
  62. BIN
      static/image/workbench/index1.png
  63. BIN
      static/image/workbench/index10.png
  64. BIN
      static/image/workbench/index11.png
  65. BIN
      static/image/workbench/index12.png
  66. BIN
      static/image/workbench/index2.png
  67. BIN
      static/image/workbench/index3.png
  68. BIN
      static/image/workbench/index4.png
  69. BIN
      static/image/workbench/index5.png
  70. BIN
      static/image/workbench/index6.png
  71. BIN
      static/image/workbench/index7.png
  72. BIN
      static/image/workbench/index8.png
  73. BIN
      static/image/workbench/index9.png
  74. 61
      user/account/account.vue
  75. 51
      user/addStaff/addStaff.vue
  76. 222
      user/article/article.vue
  77. 46
      user/info/info.vue
  78. 281
      user/plans/plans.vue
  79. 168
      user/qrcode/qrcode.vue
  80. 116
      user/scheme/scheme.vue
  81. 92
      user/setting/setting.vue
  82. 289
      user/study/study.vue

@ -1,6 +1,10 @@
import request from '@/apis/request.js' import request from '@/apis/request.js'
const { get, post } = request const { get, post } = request
export const getPlayAuth = id => {
return get('nakadai/nakadai/oss/getPlayAuth/' + id)
}
export const getSchoolCourseAuthority = () => { export const getSchoolCourseAuthority = () => {
return get('nakadai/nakadai/curriculum/getSchoolCourseAuthority') return get('nakadai/nakadai/curriculum/getSchoolCourseAuthority')
} }

@ -1,399 +0,0 @@
<template>
<view class="page">
<uni-card :is-shadow="false" :border="false" padding="0" is-full>
<uni-search-bar class="search" radius="5" placeholder="请输入产品名称" clearButton="auto" cancelButton="none" v-model="keyword" />
</uni-card>
<ul class="tab-wrap">
<view class="tab">
<li :class="{active: curTab === ''}" @click="tabChange('')">全部</li>
</view>
<scroll-view scroll-x :scroll-left="scrollLeft" class="tab tab-scroll">
<li v-for="(tab, i) in tabs" :key="i" :class="{active: curTab === tab.id}" @click="tabChange(tab.id)">{{ tab.name }}</li>
</scroll-view>
</ul>
<ul class="list">
<li v-for="(item, i) in list" :key="i">
<uni-data-checkbox v-if="item.check" class="check" multiple :value="[1]" :localdata="item.checkData" @change="e => checkChange(e, i)"></uni-data-checkbox>
<uni-data-checkbox v-else class="check" multiple v-model="item.check" :localdata="item.checkData" @change="e => checkChange(e, i)"></uni-data-checkbox>
<image class="icon" :src="$util.getIcon(item)"></image>
{{ item.productName }}
</li>
</ul>
<uni-load-more :status="status" />
<view class="btn-wrap">
<uni-data-checkbox class="check" multiple v-model="checkAll" :localdata="checkAllData" @change="allChange"></uni-data-checkbox>
<view class="btn" @click="submit">确定({{ checked.length }})</view>
</view>
</view>
</template>
<script>
import { productTypeList, listOfGoods } from '@/apis/modules/product.js'
import { renew, queryCitySettlementPrice } from '@/apis/modules/order.js'
export default {
data() {
return {
// authority: 01234
orderType: 1,
customerId: '',
provinceId: '',
cityId: '',
curTab: '',
tabs: [],
scrollLeft: 0,
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
orderStatus: '',
productStatus: '',
keyword: '',
list: [],
listAll: [],
page: 1,
pageSize: 10,
check: [1],
noCheck: [],
checkData: [{
text: '',
value: 1
}],
checkAll: [],
checkAllData: [{
text: '全部',
value: 1
}],
checked: uni.getStorageSync('courses') || [], //
courses: uni.getStorageSync('courses') || [],
submiting: false,
}
},
watch: {
keyword () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initList()
}, 500)
}
},
//
onPullDownRefresh() {
this.initList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
//
onReachBottom() {
if (this.reachBottom >= 0) {
this.reachBottom = 1
this.status = 'loading'
this.getList()
}
},
onShow() {
const pages = getCurrentPages()
const { options } = pages[pages.length - 1]
this.orderType = options.orderType
this.customerId = options.customerId
this.provinceId = options.provinceId
this.cityId = options.cityId
this.getTypes()
this.getList()
},
methods: {
//
getTypes() {
productTypeList().then(res => {
res.typeList.forEach(e => {
e.id = e.typeId
e.name = e.typeName
})
this.tabs.push(...res.typeList)
}).catch(e => {})
},
//
getList() {
uni.showLoading({
title: '加载中'
})
listOfGoods({
pageNum: this.page,
pageSize: this.pageSize,
sort: 0,
isShelves: 0,
hotTag: 1,
productName: this.keyword,
productType: this.curTab,
}).then(({ page }) => {
const { records } = page
const list = this.courses
const all = this.checkAll.length //
const pageChange = this.reachBottom > 0 //
const { checked } = this //
//
records.map(e => {
const checkData = {
text: '',
value: 1
}
e.check = (all && pageChange) || checked.find(n => n.mallId === e.mallId) ? 1 : 0
//
if (list.find(n => n.mallId == e.mallId)) {
//
checkData.disable = true
e.check = 1
}
e.checkData = [checkData]
})
// list
this.list = pageChange ? [...this.list, ...records] : records
this.page++ // page+1
const noMore = this.list.length === page.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
uni.hideLoading()
}).catch(e => {
uni.hideLoading()
})
},
initList() {
this.page = 1
this.reachBottom = 0
this.getList()
},
// tab
tabChange(id) {
this.curTab = id
this.initList()
},
//
checkChange(e, i) {
const { checked } = this
const item = this.list[i]
const { mallId } = item
const include = checked.findIndex(e => e.mallId === mallId)
// pushpush
if (e.detail.value.length) {
include === -1 && checked.push(item)
} else {
//
if (include !== -1) {
checked.splice(include, 1)
this.checkAll = []
}
}
},
//
allChange(e) {
const isCheck = !!e.detail.value.length //
const { checked, list } = this
list.map(e => {
e.check = isCheck ? 1 : 0
const { mallId } = e
const include = checked.findIndex(n => n.mallId === mallId)
// pushpush
if (isCheck) {
include === -1 && checked.push(e)
} else {
//
include === -1 || checked.splice(include, 1)
}
})
},
//
createParam(e, authority) {
const { orderType } = this
const trial = orderType == 2 //
return {
dataOrCourseId: e.associatedProduct, // id
mallId: e.mallId,
productName: e.productName, //
periodOfUse: trial ? 1 : '', // 使
startTime: this.$util.formatDate(new Date(), 'yyyy-MM-dd'), //
endTime: '', //
remainingPeriod: '', //
marketValue: '', //
marketPrice: e.marketUnitPrice, //
finalPrice: trial ? 0 : '', //
finalValue: trial ? 0 : '', //
discountRate: trial ? '0%' : '', //
accountNum: authority ? 1 : '', //
totalAmount: '', //
isEnable: 0, // 10
ship: 0, // 01
authority, // 01
options: trial ? 1 : 2,
miniProgramPictureAddress: e.appletIcon || '', //
settlementPrice: trial ? 0 : '', //
settlementPriceUnit: e.settlementPrice || 0, //
serviceFee: 0, //
mallNonAssociatedLinks: e.mallNonAssociatedLinks, //
typeId: e.typeId,
typeName: e.typeName,
classificationId: e.classificationId,
}
},
//
handleRenew(authority, customerId, productId, result, resolve, reject) {
renew({
authority,
customerId,
productId
}).then(({ orderOthers }) => {
result.map(e => {
const item = orderOthers.find(n => n.dataOrCourseId == e.dataOrCourseId && n.authority == authority && e.authority == authority)
if (item) {
let date = new Date(item.endTime)
date = new Date(date.setDate(date.getDate() + 1))
e.startTime = this.$util.formatDate(date, 'yyyy-MM-dd')
}
})
resolve()
}).catch(e => {
reject()
})
},
//
submit() {
const list = this.checked //
if (list.length) {
if (this.submiting) return false
this.submiting = true
uni.showLoading({
title: '加载中'
})
const result = this.courses
const list1 = [] //
const list0 = [] //
const list2 = [] //
const list3 = [] //
const list4 = [] //
const { customerId } = this
const listPromise = []
list.forEach(async e => {
listPromise.push(new Promise(async (resolve, reject) => {
// id
if (!result.find(n => (n.dataOrCourseId == e.associatedProduct || n.dataOrCourseId == e.dataOrCourseId) && n.authority == e.authority)) {
//
if (this.provinceId) {
const res = await queryCitySettlementPrice(e.mallId, this.provinceId, this.cityId)
if (res.mallPrice) e.settlementPrice = res.mallPrice.discountRate
}
const classId = e.classificationId
const pid = +e.associatedProduct
const { mallId } = e
if (classId == 1 || classId == 2) {
list1.push(mallId)
} else if (classId == 3) {
list2.push(mallId)
} else if (classId == 4) {
list3.push(mallId)
} else if (classId == 5) {
list0.push(mallId)
} else if (classId == 6) {
list4.push(mallId)
}
result.push(this.createParam(e, this.$util.getOrderType(classId)))
resolve()
} else {
resolve()
}
}))
})
Promise.all(listPromise).then(_ => {
const promises = []
// 5authorityrenew
list0.length && promises.push(new Promise((resolve, reject) => {
this.handleRenew(0, customerId, list0, result, resolve, reject)
}))
list1.length && promises.push(new Promise((resolve, reject) => {
this.handleRenew(1, customerId, list1, result, resolve, reject)
}))
list2.length && promises.push(new Promise((resolve, reject) => {
this.handleRenew(2, customerId, list2, result, resolve, reject)
}))
list3.length && promises.push(new Promise((resolve, reject) => {
this.handleRenew(3, customerId, list3, result, resolve, reject)
}))
list4.length && promises.push(new Promise((resolve, reject) => {
this.handleRenew(4, customerId, list4, result, resolve, reject)
}))
Promise.all(promises).then(_ => {
console.log(33, result)
uni.setStorageSync('courses', result) //
uni.redirectTo({
url: `../editCourse/editCourse?customerId=${customerId}&orderType=${this.orderType}`
})
})
})
} else {
this.$util.errMsg('请选择产品!')
}
}
}
}
</script>
<style scoped lang="scss">
.page {
padding-bottom: 130rpx;
}
.tab-wrap {
display: flex;
.tab-scroll {
width: calc(100% - 100rpx);
white-space: nowrap;
li {
display: inline-block;
}
}
}
.list {
li {
display: flex;
align-items: center;
padding: 30rpx 24rpx;
margin: 16rpx 24rpx;
font-size: 30rpx;
color: #333;
background-color: #fff;
border-radius: 16rpx;
}
.icon {
width: 80rpx;
min-width: 80rpx;
height: 80rpx;
margin: 0 20rpx;
border-radius: 4px;
}
}
/deep/.check {
.checklist-box {
margin: 0 !important;
}
.checkbox__inner {
width: 40rpx !important;
height: 40rpx !important;
border-radius: 50% !important;
}
.checkbox__inner-icon {
top: 8rpx !important;
left: 14rpx !important;
}
}
.btn-wrap {
position: fixed;
justify-content: space-between;
.btn {
width: 340rpx;
margin-left: 27rpx;
}
}
</style>

@ -1,280 +0,0 @@
<template>
<view>
<view :class="['page', {'not-auth': !per}]">
<view class="filter">
<uni-search-bar class="search" radius="30" placeholder="请输入客户名称" v-model="keyword" clearButton="auto" cancelButton="none" />
<uni-icons class="icon" custom-prefix="iconfont" type="icon-filter" size="22" color="#007eff" @click="popup = true"></uni-icons>
</view>
<ul class="tab">
<li v-for="(tab, i) in tabs" :class="{active: curTab === tab.id}" @click="tabChange(tab)">{{ tab.name }}</li>
</ul>
<template v-if="list.length">
<ul class="list">
<li v-for="item in list" @click="toDetail(item)">
<view class="c-name">{{ item.customerName }}</view>
<view class="info">
<view class="left">
<view class="line">
<text class="name">联系人</text>
<text class="val">{{ item.orderContact }}</text>
</view>
<view class="line">
<text class="name">账号</text>
<text class="val">{{ item.account }}</text>
</view>
<view class="line">
<text class="name">产品到期时间</text>
<text class="val">{{ item.expireDate.split(' ')[0] }}</text>
</view>
<view class="line">
<text class="name">商务经理</text>
<text class="val">{{ item.businessManagerName }}</text>
</view>
</view>
<view class="type">
{{ filterData[0].data.find(e => e.value === item.customerType).title }}客户
</view>
</view>
</li>
</ul>
<uni-load-more :status="status" />
</template>
<empty v-else text="您当前暂无有下单的客户,请快去给客户下订单吧"></empty>
<uni-icons class="plus" type="plus-filled" size="60" color="#007eff" @click="$util.to('../clientDetail/clientDetail')"></uni-icons>
<filter-popup :data="filterData" :form.sync="filterForm" v-model="popup" title="全部筛选" height="1104rpx" @finsh="subFinsh"></filter-popup>
</view>
<notAuth v-if="!per"></notAuth>
</view>
</template>
<script>
import { list, all } from '@/apis/modules/client.js'
export default {
data() {
return {
per: true, //
popup: false,
//
filterData: [
{
children: false,//
title: "客户类型",
key: "customerType", //
keyValue: "value", //
isRadio: true, //
data: [
{
title: '正式',
value: 1
},
{
title: '试用',
value: 2
},
{
title: '到期',
value: 3
}
],
}
],
filterForm: {
customerType: []
},
curTab: 0,
tabs: [],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
customerType: '',
keyword: '',
list: [],
page: 1,
pageSize: 10
}
},
watch: {
keyword () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initList()
}, 500)
}
},
//
onPullDownRefresh() {
this.initList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
//
onReachBottom() {
if (this.reachBottom >= 0) {
this.reachBottom = 1
this.status = 'loading'
this.getList()
}
},
onShow() {
this.per = true
this.initRole()
},
methods: {
//
initRole() {
this.tabs = []
const auth = uni.getStorageSync('auth')
auth.includes('工作台:客户:我的客户') && this.tabs.push({
name: '我的客户',
id: 0
})
auth.includes('工作台:客户:团队全部客户') && this.tabs.push({
name: '团队全部客户',
id: 1
})
const len = this.tabs.length
if (len) {
// tab
if (len === 1) {
this.curTab = this.tabs[0].id
this.tabs = []
}
this.initList()
} else {
this.list = [
{
orderContact: '智信云',
account: '智信云师资培训班',
businessManagerName: 'python实训系统',
expireDate: '2023-08-08'
},
{
orderContact: '智信云智信云',
account: '智信云师资培训班智信云师资培训班',
businessManagerName: 'python实训系统',
expireDate: '2023-08-08'
},
{
orderContact: '智信云智信云',
account: '智信云师资培训班智信云师资培训班',
businessManagerName: 'python实训系统实训系统',
expireDate: '2023-08-08'
},
{
orderContact: '智信云智信云',
account: '智信云师资培训班智信云师资培训班',
businessManagerName: 'python实训系统',
expireDate: '2023-08-08'
},
]
this.per = false //
}
},
//
getList() {
const data = {
businessManagerId: this.$util.getBmId(),
teamId: uni.getStorageSync('team').id,
customerType: this.customerType,
keywords: this.keyword,
pageNum: this.page,
pageSize: this.pageSize,
type: this.curTab // 团队:1 / 个人:0
}
uni.showLoading({
title: '加载中'
})
all(data).then(({ data }) => {
uni.hideLoading()
// list
this.list = this.reachBottom > 0 ? [...this.list, ...data.records] : data.records
this.page++ // page+1
const noMore = this.list.length === data.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
}).catch(e => {
uni.hideLoading()
})
},
initList() {
this.page = 1
this.reachBottom = 0
this.getList()
},
//
subFinsh(val) {
const { customerType } = val
this.customerType = customerType.length ? customerType[0] : ''
this.initList()
},
// tab
tabChange(tab) {
this.curTab = tab.id
this.initList()
},
//
toDetail(item) {
this.$util.to(`../clientDetail/clientDetail?customerId=${item.customerId}&show=1`)
}
}
}
</script>
<style scoped lang="scss">
.page {
padding-bottom: 90px;
}
.filter {
display: flex;
align-items: center;
.search {
flex: 1;
}
.sl-filter {
width: 30%;
margin-left: 10%;
}
}
.list {
margin-top: 20rpx;
background-color: #fff;
li {
padding: 20rpx 40rpx;
border-bottom: 1px solid #f1f1f1;
}
.c-name {
font-size: 30rpx;
color: #333;
}
.info {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10rpx;
}
.line {
display: flex;
padding: 10rpx 0;
}
.name {
width: 200rpx;
margin-right: 10rpx;
font-size: 28rpx;
color: #999;
}
.val {
max-width: 70%;
font-size: 28rpx;
color: #333;
}
.type {
font-size: 28rpx;
color: #ff7b2d;
white-space: nowrap;
}
}
</style>

@ -1,7 +1,11 @@
<template> <template>
<view class="wrap"> <view class="wrap">
<view class="banner-wrap bg-wh"> <view class="file-wrap">
<image class="pic" :src="form.mall.coverDrawing" mode="widthFix"></image> <image v-if="curRow.isPic" class="pic" :src="curRow.fileUrl" mode="widthFix"></image>
<video v-else-if="curRow.isVideo" class="video" :key="curRow.fileUrl" width="100%" height="100%" autoplay controls :src="curRow.fileUrl" type="video/mp4">
<!-- <source :src="curRow.fileUrl" type="video/mp4">
您的终端不支持 video 标签 -->
</video>
</view> </view>
<view class="detail"> <view class="detail">
@ -25,8 +29,7 @@
<uni-icons class="arrow" type="bottom" color="#909090"></uni-icons> <uni-icons class="arrow" type="bottom" color="#909090"></uni-icons>
</view> </view>
<view class="section" v-if="item.subsectionList.length"> <view class="section" v-if="item.subsectionList.length">
<view class="sectionName" :class="{ active: curLink === `${item.name}${section.name}` }" <view v-for="(section, j) in item.subsectionList" :key="j"class="sectionName" :class="{ active: curLink === `${item.name}${section.name}` }" @click="secClick(section, item)">
v-for="(section, i) in item.subsectionList" :key="i" @click="preview(section, item.name)">
<image v-if="section.fileType === 'pptx'" class="ext" src="https://izhixinyun.com/images/exts/ppt.png" alt=""> <image v-if="section.fileType === 'pptx'" class="ext" src="https://izhixinyun.com/images/exts/ppt.png" alt="">
<image v-else-if="section.fileType === 'mp4'" class="ext" src="https://izhixinyun.com/images/exts/video.png" alt=""> <image v-else-if="section.fileType === 'mp4'" class="ext" src="https://izhixinyun.com/images/exts/video.png" alt="">
<image v-else-if="section.fileType === 'doc' || section.fileType === 'docx'" class="ext" <image v-else-if="section.fileType === 'doc' || section.fileType === 'docx'" class="ext"
@ -58,7 +61,7 @@
<view class="c-name">{{ item.experimentalName }}</view> <view class="c-name">{{ item.experimentalName }}</view>
<view class="line">得分{{ item.score }}&emsp;&emsp;耗时{{ item.timeSum }}min</view> <view class="line">得分{{ item.score }}&emsp;&emsp;耗时{{ item.timeSum }}min</view>
<view class="line">考核开始时间{{ item.startTime }}</view> <view class="line">考核开始时间{{ item.startTime }}</view>
<view class="line">考核结束时间{{ item.lastTime }}</view> <view class="line">考核结束时间{{ item.submitTime }}</view>
<view class="btn">成绩报告</view> <view class="btn">成绩报告</view>
</view> </view>
</view> </view>
@ -67,7 +70,9 @@
</template> </template>
<script> <script>
import { queryChaptersAndSubsections, curriculumDetail, queryPracticeByStudent, queryAssessmentByStudent } from '@/apis/modules/course.js' import { queryChaptersAndSubsections, curriculumDetail, queryPracticeByStudent, queryAssessmentByStudent, getPlayAuth } from '@/apis/modules/course.js'
// import Aliplayer from 'aliyun-aliplayer';
// import 'aliyun-aliplayer/build/skins/default/aliplayer-min.css';
export default { export default {
data() { data() {
return { return {
@ -119,7 +124,11 @@
mpStyle: { mpStyle: {
p: 'font-size: 25rpx !important;font-family: Microsoft Yahei !important;font-weight: 400 !important;color: #333 !important;', p: 'font-size: 25rpx !important;font-family: Microsoft Yahei !important;font-weight: 400 !important;color: #333 !important;',
span: 'font-size: 25rpx !important;font-family: Microsoft Yahei !important;font-weight: 400 !important;color: #333 !important;' span: 'font-size: 25rpx !important;font-family: Microsoft Yahei !important;font-weight: 400 !important;color: #333 !important;'
} },
playAuth: '',
player: null,
curRow: {},
} }
}, },
watch: { watch: {
@ -230,18 +239,68 @@
toPrac(row) { toPrac(row) {
this.$util.to(`../practiceDetail/practiceDetail?cid=${this.cid}&projectId=${row.projectId || ''}&paperId=${row.paperId || ''}`) this.$util.to(`../practiceDetail/practiceDetail?cid=${this.cid}&projectId=${row.projectId || ''}&paperId=${row.paperId || ''}`)
}, },
//
transferType (ext) {
const suf = ext.toLowerCase()
if ('jpg,jpeg,png,gif,svg,psd'.includes(suf)) return '图片'
if ('mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv'.includes(suf)) return '视频'
return suf
},
// //pdf
handleFileType(row) {
if (this.$util.exts.video.includes(row.fileType)) {
// this.$set(row, 'isVideo', true)
row.isVideo = true
} else if (this.$util.exts.img.includes(row.fileType)) {
row.isPic = true
}
this.curRow = row
},
//
secClick(row) {
this.handleFileType(row)
// debugger
if (this.curRow.isVideo) {
//
if (row.fileId) {
getPlayAuth(row.fileId).then(res => {
this.playAuth = res.playAuth;
//
if (this.player) {
this.player.dispose()
this.player = null
}
this.$nextTick(() => {
if (this.player) {
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth);
} else {
this.player = new Aliplayer({
id: "player",
width: "100%",
autoplay: false,
vid: row.fileId,
playauth: this.playAuth,
encryptType: 1 //
});
}
});
}).catch(res => { });
}
}
},
} }
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.wrap { .file-wrap {
padding-bottom: 140rpx; .pic, .video {
}
.banner-wrap {
width: 100%;
.pic {
width: 100%; width: 100%;
height: 400rpx;
}
.pic {
object-fit: cover;
} }
} }
.tabs { .tabs {
@ -293,14 +352,14 @@
.sectionName { .sectionName {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 20rpx 0; margin: 30rpx 0;
font-size: 26rpx; font-size: 26rpx;
color: #333; color: #333;
} }
.ext { .ext {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
margin-right: 10rpx; margin-right: 20rpx;
} }
} }
.list { .list {

@ -1,273 +0,0 @@
<template>
<view>
<view class="filter">
<uni-search-bar class="search" radius="30" placeholder="请输入订单号、内容" v-model="keyword" clearButton="auto" cancelButton="none" />
<uni-icons class="icon" custom-prefix="iconfont" type="icon-filter" size="22" color="#007eff" @click="popup = true"></uni-icons>
</view>
<template v-if="list.length">
<view class="list">
<uni-swipe-action>
<uni-swipe-action-item
v-for="item in list"
:threshold="0"
:right-options="delOption"
@click="del(item)"
>
<view class="item" @click="toDetail(item)">
<view class="c-name">{{ item.orderNumber }}</view>
<view class="info">
<view class="left">
<view v-if="curTab" class="line">
<text class="name">商务经理</text>
<text class="val">{{ item.businessManagerName }}</text>
</view>
<view class="line">
<text class="name">客户名称</text>
<text class="val">{{ item.customerName }}</text>
</view>
<view class="line">
<text class="name">订单金额</text>
<text class="val">{{ item.orderAmount }}</text>
</view>
<view class="line">
<text class="name">订单内容</text>
<view class="val ell-wrap">
<view :class="{ell: !item.toggle}">{{ item.productName }}</view>
<view v-if="item.productName.length > 14" class="toggle" @click.stop="toggle(item)">{{ item.toggle ? '收起' : '展开' }}</view>
</view>
</view>
<view class="line">
<text class="name">下单日期</text>
<text class="val">{{ item.createTime }}</text>
</view>
</view>
<view :class="['type', 'type' + item.orderStatus]">
{{ filterData[0].data.find(e => e.value === item.orderStatus).title }}
</view>
</view>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
<uni-load-more :status="status" />
</template>
<empty v-else></empty>
<uni-icons class="plus" type="plus-filled" size="60" color="#007eff" @click="$util.to(`../orderDetail/orderDetail?customerId=${customerId}`)"></uni-icons>
<filter-popup :data="filterData" :form.sync="filterForm" v-model="popup" title="全部筛选" height="1104rpx" @finsh="subFinsh"></filter-popup>
</view>
</template>
<script>
import { miniProgramOrderRecord, del } from '@/apis/modules/order.js'
export default {
data() {
return {
customerId: '',
customerName: '',
popup: false,
//
filterData: [
{
children: false,//
title: "订单状态",
key: "orderStatus", //
keyValue: "value", //
isRadio: true, //
data: [
{
title: "待发货",
value: 0
},
{
title: "已完成",
value: 1
},
],
}
],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
filterForm: {},
searchTimer: null,
orderStatus: '',
keyword: '',
list: [],
page: 1,
pageSize: 10,
delOption: [{
text: '删除',
style: {
backgroundColor: '#F56C6C'
}
}]
}
},
watch: {
keyword () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initList()
}, 500)
}
},
//
onReachBottom() {
if (this.reachBottom >= 0) {
this.reachBottom = 1
this.status = 'loading'
this.getList()
}
},
//
onPullDownRefresh() {
this.getList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
onShow() {
const pages = getCurrentPages()
const { options } = pages[pages.length - 1]
this.customerId = options.customerId
this.customerName = options.name
//
try {
uni.removeStorageSync('orderForm')
uni.removeStorageSync('courses')
} catch (e) {}
this.initList()
},
methods: {
getList() {
uni.showLoading({
title: '加载中'
})
const team = uni.getStorageSync('team')
const { orderStatus } = this
miniProgramOrderRecord({
businessManagerId: this.$util.getBmId(),
teamId: team.id,
customerId: +this.customerId,
orderStatus: orderStatus === '' ? null : orderStatus,
isAdmin: +team.isTeam, // (0 1)
pageNum: this.page,
pageSize: this.pageSize,
keywords: this.keyword
}).then(({ data }) => {
const { records } = data
records.map(e => {
e.toggle = e.productName.length < 14 // 14
})
this.list = this.reachBottom > 0 ? [...this.list, ...records] : records
this.page++ // page+1
const noMore = this.list.length === data.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
uni.hideLoading()
}).catch(e => {
uni.hideLoading()
})
},
initList() {
this.page = 1
this.reachBottom = 0
this.getList()
},
//
toggle(item) {
item.toggle = !item.toggle
},
//
subFinsh(val) {
const { orderStatus } = val
this.orderStatus = orderStatus.length ? orderStatus[0] : ''
this.initList()
},
//
toDetail(item) {
this.$util.to(`../orderDetail/orderDetail?orderId=${item.orderId}&show=1`)
},
//
del(e) {
const that = this
uni.showModal({
title: '提示',
content: '确定要删除吗?',
success(res) {
if (res.confirm) {
del({
ids: [e.orderId]
}).then(res => {
that.$util.sucMsg('删除成功')
that.getList()
}).catch(res => {})
}
}
})
},
}
}
</script>
<style scoped lang="scss">
.list {
margin-top: 20rpx;
background-color: #fff;
.item {
width: 100%;
padding: 20rpx 40rpx;
border-bottom: 1px solid #f1f1f1;
box-sizing: border-box;
}
.c-name {
font-size: 30rpx;
color: #333;
}
.info {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10rpx;
}
.left {
max-width: 70%;
}
.line {
display: flex;
padding: 10rpx 0;
}
.name {
margin-right: 10rpx;
white-space: nowrap;
font-size: 28rpx;
color: #999;
}
.val {
max-width: 88%;
font-size: 28rpx;
color: #333;
}
.ell {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.toggle {
margin-top: 10rpx;
white-space: nowrap;
font-size: 24rpx;
color: #0e92ef;
}
.type {
margin-left: 20rpx;
font-size: 28rpx;
color: #ff7b2d;
white-space: nowrap;
}
.type1 {
color: #bdbdbd;
}
}
</style>

@ -1,504 +0,0 @@
<template>
<view class="page">
<template v-for="c in courses">
<view v-if="c.list.length && c.list.filter(e => !e.edited).length" class="block">
<view class="type-wrap">
<view class="l-title">{{ c.name }}</view>
<view class="batch">
<input class="deadline" type="number" v-model="c.deadline" placeholder="批量输入" @change="batchDeadlineChange(c)">
<view :class="['unit', {placeholder: c.unit === ''}]" @click="batchUnitChange(c)">{{ c.unit !== '' ? units.find(e => e.id === c.unit).text : '请选择' }}</view>
</view>
<uni-icons class="arrow" type="top" size="20" color="#007EFF" @click="toggle(c)"></uni-icons>
</view>
<view v-show="!c.shrink">
<template v-for="(item, i) in c.list">
<view v-if="!item.edited" :key="i">
<view class="pro-name">
<view class="left">
<image class="icon" :src="$util.getIcon(item)" mode="widthFix"></image>
{{ item.productName }}
</view>
<uni-icons class="del" type="trash" size="25" color="#ADADAD" @click="delCourse(c, i)"></uni-icons>
</view>
<view class="form-list">
<view class="line">
<view class="name">产品类型</view>
<view class="val">{{ item.typeName }}</view>
</view>
<view :class="['line req', {err: err === 'periodOfUse' + item.dataOrCourseId + item.authority}]">
<view class="name">使用期限</view>
<input class="period" type="number" v-model="item.periodOfUse" placeholder="请输入" @input="dateChange(item, !item.authority)" @change="handleErr(item, 'periodOfUse')">
<view class="val unit" @click="selectUnit(item)">
<text>{{ units.find(e => e.id === item.options).text }}</text>
<image class="icon" src="@/static/image/arrow-down.png" mode="widthFix"></image>
</view>
</view>
<view :class="['line req', {err: err === 'startTime' + item.dataOrCourseId + item.authority}]">
<view class="name">起止日期</view>
<uni-datetime-picker type="date" v-model="item.startTime" :border="false" @change="dateChange(item)">
<view :class="['ph', {val: item.startTime}]">
{{ item.endTime ? item.startTime + ' - ' + item.endTime : item.startTime}}
</view>
</uni-datetime-picker>
</view>
<view :class="['line req', {err: err === 'accountNum' + item.dataOrCourseId + item.authority}]">
<view class="name">数量</view>
<view v-if="item.authority" class="val">1</view>
<input v-else type="number" v-model="item.accountNum" placeholder="请输入账号数量" @input="calcFinalPrice(item)" @change="handleErr(item, 'accountNum')">
</view>
<view class="line">
<view class="name">{{ item.authority ? '市场价' : '市场单价' }}</view>
<view class="val">{{ item.marketValue }}</view>
</view>
<view class="line">
<view class="name">结算价</view>
<view class="val">{{ item.settlementPrice && item.settlementPrice + '元' }}</view>
</view>
<view class="line">
<view class="name">折扣率</view>
<view class="val">{{ item.discountRate }}</view>
</view>
<view class="line">
<view class="name">市场服务费</view>
<view class="val">{{ item.serviceFee }}</view>
</view>
<view :class="['line req', {err: err === 'finalPrice' + item.dataOrCourseId + item.authority}]">
<view class="name">成交价</view>
<view class="inline">
<input type="number" v-model="item.finalPrice" placeholder="请输入" @input="calcFinalValue(item)" @change="handleErr(item, 'finalPrice')">
</view>
</view>
</view>
</view>
</template>
</view>
</view>
</template>
<view class="btn-wrap">
<view class="btn" @click="submit">确定</view>
</view>
</view>
</template>
<script>
import { getOrderOtherTime, queryCitySettlementPrice, renew } from '@/apis/modules/order.js'
import { getPartnerTeamRates } from '@/apis/modules/parner.js'
import { productTypeList } from '@/apis/modules/product.js'
export default {
data() {
return {
orderType: 1,
customerId: '',
action: '',
provinceId: '',
cityId: '',
timer: null,
units: [{
text: '日',
id: 0
}, {
text: '月',
id: 1
}, {
text: '年',
id: 2
}],
unitText: ['日', '月', '年'],
courses: {} , //
orderRepeat: [],
repeatMsg: '',
err: '',
rate: '',
submiting: false,
}
},
onShow() {
const pages = getCurrentPages()
const { options } = pages[pages.length - 1]
this.orderType = options.orderType
this.customerId = options.customerId
this.action = options.action
this.provinceId = options.provinceId
this.cityId = options.cityId
this.handleProduct()
this.getRate()
},
methods: {
//
async handleProduct() {
const list = uni.getStorageSync('courses')
let courses = {}
//
productTypeList().then(res => {
res.typeList.forEach(e => {
courses['list' + e.typeId] = {
shrink: false,
name: e.typeName,
deadline: '',
unit: '',
list: []
}
})
const { provinceId, cityId } = this
const isTrial = this.orderType == 2
list.map(async e => {
//
if (provinceId) {
const res = await queryCitySettlementPrice(e.mallId, provinceId, cityId)
if (res.mallPrice) e.settlementPriceUnit = res.mallPrice.discountRate || 0
}
//
const res = await renew({
authority: e.authority,
customerId: this.customerId,
productId: [e.mallId]
})
const item = res.orderOthers
if (item && item.length) {
let date = new Date(item[0].endTime)
date = new Date(date.setDate(date.getDate() + 1))
e.startTime = this.$util.formatDate(date, 'yyyy-MM-dd')
}
// 1
if (isTrial) {
this.calcDate(e, !e.authority)
}
courses['list' + e.typeId].list.push(e)
})
this.courses = courses
}).catch(e => {})
},
//
batchDeadlineChange (c) {
c.list.map(e => {
e.periodOfUse = c.deadline
this.calcDate(e, !e.authority)
})
},
//
batchUnitChange(c) {
const that = this
uni.showActionSheet({
title: '标题',
itemList: that.unitText,
success: ({ tapIndex }) => {
if (tapIndex !== '') {
c.unit = tapIndex
c.list.map(e => {
e.options = tapIndex
that.calcDate(e, !e.authority)
})
}
}
})
},
//
selectUnit(item) {
const that = this
uni.showActionSheet({
title: '标题',
itemList: that.unitText,
success: ({ tapIndex }) => {
if (tapIndex !== '') {
item.options = tapIndex
that.calcDate(item)
}
}
})
},
showUnit(i) {
this.$refs.unit[i].show()
},
//
toggle(c) {
c.shrink = !c.shrink
},
//
delCourse(c, i) {
uni.showModal({
title: '提示',
content: '确定要删除吗?',
success(res) {
res.confirm && c.list.splice(i, 1)
}
})
},
// 使
dateChange(row, fromData) {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.calcDate(row, fromData)
}, 500)
},
// 使
calcDate(row, fromData) {
const { periodOfUse, options } = row
let optionsData = 0
if (periodOfUse) {
if (options == 1){
optionsData = periodOfUse === '12' ? 31536000000 : periodOfUse*30*24*60*60*1000
} else if (options == 2){
optionsData = periodOfUse*365*24*60*60*1000
} else {
optionsData = periodOfUse*24*60*60*1000
}
}
let time = new Date(row.startTime).getTime()
let endTime = time + optionsData
let dt = new Date(endTime)
row.endTime = (dt.getFullYear()) + "-" + (dt.getMonth() + 1) + "-" + (dt.getDate())
let endYear = endTime - time
let endYears = endYear/1000/60/60/24
row.remainingPeriod = endYears
const unit = row.options // 使
const useUnit = row.periodOfUse // 使
//
const price = row.marketPrice //
// //365,/12)
row.marketValue = (!unit ?
price / 365 * useUnit :
unit === 1 ?
price / 12 * useUnit :
price * useUnit).toFixed(2)
this.dealSettlePrice(row)
// +1
if (!fromData) {
const cId = row.dataOrCourseId
const date = new Date(row.startTime)
const orderRepeat = this.orderRepeat
getOrderOtherTime({
authority: row.authority,
customerId: this.customerId,
id: cId,
startTime: this.$util.formatDate(date, 'yyyy-MM-dd'),
endTime: row.endTime
}).then(res => {
orderRepeat.includes(cId) && orderRepeat.splice(orderRepeat.findIndex(e => e == cId), 1)
if (res.endTime) {
let time = new Date(res.endTime)
time = new Date(time.setDate(time.getDate() + 1))
row.startTime = this.$util.formatDate(time, 'yyyy-MM-dd')
}
}).catch(res => {
this.repeatMsg = res.message
orderRepeat.includes(cId) || orderRepeat.push(cId)
})
}
//
this.calcDiscount(row)
},
//
dealSettlePrice(row) {
// 0
if (this.orderType != 1) {
row.settlementPrice = 0
row.serviceFee = 0
} else {
const unit = row.options // 使
const useUnit = row.periodOfUse // 使
let sPrice = ''
// **/**(1)
const priceUnit = row.settlementPriceUnit
sPrice = ((!unit ?
priceUnit / 365 * useUnit :
unit === 1 ?
priceUnit / 12 * useUnit :
priceUnit * useUnit) * (row.authority ?
1 :
row.accountNum)).toFixed((2))
row.settlementPrice = this.$util.handleNaN(sPrice)
//
if (row.settlementPrice) {
row.serviceFee = (row.finalPrice * (this.rate / 100)).toFixed(2)
}
}
},
//
getRate() {
getPartnerTeamRates({
teamId: uni.getStorageSync('team').teamId
}).then(({ teamRates }) => {
this.rate = teamRates.annualMarketingFee || 0
}).catch(res => {})
},
//
calcDiscount(row) {
const price = row.authority ? row.finalPrice : row.finalValue
const { marketValue } = row
// (-)÷ x100%
if (price) row.discountRate = marketValue != 0 ? ((marketValue - price) / marketValue * 100).toFixed(2) + '%' : '0%'
},
// ////
calcFinalValue(row) {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
const { authority, periodOfUse, options, accountNum, finalPrice } = row
if (!authority && periodOfUse && accountNum && finalPrice) {
row.finalValue = (finalPrice / accountNum / periodOfUse).toFixed(2)
}
//
this.calcDiscount(row)
//
this.dealSettlePrice(row)
}, 500)
},
// **//
calcFinalPrice(row) {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
const { finalValue, accountNum, periodOfUse, finalPrice } = row
if (periodOfUse) {
if (accountNum) {
// =**
if (finalValue) {
row.finalPrice = Math.round(finalValue * periodOfUse * accountNum)
} else if (!finalValue && finalPrice) {
// =//
row.finalValue = (finalPrice / periodOfUse / accountNum).toFixed(2)
this.calcDiscount(row)
}
} else if (finalValue && finalPrice && !row.authority) {
// =//
row.accountNum = Math.floor(finalPrice / periodOfUse / finalValue)
}
}
this.dealSettlePrice(row)
}, 500)
},
//
handleErr(e, val) {
if (val + e.dataOrCourseId + e.authority === this.err) this.err = ''
},
//
submit() {
if (this.submiting) return false
const { courses } = this
const list = []
let msg = ''
// push便
for (const i in courses) {
list.push(...courses[i].list)
}
//
for (const i in list) {
const e = list[i]
const suf = e.dataOrCourseId + '' + e.authority
if (e.periodOfUse === '') {
this.err = 'periodOfUse' + suf
msg = '请输入使用期限!'
break
}
if (e.options === '') {
this.err = 'accountNum' + suf
msg = '请选择期限!'
break
}
if (!e.startTime) {
this.err = 'startTime' + suf
msg = '请选择起止日期!'
break
}
if (e.accountNum === '') {
this.err = 'accountNum' + suf
msg = '请输入数量!'
break
}
if (e.finalPrice === '') {
this.err = 'finalPrice' + suf
msg = '请输入成交价!'
break
}
}
if (msg) return this.$util.errMsg(msg)
if (this.orderRepeat.length) return this.$util.errMsg(this.repeatMsg) //
this.submiting = true
uni.showLoading({
title: '加载中'
})
list.forEach(e => {
e.edited = 1 //
})
uni.setStorageSync('courses', this.courses)
uni.redirectTo({
url: `../orderDetail/orderDetail?edited=1`
})
},
}
}
</script>
<style scoped lang="scss">
.page {
padding-bottom: 130rpx;
-webkit-overflow-scrolling: touch;
}
.block {
position: relative;
padding: 0;
.l-title {
margin: 0 24rpx;
}
.type-wrap {
display: flex;
justify-content: space-between;
align-items: center;
}
.batch {
display: inline-flex;
align-items: center;
.deadline, .unit {
font-size: 28rpx;
color: #333;
}
.deadline {
width: 130rpx;
}
.unit {
min-width: 80rpx;
text-align: center;
&.placeholder {
color: #797979;
}
}
}
}
.pro-name {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14rpx 24rpx;
font-size: 30rpx;
color: #333;
background: linear-gradient(90deg, #FFF5E5 0%, #FFFFFF 100%);
.left {
display: inline-flex;
align-items: center;
}
.icon {
width: 60rpx;
height: 60rpx;
margin-right: 12rpx;
border-radius: 10rpx;
}
}
.form-list {
padding: 0 24rpx;
border-top: 0;
.period {
text-align: center;
}
.unit {
display: inline-flex;
align-items: center;
.icon {
width: 28rpx;
margin-left: 20rpx;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -1,285 +0,0 @@
<template>
<view>
<view class="filter">
<uni-search-bar class="search" radius="30" placeholder="请输入产品名称" v-model="keyword" clearButton="auto" cancelButton="none" />
<uni-icons class="icon" custom-prefix="iconfont" type="icon-filter" size="22" color="#007eff" @click="popup = true"></uni-icons>
</view>
<ul class="tab-wrap">
<scroll-view scroll-x :scroll-left="scrollLeft" class="tab">
<li v-for="(tab, i) in tabs" :class="{active: curTab === tab.id}" @click="tabChange(tab)">{{ tab.name }}</li>
</scroll-view>
</ul>
<ul v-if="list.length" class="list">
<li v-for="item in list">
<view class="pro-name">
<image class="icon" :src="item.miniProgramPictureAddress ? item.miniProgramPictureAddress : normalIcon" mode="widthFix"></image>
{{ item.productName }}
</view>
<view class="info">
<view class="line">
<text class="name">起止日期</text>
<text class="val">{{ item.startAndEndTime }}</text>
</view>
<view class="line">
<text class="name">订阅状态</text>
<text class="val">{{ item.status }}</text>
</view>
<view class="line">
<text class="name">产品状态</text>
<text class="val">{{ item.isEnable }}</text>
</view>
</view>
</li>
</ul>
<empty v-else></empty>
<filter-popup :data="filterData" :form.sync="filterForm" v-model="popup" title="全部筛选" height="1104rpx" @finsh="subFinsh"></filter-popup>
</view>
</template>
<script>
import { productCategoryList } from '@/apis/modules/product.js'
import { getProductsSubscribedByCustomers } from '@/apis/modules/client.js'
import product from '@/config/product.js'
export default {
data() {
return {
normalIcon: product.normalIcon,
customerId: '',
popup: false,
//
filterData: [
{
children: false,//
title: "订阅状态",
key: "orderStatus", //
keyValue: "value", //
isRadio: true, //
data: [
{
title: '生效',
value: 1
},
{
title: '过期',
value: 2
},
],
},
{
children: false,//
title: "产品状态",
key: "productStatus", //
keyValue: "value", //
isRadio: true, //
data: [
{
title: '启用',
value: 1
},
{
title: '禁用',
value: 2
},
],
}
],
filterForm: {},
curTab: '',
tabs: [
{
name: '全部',
id: ''
},
],
searchTimer: null,
orderStatus: '',
productStatus: '',
keyword: '',
list: [],
listAll: [],
page: 1,
pageSize: 10
}
},
watch: {
keyword () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.filter()
}, 500)
}
},
//
onPullDownRefresh() {
this.getList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
onShow() {
const pages = getCurrentPages()
this.customerId = pages[pages.length - 1].options.customerId
this.getTypes()
this.getList()
},
methods: {
getList() {
uni.showLoading({
title: '加载中'
})
getProductsSubscribedByCustomers({
customeId: this.customerId
}).then(({ data }) => {
const { tabs } = this
data.map(e => {
const list = e.startAndEndTimeList
if (list && list.length) {
let connect = true //
list.map((n, i) => {
//
if (i) {
if (new Date(n.startTime).getTime() - 86400000 !== new Date(list[i - 1].endTime).getTime()) connect = false
}
})
// //
const now = Date.now()
if (now < list[0].startTime) {
e.startTime = list[0].startTime
e.endTime = connect ? list[list.length - 1].endTime : list[0].endTime
e.status = '未生效'
} else if (now > list[list.length - 1].endTime) {
e.status = '已过期'
} else {
//
if (connect) {
e.startTime = list[0].startTime
e.endTime = list[list.length - 1].endTime
e.status = '生效中'
e.orderEnable = list[0].isEnable
} else {
for (const i in list) {
const n = list[i]
if (now >= new Date(n.startTime).getTime() && now <= new Date(n.endTime).getTime()) {
//
e.startTime = n.startTime
e.endTime = n.endTime
e.status = '生效中'
e.orderEnable = n.isEnable
break
} else if (i && list[i - 1] && now > new Date(list[i - 1].endTime).getTime() && now < new Date(n.startTime).getTime()) {
//
e.startTime = n.startTime
e.endTime = n.endTime
e.status = '未生效'
e.orderEnable = n.isEnable
break
} else {
e.status = '已过期'
}
}
}
}
const date = new Date()
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0)
if (e.startTime) e.startAndEndTime = e.startTime + ' ~ ' + e.endTime
// 1 0
e.isEnable = (e.status === '已过期' || !e.orderEnable) ? '禁用' : '启用'
}
})
this.list = data
this.listAll = data
uni.hideLoading()
}).catch(e => {
uni.hideLoading()
})
},
//
getTypes() {
productCategoryList().then(res => {
res.classificationList.forEach(e => {
e.id = e.classificationId
e.name = e.classificationName
})
this.tabs.push(...res.classificationList)
}).catch(e => {})
},
//
subFinsh(val) {
const { orderStatus, productStatus } = val
this.orderStatus = orderStatus.length ? orderStatus[0] : ''
this.productStatus = productStatus.length ? productStatus[0] : ''
this.filter()
},
//
filter() {
const list = this.listAll
const { orderStatus, productStatus, keyword, curTab } = this
this.list = list.filter(e => (orderStatus === '' || ((orderStatus === 2 && e.status === '已过期') || (orderStatus === 1 && e.status === '生效中'))) && (productStatus === '' || ((productStatus === 2 && e.isEnable === '禁用') || (productStatus === 1 && e.isEnable === '启用'))) && e.productName.includes(keyword) && (curTab === '' || (curTab === e.productType)))
},
// tab
tabChange(tab) {
this.curTab = tab.id
this.filter()
},
//
toDetail(item) {
this.$util.to(`../clientDetail/clientDetail?customerId=${item.customerId}&show=1`)
}
}
}
</script>
<style scoped lang="scss">
.filter {
margin-bottom: 10px;
}
.tab-wrap {
.tab {
width: 100%;
white-space: nowrap;
li {
display: inline-block;
}
}
}
.list {
li {
padding: 0 24rpx;
margin: 16rpx 24rpx;
background-color: #fff;
border-radius: 16rpx;
}
.pro-name {
display: flex;
align-items: center;
padding: 18rpx 0;
font-size: 30rpx;
color: #333;
border-bottom: 1px solid #E6E8ED;
.icon {
width: 52rpx;
margin-right: 20rpx;
}
}
.info {
padding: 12rpx 0;
}
.line {
display: flex;
padding: 12rpx 0;
}
.name {
margin-right: 10rpx;
font-size: 28rpx;
color: #999;
}
.val {
font-size: 28rpx;
color: #333;
}
}
</style>

@ -13,6 +13,7 @@
</template> </template>
<script> <script>
import OSS from '@/libs/Oss/upload'
import { practiceByStudentDetail, exportExamPaperReport } from '@/apis/modules/course.js' import { practiceByStudentDetail, exportExamPaperReport } from '@/apis/modules/course.js'
export default { export default {
data() { data() {
@ -67,65 +68,34 @@
this.reachBottom = noMore ? -1 : 0 // -1 this.reachBottom = noMore ? -1 : 0 // -1
}, },
saveFile(fileData) { saveFile(fileData) {
const fs = uni.getFileSystemManager(); console.log('url:', fileData)
uni.downloadFile({
// // url: 'https://eduvessel.com/images/occupationlab/ac.docx',
const tempFilePath = `${uni.env.USER_DATA_PATH}/tempFile`; url: fileData,
console.log('临时文件路径:', uni.env, tempFilePath, fileData) success: function(res) {
// console.log(11, res)
fs.writeFile({ uni.hideLoading();
filePath: tempFilePath, // uni.showLoading({
data: fileData, // title: '',
encoding: 'binary', // 使 binary // mask: true
success: (res) => { // })
console.log('文件写入成功', res); // doc, xls, ppt, pdf, docx, xlsx, pptx
uni.openDocument({
// filePath: res.tempFilePath,
uni.saveFile({ fileType: 'docx', // doc, xls, ppt, pdf, docx, xlsx, pptx
tempFilePath: tempFilePath, showMenu: true, //
success: (res) => { success: res => {
console.log('文件保存成功', res.savedFilePath); uni.hideLoading()
uni.downloadFile({
// url: 'https://eduvessel.com/images/occupationlab/ac.docx',
url: res.savedFilePath,
success: function(res) {
console.log(11, res)
uni.hideLoading();
uni.showLoading({
title: '正在打开',
mask: true
})
// doc, xls, ppt, pdf, docx, xlsx, pptx
uni.openDocument({
filePath: res.tempFilePath,
fileType: 'docx', // doc, xls, ppt, pdf, docx, xlsx, pptx
showMenu: true, //
success: res => {
uni.hideLoading()
},
fail: openError => {
uni.hideLoading()
}
})
}, },
fail: function(err) { fail: openError => {
uni.hideLoading() uni.hideLoading()
} }
}) })
},
fail: function(err) {
uni.hideLoading()
}, }
fail: (err) => { })
console.error('文件保存失败', err);
}
});
},
fail: (err) => {
console.error('文件写入失败', err);
}
});
}, },
// //
async toDetail(row) { async toDetail(row) {
@ -134,6 +104,32 @@
mask: true mask: true
}) })
const that = this
uni.request({
header: {
token: uni.getStorageSync('token')
},
url: 'https://izhixinyun.com/exam/exam/paper/exportExamPaperReport?reportId=73157',
method: 'GET', // GET
data: {},
// responseType: 'blob',
success: (res) => {
console.log(4444, res)
OSS(res.data, ({ url }) => {
console.log('ffff:', url)
// that.saveFile(url)
})
},
fail: err => {
console.log('fail:',fail)
uni.showToast({
title: '请求失败!',
icon: 'none'
})
},
})
return
const res = await exportExamPaperReport({ const res = await exportExamPaperReport({
reportId: row.reportId reportId: row.reportId
}) })

@ -1,399 +0,0 @@
<template>
<view>
<view class="filter">
<uni-search-bar class="search" radius="30" placeholder="请输入产品名称" v-model="keyword" clearButton="auto" cancelButton="none" />
<uni-icons class="icon" custom-prefix="iconfont" type="icon-filter" size="22" color="#007eff" @click="popup = true"></uni-icons>
</view>
<ul class="tab-wrap">
<view class="tab">
<li :class="{active: curTab === ''}" @click="tabChange('')">全部</li>
</view>
<scroll-view scroll-x :scroll-left="scrollLeft" class="tab tab-scroll">
<li v-for="(tab, i) in tabs" :key="i" :class="{active: curTab === tab.value}" @click="tabChange(tab.value)">{{ tab.title }}</li>
</scroll-view>
</ul>
<view class="tags">
<view v-if="categoryName" class="tag" @click="delCategory">
{{ categoryName }}
<uni-icons class="icon" type="closeempty" size="15" color="#007EFF"></uni-icons>
</view>
<view v-if="productTypeName" class="tag" @click="delProductType">
{{ productTypeName }}
<uni-icons class="icon" type="closeempty" size="15" color="#007EFF"></uni-icons>
</view>
<view v-if="form.selection" class="tag" @click="delSelection">
官方精选
<uni-icons class="icon" type="closeempty" size="15" color="#007EFF"></uni-icons>
</view>
<view v-if="tagName" class="tag" @click="delTag">
{{ tagName }}
<uni-icons class="icon" type="closeempty" size="15" color="#007EFF"></uni-icons>
</view>
</view>
<ul class="list">
<li v-for="(item, i) in list" :key="i" @click="toDetail(item)">
<view class="pro-name">
<image class="icon" :src="$util.getIcon(item)"></image>
{{ item.productName }}
</view>
<view class="info">
<view class="line">
<text class="name">产品简介</text>
<view class="val ell-wrap">
<view class="ell">{{ item.productIntroduction }}</view>
</view>
</view>
<view class="line">
<text class="name">产品类型</text>
<text class="val">{{ item.typeName }}</text>
</view>
<view class="line">
<text class="name">适用专业</text>
<text class="val">{{ item.professionalName }}</text>
</view>
<view class="line">
<text class="name">市场建议单价</text>
<text class="val">{{ item.marketUnitPrice }}/</text>
</view>
</view>
</li>
</ul>
<view v-if="auth('产品:购物车')" class="plus">
<uni-badge size="small" :text="total" absolute="topRight" type="error">
<image class="icon" src="@/static/image/product/shop-blue.png" mode="widthFix" @click="$util.to('../shopCart/shopCart')"></image>
</uni-badge>
</view>
<filter-popup ref="filter" showCategory :data="filters" :form.sync="filterForm" v-model="popup" title="全部筛选" height="1104rpx" @finsh="subFinsh"></filter-popup>
</view>
</template>
<script>
import { tagsList, listOfGoods, productTypeList, shoppingCartList } from '@/apis/modules/product.js'
export default {
data() {
return {
popup: false,
//
filters: [
{
children: false,//
title: "产品类型",
key: "productType", //
keyValue: "value", //
isRadio: true, //
data: [],
},
{
children: false,//
title: "官方精选",
key: "selection", //
keyValue: "value", //
data: [
{
value: 1,
title: '官方精选'
}
],
},
{
children: false,//
title: "产品标签",
key: "tagId", //
keyValue: "value", //
isRadio: true, //
data: [],
},
],
filterForm: {
productType: [],
selection: [],
tagId: []
},
form: {
categoryId: '',
professionalCategoryId: '',
professionalId: '',
productType: '',
selection: '',
tagId: ''
},
tagId: '',
curTab: '',
tabs: [],
scrollLeft: 0,
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
sort: 0,
keyword: '',
list: [],
page: 1,
pageSize: 10,
total: 0,
cartNum: '',
productTypeName: '',
tagName: '',
categoryName: '',
}
},
watch: {
keyword () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initList()
}, 500)
}
},
//
onPullDownRefresh() {
this.initList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
//
onReachBottom() {
if (this.reachBottom >= 0) {
this.reachBottom = 1
this.status = 'loading'
this.getList()
}
},
onShow() {
const pages = getCurrentPages()
const { options } = pages[pages.length - 1]
const { tagId, tagsName } = options
this.form.tagId = +tagId || ''
if (tagId) {
this.filterForm.tagId = [+tagId]
// this.tagName = tagsName
}
this.keyword = options.keyword || ''
this.page = 1
this.getList()
this.getFilter()
this.getShopCart()
},
methods: {
getList() {
listOfGoods({
pageNum: this.page,
pageSize: this.pageSize,
sort: 0,
isShelves: 0,
hotTag: this.form.tagId ? 2 : 1,
...this.form,
productName: this.keyword,
productType: this.curTab
}).then(({ page }) => {
// list
const list = page.records
list.map(e => {
e.productIntroduction = this.$util.removeTag(e.productIntroduction)
})
this.list = this.reachBottom > 0 ? [...this.list, ...list] : list
this.page++ // page+1
const noMore = this.list.length === page.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
}).catch(e => {})
},
initList() {
this.page = 1
this.reachBottom = 0
this.getList()
},
//
getShopCart() {
shoppingCartList({
pageNum: 1,
pageSize: 1000,
}).then(({ data }) => {
this.total = data.total
}).catch(e => {})
},
//
getFilter() {
//
productTypeList().then(res => {
res.typeList.forEach(e => {
e.value = e.typeId
e.title = e.typeName
})
this.tabs = res.typeList
this.filters[0].data = res.typeList
}).catch(e => {})
//
tagsList().then(res => {
res.tagsList.forEach(e => {
e.value = e.tagsId
e.title = e.tagsName
})
this.filters[2].data = res.tagsList
}).catch(e => {})
},
//
subFinsh(val) {
const { productType, selection, tagId, categoryId, professionalCategoryId, professionalId, categoryName } = val
this.form = {
categoryId: categoryId || '',
professionalCategoryId: professionalCategoryId || '',
professionalId: professionalId || '',
productType: productType.length ? productType[0] : '',
selection: selection.length ? selection[0] : '',
tagId: tagId.length ? tagId[0] : ''
}
this.categoryName = categoryName || ''
this.productTypeName = this.form.productType ? this.filters[0].data.find(e => e.value == this.form.productType).title : ''
this.tagName = this.form.tagId ? this.filters[2].data.find(e => e.value == this.form.tagId).title : ''
this.initList()
},
//
delCategory() {
this.$refs.filter.category = []
this.$refs.filter.categoryName = ''
this.$refs.filter.categoryId = ''
this.$refs.filter.professionalCategoryId = ''
this.$refs.filter.professionalId = ''
this.form.categoryId = ''
this.form.professionalCategoryId = ''
this.form.professionalId = ''
this.categoryName = ''
this.initList()
},
//
delProductType() {
this.filterForm.productType = []
this.form.productType = ''
this.productTypeName = ''
this.initList()
},
//
delSelection() {
this.filterForm.selection = []
this.form.selection = ''
this.initList()
},
//
delTag() {
this.filterForm.tagId = []
this.form.tagId = ''
this.tagName = ''
this.initList()
},
// tab
tabChange(id) {
this.curTab = id
this.initList()
},
//
toDetail(item) {
console.log(44, item)
this.$util.to(`../productDetail/productDetail?id=${item.mallId}`)
},
}
}
</script>
<style scoped lang="scss">
.tab-wrap {
display: flex;
.tab-scroll {
width: calc(100% - 100rpx);
white-space: nowrap;
li {
display: inline-block;
}
}
}
.tags {
display: flex;
align-items: center;
flex-wrap: wrap;
padding: 0 24rpx;
.tag {
display: inline-flex;
align-items: center;
padding: 10rpx 14rpx;
margin: 0 20rpx 16rpx 0;
font-size: 28rpx;
color: #007EFF;
background-color: #fff;
border-radius: 4px;
}
.icon {
margin-left: 6rpx;
}
}
.list {
li {
padding: 0 24rpx;
margin: 16rpx 24rpx;
background-color: #fff;
border-radius: 16rpx;
}
.pro-name {
display: flex;
align-items: center;
padding: 18rpx 0;
font-size: 30rpx;
font-weight: 600;
color: #333;
border-bottom: 1px solid #E6E8ED;
.icon {
width: 58rpx;
min-width: 58rpx;
height: 58rpx;
margin-right: 20rpx;
border-radius: 4px;
}
}
.info {
padding: 12rpx 0;
}
.line {
display: flex;
padding: 12rpx 0;
}
.name {
margin-right: 10rpx;
font-size: 28rpx;
color: #999;
}
.val {
max-width: 70%;
font-size: 28rpx;
color: #333;
}
.ell-wrap {
display: inline-flex;
align-items: center;
}
.ell {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.toggle {
margin-left: 10rpx;
white-space: nowrap;
font-size: 24rpx;
color: #0e92ef;
}
}
.plus {
bottom: 140rpx;
right: 60rpx;
.icon {
width: 102rpx;
}
}
</style>

@ -1,317 +0,0 @@
<template>
<view class="page">
<ul class="list">
<uni-swipe-action>
<uni-swipe-action-item
v-for="(item, i) in list"
:key="i"
:threshold="0"
:right-options="delOption"
@click="del(item)"
>
<li>
<uni-data-checkbox v-if="item.check" class="check" multiple :value="[1]" :localdata="item.checkData" @change="e => checkChange(e, i)"></uni-data-checkbox>
<uni-data-checkbox v-else class="check" multiple v-model="item.check" :localdata="item.checkData" @change="e => checkChange(e, i)"></uni-data-checkbox>
<image class="icon" :src="$util.getIcon(item)"></image>
<view class="texts">
<view class="name">{{ item.productName }}</view>
<view class="price">市场建议价{{ item.marketUnitPrice }}/</view>
</view>
</li>
</uni-swipe-action-item>
</uni-swipe-action>
</ul>
<uni-load-more :status="status" />
<view class="btn-wrap">
<uni-data-checkbox class="check" multiple v-model="checkAll" :localdata="checkAllData" @change="allChange"></uni-data-checkbox>
<view class="btns">
<view class="btn del" @click="batchDel">删除</view>
<view class="btn" @click="submit">生成订单</view>
</view>
</view>
</view>
</template>
<script>
import { shoppingCartList, delCart, detailsOfGoods } from '@/apis/modules/product.js'
export default {
data() {
return {
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
list: [],
page: 1,
pageSize: 10,
check: [1],
noCheck: [],
checkData: [{
text: '',
value: 1
}],
checkAll: [],
checkAllData: [{
text: '全部',
value: 1
}],
checked: [], //
delOption: [{
text: '删除',
style: {
backgroundColor: '#F56C6C'
}
}],
}
},
//
onPullDownRefresh() {
this.initList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
//
onReachBottom() {
if (this.reachBottom >= 0) {
this.reachBottom = 1
this.status = 'loading'
this.getList()
}
},
onShow() {
this.checked = []
//
try {
uni.removeStorageSync('orderForm')
uni.removeStorageSync('courses')
uni.removeStorageSync('orderEdited')
} catch (e) {}
this.initList()
},
methods: {
//
getList() {
uni.showLoading({
title: '加载中'
})
shoppingCartList({
pageNum: this.page,
pageSize: this.pageSize,
}).then(({ data }) => {
const { records } = data
const all = this.checkAll.length //
const pageChange = this.reachBottom > 0 //
//
records.forEach(e => {
e.check = 0
e.checkData = [{
text: '',
value: 1
}]
})
// list
this.list = pageChange ? [...this.list, ...records] : records
this.page++ // page+1
const noMore = this.list.length === data.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
uni.hideLoading()
}).catch(e => {
uni.hideLoading()
})
},
initList() {
this.page = 1
this.reachBottom = 0
this.getList()
},
//
checkChange(e, i) {
const { checked } = this
const item = this.list[i]
const { id } = item
const include = checked.findIndex(e => e.id === id)
// pushpush
if (e.detail.value.length) {
include === -1 && checked.push(item)
} else {
//
if (include !== -1) {
checked.splice(include, 1)
this.checkAll = []
}
}
console.log(11, checked)
},
//
allChange(e) {
const isCheck = !!e.detail.value.length //
const { list } = this
this.checked = isCheck ? JSON.parse(JSON.stringify(list)) : []
list.forEach(e => {
e.check = isCheck ? 1 : 0
})
},
//
createParam(e, authority, shopCartId) {
const { orderType } = this
const { mall, typeIds } = e
const trial = orderType == 2 //
return {
dataOrCourseId: mall.associatedProduct, // id
mallId: mall.mallId,
productName: mall.productName, //
periodOfUse: '', // 使
startTime: this.$util.formatDate(new Date(), 'yyyy-MM-dd'), //
endTime: '', //
remainingPeriod: '', //
marketValue: '', //
marketPrice: mall.marketUnitPrice, //
finalPrice: 0, //
finalValue: 0, //
discountRate: '0%', //
accountNum: 1, //
totalAmount: '', //
isEnable: 0, // 10
ship: 0, // 01
authority, // 01
options: 2,
miniProgramPictureAddress: mall.appletIcon || '', //
settlementPrice: trial ? 0 : '', //
settlementPriceUnit: 0, //
serviceFee: 0, //
shopCartId, // id
typeId: typeIds && typeIds.length ? typeIds[0] : '',
}
},
//
del(e) {
const that = this
uni.showModal({
title: '提示',
content: '确定要删除吗?',
success(res) {
if (res.confirm) {
delCart([e.id]).then(res => {
that.initList()
}).catch(e => {})
}
}
})
},
//
batchDel() {
const list = this.checked //
if (list.length) {
const that = this
uni.showModal({
title: '提示',
content: '确定要删除吗?',
success(res) {
if (res.confirm) {
delCart(list.map(e => e.id)).then(res => {
that.checkAll = []
that.checked = []
that.initList()
}).catch(e => {})
}
}
})
} else {
this.$util.errMsg('请选择产品!')
}
},
//
submit() {
const list = this.checked //
if (list.length) {
//
if (new Set(list.map(e => e.mallId)).size !== list.length) return this.$util.errMsg('所选产品存在重复,请重新选择')
const promises = []
let courses = []
list.forEach(e => {
promises.push(new Promise(async (resolve, reject) => {
//
const res = await detailsOfGoods(e.mallId)
const n = res.orderDetails
courses.push(this.createParam(n, this.$util.getOrderType(n.classificationIds[0]), e.id))
resolve()
}))
})
Promise.all(promises).then(_ => {
uni.setStorageSync('courses', courses)
this.$util.to(`../orderDetail/orderDetail?shopCart=1`)
})
} else {
this.$util.errMsg('请先添加产品!')
}
}
}
}
</script>
<style scoped lang="scss">
.page {
padding-bottom: 130rpx;
}
.list {
li {
display: flex;
align-items: center;
width: 100%;
padding: 30rpx 24rpx;
margin: 16rpx 24rpx;
background-color: #fff;
border-radius: 16rpx;
box-sizing: border-box;
}
.name {
margin-bottom: 10rpx;
font-size: 30rpx;
color: #333;
}
.price {
font-size: 26rpx;
color: #333;
}
.icon {
width: 100rpx;
min-width: 100rpx;
height: 100rpx;
margin: 0 20rpx;
border-radius: 4px;
}
}
/deep/.check {
.checklist-box {
margin: 0 !important;
}
.checkbox__inner {
width: 40rpx !important;
height: 40rpx !important;
border-radius: 50% !important;
}
.checkbox__inner-icon {
top: 8rpx !important;
left: 14rpx !important;
}
}
.btn-wrap {
position: fixed;
justify-content: space-between;
.btns {
display: inline-flex;
}
.btn {
width: auto;
padding: 0 50rpx;
}
.del {
margin-right: 20rpx;
background-color: #b5b5b5;
}
}
</style>

@ -1,5 +1,3 @@
import Product from '@/config/product'
const files = [ const files = [
'https://huoran.oss-cn-shenzhen.aliyuncs.com/用户服务协议.docx', // 用户服务协议 'https://huoran.oss-cn-shenzhen.aliyuncs.com/用户服务协议.docx', // 用户服务协议
'https://huoran.oss-cn-shenzhen.aliyuncs.com/用户隐私协议.docx', // 用户隐私协议 'https://huoran.oss-cn-shenzhen.aliyuncs.com/用户隐私协议.docx', // 用户隐私协议
@ -7,8 +5,14 @@ const files = [
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798621083.docx', // 大数据 'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798621083.docx', // 大数据
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798646462.docx', // 金融科技 'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798646462.docx', // 金融科技
] ]
const docExts = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'] const exts = {
video: 'mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv',
audio: 'mp3,aac,ape,flac,wav,wma,amr,mid',
img: 'jpg,jpeg,png,gif,svg,psd',
doc: 'doc,docx,txt,xls,xlsx,csv,xml,ppt,pptx'
}
export default { export default {
exts,
// 路由跳转 // 路由跳转
to(url) { to(url) {
uni.navigateTo({ uni.navigateTo({
@ -60,22 +64,6 @@ export default {
} }
return fmt return fmt
}, },
// 获取商务经理id
getBmId(val) {
return uni.getStorageSync('team').partnerId
},
// 获取商务经理名称
getBmName(val) {
return uni.getStorageSync('team').partnerClassificationName
},
// 返回图标。如果有图标,则直接返回
getIcon(e) {
return e.appletIcon || Product.normalIcon
},
// 判断文件类型是否能够通过uni.openDocument打开(doc, xls, ppt, pdf, docx, xlsx, pptx)
isDoc(ext) {
return docExts.includes(ext)
},
// 预览文档 // 预览文档
openFile(id) { openFile(id) {
uni.showLoading({ uni.showLoading({
@ -110,14 +98,6 @@ export default {
} }
}) })
}, },
// 产品管理的产品分类(classificationId)有6个,订单管理的产品分类(authority)有5个,后者是由前者决定的,但是id不一样。把产品管理的分类id传入这个函数,即可返回订单的分类id
getOrderType(id) {
if (id == 1 || id == 2) return 1
if (id == 3) return 2
if (id == 4) return 3
if (id == 5) return 0
if (id == 6) return 4
},
// 去掉html标签 // 去掉html标签
removeTag(str) { removeTag(str) {
return str.replace(/(<[^>]+>)|((&nbsp;)+)/g , '') return str.replace(/(<[^>]+>)|((&nbsp;)+)/g , '')

13
package-lock.json generated

@ -25,6 +25,14 @@
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
}, },
"aliyun-aliplayer": {
"version": "2.27.1",
"resolved": "https://registry.npmmirror.com/aliyun-aliplayer/-/aliyun-aliplayer-2.27.1.tgz",
"integrity": "sha512-vm3YmxW7BAD/ZPYEdxS5HlCjwF2ayPXA0YWMvNIMpNHJX0FQiNpZcGhVz7mtWolN2+5hjbyGlC0GYkIKEwMs8w==",
"requires": {
"crypto-js": "^4.1.1"
}
},
"ansi-colors": { "ansi-colors": {
"version": "3.2.4", "version": "3.2.4",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
@ -161,6 +169,11 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
}, },
"crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"cyclist": { "cyclist": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",

@ -10,6 +10,7 @@
"上拉筛选" "上拉筛选"
], ],
"dependencies": { "dependencies": {
"aliyun-aliplayer": "^2.27.1",
"copy-webpack-plugin": "^5.0.3", "copy-webpack-plugin": "^5.0.3",
"umtrack-wx": "^2.8.0" "umtrack-wx": "^2.8.0"
} }

@ -90,15 +90,6 @@
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{
"path" : "setting/setting",
"style" :
{
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false
}
},
{ {
"path" : "password/password", "path" : "password/password",
"style" : "style" :
@ -106,22 +97,6 @@
"navigationBarTitleText": "修改密码", "navigationBarTitleText": "修改密码",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
},
{
"path" : "addStaff/addStaff",
"style" :
{
"navigationBarTitleText": "邀请成员",
"enablePullDownRefresh": false
}
},
{
"path" : "account/account",
"style" :
{
"navigationBarTitleText": "修改账号",
"enablePullDownRefresh": false
}
} }
,{ ,{
"path" : "phone/phone", "path" : "phone/phone",
@ -139,24 +114,6 @@
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
} }
,{
"path" : "qrcode/qrcode",
"style" :
{
"navigationBarTitleText": "邀请加入",
"enablePullDownRefresh": false
}
}
,{
"path" : "article/article",
"style" :
{
"navigationBarTitleText": "学习",
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#fff",
"enablePullDownRefresh": false
}
}
] ]
} }
], ],

@ -58,7 +58,7 @@
<view class="c-name">{{ item.experimentalName }}</view> <view class="c-name">{{ item.experimentalName }}</view>
<view class="line">得分{{ item.score }}&emsp;&emsp;耗时{{ item.timeSum }}min</view> <view class="line">得分{{ item.score }}&emsp;&emsp;耗时{{ item.timeSum }}min</view>
<view class="line">考核开始时间{{ item.startTime }}</view> <view class="line">考核开始时间{{ item.startTime }}</view>
<view class="line">考核结束时间{{ item.lastTime }}</view> <view class="line">考核结束时间{{ item.submitTime }}</view>
<view class="btn">成绩报告</view> <view class="btn">成绩报告</view>
</view> </view>
</view> </view>

@ -63,7 +63,7 @@
}, 1500) }, 1500)
}, },
onShow() { onShow() {
uni.setStorageSync('token', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjM5NTc2LCJyblN0ciI6IlNMbWxtU1E0akE2RUlBT2RPVTV5eENPSHVZa3lpeDUzIiwiYWNjb3VudElkIjozOTU3NiwidXNlcklkIjozOTU3NSwic2Nob29sSWQiOjI4NDYsInVzZXJOYW1lIjoiYWMiLCJwbGF0Zm9ybUlkIjoiMSJ9.ouC5QsZkRnTCI6qk7ZqEYMRoapp2qq0kkAxWakzvjC8') uni.setStorageSync('token', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjM5NTc2LCJyblN0ciI6IlpFVDVjb0k3Y2VBVHRYb0RtaDNiaHc5TlF2OVhmYmNRIiwiYWNjb3VudElkIjozOTU3NiwidXNlcklkIjozOTU3NSwic2Nob29sSWQiOjI4NDYsInVzZXJOYW1lIjoiYWMiLCJwbGF0Zm9ybUlkIjoiMSJ9.2Sltl681nbYYPnE0YX5xbF630uOe8hbEcYZqX3mqwCM')
this.getTab() this.getTab()
}, },
methods: { methods: {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

@ -1,61 +0,0 @@
<template>
<view class="page">
<view class="input">
<uni-easyinput v-model.trim="account" placeholder="请输入账号" @input="accountChange"></uni-easyinput>
</view>
<button type="primary" @click="submit">确认</button>
</view>
</template>
<script>
import { checkIfAnAccountExists, changeAccount } from '@/apis/modules/user.js'
export default {
data() {
return {
timer: null,
account: '',
repeat: false
}
},
onShow() {
},
methods: {
//
accountChange() {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
checkIfAnAccountExists(this.account).then(() => {
this.repeat = false
}).catch(e => {
this.repeat = true
})
}, 500)
},
submit() {
const { account } = this
if(!account) return this.$util.errMsg('请输入账号')
if (this.repeat) return this.$util.errMsg('账号已存在!')
changeAccount(account).then(res => {
this.$util.sucMsg('修改成功!')
setTimeout(() => {
uni.navigateBack()
}, 1000)
}).catch(e => {})
}
}
}
</script>
<style scoped lang="scss">
.page {
padding: 20px;
background-color: #fff;
}
/deep/.input {
margin-bottom: 15px;
.is-input-border {
border-color: #dedede !important;
}
}
</style>

@ -1,51 +0,0 @@
<template>
<view>
<uni-section title="邀请成员" type="line">
<uni-list>
<uni-list-item thumb-size="sm" showArrow title="二维码邀请" clickable :to="`../qrcode/qrcode`">
<template v-slot:header>
<view class="slot-box">
<image class="icon" src="@/static/image/qrcode.png" mode="widthFix"></image>
</view>
</template>
<template v-slot:body>
<text class="slot-box text">二维码邀请</text>
</template>
</uni-list-item>
</uni-list>
</uni-section>
</view>
</template>
<script>
export default {
data() {
return {
extraIcon: {
color: '#007eff',
size: '22',
type: 'icon-qrcode'
}
}
},
methods: {
}
}
</script>
<style scoped lang="scss">
.slot-box {
display: flex;
flex-direction: row;
align-items: center;
}
.icon {
width: 25px;
height: 25px;
margin-right: 10px;
}
.text {
font-size: 14px;
}
</style>

@ -1,222 +0,0 @@
<template>
<view class="page">
<view class="block">
<view class="title">上传营业执照</view>
<image class="credential" :src="businessLicensePicture || 'http://124.71.79.122/images/miniProgram/credentials1.png'" mode="widthFix" @click="uploadBusinessLicense"></image>
</view>
<view v-if="isPreschool" class="block">
<view class="title">上传办学许可证</view>
<image class="credential" :src="licenseForRunningSchool || 'http://124.71.79.122/images/miniProgram/credentials2.png'" mode="widthFix" @click="uploadSchoolLicense"></image>
</view>
<view class="block">
<view class="form-list">
<view class="line with-arrow">
<view class="name">{{ isPreschool ? '幼儿园' : '企业' }}名称</view>
<input type="text" :placeholder="'请输入' + platformName + '名称'" v-model="form.companyName" />
<uni-icons type="right" size="18" color="#ababab"></uni-icons>
</view>
<view class="line with-arrow">
<view class="name">统一社会信用代码</view>
<input type="text" placeholder="请输入证件号码" v-model="form.creditCode" />
<uni-icons type="right" size="18" color="#ababab"></uni-icons>
</view>
<view class="line with-arrow">
<view class="name">法人</view>
<input type="text" placeholder="请输入法人" v-model="form.legalPerson" />
<uni-icons type="right" size="18" color="#ababab"></uni-icons>
</view>
</view>
</view>
<view class="btn-wrap">
<view class="btn" @click="submit">认证信息</view>
</view>
</view>
</template>
<script>
import OSS from '@/libs/Oss/upload'
export default {
data() {
return {
openId: uni.getStorageSync('openId'),
form: {
companyName: '',
creditCode: '',
legalPerson: '',
},
platformId: '',
businessLicensePicture: '',
licenseForRunningSchool: '',
}
},
onShow() {
const pages = getCurrentPages()
const { options } = pages[pages.length - 1]
// this.getEnterInfo()
},
methods: {
//
async getEnterInfo() {
const res = await enterpriseCertificationStatus(this.openId)
if (res.data) {
const { data } = res
this.businessLicensePicture = data.businessLicensePicture || ''
this.licenseForRunningSchool = data.licenseForRunningSchool || ''
this.form.companyName = data.companyName || ''
this.form.creditCode = data.creditCode || ''
this.form.legalPerson = data.legalPerson || ''
this.form.address = data.address || ''
this.form.business = data.business || ''
this.form.capital = data.capital || ''
this.form.establishDate = data.establishDate || ''
this.form.type = data.type || ''
this.form.validPeriod = data.validPeriod || ''
this.form.platformSource = this.platformId
}
},
//
uploadBusinessLicense() {
const that = this
uni.chooseImage({
success: (res) => {
const file = res.tempFilePaths[0];
OSS(file, async ({ url }) => {
that.businessLicensePicture = url
const { data } = await businessLicensePictureVerification(url)
if (data) {
that.form = {
companyName: data.name,
creditCode: data.reg_num,
legalPerson: data.person,
address: data.address,
business: data.business,
capital: data.capital,
establishDate: data.establish_date,
type: data.type,
validPeriod: data.valid_period,
platformSource: this.platformId,
}
}
})
}
});
},
//
uploadSchoolLicense() {
const that = this
uni.chooseImage({
success: (res) => {
const file = res.tempFilePaths[0];
OSS(file, async ({ url }) => {
that.licenseForRunningSchool = url
})
}
});
},
//
publicNotice() {
const that = this
uni.requestSubscribeMessage({
tmplIds: ['ZB6wTenlv13mivxXwi-DWwjgVoNJ6eUr1vBvNdQGbJw'],
success: (res) => {
uni.setStorageSync('platformId', that.platformId)
const name = that.platformId == 6 ? '供应商' : '幼儿园'
that.$util.errMsg(`您已成功提交${name}认证,现在为您切换到${name}端。`)
setTimeout(() => {
uni.switchTab({
url: '/pages/person/person'
})
}, 2000)
},
fail: function(err) {
uni.showToast({
title: err,
duration: 2000,
icon: 'error'
});
}
})
},
//
async submit() {
if (this.submiting) return false
const { form } = this
if (!form.companyName) return this.$util.errMsg(`请输入${platformName}名称!`)
if (!form.creditCode) return this.$util.errMsg('请输入统一社会信用代码!')
if (!form.legalPerson) return this.$util.errMsg('请输入法人!')
this.submiting = true
uni.showLoading({
title: '提交中'
})
const data = {
...form,
auditStatus: 1,
authenticationStatus: 1,
businessLicensePicture: this.businessLicensePicture,
licenseForRunningSchool: this.licenseForRunningSchool,
openId: this.openId
}
try {
//
if (uni.getStorageSync('platformId') === 7) {
//
const res = await kindergartenWeChatApplication({
openId: this.openId,
platformId: this.platformId,
organizationName: form.companyName
})
data.accountId = res.data.registerId
await organizationCertification(data)
} else { // /
await creditCodeAuthentication(data)
//
await updateTeamInfo({
id: uni.getStorageSync('teamId'),
classificationName: form.companyName
})
}
uni.hideLoading()
this.publicNotice()
} catch(e) {
setTimeout(() => {
uni.hideLoading()
}, 1500)
this.submiting = false
}
},
}
}
</script>
<style scoped lang="scss">
.page {
padding-bottom: 170rpx;
-webkit-overflow-scrolling: touch;
}
.avatar {
width: 80rpx;
height: 80rpx;
border: 0;
border-radius: 50%;
}
.block {
padding: 24rpx;
}
.title {
margin-bottom: 20rpx;
font-size: 28rpx;
}
.credential {
width: 100%;
}
.form-list {
.name {
min-width: 250rpx;
}
}
</style>

@ -5,15 +5,10 @@
<image class="icon" src="https://eduvessel.com/images/occupationlab/user.svg" mode="widthFix"></image> 账号信息 <image class="icon" src="https://eduvessel.com/images/occupationlab/user.svg" mode="widthFix"></image> 账号信息
</view> </view>
<view class="form-list"> <view class="form-list">
<view class="line"> <button class="avatar-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<view class="name"> <image class="avatar" :src="hrUserInfo.avatar" mode=""></image>
<button class="avatar-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image class="avatar" :src="hrUserInfo.avatar" mode=""></image>
</button>
</view>
<view class="val">修改头像</view> <view class="val">修改头像</view>
<uni-icons class="arrow" type="right" size="18" color="#ababab"></uni-icons> </button>
</view>
<view class="line"> <view class="line">
<view class="name">学号</view> <view class="name">学号</view>
<view class="val">{{ userAccount.workNumber }}</view> <view class="val">{{ userAccount.workNumber }}</view>
@ -120,9 +115,9 @@
</view> </view>
</view> </view>
<view class="fold" v-if="archivesList.length > 1"> <view class="fold" v-if="archivesList.length > 1">
<view :class="{ active: showArch }" @click="showArch = !showArch"> <view :class="['fold-inner', { active: showArch }]" @click="showArch = !showArch">
展开更多 展开更多
<uni-icons class="plus" type="bottom" size="20" color="#007EFF"></uni-icons> <uni-icons class="icon" type="bottom" size="20" color="#007EFF"></uni-icons>
</view> </view>
</view> </view>
</view> </view>
@ -494,18 +489,25 @@
padding-bottom: 130rpx; padding-bottom: 130rpx;
} }
.avatar-btn { .avatar-btn {
display: inline-block; display: flex;
padding: 0; align-items: center;
margin: 0 28rpx 0 0; padding: 14rpx 0;
line-height: 0; line-height: 0;
border: 0 !important; text-align: left;
border: 0;
border-bottom: 1px solid #E6E8ED;
background-color: transparent; background-color: transparent;
border-radius: 0;
outline: none; outline: none;
border-radius: 50%; &:after {
display: none;
}
.avatar { .avatar {
width: 50rpx; width: 60rpx;
height: 50rpx; height: 60rpx;
margin-right: 20rpx;
border: 0; border: 0;
border-radius: 50%;
} }
} }
.arch-title { .arch-title {
@ -533,12 +535,14 @@
font-size: 24rpx; font-size: 24rpx;
color: #006EFF; color: #006EFF;
span { .fold-inner {
cursor: pointer; display: flex;
i { justify-content: center;
align-items: center;
.icon {
transition: .5s; transition: .5s;
} }
&.active i { &.active .icon {
transform: rotate(180deg); transform: rotate(180deg);
} }
} }

@ -1,281 +0,0 @@
<template>
<view>
<view :class="[{'not-auth': !per}]">
<view class="filter">
<uni-search-bar class="search" radius="30" placeholder="请输入方案名称" clearButton="auto" cancelButton="none" v-model="keyword" />
</view>
<ul class="tab">
<li v-for="(tab, i) in classifications.slice(0, 4)" :class="{active: active === tab.id}" @click="tabChange(tab)">{{ tab.classificationName }}</li>
<uni-icons class="icon" custom-prefix="iconfont" type="icon-filter" size="22" color="#007eff" @click="typeVisible = true"></uni-icons>
</ul>
<view v-if="list.length" class="list">
<view v-for="(item, i) in list" class="item" @click="toDetail(item)">
<view class="c-name ell">{{ item.title }}</view>
<view class="content">
<view class="info">
<view class="line">
<view class="name">产品</view>
<view class="val ell-wrap">
<view v-if="!item.toggle" class="product ell">{{ item.productNames }}</view>
<view v-else class="product" v-html="item.productNamesHtml"></view>
<view v-if="item.productNames && item.productNames.length > 14" class="toggle" @click.stop="toggle(item)">{{ item.toggle ? '收起' : '展开' }}</view>
</view>
</view>
<view class="line">
<view class="name">更新日期</view>
<view class="val">{{ item.updateTime }}</view>
</view>
<view class="line">
<view class="name">适用专业</view>
<view class="val">{{ item.applicableMajor }}</view>
</view>
</view>
<!-- <view class="detail" @click.stop="toEmail(i)">下载</view> -->
</view>
</view>
</view>
<empty v-else></empty>
<view :class="['type-popup', {active: typeVisible}]">
<uni-icons class="close" type="closeempty" size="20" color="#757575" @click="closeType"></uni-icons>
<view class="title">所属分类</view>
<view class="types">
<view v-for="(item, i) in classifications" :key="i" :class="['item', {active: active == item.id}]" @click="classificationClick(item)">{{ item.classificationName }}</view>
</view>
</view>
</view>
<notAuth v-if="!per"></notAuth>
</view>
</template>
<script>
import { schemeList, queryClassificationByType } from '@/apis/modules/article.js'
export default {
data() {
return {
per: true, //
active: '',
typeVisible: false,
classifications: [],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
articleNameSort: 'desc',
keyword: '',
list: [],
page: 1,
pageSize: 10,
}
},
watch: {
keyword () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initList()
}, 500)
}
},
//
onPullDownRefresh() {
this.initList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
//
onReachBottom() {
if (this.reachBottom >= 0) {
this.reachBottom = 1
this.status = 'loading'
this.getList()
}
},
onShow() {
this.per = true
this.keyword = ''
this.active = ''
this.initRole()
},
methods: {
//
initRole() {
const auth = uni.getStorageSync('auth')
if (!auth.includes('工作台:方案')) {
this.per = false
this.list = [
{
title: '智信云',
productNames: '智信云师资培训班',
applicableMajor: 'python实训系统',
updateTime: '2023-08-08'
},
{
title: '智信云',
productNames: '智信云师资培训班智信云师资培训班',
applicableMajor: 'python实训系统',
updateTime: '2023-08-08'
},
{
title: '智信云智信云',
productNames: '智信云师资培训班智信云师资培训班',
applicableMajor: 'python实训系统',
updateTime: '2023-08-08'
},
{
title: '智信云',
productNames: '智信云师资培训班智信云师资培训班',
applicableMajor: 'python实训系统实训系统',
updateTime: '2023-08-08'
},
]
} else {
this.initList()
this.getClassification()
}
},
getList() {
uni.showLoading({
title: '加载中'
})
schemeList({
keyWord: this.keyword,
pageNum: this.page,
pageSize: this.pageSize,
querySource: 4,
classificationId: this.active
}).then(({ data }) => {
uni.hideLoading()
// list
const list = data.records
list.forEach(e => {
if (e.productNames) {
e.toggle = e.productNames.length < 14 // 14
e.productNamesHtml = e.productNames.split(',').join('<br>')
}
})
this.list = this.reachBottom > 0 ? [...this.list, ...list] : list
this.page++ // page+1
const noMore = this.list.length === data.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
}).catch(e => {
uni.hideLoading()
})
},
initList() {
this.page = 1
this.reachBottom = 0
this.getList()
},
//
getClassification() {
queryClassificationByType(3).then(({ data }) => {
this.classifications = [
{
id: '',
classificationName: '不限'
}
]
this.classifications.push(...data)
}).catch(e => {})
},
//
classificationClick(item, query) {
this.active = item.id
query && this.initList()
},
//
closeType() {
this.typeVisible = false
this.initList()
},
// tab
tabChange(tab) {
this.active = tab.id
this.initList()
},
//
toDetail(item) {
this.$util.to(`/team/scheme/scheme?id=` + item.id)
},
//
toEmail(id) {
this.$util.to(`../send/send?id=${id}`)
},
//
toggle(item) {
item.toggle = !item.toggle
}
}
}
</script>
<style scoped lang="scss">
.tab {
position: relative;
justify-content: flex-start;
li {
padding: 0 30rpx;
}
.icon {
position: absolute;
top: 32rpx;
right: 44rpx;
}
}
.list {
background-color: #fff;
.item {
padding: 20rpx 40rpx;
border-bottom: 1px solid #f1f1f1;
}
.c-name {
font-size: 30rpx;
color: #333;
}
.line {
display: flex;
padding: 10rpx 0;
}
.content {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20rpx;
}
.name {
width: 140rpx;
margin-right: 10rpx;
white-space: nowrap;
font-size: 28rpx;
color: #999;
}
.val {
font-size: 28rpx;
color: #333;
}
.product {
max-width: 67vw;
white-space: pre-wrap;
&.ell {
white-space: nowrap;
}
}
.toggle {
margin-top: 10rpx;
white-space: nowrap;
font-size: 24rpx;
color: #0e92ef;
}
.detail {
margin-left: 20rpx;
font-size: 26rpx;
color: #1f83ff;
white-space: nowrap;
}
}
</style>

@ -1,168 +0,0 @@
<template>
<view class="page">
<view class="wrap">
<view class="inner">
<view class="info">
<image class="avatar" :src="avatar" mode=""></image>
<view class="text">
<view class="invite">
<text class="name">{{ my.info.userName }}</text> 邀请你加入城市合伙人计划
</view>
</view>
</view>
<view class="com">{{ team.partnerClassificationName }}</view>
<u-qrcode v-if="link" class="qrcode" ref="qrcode" canvas-id="qrcode" isQueueLoadImage :size="size" :value="link" @complete="qrcodeComplete"></u-qrcode>
<image class="qrcode-img" :src="qrcodeImg" show-menu-by-longpress @click="previewImage"></image>
<view class="tips" style="margin-top: 20rpx;">扫一扫加入我们吧</view>
<view class="tips">长按可转发至微信好友和保存图片</view>
</view>
<view class="warn">邀请二维码失效日期{{ expireTime }}</view>
</view>
</view>
</template>
<script>
import { generateInvitationCode, my } from '@/apis/modules/parner.js'
export default {
data() {
return {
avatar: uni.getStorageSync('avatar') || '@/static/image/avatar.png',
my: {
info: {},
},
expireTime: '',
qrcode: '',
link: '',
qrcodeImg: '',
size: uni.upx2px(420),
team: uni.getStorageSync('team')
}
},
onShow() {
this.getInfo()
},
methods: {
//
getInfo() {
const team = uni.getStorageSync('team')
my({
partnerId: team.partnerId,
teamId: team.teamId
}).then(({ my }) => {
this.my = my
this.$nextTick(() => {
this.getQrcode()
})
}).catch(e => {})
},
//
getQrcode() {
const { team } = this
//
generateInvitationCode(uni.getStorageSync('team').accountId).then(({ expireTime }) => {
const date = new Date(Date.now() + expireTime * 1000) // *1000
this.expireTime = `${date.getFullYear()}-${this.$util.preZero(date.getMonth() + 1)}-${this.$util.preZero(date.getDate())} ${this.$util.preZero(date.getHours())}:${this.$util.preZero(date.getMinutes())}:${this.$util.preZero(date.getMinutes())}`
this.link = `https://www.occupationlab.com/#/join?accountId=${team.accountId}&id=${team.teamId}&isTeam=0&teamName=${this.my.info.userName}&provinceId=${uni.getStorageSync('provinceId')}&cityId=${uni.getStorageSync('cityId')}`
// this.link = `http://121.37.12.51/backstage/#/join?accountId=${team.accountId}&id=${team.teamId}&isTeam=0&teamName=${this.my.info.userName}&provinceId=${uni.getStorageSync('provinceId')}&cityId=${uni.getStorageSync('cityId')}`
}).catch(e => {})
},
// imageimage
qrcodeComplete() {
console.log('complete', this.$refs.qrcode.toTempFilePath, this.link)
this.$refs.qrcode.toTempFilePath({
success: res => {
this.qrcodeImg = res.tempFilePath
},
fail: res => {
console.log('fail', res)
}
});
},
previewImage(e){
uni.previewImage({
// urls
urls: [e.target.src],
// /
current: e.target.src,
//
indicator:'default',
//
loop:false,
//
// longPressActions:{
// itemList:[this.l(''),this.l]
// },
success: res => {
console.log('previewImage res', res);
},
fail: err => {}
})
},
}
}
</script>
<style scoped lang="scss">
.page {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
overflow: hidden;
}
.wrap {
padding-bottom: 40rpx;
text-align: center;
background-color: #fff;
.inner {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 40rpx 80rpx 0;
}
.info {
display: flex;
align-items: center;
margin-bottom: 40rpx;
text-align: left;
}
.avatar {
width: 80rpx;
height: 80rpx;
margin-right: 20rpx;
border-radius: 50%;
}
.invite {
font-size: 26rpx;
}
.name {
margin-right: 5rpx;
font-size: 30rpx;
color: $uni-primary;
}
.com {
margin: 20rpx 0;
font-size: 30rpx;
}
.qrcode {
display: none;
}
.qrcode-img {
width: 420rpx;
height: 420rpx;
}
.tips {
margin-bottom: 10rpx;
font-size: 24rpx;
color: #333;
}
.warn {
margin-top: 10rpx;
font-size: 24rpx;
color: #f00;
}
}
</style>

@ -1,116 +0,0 @@
<template>
<view class="wrap">
<view class="title">{{ form.title }}</view>
<view class="text">{{ form.applicableMajor }}</view>
<view class="text">{{ form.schemeIntroduction }}</view>
<view class="text" v-html="form.product"></view>
<template v-if="form.fileName">
<view class="file">{{ form.fileName }}</view>
<view class="detail" @click.stop="download">下载</view>
</template>
</view>
</template>
<script>
import { schemeFindById } from '@/apis/modules/article.js'
export default {
data() {
return {
id: '',
form: {
totalBrowsing: ''
}
}
},
onShow() {
const pages = getCurrentPages()
const { options } = pages[pages.length - 1]
this.id = options.id
this.getInfo()
},
methods: {
//
getInfo() {
uni.showLoading({
title: '加载中'
})
schemeFindById(this.id).then(({ data }) => {
if (data.productList) data.product = data.productList.map(e => e.productName).join('<br>')
this.form = data
uni.hideLoading()
}).catch(e => {
uni.hideLoading()
})
},
//
download() {
uni.setStorageSync('files', {
copyWriting: this.form.title,
fileName: [this.form.fileName],
urls: [this.form.schemeFile]
})
this.$util.to(`/team/send/send`)
// uni.showLoading({
// title: '',
// mask: true
// })
// const url = this.form.schemeFile
// const that = this
// //
// uni.downloadFile({
// url,
// success: function(res) {
// console.log(444, res)
// uni.saveFile({
// tempFilePath: res.tempFilePath,
// success: function(res) {
// console.log(555, res)
// // doc, xls, ppt, pdf, docx, xlsx, pptx
// that.$util.isDoc(url.substring(url.lastIndexOf('.') +1)) && uni.openDocument({
// filePath: res.savedFilePath,
// showMenu: true, //
// success: res => {
// uni.hideLoading()
// },
// fail: openError => {
// uni.hideLoading()
// }
// })
// }
// })
// },
// fail: function(err) {
// uni.hideLoading()
// }
// })
}
}
}
</script>
<style scoped lang="scss">
.wrap {
padding: 30rpx;
background-color: #fff;
}
.title {
font-size: 34rpx;
font-weight: 600;
color: #333;
}
.text {
margin: 20rpx 0;
font-size: 28rpx;
line-height: 1.6;
}
.file {
margin: 20rpx 0;
font-size: 26rpx;
word-break: break-all;
}
.detail {
font-size: 30rpx;
color: #1f83ff;
}
</style>

@ -1,92 +0,0 @@
<template>
<view>
<uni-list>
<uni-list-item :show-extra-icon="true" showArrow :extra-icon="phoneIcon" title="手机号" :rightText="info.phone" clickable @click="toPage('../phone/phone')" />
<uni-list-item :show-extra-icon="true" showArrow :extra-icon="mailIcon" title="邮箱" :rightText="info.email" clickable @click="toPage('../email/email')" />
<uni-list-item :show-extra-icon="true" showArrow :extra-icon="accountIcon" title="账号" :rightText="info.account" clickable @click="toPage('../account/account')" />
<uni-list-item :show-extra-icon="true" showArrow :extra-icon="pwdIcon" title="密码" rightText="******" clickable @click="toPage('../password/password')" />
</uni-list>
<view class="logout" @click="logout">退出登录</view>
</view>
</template>
<script>
import { my } from '@/apis/modules/parner.js'
export default {
data() {
return {
phoneIcon: {
color: '#007eff',
size: '22',
type: 'phone'
},
mailIcon: {
color: '#007eff',
size: '22',
type: 'email'
},
accountIcon: {
color: '#007eff',
size: '22',
type: 'person'
},
pwdIcon: {
color: '#007eff',
size: '22',
type: 'locked'
},
info: {
account: '',
phone: '',
email: ''
},
}
},
onShow() {
this.getInfo()
},
methods: {
//
getInfo() {
const { partnerId, teamId } = uni.getStorageSync('team')
my({
partnerId,
teamId
}).then(({ my }) => {
this.info = my.info
}).catch(e => {})
},
toPage(path) {
this.$util.to(path)
},
// 退
logout() {
const that = this
uni.showModal({
title: '提示',
content: '确定要退出账号吗?',
success(res) {
if (res.confirm) {
uni.clearStorageSync()
uni.reLaunch({
url: '/pages/index/index'
})
}
}
})
}
}
}
</script>
<style scoped lang="scss">
.logout {
padding: 30rpx 0;
margin-top: 30rpx;
font-size: 28rpx;
color: #333;
text-align: center;
background-color: #fff;
}
</style>

@ -1,289 +0,0 @@
<template>
<view>
<view class="search-wrap">
<image class="bg" src="@/static/image/study-bg.jpg"></image>
<view class="info">
<view class="text">销售必备技能</view>
<uni-search-bar class="search" radius="30" placeholder="请输入文章名称,标签" v-model="keyword" clearButton="auto" cancelButton="none" bgColor="#fff" />
</view>
</view>
<view class="type">
<view v-for="(item, i) in classifications.slice(0, 4)" :key="i" :class="['item', {active: active == item.id}]" @click="classificationClick(item, 1)">{{ item.classificationName }}</view>
<uni-icons class="icon" custom-prefix="iconfont" type="icon-filter" size="22" color="#007eff" @click="typeVisible = true"></uni-icons>
</view>
<template v-if="list.length">
<view class="list">
<view v-for="(item, i) in list" :key="i" class="item" @click="toDetail(item)">
<image class="pic" :src="item.bannerImg"></image>
<view class="right">
<view class="title ell">{{ item.title }}</view>
<view v-if="item.labelName" class="labels">
<view v-for="(label, j) in item.labelName.split(',').slice(0, 2)" :key="j" class="label">{{ label }}</view>
</view>
<view class="metas">
<view class="meta">
<uni-icons class="icon" type="eye" size="22" color="#007FFF"></uni-icons>
{{ item.learnerNumber }}人学过
</view>
<view class="meta" @click.stop="collect(item)">
<uni-icons class="icon" :type="item.collectionStatus ? 'star-filled' : 'star'" size="22" color="#007eff"></uni-icons>
{{ item.collectionNumber }}
</view>
</view>
<view v-if="item.lastReading" class="last">上次阅读</view>
</view>
</view>
</view>
<uni-load-more :status="status" />
</template>
<empty v-else></empty>
<view :class="['type-popup', {active: typeVisible}]">
<uni-icons class="close" type="closeempty" size="20" color="#757575" @click="closeType"></uni-icons>
<view class="title">所属分类</view>
<view class="types">
<view v-for="(item, i) in classifications" :key="i" :class="['item', {active: active == item.id}]" @click="classificationClick(item)">{{ item.classificationName }}</view>
</view>
</view>
</view>
</template>
<script>
import { partnerOperatingList, queryClassificationByType, collectCourse } from '@/apis/modules/article.js'
export default {
data() {
return {
classifications: [],
active: '',
typeVisible: false,
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
articleNameSort: '',
keyword: '',
list: [],
page: 1,
pageSize: 10,
}
},
watch: {
keyword () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initList()
}, 500)
}
},
//
onPullDownRefresh() {
this.initList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
//
onReachBottom() {
if (this.reachBottom >= 0) {
this.reachBottom = 1
this.status = 'loading'
this.getList()
}
},
onShow() {
this.keyword = ''
this.active = ''
this.typeVisible = false
this.initRole()
},
methods: {
//
initRole() {
if (!uni.getStorageSync('auth').includes('学习')) {
this.per = false
}
this.initList()
this.getClassification()
},
getList() {
const data = {
keyWord: this.keyword,
pageNum: this.page,
pageSize: this.pageSize,
querySource: 4,
typeId: 1,
articleNameSort: this.articleNameSort,
classificationId: this.active
}
uni.showLoading({
title: '加载中'
})
partnerOperatingList(data).then(({ page, total }) => {
uni.hideLoading()
// list
const list = page
this.list = this.reachBottom > 0 ? [...this.list, ...list] : list
this.page++ // page+1
const noMore = this.list.length === total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
}).catch(e => {
uni.hideLoading()
})
},
initList() {
this.page = 1
this.reachBottom = 0
this.getList()
},
//
getClassification() {
queryClassificationByType(1).then(({ data }) => {
this.classifications = [
{
id: '',
classificationName: '不限'
}
]
this.classifications.push(...data)
}).catch(e => {})
},
//
classificationClick(item, query) {
this.active = item.id
query && this.initList()
},
//
closeType() {
this.typeVisible = false
this.initList()
},
//
toggle(item) {
item.toggle = !item.toggle
},
//
switchSort() {
this.articleNameSort = this.articleNameSort === 'desc' ? 'asc' : 'desc'
this.initList()
},
//
collect(item) {
const state = item.collectionStatus ? 0 : 1
collectCourse(item.id, state).then(({ data }) => {
item.collectionStatus = state
state ? ++item.collectionNumber : --item.collectionNumber
}).catch(e => {})
},
//
toDetail(item) {
this.$util.to(`/team/article/article?id=` + item.id)
},
}
}
</script>
<style scoped lang="scss">
.search-wrap {
position: relative;
height: 300rpx;
padding: 120rpx 10px 0;
.bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.info {
position: relative;
}
.text {
margin: 0 10px 10rpx;
font-size: 50rpx;
color: #fff;
}
}
.type {
position: relative;
display: flex;
padding: 30rpx;
background-color: #fff;
.item {
padding: 0 15rpx;
line-height: 1.6;
font-size: 28rpx;
color: #333;
white-space: nowrap;
&.active {
color: #007FFF;
font-weight: 600;
}
}
.icon {
position: absolute;
right: 40rpx;
width: 40rpx;
}
}
.list {
background-color: #fff;
.item {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
padding: 20rpx 40rpx;
border-bottom: 1px solid #f1f1f1;
}
.pic {
width: 260rpx;
height: 180rpx;
border-radius: 8px;
}
.right {
width: calc(100% - 280rpx);
}
.title {
margin-bottom: 15rpx;
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.labels {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.label {
padding: 2px 6px;
margin: 0 20rpx 15rpx 0;
font-size: 24rpx;
color: #fff;
background-color: #ccc;
border-radius: 4px;
}
.metas {
display: flex;
align-items: center;
}
.meta {
display: inline-flex;
align-items: center;
margin-right: 20rpx;
font-size: 24rpx;
}
.icon {
margin-right: 5rpx;
}
.last {
position: absolute;
bottom: 20rpx;
right: 40rpx;
font-size: 28rpx;
color: #007FFF;
}
}
</style>
Loading…
Cancel
Save