Compare commits

..

12 Commits

  1. 4
      .hbuilderx/launch.json
  2. 14
      apis/modules/article.js
  3. 4
      apis/modules/order.js
  4. 8
      apis/modules/parner.js
  5. 44
      apis/modules/product.js
  6. 4
      apis/modules/user.js
  7. 43
      apis/request.js
  8. 4
      config/request.js
  9. 28
      libs/util.js
  10. 214
      order/addCourse/addCourse.vue
  11. 37
      order/clientDetail/clientDetail.vue
  12. 2
      order/clients/clients.vue
  13. 8
      order/curClient/curClient.vue
  14. 247
      order/editCourse/editCourse.vue
  15. 736
      order/orderDetail/orderDetail.vue
  16. 55
      order/ordered/ordered.vue
  17. 13
      order/orders/orders.vue
  18. 108
      order/products/products.vue
  19. 331
      pages.json
  20. 8
      pages/index/index.vue
  21. 6
      pages/login/login.vue
  22. 2
      pages/person/person.vue
  23. 199
      pages/plans/plans.vue
  24. 8
      pages/teams/teams.vue
  25. BIN
      static/image/edit.png
  26. BIN
      static/image/unfold.png
  27. 8
      styles/common.scss
  28. 0
      team/account/account.vue
  29. 0
      team/addStaff/addStaff.vue
  30. 0
      team/editTeam/editTeam.vue
  31. 0
      team/email/email.vue
  32. 0
      team/password/password.vue
  33. 0
      team/phone/phone.vue
  34. 272
      team/plans/plans.vue
  35. 0
      team/qrcode/qrcode.vue
  36. 83
      team/scheme/scheme.vue
  37. 22
      team/send/send.vue
  38. 2
      team/setting/setting.vue
  39. 2
      team/teamDetail/teamDetail.vue
  40. 10
      uni_modules/uni-tooltip/changelog.md
  41. 70
      uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue
  42. 83
      uni_modules/uni-tooltip/package.json
  43. 8
      uni_modules/uni-tooltip/readme.md

@ -6,6 +6,10 @@
{
"launchtype" : "local"
},
"h5" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"

@ -0,0 +1,14 @@
import request from '@/apis/request.js'
const { get, post } = request
export const queryClassificationByType = id => {
return post('nakadai/nakadai/partner/article/classification/queryClassificationByType?typeId=' + id)
}
export const schemeList = data => {
return post('nakadai/nakadai/partner/schemeManagement/schemeList', data)
}
export const schemeFindById = id => {
return post('nakadai/nakadai/partner/schemeManagement/findById?id=' + id)
}

@ -48,3 +48,7 @@ export const publicConfiguration = (data) => {
export const bulkShipping = (data) => {
return post('nakadai/nakadai/orderOther/bulkShipping', data)
}
export const queryCitySettlementPrice = (mallId, provinceId, cityId) => {
return post(`nakadai/mallPrice/queryCitySettlementPrice?mallId=${mallId}&provinceId=${provinceId}&cityId=${cityId}`)
}

@ -40,3 +40,11 @@ export const queryTeamMembers = (data) => {
export const updatePartner = (data) => {
return post('nakadai/nakadai/partnerClassification/update', data)
}
export const editProvinceCity = data => {
return post(`nakadai/nakadai/partner-team/editProvinceCity`, data)
}
export const getPartnerTeamRates = data => {
return post(`nakadai/nakadai/partner-team/getPartnerTeamRates`, data)
}

@ -4,3 +4,47 @@ const { get, post } = request
export const AppletsDataProductList = (data) => {
return post('nakadai/nakadai/dataProduct/AppletsDataProductList', data)
}
export const tagsList = () => {
return get('nakadai/tags/tagsList')
}
export const listOfGoods = (data) => {
return post('nakadai/mall/listOfGoods', data)
}
export const detailsOfGoods = (id) => {
return get('nakadai/mall/detailsOfGoods?mallId=' + id)
}
export const productCategoryList = () => {
return get('nakadai/productClassification/productCategoryList')
}
export const productTypeList = () => {
return get('nakadai/productType/productTypeList')
}
export const addToShoppingCart = (data) => {
return post('nakadai/mini/program/shopping/cart/addToShoppingCart', data)
}
export const delCart = (data) => {
return post('nakadai/mini/program/shopping/cart/batchDeletion', data)
}
export const shoppingCartList = (data) => {
return post('nakadai/mini/program/shopping/cart/shoppingCartList', data)
}
export const courseDiscipline = () => {
return get('nakadai/nakadai/subject/courseDiscipline')
}
export const courseProfessionalClass = id => {
return get('nakadai/nakadai/subject/courseProfessionalClass?disciplineId=' + id)
}
export const courseProfessional = id => {
return get('nakadai/nakadai/subject/courseProfessional?professionalClassId=' + id)
}

@ -9,6 +9,10 @@ export const userBinding = (data) => {
return post('users/users/user/userBinding', data)
}
export const sendPhoneOrEmailCode = (data) => {
return post('users/users/userAccount/sendPhoneOrEmailCode', data)
}
export const queryProvince = () => {
return get('nakadai/nakadai/province/queryProvince')
}

@ -1,16 +1,7 @@
import config from '@/config/request'
let HTTP_COUNT = 0 // loading次数
let logouted = 0
const request = options => {
HTTP_COUNT++
if (config.showLoading) {
// 请求数据时的loading
// uni.showToast({
// title: '加载中',
// duration: 200,
// icon: 'loading'
// })
}
const header = Object.assign({}, config.headers, {
token: uni.getStorageSync('token')
})
@ -29,18 +20,22 @@ const request = options => {
if (status === 200) {
resolve(data)
} else if (status == 401) {
// 登录过期
uni.clearStorageSync()
uni.showToast({
title: message,
icon: 'none'
})
setTimeout(() => {
uni.navigateTo({
url: '../login/login'
if (!logouted) {
// 登录过期
uni.clearStorageSync()
uni.showToast({
title: message,
icon: 'none'
})
}, 1500)
reject(data)
setTimeout(() => {
logouted = 0
uni.reLaunch({
url: '/pages/index/index'
})
}, 1500)
reject(data)
logouted = 1
}
} else if (!status) {
resolve(data)
} else {
@ -58,12 +53,6 @@ const request = options => {
})
reject(err)
},
complete: () => {
if (config.showLoading) {
// HTTP_COUNT--
// HTTP_COUNT || uni.hideLoading()
}
}
})
})
}

@ -5,8 +5,8 @@
*/
export default {
baseURL: 'https://huorantech.cn/',
// baseURL: 'http://192.168.31.151:9000/',
baseURL: 'https://www.occupationlab.com/',
// baseURL: 'http://192.168.31.51:9000/',
// baseURL: 'http://121.37.12.51/',
headers: {
'Content-Type': 'application/json;charset=UTF-8'

@ -1,11 +1,11 @@
import Product from '@/config/product'
const files = [
'https://huorantech.cn/%E7%94%A8%E6%88%B7%E6%9C%8D%E5%8A%A1%E5%8D%8F%E8%AE%AE.docx', // 用户服务协议
'https://huorantech.cn/%E7%94%A8%E6%88%B7%E9%9A%90%E7%A7%81%E5%8D%8F%E8%AE%AE.docx', // 用户隐私协议
'https://huorantech.cn/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD%E5%AE%9E%E9%AA%8C%E5%AE%A4%E5%BB%BA%E8%AE%BE%E6%96%B9%E6%A1%88-2020.1.docx', // 人工智能
'https://huorantech.cn/%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%AE%A1%E7%90%86%E4%B8%8E%E5%BA%94%E7%94%A8%E4%B8%93%E4%B8%9A%E5%BB%BA%E8%AE%BE%E6%96%B9%E6%A1%88.docx', // 大数据
'https://huorantech.cn/%E9%87%91%E8%9E%8D%E7%A7%91%E6%8A%80%E5%AE%9E%E9%AA%8C%E5%AE%A4%E5%BB%BA%E8%AE%BE%E6%96%B9%E6%A1%88V2.0.docx', // 金融科技
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798714897.docx', // 用户服务协议
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798737175.docx', // 用户隐私协议
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798668435.docx', // 人工智能
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798621083.docx', // 大数据
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798646462.docx', // 金融科技
]
export default {
// 路由跳转
@ -67,9 +67,9 @@ export default {
getBmName(val) {
return uni.getStorageSync('team').partnerClassificationName
},
// 返回图标。如果有图标,则直接返回,否则判断是否是数据产品,即productType=2,如果是,则取数据图标,否则则显示通用图标,这两个图标都在config/product.js里有配置
// 返回图标。如果有图标,则直接返回
getIcon(e) {
return e.miniProgramPictureAddress || (e.productType === 2 ? Product.dataIcon : Product.normalIcon)
return e.appletIcon || Product.normalIcon
},
// 预览文档
openFile(id) {
@ -103,5 +103,17 @@ export default {
uni.hideLoading()
}
})
}
},
// 产品管理的产品分类(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标签
removeTag(str) {
return str.replace(/(<[^>]+>)|((&nbsp;)+)/g , '')
},
}

@ -4,15 +4,21 @@
<uni-search-bar class="search" radius="5" placeholder="请输入产品名称" clearButton="auto" cancelButton="none" v-model="keyword" />
</uni-card>
<ul class="tab">
<li v-for="(tab, i) in tabs" :class="{active: curTab === tab.id}" @click="tabChange(tab)">{{ tab.name }}</li>
<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">
<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)" mode="widthFix"></image>
<image class="icon" :src="$util.getIcon(item)"></image>
{{ item.productName }}
</li>
</ul>
@ -26,32 +32,19 @@
</template>
<script>
import { AppletsDataProductList } from '@/apis/modules/product.js'
import { renew } from '@/apis/modules/order.js'
import { productCategoryList, 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: '',
teamId: '',
curTab: '',
tabs: [
{
name: '全部',
id: ''
},
{
name: '实训课程',
id: 1
},
{
name: '理论课程',
id: 0
},
{
name: '数据产品',
id: 2
}
],
tabs: [],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
@ -105,22 +98,38 @@
const { options } = pages[pages.length - 1]
this.orderType = options.orderType
this.customerId = options.customerId
this.provinceId = options.provinceId
this.cityId = options.cityId
this.teamId = options.teamId
this.getTypes()
this.getList()
},
methods: {
//
getTypes() {
productCategoryList().then(res => {
res.classificationList.forEach(e => {
e.id = e.classificationId
e.name = e.classificationName
})
this.tabs.push(...res.classificationList)
}).catch(e => {})
},
//
getList() {
uni.showLoading({
title: '加载中'
})
AppletsDataProductList({
sort: 'desc',
keywords: this.keyword,
productType: this.curTab,
listOfGoods({
pageNum: this.page,
pageSize: this.pageSize
}).then(({ data }) => {
const { records } = data
pageSize: this.pageSize,
sort: 0,
isShelves: 0,
hotTag: 1,
productName: this.keyword,
productClassification: this.curTab,
}).then(({ page }) => {
const { records } = page
const list = this.courses
const all = this.checkAll.length //
const pageChange = this.reachBottom > 0 //
@ -131,9 +140,9 @@
text: '',
value: 1
}
e.check = (all && pageChange) || checked.find(n => n.id === e.id && n.productType === e.productType) ? 1 : 0
e.check = (all && pageChange) || checked.find(n => n.mallId === e.mallId) ? 1 : 0
//
if (list.find(n => n.dataOrCourseId == e.id && n.productType == e.productType)) {
if (list.find(n => n.mallId == e.mallId)) {
//
checkData.disable = true
e.check = 1
@ -144,7 +153,7 @@
// list
this.list = pageChange ? [...this.list, ...records] : records
this.page++ // page+1
const noMore = this.list.length === data.total //
const noMore = this.list.length === page.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
uni.hideLoading()
@ -158,16 +167,16 @@
this.getList()
},
// tab
tabChange(tab) {
this.curTab = tab.id
tabChange(id) {
this.curTab = id
this.initList()
},
//
checkChange(e, i) {
const { checked } = this
const item = this.list[i]
const { id, productType } = item
const include = checked.findIndex(e => e.id === id && e.productType === productType)
const { mallId } = item
const include = checked.findIndex(e => e.mallId === mallId)
// pushpush
if (e.detail.value.length) {
include === -1 && checked.push(item)
@ -185,8 +194,8 @@
const { checked, list } = this
list.map(e => {
e.check = isCheck ? 1 : 0
const { id, productType } = e
const include = checked.findIndex(n => n.id === id && n.productType === productType)
const { mallId } = e
const include = checked.findIndex(n => n.mallId === mallId)
// pushpush
if (isCheck) {
include === -1 && checked.push(e)
@ -196,35 +205,37 @@
}
})
},
//
createParam(e) {
createParam(e, authority) {
const { orderType } = this
const trial = orderType == 2 //
return {
dataOrCourseId: e.id, // id
dataOrCourseId: e.associatedProduct, // id
mallId: e.mallId,
productName: e.productName, //
typeName: e.typeName, //
periodOfUse: '', // 使
startTime: this.$util.formatDate(new Date(), 'yyyy-MM-dd'), //
endTime: '', //
remainingPeriod: '', //
marketValue: '', //
marketPrice: e.marketPrice, //
marketPrice: e.marketUnitPrice, //
finalPrice: trial ? 0 : '', //
finalValue: trial ? 0 : '', //
discountRate: trial ? '0%' : '', //
accountNum: e.productType === 2 ? '' : 1, //
accountNum: authority ? 1 : '', //
totalAmount: '', //
isEnable: 1, // 10
isEnable: 0, // 10
ship: 0, // 01
authority: e.productType === 2 ? 0 : 1, // 01
productType: e.productType, // (0-> 1- 2 )
authority, // 01
options: 2,
miniProgramPictureAddress: e.miniProgramPictureAddress, //
miniProgramPictureAddress: e.appletIcon || '', //
settlementPrice: trial ? 0 : '', //
settlementMethod: e.settlementMethod, // 01
settlementPriceUnit: e.settlementPrice, //
businessProportion: e.businessProportion, //
serviceFee: 0 //
settlementPriceUnit: e.settlementPrice || 0, //
serviceFee: 0, //
mallNonAssociatedLinks: e.mallNonAssociatedLinks, //
typeName: e.typeName
}
},
//
@ -232,15 +243,14 @@
renew({
authority,
customerId,
productId
productId,
}).then(({ orderOthers }) => {
result.map(e => {
const item = orderOthers.find(n => n.dataOrCourseId == e.dataOrCourseId && n.authority == authority == e.authority)
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')
e.renew = 1
}
})
resolve()
@ -253,29 +263,70 @@
const list = this.checked //
if (list.length) {
const result = this.courses
const courseIds = []
const dataIds = []
console.log(123, result)
const list1 = [] //
const list0 = [] //
const list2 = [] //
const list3 = [] //
const list4 = [] //
const { customerId } = this
list.map(e => {
// id
if (!result.find(n => (n.dataOrCourseId == e.id || n.dataOrCourseId == e.dataOrCourseId) && ((n.authority && e.productType != 2) || (!n.authority && e.productType == 2)))) {
e.productType === 2 ? dataIds.push(e.id) : courseIds.push(e.id)
result.push(this.createParam(e))
}
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
}
console.log(44, e)
const classId = e.classificationId
const pid = +e.associatedProduct
const mallId = e.mallId
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()
}
}))
})
const promises = []
//
dataIds.length && promises.push(new Promise((resolve, reject) => {
this.handleRenew(0, customerId, dataIds, result, resolve, reject)
}))
courseIds.length && promises.push(new Promise((resolve, reject) => {
this.handleRenew(1, customerId, courseIds, result, resolve, reject)
}))
Promise.all(promises).then(_ => {
uni.setStorageSync('courses', result) //
uni.redirectTo({
url: `../editCourse/editCourse?customerId=${customerId}&orderType=${this.orderType}&action=add`
})
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(_ => {
uni.setStorageSync('courses', result) //
uni.redirectTo({
url: `../editCourse/editCourse?customerId=${customerId}&orderType=${this.orderType}&teamId=${this.teamId}`
})
})
})
} else {
this.$util.errMsg('请选择产品!')
@ -289,6 +340,16 @@
.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;
@ -302,7 +363,10 @@
}
.icon {
width: 80rpx;
min-width: 80rpx;
height: 80rpx;
margin: 0 20rpx;
border-radius: 4px;
}
}
/deep/.check {

@ -37,27 +37,37 @@
<view :class="['line req', {err: err === 'name'}]">
<view class="name">联系人姓名</view>
<view v-if="isDetail" class="val">{{ form.name }}</view>
<input v-else type="text" placeholder="请输入" v-model="form.name" @change="handleErr('name')">
<template v-else>
<input type="text" placeholder="请输入" v-model="form.name" @change="handleErr('name')">
</template>
</view>
<view :class="['line req', {err: err === 'phone'}]">
<view class="name">手机</view>
<view v-if="isDetail" class="val">{{ form.phone }}</view>
<input v-else type="number" maxlength="11" placeholder="请输入" v-model="form.phone" @change="handleErr('phone')">
<template v-else>
<input type="number" maxlength="11" placeholder="请输入" v-model="form.phone" @change="handleErr('phone')">
</template>
</view>
<view :class="['line req', {err: err === 'account'}]">
<view class="name">账号</view>
<view v-if="isDetail" class="val">{{ form.account }}</view>
<input v-else type="text" placeholder="请以院校首字母+admin的格式来设置" v-model="form.account" @change="handleErr('account')">
<template v-else>
<input type="text" placeholder="请以院校首字母+admin的格式来设置" v-model="form.account" @change="handleErr('account')">
</template>
</view>
<view class="line">
<view class="name">职务</view>
<view v-if="isDetail" class="val">{{ form.position }}</view>
<input v-else type="text" placeholder="请输入" v-model="form.position">
<template v-else>
<input type="text" placeholder="请输入" v-model="form.position">
</template>
</view>
<view class="line">
<view class="name">邮箱</view>
<view v-if="isDetail" class="val">{{ form.email }}</view>
<input v-else type="text" placeholder="请输入" v-model="form.email">
<template v-else>
<input type="text" placeholder="请输入" v-model="form.email">
</template>
</view>
<view v-if="customerId" class="line">
<view class="name">产品到期时间</view>
@ -71,7 +81,7 @@
</view>
<view v-if="isDetail" class="action">
<view class="item" @click="toPage(`../clientDetail/clientDetail?customerId=${customerId}`)">
<view class="item" v-if="auth('客户管理:编辑')" @click="toPage(`../clientDetail/clientDetail?customerId=${customerId}`)">
<uni-icons class="icon" custom-prefix="iconfont" type="icon-edit" size="30" color="#959595"></uni-icons>
<view class="text">编辑</view>
</view>
@ -79,7 +89,7 @@
<uni-icons class="icon" custom-prefix="iconfont" type="icon-product" size="30" color="#959595"></uni-icons>
<view class="text">已订阅产品</view>
</view>
<view class="item" @click="toPage(`/order/curClient/curClient?customerId=${customerId}&name=${form.customerName}`)">
<view v-if="auth('订单管理')" class="item" @click="toPage(`/order/curClient/curClient?customerId=${customerId}&name=${form.customerName}`)">
<uni-icons class="icon" custom-prefix="iconfont" type="icon-dingdan" size="30" color="#959595"></uni-icons>
<view class="text">订单</view>
</view>
@ -355,4 +365,17 @@
margin-right: 10rpx;
}
}
.form-list {
.edit {
margin-left: 10rpx;
}
}
.editIcon {
width: 50rpx;
height: 50rpx;
margin-left: 20rpx;
image{
width: 100%;height: 100%
}
}
</style>

@ -33,7 +33,7 @@
</template>
<empty v-else text="您当前暂无有下单的客户,请快去给客户下订单吧"></empty>
<uni-icons class="plus" type="plus-filled" size="60" color="#007eff" @click="$util.to('../clientDetail/clientDetail')"></uni-icons>
<uni-icons class="plus" v-if="auth('客户管理:新增')" 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>
</template>

@ -12,6 +12,7 @@
v-for="item in list"
:threshold="0"
:right-options="delOption"
:disabled="!auth('订单管理:删除')"
@click="del(item)"
>
<view class="item" @click="toDetail(item)">
@ -54,7 +55,7 @@
</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>
<uni-icons v-if="auth('订单管理:新建订单')" 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>
@ -133,6 +134,11 @@
this.customerId = options.customerId
this.customerName = options.name
this.initList()
//
try {
uni.removeStorageSync('courses')
uni.removeStorageSync('orderEdited')
} catch (e) {}
},
methods: {
getList() {

@ -1,74 +1,81 @@
<template>
<view class="page">
<template v-for="c in courses">
<view v-if="c.list.length" class="block">
<view v-if="c.list.length && c.list.filter(e => !e.edited).length" class="block">
<view class="l-title">{{ c.name }}</view>
<uni-icons class="arrow" type="top" size="20" color="#007EFF" @click="toggle(c)"></uni-icons>
<view v-show="!c.shrink">
<view v-for="(item, i) in c.list">
<view class="pro-name">
<view class="left">
<image class="icon" :src="$util.getIcon(item)" mode="widthFix"></image>
{{ item.productName }}
</view>
<uni-icons v-if="isAdd || isRenew" 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">{{ productTypes.find(e => e.id === item.productType).name }}</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="请输入" :disabled="isEdit" @input="calcDate(item, !item.authority)" @change="handleErr(item, 'periodOfUse')">
<view v-if="isEdit">{{ units.find(e => e.id === item.options).text }}</view>
<view v-else 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>
<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 v-if="isAdd || isRenew" class="del" type="trash" size="25" color="#ADADAD" @click="delCourse(c, i)"></uni-icons>
</view>
<view :class="['line req', {err: err === 'startTime' + item.dataOrCourseId + item.authority}]">
<view class="name">起止日期</view>
<view v-if="isEdit">{{ item.endTime ? item.startTime + ' - ' + item.endTime : item.startTime}}</view>
<uni-datetime-picker v-else type="date" v-model="item.startTime" :border="false" @change="calcDate(item)">
<view :class="['ph', {val: item.startTime}]">
{{ item.endTime ? item.startTime + ' - ' + item.endTime : item.startTime}}
<view class="form-list">
<view class="line">
<view class="name">产品类型</view>
<view class="val">{{ item.typeName }}</view>
</view>
<view :class="['line', {err: err === 'periodOfUse' + item.dataOrCourseId + item.authority}]">
<view class="name">使用期限</view>
<view class="period-wrap">
<input class="period" type="number" v-model="item.periodOfUse" placeholder="请输入" :disabled="isEdit" @input="calcDate(item, !item.authority)" @change="handleErr(item, 'periodOfUse')">
</view>
<view v-if="isEdit">{{ units.find(e => e.id === item.options).text }}</view>
<view v-else 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>
</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="inline">
<input type="number" v-model="item.settlementPrice" placeholder="请输入" @change="handleErr(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="请输入" :disabled="isEdit && !item.authority" @input="calcFinalValue(item)" @change="handleErr(item, 'finalPrice')">
<view :class="['line req', {err: err === 'startTime' + item.dataOrCourseId + item.authority}]">
<view class="name">起止日期</view>
<view v-if="isEdit">{{ item.endTime ? item.startTime + ' - ' + item.endTime : item.startTime}}</view>
<view v-else class="val unit">
<uni-datetime-picker type="date" v-model="item.startTime" :border="false" @change="calcDate(item)">
<view :class="['ph', {val: item.startTime}]">
{{ item.endTime ? item.startTime + ' - ' + item.endTime : item.startTime}}
</view>
</uni-datetime-picker>
<image class="icon" src="@/static/image/arrow-down.png" mode="widthFix"></image>
</view>
</view>
<view :class="['line req', {err: err === 'accountNum' + item.dataOrCourseId + item.authority}]">
<view class="name">数量</view>
<view v-if="item.authority" class="ph">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="ph">{{ item.marketValue }}</view>
</view>
<view class="line">
<view class="name">结算价</view>
<view class="inline">
<input type="number" v-model="item.settlementPrice" placeholder="请输入" @change="handleErr(item, 'settlementPrice')">
</view>
</view>
<view class="line">
<view class="name">折扣率</view>
<view class="ph">{{ item.discountRate }}</view>
</view>
<view class="line">
<view class="name">平台服务费</view>
<view class="ph">{{ 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="请输入" :disabled="isEdit && !item.authority" @input="calcFinalValue(item)" @change="handleErr(item, 'finalPrice')">
</view>
</view>
</view>
</view>
</view>
</template>
</view>
</view>
</template>
@ -80,6 +87,8 @@
<script>
import { getOrderOtherTime } from '@/apis/modules/order.js'
import { getPartnerTeamRates } from '@/apis/modules/parner.js'
import { productCategoryList, productTypeList } from '@/apis/modules/product.js'
export default {
data() {
return {
@ -89,6 +98,7 @@
isRenew: 0, //
orderType: 1,
customerId: '',
teamId: '',
timer: null,
units: [{
text: '日',
@ -101,24 +111,12 @@
id: 2
}],
unitText: ['日', '月', '年'],
productTypes: [
{
name: '实训课程',
id: 1
},
{
name: '理论课程',
id: 0
},
{
name: '数据产品',
id: 2
}
],
productTypes: [],
courses: {} , //
orderRepeat: [],
repeatMsg: '',
err: ''
err: '',
rate: ''
}
},
onShow() {
@ -130,40 +128,34 @@
this.isHandle = options.action === 'handle'
this.isRenew = options.action === 'renew'
this.isAdd = options.action === 'add'
this.teamId = options.teamId
this.handleProduct()
this.teamId && this.getRate()
},
methods: {
//
handleProduct() {
const list = uni.getStorageSync('courses')
const courses = {
practice: {
shrink: false,
name: '实训课程产品',
list: []
},
theory: {
shrink: false,
name: '理论课程产品',
list: []
},
data: {
shrink: false,
name: '数据产品',
list: []
}
}
// 3push(0-> 1- 2 )
list.map(e => {
const type = e.productType
!type ?
courses.theory.list.push(e) :
type === 1 ?
courses.practice.list.push(e) :
courses.data.list.push(e)
//
productTypeList().then(res => {
this.productTypes = res.typeList
}).catch(e => {})
})
this.courses = courses
const list = uni.getStorageSync('courses')
let courses = {}
//
productCategoryList().then(res => {
res.classificationList.forEach(e => {
courses['list' + this.$util.getOrderType(e.classificationId)] = {
shrink: false,
name: e.classificationName,
list: []
}
})
list.map(e => {
courses['list' + e.authority].list.push(e)
})
this.courses = courses
}).catch(e => {})
try {
uni.removeStorageSync('courses')
} catch (e) {}
@ -258,35 +250,37 @@
},
//
dealSettlePrice(row) {
// 0
if (this.orderType == 2) {
// 0
console.log('dealSettlePrice=>', row, this.orderType)
if (this.orderType != 1) {
row.settlementPrice = 0
row.serviceFee = 0
} else {
const unit = row.options // 使
const useUnit = row.periodOfUse // 使
let sPrice = ''
if (row.settlementMethod == 0) {
// **/**(1)
const priceUnit = row.settlementPriceUnit
sPrice = ((!unit ?
priceUnit / 365 * useUnit :
unit === 1 ?
priceUnit / 12 * useUnit :
priceUnit * useUnit) * (row.authority ?
1 :
row.accountNum)).toFixed((2))
} else {
// *
sPrice = (row.finalPrice * row.businessProportion / 100).toFixed((2))
}
// **/**(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)
// *10%
if (row.settlementPrice) {
row.serviceFee = (row.settlementPrice * 0.1).toFixed(2)
}
//
row.serviceFee = (row.finalPrice * (this.rate / 100)).toFixed(2)
}
},
//
getRate() {
getPartnerTeamRates({
teamId: this.teamId
}).then(({ teamRates }) => {
this.rate = teamRates.annualMarketingFee || 0
}).catch(res => {})
},
//
calcDiscount(row) {
const price = row.authority ? row.finalPrice : row.finalValue
@ -372,10 +366,12 @@
msg = '请输入成交价!'
break
}
e.edited = 1 //
}
if (msg) return this.$util.errMsg(msg)
if (this.orderRepeat.length) return this.$util.errMsg(this.repeatMsg) //
uni.setStorageSync('courses', this.courses)
uni.setStorageSync('orderEdited', 1)
uni.navigateBack()
},
}
@ -421,7 +417,13 @@
.form-list {
padding: 0 24rpx;
border-top: 0;
.period-wrap {
display: inline-flex;
align-items: center;
}
.period {
flex: none;
width: 100rpx;
text-align: center;
}
.unit {
@ -432,5 +434,8 @@
margin-left: 20rpx;
}
}
.edit {
margin-left: 10rpx;
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -5,8 +5,14 @@
<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 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 v-if="list.length" class="list">
@ -37,6 +43,7 @@
</template>
<script>
import { productCategoryList } from '@/apis/modules/product.js'
import { getProductsSubscribedByCustomers } from '@/apis/modules/client.js'
import product from '@/config/product.js'
export default {
@ -84,24 +91,7 @@
],
filterForm: {},
curTab: '',
tabs: [
{
name: '全部',
id: ''
},
{
name: '实训课程',
id: 1
},
{
name: '理论课程',
id: 0
},
{
name: '数据产品',
id: 3
}
],
tabs: [],
searchTimer: null,
orderStatus: '',
productStatus: '',
@ -130,6 +120,7 @@
onShow() {
const pages = getCurrentPages()
this.customerId = pages[pages.length - 1].options.customerId
this.getTypes()
this.getList()
},
methods: {
@ -201,6 +192,16 @@
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
@ -215,8 +216,8 @@
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
tabChange(id) {
this.curTab = id
this.filter()
},
//
@ -231,6 +232,16 @@
.filter {
margin-bottom: 10px;
}
.tab-wrap {
display: flex;
.tab-scroll {
width: calc(100% - 100rpx);
white-space: nowrap;
li {
display: inline-block;
}
}
}
.list {
li {
padding: 0 24rpx;

@ -13,6 +13,7 @@
v-for="item in list"
:threshold="0"
:right-options="ops"
:disabled="!auth('订单管理:删除')"
@click="e => handle(item)"
>
<view class="item" @click="toDetail(item)">
@ -51,7 +52,7 @@
</template>
<empty v-else></empty>
<uni-icons class="plus" type="plus-filled" size="60" color="#007eff" @click="$util.to('../orderDetail/orderDetail')"></uni-icons>
<uni-icons v-if="auth('订单管理:新建订单')" class="plus" type="plus-filled" size="60" color="#007eff" @click="toAdd"></uni-icons>
<filter-popup :data="filterData" :form.sync="filterForm" showArea v-model="popup" title="全部筛选" height="1104rpx" @finsh="subFinsh"></filter-popup>
</view>
</template>
@ -144,9 +145,10 @@
}
},
onShow() {
//
//
try {
uni.removeStorageSync('courses')
uni.removeStorageSync('orderEdited')
} catch (e) {}
this.initList()
},
@ -205,8 +207,15 @@
this.sort = this.sort ? 0 : 1
this.initList()
},
toAdd() {
this.$util.to('../orderDetail/orderDetail')
// uni.redirectTo({
// url: '../orderDetail/orderDetail'
// })
},
//
toDetail(item) {
// if(!this.auth(':')) return
this.$util.to(`../orderDetail/orderDetail?orderId=${item.orderId}&show=1`)
},
//

@ -5,39 +5,41 @@
<view :class="['sort', sort]" @click="switchSort"></view>
</view>
<ul class="tab">
<li v-for="(tab, i) in tabs" :class="{active: curTab === tab.id}" @click="tabChange(tab)">{{ tab.name }}</li>
<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 in list">
<view class="pro-name">
<image class="icon" :src="$util.getIcon(item)" mode="widthFix"></image>
<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.toggle}">{{ item.briefIntroduction }}</view>
<view class="toggle" @click="toggle(item)">{{ item.toggle ? '收起' : '展开' }}</view>
<view :class="{ell: !item.toggle}">{{ item.productIntroduction }}</view>
<view v-if="item.productIntroduction.length > 14" class="toggle" @click="toggle(item)">{{ item.toggle ? '收起' : '展开' }}</view>
</view>
</view>
<view class="line">
<text class="name">产品类型</text>
<text class="val">{{ tabs.find(e => e.id === item.productType).name }}</text>
</view>
<view class="line">
<text class="name">市场单价</text>
<text class="val">{{ item.marketPrice }}/</text>
<text class="val">{{ item.typeName }}</text>
</view>
<view class="line">
<text class="name">结算方式</text>
<text class="val">{{ item.settlementMethod ? '比例分成' : '结算单价' }}</text>
<text class="name">适用专业</text>
<text class="val">{{ item.professionalName }}</text>
</view>
<view class="line">
<text class="name">供应厂商</text>
<text class="val">{{ item.supplierName }}</text>
<text class="name">市场建议单价</text>
<text class="val">{{ item.marketUnitPrice }}/</text>
</view>
</view>
</li>
@ -47,29 +49,12 @@
</template>
<script>
import { AppletsDataProductList } from '@/apis/modules/product.js'
import { productCategoryList, listOfGoods } from '@/apis/modules/product.js'
export default {
data() {
return {
curTab: '',
tabs: [
{
name: '全部',
id: ''
},
{
name: '实训课程',
id: 1
},
{
name: '理论课程',
id: 0
},
{
name: '数据产品',
id: 2
}
],
tabs: [],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
@ -104,25 +89,31 @@
}
},
onShow() {
this.getFilter()
this.initList()
},
methods: {
getList() {
AppletsDataProductList({
sort: this.sort,
keywords: this.keyword,
productType: this.curTab,
listOfGoods({
pageNum: this.page,
pageSize: this.pageSize
}).then(({ data }) => {
pageSize: this.pageSize,
sort: this.sort == 'desc' ? 2 : 5,
isShelves: 0,
productClassification: this.curTab,
hotTag: 1,
productName: this.keyword,
}).then(({ page }) => {
// list
const list = data.records
const list = page.records
list.map(e => {
e.toggle = e.briefIntroduction.length < 14 // 14
if (e.productIntroduction) {
e.productIntroduction = this.$util.removeTag(e.productIntroduction)
e.toggle = e.productIntroduction.length < 14 // 14
}
})
this.list = this.reachBottom > 0 ? [...this.list, ...list] : list
this.page++ // page+1
const noMore = this.list.length === data.total //
const noMore = this.list.length === page.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
}).catch(e => {})
@ -132,6 +123,19 @@
this.reachBottom = 0
this.getList()
},
//
getFilter() {
console.log(11)
//
productCategoryList().then(res => {
const list = res.classificationList
list.forEach(e => {
e.id = e.classificationId
e.name = e.classificationName
})
this.tabs = list
}).catch(e => {})
},
//
toggle(item) {
item.toggle = !item.toggle
@ -142,8 +146,8 @@
this.initList()
},
// tab
tabChange(tab) {
this.curTab = tab.id
tabChange(id) {
this.curTab = id
this.initList()
}
}
@ -162,6 +166,16 @@
margin-left: 10%;
}
}
.tab-wrap {
display: flex;
.tab-scroll {
width: calc(100% - 100rpx);
white-space: nowrap;
li {
display: inline-block;
}
}
}
.list {
li {
padding: 0 24rpx;
@ -174,11 +188,13 @@
align-items: center;
padding: 18rpx 0;
font-size: 30rpx;
font-weight: 600;
color: #333;
border-bottom: 1px solid #E6E8ED;
.icon {
width: 52rpx;
height: 52rpx;
width: 58rpx;
min-width: 58rpx;
height: 58rpx;
margin-right: 20rpx;
}
}

@ -16,54 +16,6 @@
"enablePullDownRefresh": false
}
},
{
"path" : "pages/qrcode/qrcode",
"style" :
{
"navigationBarTitleText": "邀请加入",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/clients/clients",
"style" :
{
"navigationBarTitleText": "客户列表",
"enablePullDownRefresh": true
}
},
{
"path" : "pages/products/products",
"style" :
{
"navigationBarTitleText": "产品",
"enablePullDownRefresh": true
}
},
{
"path" : "pages/clientDetail/clientDetail",
"style" :
{
"navigationBarTitleText": "客户详情",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/addStaff/addStaff",
"style" :
{
"navigationBarTitleText": "邀请成员",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/plans/plans",
"style" :
{
"navigationBarTitleText": "产品方案",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/person/person",
"style" :
@ -71,30 +23,6 @@
"navigationBarTitleText": "我的",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/send/send",
"style" :
{
"navigationBarTitleText": "下载发送",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/password/password",
"style" :
{
"navigationBarTitleText": "修改密码",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/setting/setting",
"style" :
{
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/teams/teams",
@ -103,102 +31,189 @@
"navigationBarTitleText": "合伙人",
"enablePullDownRefresh": true
}
},
{
"path" : "pages/account/account",
"style" :
{
"navigationBarTitleText": "修改账号",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/phone/phone",
"style" :
{
"navigationBarTitleText": "修改手机号",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/email/email",
"style" :
{
"navigationBarTitleText": "修改邮箱",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/teamDetail/teamDetail",
"style" :
{
"navigationBarTitleText": "团队成员",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/editTeam/editTeam",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
],
"subPackages": [{
"root": "order",
"pages": [
{
"path": "orders/orders",
"style" :
{
"navigationBarTitleText": "订单列表",
"enablePullDownRefresh": true
}
},
{
"path" : "addCourse/addCourse",
"style" :
"subPackages": [
{
"root": "order",
"pages": [
{
"navigationBarTitleText": "选择产品",
"enablePullDownRefresh": true
}
},
{
"path" : "orderDetail/orderDetail",
"style" :
"path" : "clients/clients",
"style" :
{
"navigationBarTitleText": "客户列表",
"enablePullDownRefresh": true
}
},
{
"navigationBarTitleText": "订单详情",
"enablePullDownRefresh": false
}
},
{
"path" : "ordered/ordered",
"style" :
"path" : "clientDetail/clientDetail",
"style" :
{
"navigationBarTitleText": "客户详情",
"enablePullDownRefresh": false
}
},
{
"path" : "products/products",
"style" :
{
"navigationBarTitleText": "产品",
"enablePullDownRefresh": true
}
},
{
"path": "orders/orders",
"style" :
{
"navigationBarTitleText": "订单列表",
"enablePullDownRefresh": true
}
},
{
"navigationBarTitleText": "已订阅产品",
"enablePullDownRefresh": false
"path" : "addCourse/addCourse",
"style" :
{
"navigationBarTitleText": "选择产品",
"enablePullDownRefresh": true
}
},
{
"path" : "orderDetail/orderDetail",
"style" :
{
"navigationBarTitleText": "订单详情",
"enablePullDownRefresh": false
}
},
{
"path" : "ordered/ordered",
"style" :
{
"navigationBarTitleText": "已订阅产品",
"enablePullDownRefresh": false
}
},
{
"path" : "editCourse/editCourse",
"style" :
{
"navigationBarTitleText": "编辑产品",
"enablePullDownRefresh": false
}
},
{
"path" : "curClient/curClient",
"style" :
{
"navigationBarTitleText": "订单记录",
"enablePullDownRefresh": false
}
}
},
{
"path" : "editCourse/editCourse",
"style" :
]
},
{
"root": "team",
"pages": [
{
"navigationBarTitleText": "编辑产品",
"enablePullDownRefresh": false
"path" : "account/account",
"style" :
{
"navigationBarTitleText": "修改账号",
"enablePullDownRefresh": false
}
}
,{
"path" : "phone/phone",
"style" :
{
"navigationBarTitleText": "修改手机号",
"enablePullDownRefresh": false
}
}
,{
"path" : "email/email",
"style" :
{
"navigationBarTitleText": "修改邮箱",
"enablePullDownRefresh": false
}
}
},
{
"path" : "curClient/curClient",
"style" :
,{
"path" : "teamDetail/teamDetail",
"style" :
{
"navigationBarTitleText": "团队成员",
"enablePullDownRefresh": false
}
}
,{
"path" : "editTeam/editTeam",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path" : "send/send",
"style" :
{
"navigationBarTitleText": "下载发送",
"enablePullDownRefresh": false
}
},
{
"path" : "password/password",
"style" :
{
"navigationBarTitleText": "修改密码",
"enablePullDownRefresh": false
}
},
{
"path" : "setting/setting",
"style" :
{
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false
}
},
{
"path" : "qrcode/qrcode",
"style" :
{
"navigationBarTitleText": "邀请加入",
"enablePullDownRefresh": false
}
},
{
"path" : "addStaff/addStaff",
"style" :
{
"navigationBarTitleText": "邀请成员",
"enablePullDownRefresh": false
}
},
{
"path" : "plans/plans",
"style" :
{
"navigationBarTitleText": "产品方案",
"enablePullDownRefresh": false
}
},
{
"navigationBarTitleText": "订单记录",
"enablePullDownRefresh": false
"path" : "scheme/scheme",
"style" :
{
"navigationBarTitleText": "方案详情",
"enablePullDownRefresh": false
}
}
}
]
}],
]
}
],
"preloadRule": {
"pages/index/index": {
"network": "all",

@ -11,19 +11,19 @@
</view>
<ul class="entry">
<li v-if="auth('客户管理')" @click="$util.to('../clients/clients')">
<li v-if="auth('客户管理')" @click="$util.to('/order/clients/clients')">
<image class="icon" src="@/static/image/index/index3.png" mode="widthFix"></image>
<view class="text">客户</view>
</li>
<li @click="$util.to('../plans/plans')">
<li @click="$util.to('/team/plans/plans')">
<image class="icon" src="@/static/image/index/index4.png" mode="widthFix"></image>
<view class="text">方案</view>
</li>
<li v-if="auth('订单管理')" @click="$util.to('/order/orders/orders')">
<li @click="$util.to('/order/orders/orders')">
<image class="icon" src="@/static/image/index/index5.png" mode="widthFix"></image>
<view class="text">订单</view>
</li>
<li @click="$util.to('../products/products')">
<li @click="$util.to('/order/products/products')">
<image class="icon" src="@/static/image/index/index6.png" mode="widthFix"></image>
<view class="text">产品</view>
</li>

@ -9,8 +9,8 @@
</button>
<template v-else>
<view class="btn wechat" @click="login">
<image src="@/static/image/wechat.png" mode="widthFix"></image>
微信授权登录
<!-- <image src="@/static/image/wechat.png" mode="widthFix"></image> -->
快捷登录
</view>
</template>
@ -75,7 +75,7 @@
this.submiting = true
login({
code,
avatarUrl: userInfo.avatarUrl
// avatarUrl: userInfo.avatarUrl
}).then(({ data }) => {
const e = data.sessionKey
this.sessionKey = e.session_key

@ -10,7 +10,7 @@
</view>
</view>
<view class="list">
<view class="item" @click="$util.to('../setting/setting')">
<view class="item" @click="$util.to('/team/setting/setting')">
<view class="left">
<image class="icon" src="@/static/image/person3.png" mode=""></image>
<text class="name">设置</text>

@ -1,199 +0,0 @@
<template>
<view>
<view class="filter">
<uni-search-bar class="search" radius="30" placeholder="请输入方案名称" clearButton="auto" cancelButton="none" @confirm="search" />
</view>
<ul class="tab">
<li v-for="(tab, i) in tabs" :class="{active: curTab === tab.id}" @click="tabChange(tab)">{{ tab.name }}</li>
</ul>
<view v-if="list.length" class="list">
<view v-for="(item, i) in list" class="item" @click="toDetail(i + 2)">
<view class="c-name">{{ item.name }}</view>
<view class="content">
<view class="info">
<view class="line">
<view class="name">产品</view>
<view class="val ell-wrap">
<view :class="{ell: !item.toggle}" v-html="item.product"></view>
<view v-if="item.product.length > 14" class="toggle" @click.stop="toggle(item)">{{ item.toggle ? '收起' : '展开' }}</view>
</view>
</view>
<view class="line">
<view class="name">更新日期</view>
<view class="val">{{ item.date }}</view>
</view>
<view class="line">
<view class="name">适用专业</view>
<view class="val">{{ item.major }}</view>
</view>
</view>
<view class="detail" @click.stop="toEmail(i)">下载</view>
</view>
</view>
</view>
<empty v-else></empty>
</view>
</template>
<script>
export default {
data() {
return {
curTab: '',
tabs: [
{
name: '不限',
id: ''
},
{
name: '标准方案',
id: 1
},
{
name: '智信云方案',
id: 2
}
],
list: [],
all: [
{
type: 1,
toggle: false,
name: '人工智能实验室建设方案-2020.1',
product: `python程序设计实验教学系统<br>
Docker技术实验教学系统<br>
JAVA语言程序设计实验教学系统<br>
大数据开发实验教学系统<br>
Openstack云计算实验教学系统`,
date: '2022-06-02',
major: '人工智能方向'
},
{
type: 1,
toggle: false,
name: '大数据管理与应用专业建设方案',
product: `python程序设计实验教学系统<br>
量化投资实验教学系统<br>
区块链数字货币交易实验系统<br>
大数分析实验教学系统<br>
数据可视化实验教学系统<br>
大数据实证科研平台<br>
全球宏观经济<br>
数据库全球金融交易数据库 `,
date: '2022-06-02',
major: '大数据方向'
},
{
type: 1,
toggle: false,
name: '金融科技实验室建设方案V2.0',
product: `python程序设计实验教学系统<br>
量化投资实验教学系统<br>
区块链数字货币交易实验教学系统<br>
大数据采集实验教学系统<br>
大数据分析实验教学系统<br>
金融建模实验教学系统<br>
互联网小贷实验教学系统<br>
互联网支付实验教学系统<br>
R语言实验教学系统<br>
供应链金融实验教学系统<br>
Python数据清洗实验教学系统<br>
数据可视化实验教学系统<br>
金融随机过程实验教学系统<br>
银行综合系统<br>
大数据实证科研平台<br>
财经数据库`,
date: '2022-06-02',
major: '金融科技,大数据方向'
}
]
}
},
onShow() {
this.list = JSON.parse(JSON.stringify(this.all))
},
methods: {
search(res) {
uni.showToast({
title: '搜索:' + res.value,
icon: 'none'
})
},
// tab
tabChange(tab) {
const { id } = tab
const { all } = this
this.curTab = id
this.list = id ? all.filter(e => e.type === id) : all
},
//
toDetail(id) {
this.$util.openFile(id)
},
//
toEmail(id) {
this.$util.to(`../send/send?id=${id}`)
},
//
toggle(item) {
item.toggle = !item.toggle
}
}
}
</script>
<style scoped lang="scss">
.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 {
max-width: 88%;
font-size: 28rpx;
color: #333;
}
.ell {
height: 38rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.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>

@ -43,14 +43,14 @@
<text class="val">{{ item.invitationAccount }}</text>
</view>
</view>
<view class="iconfont icon-edit" @click.stop="toEdit(item)"></view>
<view v-if="auth('合伙管理:账号管理:编辑分类')" class="iconfont icon-edit" @click.stop="toEdit(item)"></view>
</li>
</ul>
<uni-load-more :status="status" />
</template>
<empty v-else></empty>
<uni-icons class="plus" type="plus-filled" size="60" color="#007eff" @click="$util.to('../addStaff/addStaff')"></uni-icons>
<uni-icons v-if="auth('合伙管理:账号管理:添加城市合伙人')" class="plus" type="plus-filled" size="60" color="#007eff" @click="$util.to('/team/addStaff/addStaff')"></uni-icons>
</view>
</template>
@ -148,11 +148,11 @@
},
//
toTeam(e) {
this.$util.to(`../teamDetail/teamDetail?id=${e.teamId}`)
this.$util.to(`/team/teamDetail/teamDetail?id=${e.teamId}`)
},
//
toEdit(e) {
this.$util.to(`../editTeam/editTeam?id=${e.teamId}&areaId=${e.partnerClassificationId}`)
this.$util.to(`/team/editTeam/editTeam?id=${e.teamId}&areaId=${e.partnerClassificationId}`)
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

@ -17,6 +17,11 @@ ul {
border-radius: 16rpx;
background-color: #fff;
}
.ell {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.l-title {
display: flex;
align-items: center;
@ -232,6 +237,9 @@ ul {
border-top: 1px solid #f3f3f3;
box-shadow: 0 -2px 2px #f5f5f5;
box-sizing: border-box;
&:empty {
padding: 0 !important;
}
.item {
text-align: center;
}

@ -0,0 +1,272 @@
<template>
<view>
<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>
<image class="unfold" src="@/static/image/unfold.png" mode="widthFix" @click="typeVisible = true"></image>
</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 :class="['product', {ell: !item.toggle}]">{{ item.productNames }}</view>
<view v-if="item.productNames && item.productNames.length > 24" 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>
</view>
</view>
<empty v-else></empty>
<view class="type-popup" v-show="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 { schemeList, queryClassificationByType } from '@/apis/modules/article.js'
export default {
data() {
return {
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.keyword = ''
this.active = ''
this.initList()
this.getClassification()
},
methods: {
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 < 24 // 14
})
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)
},
//
toggle(item) {
item.toggle = !item.toggle
}
}
}
</script>
<style scoped lang="scss">
.tab {
position: relative;
justify-content: flex-start;
li {
padding: 0 30rpx;
}
.unfold {
position: absolute;
top: 32rpx;
right: 12rpx;
right: 44rpx;
width: 40rpx;
}
}
.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;
}
}
.type-popup {
z-index: 10;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 10rpx;
background-color: #fff;
.close {
position: absolute;
top: 50rpx;
right: 50rpx;
}
.title {
margin: 150rpx 20rpx 30rpx;
font-size: 30rpx;
color: #333;
}
.types {
display: flex;
flex-wrap: wrap;
}
.item {
width: calc((100% - 80rpx) / 3);
margin: 10rpx;
font-size: 28rpx;
line-height: 3;
text-align: center;
color: #1f1f1f;
background-color: #dbebff;
border-radius: 2px;
&.active {
color: #fff;
background-color: #007EFF;
}
}
}
</style>

@ -0,0 +1,83 @@
<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">{{ 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('、')
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`)
}
}
}
</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>

@ -25,7 +25,6 @@
export default {
data() {
return {
id: '',
email: '',
otherEmail: '',
myVal: 1,
@ -34,27 +33,15 @@
text: '',
value: 1
}],
files: [
'人工智能实验室建设方案-2020.1.docx',
'大数据管理与应用专业建设方案.docx',
'金融科技实验室建设方案V2.0.docx'
]
}
},
onShow() {
const pages = getCurrentPages()
const { options } = pages[pages.length - 1]
this.id = options.id
this.getInfo()
},
methods: {
//
getInfo() {
const team = uni.getStorageSync('team')
my({
partnerId: team.partnerId,
teamId: team.teamId
}).then(({ my }) => {
my().then(({ my }) => {
this.email = my.info.email
}).catch(e => {})
},
@ -69,10 +56,9 @@
const { otherEmail } = this
if (this.myVal && !this.email) return this.$util.errMsg('请选择其他邮箱!')
if (this.otherVal && !otherEmail) return this.$util.errMsg('请输入邮箱!')
mailFileSend({
copyWriting: this.files[this.id],
mail: this.myVal ? this.email : otherEmail
}).then(res => {
const data = uni.getStorageSync('files')
data.mail = this.myVal ? this.email : otherEmail
mailFileSend(data).then(res => {
this.$util.sucMsg('发送成功!')
setTimeout(() => {
uni.navigateBack()

@ -65,7 +65,7 @@
success(res) {
if (res.confirm) {
uni.clearStorageSync()
that.$util.to('../login/login')
that.$util.to('/pages/login/login')
}
}
})

@ -24,7 +24,7 @@
</template>
<empty v-else></empty>
<uni-icons class="plus" type="plus-filled" size="60" color="#007eff" @click="$util.to('../addStaff/addStaff')"></uni-icons>
<uni-icons v-if="auth('合伙管理:账号管理:添加城市合伙人')" class="plus" type="plus-filled" size="60" color="#007eff" @click="$util.to('../addStaff/addStaff')"></uni-icons>
</view>
</template>

@ -0,0 +1,10 @@
## 0.2.1(2022-05-09)
- 修复 content 为空时仍然弹出的bug
## 0.2.0(2022-05-07)
**注意:破坏性更新**
- 更新 text 属性变更为 content
- 更新 移除 width 属性
## 0.1.1(2022-04-27)
- 修复 组件根 text 嵌套组件 warning
## 0.1.0(2022-04-21)
- 初始化

@ -0,0 +1,70 @@
<template>
<view class="uni-tooltip">
<slot></slot>
<view v-if="content || $slots.content" class="uni-tooltip-popup">
<slot name="content">
{{content}}
</slot>
</view>
</view>
</template>
<script>
/**
* Tooltip 提示文字
* @description 常用于展示鼠标 hover 时的提示信息
* @tutorial https://uniapp.dcloud.io/component/uniui/uni-tooltip
* @property {String} content 弹出层显示的内容
* @property {String} placement出现位置, 目前只支持 left
*/
export default {
name: "uni-tooltip",
data() {
return {
};
},
props: {
content: {
type: String,
default: ''
},
placement: {
type: String,
default: 'bottom'
},
}
}
</script>
<style>
.uni-tooltip {
position: relative;
cursor: pointer;
}
.uni-tooltip-popup {
z-index: 1000;
display: none;
position: absolute;
top: 40rpx;
left: 0;
max-width: 90%;
background-color: #333;
border-radius: 8px;
color: #fff;
font-size: 12px;
text-align: left;
line-height: 16px;
padding: 12px;
}
.uni-tooltip:hover .uni-tooltip-popup {
display: block;
}
</style>

@ -0,0 +1,83 @@
{
"id": "uni-tooltip",
"displayName": "uni-tooltip",
"version": "0.2.1",
"description": "Tooltip 提示文字",
"keywords": [
"uni-tooltip",
"uni-ui",
"tooltip",
"tip",
"文字提示"
],
"repository": "",
"engines": {
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无 ",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

@ -0,0 +1,8 @@
## Badge 数字角标
> **组件名:uni-tooltip**
> 代码块: `uTooltip`
数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景,
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-tooltip)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
Loading…
Cancel
Save