master
yujialong 4 days ago
commit c033fc6361
  1. 2
      .gitignore
  2. 24
      .hbuilderx/launch.json
  3. 36
      App.vue
  4. 1
      README.md
  5. 26
      apis/modules/article.js
  6. 54
      apis/modules/client.js
  7. 38
      apis/modules/course.js
  8. 42
      apis/modules/order.js
  9. 42
      apis/modules/parner.js
  10. 50
      apis/modules/product.js
  11. 100
      apis/modules/user.js
  12. 80
      apis/request.js
  13. 40
      components/empty/empty.vue
  14. 130
      components/filter-popup/components/mask.vue
  15. 510
      components/filter-popup/components/popup.vue
  16. 155
      components/filter-popup/detail.md
  17. 596
      components/filter-popup/filter-popup.vue
  18. 26
      components/notAuth/notAuth.vue
  19. 10
      config/product.js
  20. 21
      config/request.js
  21. 399
      course/addCourse/addCourse.vue
  22. 280
      course/clients/clients.vue
  23. 334
      course/courseDetail/courseDetail.vue
  24. 273
      course/curClient/curClient.vue
  25. 504
      course/editCourse/editCourse.vue
  26. 1201
      course/orderDetail/orderDetail.vue
  27. 285
      course/ordered/ordered.vue
  28. 109
      course/practiceDetail/practiceDetail.vue
  29. 107
      course/privacyAgreement/privacyAgreement.vue
  30. 399
      course/products/products.vue
  31. 88
      course/serviceAgreement/serviceAgreement.vue
  32. 317
      course/shopCart/shopCart.vue
  33. 14
      index.html
  34. 135
      libs/Oss/base64.js
  35. 117
      libs/Oss/crypto.js
  36. 37
      libs/Oss/hmac.js
  37. 82
      libs/Oss/sha1.js
  38. 71
      libs/Oss/upload.js
  39. 35
      libs/WXBizDataCrypt.js
  40. 39
      libs/mtj-wx-sdk.config.js
  41. 1
      libs/mtj-wx-sdk.js
  42. 36
      libs/share.js
  43. 18
      libs/uma.js
  44. 129
      libs/util.js
  45. 43
      main.js
  46. 73
      manifest.json
  47. 777
      package-lock.json
  48. 16
      package.json
  49. 208
      pages.json
  50. 216
      pages/achievement/achievement.vue
  51. 166
      pages/index/index.vue
  52. 347
      pages/login/login.vue
  53. 360
      pages/orders/orders.vue
  54. 409
      pages/person/person.vue
  55. 32
      static/iconfont/iconfont.css
  56. BIN
      static/iconfont/iconfont.ttf
  57. BIN
      static/image/arrow-down.png
  58. BIN
      static/image/avatar.png
  59. BIN
      static/image/index/1.png
  60. BIN
      static/image/index/2.png
  61. BIN
      static/image/index/3.png
  62. BIN
      static/image/index/4.png
  63. BIN
      static/image/index/5.png
  64. BIN
      static/image/index/6.png
  65. BIN
      static/image/index/7.png
  66. BIN
      static/image/index/8.png
  67. BIN
      static/image/index/9.png
  68. BIN
      static/image/index/banner.png
  69. BIN
      static/image/index/banner1.png
  70. BIN
      static/image/info-bg.jpg
  71. BIN
      static/image/info.png
  72. BIN
      static/image/login1.png
  73. BIN
      static/image/login2.png
  74. BIN
      static/image/logo.png
  75. BIN
      static/image/logo1.png
  76. BIN
      static/image/none.png
  77. BIN
      static/image/person-bg.png
  78. BIN
      static/image/person1.png
  79. BIN
      static/image/person2.png
  80. BIN
      static/image/person26.png
  81. BIN
      static/image/person27.png
  82. BIN
      static/image/person3.png
  83. BIN
      static/image/person4.png
  84. BIN
      static/image/person5.png
  85. BIN
      static/image/person6.png
  86. BIN
      static/image/person7.png
  87. BIN
      static/image/person8.png
  88. BIN
      static/image/person9.png
  89. BIN
      static/image/phone.png
  90. BIN
      static/image/product.png
  91. BIN
      static/image/product/1.png
  92. BIN
      static/image/product/2.png
  93. BIN
      static/image/product/3.png
  94. BIN
      static/image/product/4.png
  95. BIN
      static/image/product/5.png
  96. BIN
      static/image/product/6.png
  97. BIN
      static/image/product/excel.png
  98. BIN
      static/image/product/pdf.png
  99. BIN
      static/image/product/ppt.png
  100. BIN
      static/image/product/shop-blue.png
  101. Some files were not shown because too many files have changed in this diff Show More

2
.gitignore vendored

@ -0,0 +1,2 @@
unpackage
node_modules

@ -0,0 +1,24 @@
{ // launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"h5" :
{
"launchtype" : "local"
},
"mp-toutiao" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}

@ -0,0 +1,36 @@
<script>
export default {
onLaunch: function() {
// uni.setEnableDebug({
// enableDebug: true
// })
},
onShow: function() {
console.log('App Launch');
const updateManager = uni.getUpdateManager();
//
updateManager.onCheckForUpdate(function (res) {
//
console.log('onCheckForUpdate', res.hasUpdate);
});
//
updateManager.onUpdateReady(function (res) {
updateManager.applyUpdate()
});
updateManager.onUpdateFailed(function (res) {
console.log('onUpdateFailed', res);
//
uni.showModal({
title: '已经有新版本了哟~',
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~'
});
})
}
}
</script>
<style lang="scss">
@import '@/uni_modules/uni-scss/index.scss';
</style>

@ -0,0 +1 @@
# 职站商城

@ -0,0 +1,26 @@
import request from '@/apis/request.js'
const { get, post } = request
export const partnerOperatingList = (data) => {
return post('nakadai/nakadai/partner/article/management/partnerOperatingList', data)
}
export const findById = id => {
return post('nakadai/nakadai/applets/partner/browse?contentId=' + id)
}
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)
}
export const collectCourse = (id, state) => {
return post('nakadai/nakadai/partner/article/management/collectCourse?contentId=' + id + '&state=' + state)
}

@ -0,0 +1,54 @@
import request from '@/apis/request.js'
const { get, post } = request
export const queryCustomer = (data) => {
return post('nakadai/nakadai/customer/queryCustomer', data)
}
export const list = (data) => {
return post('nakadai/nakadai/applets/customer/getCustomerListBasedOnBusinessManagerId', data)
}
export const all = (data) => {
return post('nakadai/nakadai/applets/customer/customerList', data)
}
export const queryCustomerDetails = (data) => {
return get('nakadai/nakadai/customer/queryCustomerDetails', data)
}
export const querySchool = (data) => {
return get('nakadai/nakadai/school/querySchool', data)
}
export const queryIndustryClass = (data) => {
return get('nakadai/nakadai/hrIndustryClass/queryIndustryClass', data)
}
export const queryIndustry = (data) => {
return get('nakadai/nakadai/hrIndustry/queryIndustry', data)
}
export const queryCustomerIsExists = (data) => {
return get('nakadai/nakadai/customer/queryCustomerIsExists', data)
}
export const addCustomer = (data) => {
return post('nakadai/nakadai/customer/addCustomer', data)
}
export const updateCustomer = (data) => {
return post('nakadai/nakadai/customer/updateCustomer', data)
}
export const getProductsSubscribedByCustomers = (data) => {
return get('nakadai/nakadai/customer/getProductsSubscribedByCustomers', data)
}
export const getTeamsByAccountId = (data) => {
return post('nakadai/nakadai/applets/customer/getTeamsByAccountId', data)
}
export const getTheBusinessManagerIdsUnderTheTeam = id => {
return post(`nakadai/nakadai/applets/customer/getTheBusinessManagerIdsUnderTheTeam?id=${id}`)
}

@ -0,0 +1,38 @@
import request from '@/apis/request.js'
const { get, post } = request
export const getSchoolCourseAuthority = () => {
return get('nakadai/nakadai/curriculum/getSchoolCourseAuthority')
}
export const recentUse = data => {
return post('nakadai/nakadai/curriculum/recentUse', data)
}
export const schoolCourse = data => {
return get('nakadai/nakadai/curriculum/schoolCourse', data)
}
export const queryChaptersAndSubsections = id => {
return get('nakadai/nakadai/curriculum/chapter/queryChaptersAndSubsections/' + id)
}
export const curriculumDetail = (cid, mallId) => {
return post(`nakadai/nakadai/curriculum/curriculumDetail?cid=${cid}&mallId=${mallId}`)
}
export const queryPracticeByStudent = data => {
return post('occupationlab/occupationlab/achievement/queryPracticeByStudent', data)
}
export const queryAssessmentByStudent = data => {
return post('occupationlab/occupationlab/achievement/queryAssessmentByStudent', data)
}
export const practiceByStudentDetail = data => {
return post(`occupationlab/occupationlab/achievement/practiceByStudentDetail?curriculumId=${data.cid}&projectId=${data.projectId}&paperId=${data.paperId}&pageNum=${data.page}&pageSize=${data.pageSize}`)
}
export const experimentOverview = () => {
return get('occupationlab/occupationlab/achievement/experimentOverview')
}

@ -0,0 +1,42 @@
import request from '@/apis/request.js'
const { get, post } = request
export const getOrderOtherTime = (data) => {
return post('nakadai/nakadai/orderOther/getOrderOtherTime', data)
}
export const add = (data) => {
return post('nakadai/nakadai/order/add', data)
}
export const update = (data) => {
return post('nakadai/nakadai/order/update', data)
}
export const getDetail = (data) => {
return get('nakadai/nakadai/order/get', data)
}
export const renew = (data) => {
return post('nakadai/nakadai/orderOther/renew', data)
}
export const list = (data) => {
return post('nakadai/nakadai/applets/order/orderList', data)
}
export const orderList = (data) => {
return post('nakadai/nakadai/order/list', data)
}
export const del = (data) => {
return post('nakadai/nakadai/order/delete', data)
}
export const miniProgramOrderRecord = (data) => {
return post('nakadai/nakadai/applets/order/miniProgramOrderRecord', data)
}
export const queryCitySettlementPrice = (mallId, provinceId, cityId) => {
return post(`nakadai/mallPrice/queryCitySettlementPrice?mallId=${mallId}&provinceId=${provinceId}&cityId=${cityId}`)
}

@ -0,0 +1,42 @@
import request from '@/apis/request.js'
const { get, post } = request
export const savePartnerAccount = (data) => {
return post('nakadai/nakadai/partnerAccount/savePartnerAccount', data)
}
export const teamList = (data) => {
return post('nakadai/nakadai/partnerAccount/partnerAccountList', data)
}
export const generateInvitationCode = accountId => {
return post(`nakadai/nakadai/partnerAccount/generateInvitationCode?accountId=${accountId}`)
}
export const treeList = (data) => {
return post('nakadai/nakadai/partnerClassification/treeList', data)
}
export const my = (data) => {
return get('nakadai/nakadai/partner-team/my', data)
}
export const mailFileSend = (data) => {
return post('nakadai/nakadai/partnerAccount/mailFileSend', data)
}
export const salesProgress = data => {
return post(`nakadai/nakadai/applets/partner/salesProgress`, data)
}
export const annualOperatingAnalysis = data => {
return post(`nakadai/nakadai/applets/partner/annualOperatingAnalysis`, 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)
}

@ -0,0 +1,50 @@
import request from '@/apis/request.js'
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)
}

@ -0,0 +1,100 @@
import Config from '@/config/request.js'
import request from '@/apis/request.js'
const { get, post } = request
export const studentWeChatAppletCallback = (data) => {
return post('users/users/user/studentWeChatAppletCallback', data)
}
export const studentBinding = (data) => {
return post('users/users/user/studentBinding', data)
}
export const weChatToken = (data) => {
return post('users/users/user/weChatToken', data)
}
export const captcha = (data) => {
return Config.baseURL + `users/users/user/captcha`
}
export const queryProvince = () => {
return get('nakadai/nakadai/province/queryProvince')
}
export const queryCity = (data) => {
return get('nakadai/nakadai/city/queryCity', data)
}
export const updateAvatars = url => {
return post(`users/users/user/updateAvatars?url=` + url)
}
export const userBinding = (data) => {
return post('users/users/user/userBinding', data)
}
export const sendPhoneOrEmailCode = (data) => {
return post('users/users/userAccount/sendPhoneOrEmailCode', data)
}
export const examinePassword = (data) => {
return post('users/users/userAccount/examinePassword', data)
}
export const getUserRolesPermissionMenu = (data) => {
return get('users/users/user-role/getUserRolesPermissionMenu', data)
}
export const updatePersonCenter = (data) => {
return post('users/users/userAccount/updatePersonCenter', data)
}
export const queryUserInfoDetails = () => {
return get('users/users/userAccount/queryUserInfoDetails')
}
export const updateMyEmail = (data) => {
return post('nakadai/nakadai/partner-team/updateMyEmail', data)
}
export const mailCodeSend = (data) => {
return post('nakadai/nakadai/partner-team/mailCodeSend', data)
}
export const changeAccount = account => {
return post(`users/users/applets/mine/changeAccount?account=${account}`)
}
export const changePhoneNumber = (phone, code) => {
return post(`users/users/applets/mine/changePhoneNumber?phone=${phone}&code=${code}`)
}
export const checkIfAnAccountExists = account => {
return post(`users/users/applets/mine/checkIfAnAccountExists?account=${account}`)
}
export const checkIfThePhoneNumberExists = phone => {
return post(`users/users/applets/mine/checkIfThePhoneNumberExists?phone=${phone}`)
}
export const queryPartnerAccount = data => {
return post(`nakadai/nakadai/partnerAccount/queryPartnerAccount?phone=${data.phone}&openId=${data.openId}&douYinOpenId=${data.douYinOpenId}`)
}
export const getSessionKey = data => {
return post(`users/users/user/getSessionKey`, data)
}
export const partnerAccountApplication = data => {
return post(`nakadai/nakadai/partnerAccount/partnerAccountApplication`, data)
}
export const loginByOpenid = openid => {
return post(`users/users/user/loginByOpenid?openid=${openid}`)
}
export const checkWorkNumOrAccount = account => {
return post(`occupationlab/occupationlab/architecture/checkWorkNumOrAccount?platformId=4&type=0&account=` + account)
}
export const updateUserAvatars = `http://39.108.250.202:9000/users/users/userAccount/updateUserAvatars`

@ -0,0 +1,80 @@
import config from '@/config/request'
let logouted = 0
const request = options => {
const header = Object.assign({}, config.headers, {
token: uni.getStorageSync('token')
})
const otherUrl = ['queryPartnerAccount', 'getSessionKey', 'loginByOpenid', 'partnerAccountApplication', 'checkWorkNumOrAccount']
return new Promise((resolve, reject)=>{
const { url } = options
uni.request({
header,
// url: (otherUrl.find(e => url.includes(e)) ? 'http://192.168.31.116:9000/' : config.baseURL) + url,
url: config.baseURL + url,
method: options.method || 'GET', // 请求类型,默认为GET
data: options.data || {}, // 请求参数,默认空对象
success: ({ data }) => {
const { status, message, code } = data
// 状态判断,根据后台定义并提示
if (status === 200) {
resolve(data)
} else if (status == 401 || code === 401) {
if (!logouted) {
// 登录过期
uni.clearStorageSync()
uni.showToast({
title: message || '登录过期,请重新登录',
icon: 'none'
})
setTimeout(() => {
logouted = 0
uni.reLaunch({
url: '/pages/index/index'
})
}, 1500)
reject(data)
logouted = 1
}
} else if (status == 10028 || status == 10014) { // 用户不存在
resolve(data)
} else if (!status) {
resolve(data)
} else {
uni.showToast({
title: message,
icon: 'none'
})
reject(data)
}
},
fail: err => {
uni.showToast({
title: '请求失败!',
icon: 'none'
})
reject(err)
},
})
})
}
const get = (url, data, options = {}) => {
options.method = 'GET'
options.data = data
options.url = url
return request(options)
}
const post = (url, data, options = {}) => {
options.method = 'POST'
options.data = data
options.url = url
return request(options)
}
export default {
request,
get,
post
}

@ -0,0 +1,40 @@
<template>
<view class="none">
<image src="../../static/image/none.png" mode="widthFix"></image>
<view class="text">{{ text }}</view>
</view>
</template>
<script>
export default {
props: {
text: {
type: String,
default: '暂无数据'
},
},
data() {
return {
}
},
methods: {
}
}
</script>
<style scoped lang="scss">
.none {
padding-top: 100rpx;
text-align: center;
image {
width: 426rpx;
margin-bottom: 52rpx;
}
.text {
font-size: 28rpx;
color: #333;
}
}
</style>

@ -0,0 +1,130 @@
<template>
<view
class="u-mask"
hover-stop-propagation
:style="[maskStyle, zoomStyle]"
@tap="click"
@touchmove.stop.prevent="() => {}"
:class="{
'u-mask-zoom': zoom,
'u-mask-show': show,
}"
>
<slot />
</view>
</template>
<script>
/**
* mask 遮罩
* @description 创建一个遮罩层用于强调特定的页面元素并阻止用户对遮罩下层的内容进行操作一般用于弹窗场景
* @tutorial https://www.uviewui.com/components/mask.html
* @property {Boolean} show 是否显示遮罩默认false
* @property {String Number} z-index z-index 层级默认1070
* @property {Object} custom-style 自定义样式对象见上方说明
* @property {String Number} duration 动画时长单位毫秒默认300
* @property {Boolean} zoom 是否使用scale对这招进行缩放默认true
* @property {Boolean} mask-click-able 遮罩是否可点击为false时点击不会发送click事件默认true
* @event {Function} click mask-click-able为true时点击遮罩发送此事件
* @example <u-mask :show="show" @click="show = false"></u-mask>
*/
export default {
name: "u-mask",
props: {
//
show: {
type: Boolean,
default: false,
},
// z-index
zIndex: {
type: [Number, String],
default: "",
},
//
customStyle: {
type: Object,
default() {
return {};
},
},
// 使使zoomscale
zoom: {
type: Boolean,
default: true,
},
// ms
duration: {
type: [Number, String],
default: 300,
},
//
maskClickAble: {
type: Boolean,
default: true,
},
},
data() {
return {
zoomStyle: {
transform: "",
},
scale: "scale(1.2, 1.2)",
};
},
watch: {
show(n) {
if (n && this.zoom) {
// scale1(1.2)
this.zoomStyle.transform = "scale(1, 1)";
} else if (!n && this.zoom) {
// scale1.2(1)
this.zoomStyle.transform = this.scale;
}
},
},
computed: {
maskStyle() {
let style = {};
style.backgroundColor = "rgba(0, 0, 0, 0.6)";
if (this.show)
style.zIndex = this.zIndex ? this.zIndex : this.$u.zIndex.mask;
else style.zIndex = -1;
style.transition = `all ${this.duration / 1000}s ease-in-out`;
//
if (Object.keys(this.customStyle).length)
style = {
...style,
...this.customStyle,
};
return style;
},
},
methods: {
click() {
if (!this.maskClickAble) return;
this.$emit("click");
},
},
};
</script>
<style lang="scss" scoped>
.u-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
transition: transform 0.3s;
}
.u-mask-show {
opacity: 1;
}
.u-mask-zoom {
transform: scale(1.2, 1.2);
}
</style>

@ -0,0 +1,510 @@
<template>
<view
v-if="visibleSync"
:style="[
customStyle,
{
zIndex: uZindex - 1,
},
]"
class="u-drawer"
hover-stop-propagation
>
<z-mask
:duration="duration"
:custom-style="maskCustomStyle"
:maskClickAble="maskCloseAble"
:z-index="uZindex - 2"
:show="showDrawer && mask"
@click="maskClick"
></z-mask>
<view
class="u-drawer-content"
@tap="modeCenterClose(mode)"
:class="[
safeAreaInsetBottom ? 'safe-area-inset-bottom' : '',
'u-drawer-' + mode,
showDrawer ? 'u-drawer-content-visible' : '',
zoom && mode == 'center' ? 'u-animation-zoom' : '',
]"
@transitionend="transitionend"
@touchmove.stop.prevent
@tap.stop.prevent
:style="[style]"
>
<view
class="u-mode-center-box"
@tap.stop.prevent
@touchmove.stop.prevent
v-if="mode == 'center'"
:style="[centerStyle]"
>
<u-icon
@click="close"
v-if="closeable"
class="u-close"
:class="['u-close--' + closeIconPos]"
:name="closeIcon"
:color="closeIconColor"
:size="closeIconSize"
></u-icon>
<scroll-view class="u-drawer__scroll-view" scroll-y="true">
<slot />
</scroll-view>
<slot name="fixedContent" />
</view>
<scroll-view class="u-drawer__scroll-view" scroll-y="true" v-else>
<slot />
</scroll-view>
<view @tap="close" class="u-close" :class="['u-close--' + closeIconPos]">
<u-icon
v-if="mode != 'center' && closeable"
:name="closeIcon"
:color="closeIconColor"
:size="closeIconSize"
></u-icon>
</view>
</view>
</view>
</template>
<script>
/**
* popup 弹窗
* @description 弹出层容器用于展示弹窗信息提示等内容支持上右和中部弹出组件只提供容器内部内容由用户自定义
* @tutorial https://www.uviewui.com/components/popup.html
* @property {String} mode 弹出方向默认left
* @property {Boolean} mask 是否显示遮罩默认true
* @property {Stringr | Number} length mode=left | 见官网说明默认auto
* @property {Boolean} zoom 是否开启缩放动画只在mode为center时有效默认true
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配默认false
* @property {Boolean} mask-close-able 点击遮罩是否可以关闭弹出层默认true
* @property {Object} custom-style 用户自定义样式
* @property {Stringr | Number} negative-top 中部弹出时往上偏移的值
* @property {Numberr | String} border-radius 弹窗圆角值默认0
* @property {Numberr | String} z-index 弹出内容的z-index值默认1075
* @property {Boolean} closeable 是否显示关闭图标默认false
* @property {String} close-icon 关闭图标的名称只能uView的内置图标
* @property {String} close-icon-pos 自定义关闭图标位置默认top-right
* @property {String} close-icon-color 关闭图标的颜色默认#909399
* @property {Number | String} close-icon-size 关闭图标的大小单位rpx默认30
* @event {Function} open 弹出层打开
* @event {Function} close 弹出层收起
* @example <u-popup v-model="show"><view>出淤泥而不染濯清涟而不妖</view></u-popup>
*/
import ZMask from "./mask.vue";
export default {
name: "popup",
components: {
ZMask,
},
props: {
/**
* 显示状态
*/
show: {
type: Boolean,
default: false,
},
/**
* 弹出方向left|right|top|bottom|center
*/
mode: {
type: String,
default: "left",
},
/**
* 是否显示遮罩
*/
mask: {
type: Boolean,
default: true,
},
// (mode=left|right)(mode=top|bottom)rpx"auto"
// "50%"
length: {
type: [Number, String],
default: "auto",
},
// mode=center
zoom: {
type: Boolean,
default: true,
},
// iPhoneX
safeAreaInsetBottom: {
type: Boolean,
default: false,
},
//
maskCloseAble: {
type: Boolean,
default: true,
},
//
customStyle: {
type: Object,
default() {
return {};
},
},
value: {
type: Boolean,
default: false,
},
// 使Pickerkeyboard
// v-modelprops
popup: {
type: Boolean,
default: true,
},
// rpx
borderRadius: {
type: [Number, String],
default: 0,
},
zIndex: {
type: [Number, String],
default: "10075",
},
//
closeable: {
type: Boolean,
default: false,
},
// uView
closeIcon: {
type: String,
default: "close",
},
// top-lefttop-rightbottom-leftbottom-right
closeIconPos: {
type: String,
default: "top-right",
},
//
closeIconColor: {
type: String,
default: "#909399",
},
// rpx
closeIconSize: {
type: [String, Number],
default: "30",
},
// rpx"auto"
// "50%"length
width: {
type: String,
default: "",
},
// rpx"auto"
// "50%"length
height: {
type: String,
default: "",
},
// margin-topmode=center
negativeTop: {
type: [String, Number],
default: 0,
},
//
maskCustomStyle: {
type: Object,
default() {
return {};
},
},
// ms
duration: {
type: [String, Number],
default: 250,
},
//
centerPupBg: {
type: String,
default: "#fff",
},
bgColor: {
type: String,
default: "#fff",
},
},
data() {
return {
visibleSync: false,
showDrawer: false,
timer: null,
closeFromInner: false, // value
};
},
computed: {
// mode(mode = left|right)(mode = top|bottom)
style() {
let style = {};
// translate
if (this.mode == "left" || this.mode == "right") {
style = {
width: this.width
? this.getUnitValue(this.width)
: this.getUnitValue(this.length),
height: "100%",
transform: `translate3D(${
this.mode == "left" ? "-100%" : "100%"
},0px,0px)`,
background: this.bgColor,
};
} else if (this.mode == "top" || this.mode == "bottom") {
style = {
width: "100%",
height: this.height
? this.getUnitValue(this.height)
: this.getUnitValue(this.length),
transform: `translate3D(0px,${
this.mode == "top" ? "-100%" : "100%"
},0px)`,
background: this.bgColor,
};
}
style.zIndex = this.uZindex;
// borderRadius
if (this.borderRadius) {
switch (this.mode) {
case "left":
style.borderRadius = `0 ${this.borderRadius}rpx ${this.borderRadius}rpx 0`;
break;
case "top":
style.borderRadius = `0 0 ${this.borderRadius}rpx ${this.borderRadius}rpx`;
break;
case "right":
style.borderRadius = `${this.borderRadius}rpx 0 0 ${this.borderRadius}rpx`;
break;
case "bottom":
style.borderRadius = `${this.borderRadius}rpx ${this.borderRadius}rpx 0 0`;
break;
default:
}
//
style.overflow = "hidden";
}
if (this.duration)
style.transition = `all ${this.duration / 1000}s linear`;
return style;
},
//
centerStyle() {
let style = {};
style.width = this.width
? this.getUnitValue(this.width)
: this.getUnitValue(this.length);
// auto
style.height = this.height ? this.getUnitValue(this.height) : "auto";
style.zIndex = this.uZindex;
// style.marginTop = `-${this.$u.addUnit(this.negativeTop)}`;
style.background = this.centerPupBg;
if (this.borderRadius) {
style.borderRadius = `${this.borderRadius}rpx`;
//
style.overflow = "hidden";
}
return style;
},
// z-index
uZindex() {
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
},
},
watch: {
value(val) {
if (val) {
this.open();
} else if (!this.closeFromInner) {
this.close();
}
this.closeFromInner = false;
},
},
mounted() {
// valuetruepopup
this.value && this.open();
},
methods: {
//
transitionend(e) {
// console.log(e, "popup");
},
// rpx
getUnitValue(val) {
if (/(%|px|rpx|auto)$/.test(val)) return val;
else return val + "rpx";
},
//
maskClick() {
this.close();
},
close() {
// valuewatchvalueclose
// @close
this.closeFromInner = true;
this.change("showDrawer", "visibleSync", false);
},
// .u-drawer-content
// mode=center
modeCenterClose(mode) {
if (mode != "center" || !this.maskCloseAble) return;
this.close();
},
open() {
this.change("visibleSync", "showDrawer", true);
},
//
//
change(param1, param2, status) {
// this.popupfalsepickeractionsheetpopup
if (this.popup == true) {
this.$emit("input", status);
}
this[param1] = status;
if (status) {
// #ifdef H5 || MP
this.timer = setTimeout(() => {
this[param2] = status;
this.$emit(status ? "open" : "close");
}, 50);
// #endif
// #ifndef H5 || MP
this.$nextTick(() => {
this[param2] = status;
this.$emit(status ? "open" : "close");
});
// #endif
} else {
this.timer = setTimeout(() => {
this[param2] = status;
this.$emit(status ? "open" : "close");
}, this.duration);
}
},
},
};
</script>
<style scoped lang="scss">
@mixin vue-flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: $direction;
/* #endif */
}
.u-drawer {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.u-drawer-content {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: absolute;
z-index: 1003;
transition: all 0.25s linear;
}
.u-drawer__scroll-view {
width: 100%;
height: 100%;
}
.u-drawer-left {
top: 0;
bottom: 0;
left: 0;
}
.u-drawer-right {
right: 0;
top: 0;
bottom: 0;
}
.u-drawer-top {
top: 0;
left: 0;
right: 0;
}
.u-drawer-bottom {
bottom: 0;
left: 0;
right: 0;
}
.u-drawer-center {
@include vue-flex;
flex-direction: column;
bottom: 0;
left: 0;
right: 0;
top: 0;
justify-content: center;
align-items: center;
opacity: 0;
z-index: 99999;
}
.u-mode-center-box {
min-width: 100rpx;
min-height: 100rpx;
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
}
.u-drawer-content-visible.u-drawer-center {
transform: scale(1);
opacity: 1;
}
.u-animation-zoom {
transform: scale(1.15);
}
.u-drawer-content-visible {
transform: translate3D(0px, 0px, 0px) !important;
}
.u-close {
position: absolute;
z-index: 3;
}
.u-close--top-left {
top: 30rpx;
left: 30rpx;
}
.u-close--top-right {
top: 30rpx;
right: 30rpx;
}
.u-close--bottom-left {
bottom: 30rpx;
left: 30rpx;
}
.u-close--bottom-right {
right: 30rpx;
bottom: 30rpx;
}
</style>

@ -0,0 +1,155 @@
## 导入即用 全端支持
### 有问题 + wx : zy597172583 标注来意 可评论 看到及时回复
1.使用方式
```javascript
<template>
<filter-popup :data="filterData" :form.sync="filterForm" v-model="popup.filter" title="全部筛选" height="1104rpx" @finsh="subFinsh"></filter-popup>
</template>
<script>
import FilterPopup from "@/components/filter-popup/filter-popup";
export default {
components: {
FilterPopup,
},
data() {
return {
//筛选表单数据
filterData: [
{
children: false,//是否有子项
title: "意向度",
key: "intention_type", //键名 接收对象名字
keyValue: "value", //获取的值是哪个
isRadio: true, //是否单选 否则多选
data: [
{
title: "一般意向",
id: 1,
value: 1,
},
{
title: "中意向度",
id: 2,
value: 2,
},
{
title: "高意向度",
id: 3,
value: 3,
},
],
},
{
children: false,//是否有子项
title: "手机号码",
key: "is_bind_phone", //键名 接收对象名字
keyValue: "value", //获取的值是哪个
isRadio: true, //是否单选 否则多选
data: [
{
title: "未绑定",
value: 0,
},
{
title: "已绑定",
value: 1,
},
],
},
{
children: false,//是否有子项
title: "企微好友",
key: "is_work_customer", //键名 接收对象名字
keyValue: "value", //获取的值是哪个
isRadio: true, //是否单选 否则多选
data: [
{
title: "未添加",
value: 0,
},
{
title: "已添加",
value: 1,
},
],
},
{
children: true,//是否有子项
isRadio: false, //是否单选
title: "标签内容",
key: "label", //键名 接收对象名字
keyValue: "id", //获取的值是哪个
data: [
{
title: "客户重要程度",
id: 22,
children: [
{
title: "一般意向2",
id: 32,
value: 1,
},
{
title: "一般意向3",
id: 12,
value: 1,
},
],
},
{
title: "客户重要程度2",
id: 122,
children: [
{
title: "一般意向2",
id: 43,
value: 1,
},
{
title: "一般意向3",
id: 23,
value: 1,
},
],
},
],
},
], //筛选数据
filterForm: {}, //选中的表单
};
},
}
```
2.组件props
| 参数名 | 类型 | 介绍 |
| ---------- | ------- | ------------------------------------------------- |
| form | Object | .sync双向绑定的表单值 , 可传入显示初始哪些被选中 |
| data | Array | 动态渲染选项的数据数组 |
| title | String | 标题 |
| height | String | 弹出层高度 单位 rpx px upx 百分比 vw等 |
| themeColor | String | 组件主体颜色 默认:\#0066ff |
| mask | Boolean | 是否显示弹出遮盖层 |
3.data 参数
| 参数名 | 类型 | 是否必填 | 介绍 |
| -------- | ------- | -------- | ------------------------------------------------------------ |
| children | Boolean | 是 | 是否有子项 |
| data | Array | 是 | 渲染出来的选项数据 |
| isRadio | Boolean | 是 | 是否单选 单个选项指定,单选还是多选 |
| title | String | 是 | 标签内容标题 |
| key | String | 是 | 接收对象名字 会作为@finsh返回对象的键名 |
| keyValue | String | 是 | 获取的值是哪个 自定义指定获取哪个键值 value还是id或者自己定义的 |
4.事件
| 事件名 | 返回参数 | 简介 |
| ------ | -------- | ----------------------------------------- |
| finsh | Object | 点击确定时触发 返回参数为选中值的对象数组 |
| close | 无 | 组件点击关闭时触发 |
![image-20210730095456900](https://yzhsaas-cdn.qietongvip.com/asd.png)

@ -0,0 +1,596 @@
<template>
<popup
:mask="mask"
border-radius="50"
v-model="acceptValue"
mode="bottom"
class="filter-popup"
:height="height"
@close="close"
:style="{ '--color': themeColor }"
:mask-custom-style="{ background: 'rgba(0, 0, 0, 0.7)' }"
>
<view class="top-title flex-row-sb" v-if="showTop">
<view class="popup-title flex-row-c-c">{{ title }}</view>
<text class="saasIcon flex-row-c-c" @click="close">&#xe60c;</text>
</view>
<scroll-view class="select-scroll" scroll-y :style="{ height: `calc( ${height} - 120rpx - 152rpx )` }">
<view class="select-main">
<view v-if="showCategory" class="select-item">
<view class="title">学科专业</view>
<view class="category-wrap">
<picker mode="multiSelector" v-model="category" @change="change" @columnchange="columnchange" :range="categories" range-key="title">
<view class="category">{{categoryName ? categoryName : '请选择'}}</view>
</picker>
<uni-icons v-if="categoryName" class="icon" type="closeempty" size="16" color="#333" @click.stop="delCatagory"></uni-icons>
</view>
</view>
<view class="select-item" v-for="(item, index) in data" :key="index">
<view class="title"> {{ item.title }} </view>
<view class="tag-list" v-if="!item.children">
<view
class="tag-item"
:class="[acceptForm[item.key].includes(item2.value) ? 'select-on' : '']"
v-for="(item2, index2) in item.data"
:key="index2"
@click="selectTagBuyValueOrId(item2, item.key, item.keyValue, item.isRadio)"
>
{{ item2.title }}
</view>
</view>
<!-- 有childer -->
<view class="select-childer" v-else v-for="item2 in item.data" :key="item2.id">
<view class="childer-title flex-row--c">{{ item2.title }}</view>
<view class="tag-list">
<view
class="tag-item"
:class="[acceptForm[item.key].includes(item3.id) ? 'select-on' : '']"
v-for="item3 in item2.children"
:key="item3.id"
@click="selectTagBuyValueOrId(item3, item.key, item.keyValue, item.isRadio)"
>
{{ item3.title }}
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<view class="filter-button flex-row-c">
<view class="btn flex-row">
<view class="btn-1 flex-row-c-c" @click="reset">重置</view>
<view class="btn-2 flex-row-c-c" @click="finsh">完成</view>
</view>
</view>
</popup>
</template>
<script>
import { courseDiscipline, courseProfessionalClass, courseProfessional } from '@/apis/modules/product.js'
import Popup from './components/popup.vue';
export default {
components:{
Popup
},
name: "filter-popup",
props: {
//
form: {
type: Object,
default: () => {},
},
//
themeColor: {
type: String,
default: "#0066ff",
},
//
data: {
type: Array,
default: () => [],
},
//
title: {
type: String,
default: "请选择",
},
value: {
type: Boolean,
default: false,
},
mask: {
type: Boolean,
default: true,
},
height: {
type: String,
default: "600rpx",
},
//退
showTop: {
type: Boolean,
default: true,
},
//
showCategory: {
type: Boolean,
default: false,
},
},
computed: {
//
acceptForm: {
get() {
this.originForm = JSON.parse(JSON.stringify(this.form))
if (Object.keys(this.form).length) {
return this.form;
} else {
let obj = {};
this.data.forEach((item) => {
obj[item.key] = [];
});
return obj;
}
},
set(nval) {
// console.log("set Form :>> ", nval);
this.$emit("update:form", nval);
},
},
acceptValue: {
get() {
return this.value;
},
set(nval) {
this.$emit("input", nval);
},
},
},
data() {
return {
originForm: {},
categoryName:'',
categoryId: '',
professionalCategoryId: '',
professionalId: '',
categories:[],
category: []
}
},
mounted() {
this.getDis()
},
methods: {
//value id
selectTagBuyValueOrId(item, key, keyValue, isRadio) {
//
if (isRadio) {
if (keyValue == "value") {
if (this.acceptForm[key].some((value) => value === item.value)) {
this.acceptForm[key] = this.acceptForm[key].filter((value) => value !== item.value);
return;
}
this.acceptForm[key] = [];
this.acceptForm[key].push(item.value);
} else {
if (this.acceptForm[key].some((id) => id === item.id)) {
this.acceptForm[key] = this.acceptForm[key].filter((id) => id !== item.id);
return;
}
this.acceptForm[key] = [];
this.acceptForm[key].push(item.id);
}
} else {
if (keyValue == "value") {
this.acceptForm[key].some((value) => value === item.value)
? (this.acceptForm[key] = this.acceptForm[key].filter((value) => value !== item.value))
: this.acceptForm[key].push(item.value);
} else {
this.acceptForm[key].some((id) => id === item.id)
? (this.acceptForm[key] = this.acceptForm[key].filter((id) => id !== item.id))
: this.acceptForm[key].push(item.id);
}
}
this.acceptForm = this.acceptForm;
},
//
async getDis() {
const { list } = await courseDiscipline()
list.map(e => {
e.id = e.disciplineId
e.title = e.disciplineName
})
this.categories.push(list)
const res = await courseProfessionalClass(1)
res.list.map(e => {
e.id = e.professionalClassId
e.title = e.professionalClassName
})
this.categories.push(res.list)
const res1 = await courseProfessional(1)
res1.list.map(e => {
e.id = e.professionalId
e.title = e.professionalName
})
this.categories.push(res1.list)
},
//
change(e) {
const i0 = e.detail.value[0]
const i1 = e.detail.value[1]
const i2 = e.detail.value[2]
const i1IsNumber = typeof i1 === 'number'
const i2IsNumber = typeof i2 === 'number'
const list = this.categories
this.categoryId = list[0][i0].id
this.categoryName = list[0][i0].title
this.professionalCategoryId = ''
this.professionalId = ''
if (i1IsNumber && list[1].length > 0) {
this.professionalCategoryId = list[1][i1].id
this.categoryName += '/' + list[1][i1].title
}
if (i2IsNumber && list[2].length > 0) {
this.professionalId = list[2][i2].id
this.categoryName += '/' + list[2][i2].title
}
},
//
async columnchange(e) {
const { column } = e.detail
if (column == 0) {
const { list } = await courseProfessionalClass(this.categories[0][e.detail.value].id)
list.map(e => {
e.id = e.professionalClassId
e.title = e.professionalClassName
})
this.categories[1] = list
this.categories[2] = []
this.$set(this.categories, 1, list)
console.log('inner',this.categories)
} else
if (column == 1) {
const { list } = await courseProfessional(this.categories[1][e.detail.value].id)
list.map(e => {
e.id = e.professionalId
e.title = e.professionalName
})
this.categories[2] = list
this.$set(this.categories, 2, list)
}
},
//
delCatagory() {
this.category = []
this.categoryName = ''
this.categoryId = ''
this.professionalCategoryId = ''
this.professionalId = ''
},
//
finsh() {
if (this.showCategory) {
this.acceptForm.categoryId = this.categoryId
this.acceptForm.professionalCategoryId = this.professionalCategoryId
this.acceptForm.professionalId = this.professionalId
this.acceptForm.categoryName = this.categoryName
}
this.$emit("finsh", this.acceptForm);
this.$emit("input", false);
},
close() {
this.$emit("input", false);
this.$emit("close");
},
//
reset() {
this.acceptForm = {}
this.categoryId = ''
this.professionalCategoryId = ''
this.professionalId = ''
this.categoryName = ''
this.$nextTick(() => {
this.$emit("finsh", this.acceptForm);
this.$emit("input", false);
})
},
},
};
</script>
<style lang="scss" scoped>
@font-face {
font-family: 'iconfont'; /* Project id 2729410 */
src: url('https://at.alicdn.com/t/font_2729410_3nhq3ibbcqg.woff2?t=1628330097695') format('woff2'),
url('https://at.alicdn.com/t/font_2729410_3nhq3ibbcqg.woff?t=1628330097695') format('woff'),
url('https://at.alicdn.com/t/font_2729410_3nhq3ibbcqg.ttf?t=1628330097695') format('truetype');
}
.saasIcon {
font-family: "iconfont" !important;
font-style: normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
.filter-popup {
color: #000000;
.top-title {
font-weight: bold;
height: 90rpx;
margin-left: 70rpx;
font-size: 30rpx;
margin-top: 20rpx;
.popup-title {
height: 100%;
}
.saasIcon {
// width: 150rpx;
height: 100%;
padding-right: 70rpx;
}
}
.select-scroll {
}
.category-wrap {
display: flex;
align-items: center;
margin-top: 10rpx;
.icon {
margin-left: 10rpx;
}
}
.category {
font-size: 28rpx;
}
.select-main {
padding: 0 32rpx;
.select-item {
.title {
font-weight: bold;
font-size: 28rpx;
color: #000000;
padding-top: 30rpx;
}
.tag-list {
display: flex;
flex-wrap: wrap;
margin-left: -12rpx;
.tag-item {
margin-top: 20rpx;
padding: 10rpx 40rpx;
font-size: 26rpx;
background: #f5f5f5;
color: #484848;
border-radius: 36rpx;
margin-left: 12rpx;
&.select-on {
background: var(--color);
color: #fff;
}
}
}
}
.select-childer {
.childer-title {
color: #484848;
font-size: 28rpx;
border-bottom: 1px solid #f5f5f5;
height: 80rpx;
}
}
}
.filter-button {
width: 100%;
height: 152rpx;
background: #ffffff;
box-shadow: 0px -3px 12px rgba(0, 0, 0, 0.06);
position: fixed;
bottom: 0;
.btn {
border-radius: 100rpx;
margin-top: 26rpx;
width: 680rpx;
height: 80rpx;
color: #ffffff;
font-size: 28rpx;
overflow: hidden;
.btn-1 {
flex: 1;
background: linear-gradient(271deg, #2698fb 0%, #84c6ff 100%);
}
.btn-2 {
flex: 1;
background: linear-gradient(90deg, #0066ff 0%, #1371ff 100%);
}
}
}
// css
.flex-row {
display: flex;
}
.flex-row-c {
display: flex;
justify-content: center;
}
.flex-row--c {
display: flex;
align-items: center;
}
.flex-row-c-c {
display: flex;
justify-content: center;
align-items: center;
}
.flex-row-sb-c {
display: flex;
justify-content: space-between;
align-items: center;
}
.flex-row-sb-t {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.flex-row-sb-b {
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.flex-row-c-sb {
display: flex;
justify-content: center;
align-items: space-between;
}
.flex-row-sb {
display: flex;
justify-content: space-between;
}
.flex-row-l {
display: flex;
justify-content: flex-start;
}
.flex-row-l-c {
display: flex;
justify-content: flex-start;
align-items: center;
}
.flex-row-c-t {
display: flex;
justify-content: center;
align-items: flex-start;
}
.flex-row-r-c {
display: flex;
justify-content: flex-end;
align-items: center;
}
.flex-row-r {
display: flex;
justify-content: flex-end;
}
.flex-row--b {
display: flex;
align-items: flex-end;
}
.flex-col {
display: flex;
flex-direction: column;
}
.flex-col-c {
display: flex;
flex-direction: column;
justify-content: center;
}
.flex-col--c {
display: flex;
flex-direction: column;
align-items: center;
}
.flex-col-c-c {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.flex-col-sb-c {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.flex-col-c-sb {
display: flex;
flex-direction: column;
justify-content: center;
align-items: space-between;
}
.flex-col-sb {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.flex-col-t-c {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
}
.flex-col-c-l {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
}
.flex-col-t {
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.flex-col-b {
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.flex-col-b-c {
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
}
.flex-col-c-l {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-end;
}
.flex-col--l {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.flex-col--r {
display: flex;
flex-direction: column;
align-items: flex-end;
}
}
</style>

@ -0,0 +1,26 @@
<template>
<view class="per-mask">
<view class="mask"></view>
<view class="texts">
<view class="text">权限审核中可联系下方平台运营加快审核进度</view>
<image class="qrcode" :src="src" mode="widthFix"></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
src: uni.getSystemInfoSync().uniPlatform === 'mp-toutiao' ? 'https://occupationlab.com/images/dyQrcode.jpg' : 'https://occupationlab.com/images/customer.png'
}
},
methods: {
}
}
</script>
<style scoped lang="scss">
</style>

@ -0,0 +1,10 @@
/**
/**
* 产品 配置文件
* @author yujialong
*/
export default {
normalIcon: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20220609/png/1534733700683030528.png', // 通用图标
dataIcon: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20220627/png/1541256164447641600.png' // 数据图标
}

@ -0,0 +1,21 @@
/**
/**
* 请求配置文件
* @author yujialong
*/
export default {
// baseURL: 'https://izhixinyun.com/',
baseURL: 'http://192.168.31.51:9000/',
// baseURL: 'http://121.37.12.51/',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
data: {},
method: 'POST',
responseType: 'json', // 响应数据类型
withCredentials: false, // 携带cookie
// ======================== 以下为注入axios的配置项 =============================
showLoading: true, // 是否显示加载动画
isFormData: false // 是否序列化表单数据
}

@ -0,0 +1,399 @@
<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>

@ -0,0 +1,280 @@
<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>

@ -0,0 +1,334 @@
<template>
<view class="wrap">
<view class="banner-wrap bg-wh">
<image class="pic" :src="form.mall.coverDrawing" mode="widthFix"></image>
</view>
<view class="detail">
<ul class="tabs">
<li v-for="(item, i) in tabs" :key="i" :class="{active: curTab === item.id}" @click="tabChange(item.id)">{{ item.name }}</li>
</ul>
<!-- 课程介绍 -->
<view v-show="!curTab" class="des">
<mp-html class="des-html" :tag-style="mpStyle" :content="briefIntroduction"/>
</view>
<!-- 课程目录 -->
<view v-show="curTab === 1">
<uni-search-bar class="search" radius="30" placeholder="请输入章节名称" v-model="keyword" clearButton="auto" cancelButton="none" />
<view v-if="chapterList.length" class="chapters">
<view class="chapter" v-for="(item, i) in chapterList" :key="i">
<view class="chapterName">
{{ item.name }}
<uni-icons class="arrow" type="bottom" color="#909090"></uni-icons>
</view>
<view class="section" v-if="item.subsectionList.length">
<view class="sectionName" :class="{ active: curLink === `${item.name}${section.name}` }"
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-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"
src="https://izhixinyun.com/images/exts/word.png" alt="">
<image v-else-if="section.fileType === 'txt'" class="ext" src="https://izhixinyun.com/images/exts/txt.png" alt="">
<image v-else-if="section.fileType === 'pdf'" class="ext" src="https://izhixinyun.com/images/exts/pdf.png" alt="">
<image v-else class="ext" src="https://izhixinyun.com/images/exts/pic.png" alt="">
{{ section.name }}
</view>
</view>
</view>
</view>
</view>
<!-- 练习成绩 -->
<view v-show="curTab === 2 && practices.length" class="list">
<view v-for="(item, i) in practices" :key="i" class="item" @click="toPrac(item)">
<view class="c-name">{{ item.projectName }}</view>
<view class="line">最高分{{ item.hightScore }}&emsp;&emsp;练习次数{{ item.practiceNum }}</view>
<view class="line">累计练习时长小时{{ item.hightScore }}</view>
<view class="line">最近练习时间{{ item.lastTime }}</view>
<view class="btn">练习情况</view>
</view>
</view>
<!-- 考核成绩 -->
<view v-show="curTab === 3 && ass.length" class="list">
<view v-for="(item, i) in ass" :key="i" class="item" @click="toDetail(item)">
<view class="c-name">{{ item.experimentalName }}</view>
<view class="line">得分{{ item.score }}&emsp;&emsp;耗时{{ item.timeSum }}min</view>
<view class="line">考核开始时间{{ item.startTime }}</view>
<view class="line">考核结束时间{{ item.lastTime }}</view>
<view class="btn">成绩报告</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { queryChaptersAndSubsections, curriculumDetail, queryPracticeByStudent, queryAssessmentByStudent } from '@/apis/modules/course.js'
export default {
data() {
return {
cid: '',
mallId: '',
curTab: 1,
tabs: [
{
name: '课程介绍',
id: 0
},
{
name: '课程目录',
id: 1
},
{
name: '练习成绩',
id: 2
},
{
name: '考核成绩',
id: 3
}
],
searchTimer: null,
keyword: '',
chapterList: [],
briefIntroduction: '',
practices: [],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
page: 1,
pageSize: 10,
ass: [],
reachBottomAss: 0, // 0->,1->,-1->
statusAss: 'more', // more|loading|noMore
pageAss: 1,
pageSizeAss: 10,
dotsStyles: {
backgroundColor: 'rgba(83, 200, 249,0.3)',
border: '1px rgba(83, 200, 249,0.3) solid',
color: '#fff',
selectedBackgroundColor: 'rgba(83, 200, 249,0.9)',
selectedBorder: '1px rgba(83, 200, 249,0.9) solid'
},
mpStyle: {
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;'
}
}
},
watch: {
keyword () {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.getChapter()
}, 500)
}
},
//
onPullDownRefresh() {
this.curTab === 2 && this.initPrac()
this.curTab === 3 && this.initAss()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1500)
},
//
onReachBottom() {
if (this.curTab === 2) {
//
if (this.reachBottom >= 0) {
this.reachBottom = 1
this.status = 'loading'
this.getPractices()
}
} else if (this.curTab === 3) {
//
if (this.reachBottomAss >= 0) {
this.reachBottomAss = 1
this.statusAss = 'loading'
this.getAss()
}
}
},
onShow() {
const pages = getCurrentPages()
const { options } = pages[pages.length - 1]
this.cid = options.cid
this.mallId = options.mallId
this.getChapter()
},
methods: {
//
async getChapter () {
if (this.cid) {
const res = await queryChaptersAndSubsections(this.cid)
this.chapterList = res.chapterList
// if (this.chapterList.length && this.chapterList[0].subsectionList && this.chapterList[0].subsectionList.length && !this.commentId) {
// this.preview(this.chapterList[0].subsectionList[0], this.chapterList[0].name, 1);
// }
}
},
//
async getInfo () {
if (this.cid && this.mallId) {
const { data } = await curriculumDetail(this.cid, this.mallId)
this.briefIntroduction = data.briefIntroduction
}
},
//
async getPractices () {
const { page } = await queryPracticeByStudent({
pageNum: this.page,
pageSize: this.pageSize,
mallId: this.mallId,
curriculumId: this.cid
})
this.practices = this.reachBottom > 0 ? [...this.practices, ...page.records] : page.records
this.page++ // page+1
const noMore = this.practices.length === page.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
},
//
async getAss () {
const { page } = await queryAssessmentByStudent({
pageNum: this.pageAss,
pageSize: this.pageSizeAss,
mallId: this.mallId,
curriculumId: this.cid
})
this.ass = this.reachBottom > 0 ? [...this.ass, ...page.records] : page.records
this.pageAss++ // page+1
const noMore = this.ass.length === page.total //
this.statusAss = noMore ? 'noMore' : 'more' // noMore
this.reachBottomAss = noMore ? -1 : 0 // -1
},
initPrac() {
this.page = 1
this.reachBottom = 0
this.getPractices()
},
initAss() {
this.pageAss = 1
this.reachBottomAss = 0
this.getAss()
},
// tab
tabChange(id) {
this.curTab = id
!id && !this.briefIntroduction && this.getInfo()
id === 2 && !this.practices.length && this.initPrac()
id === 3 && !this.ass.length && this.initAss()
},
//
toPrac(row) {
this.$util.to(`../practiceDetail/practiceDetail?cid=${this.cid}&projectId=${row.projectId || ''}&paperId=${row.paperId || ''}`)
},
}
}
</script>
<style scoped lang="scss">
.wrap {
padding-bottom: 140rpx;
}
.banner-wrap {
width: 100%;
.pic {
width: 100%;
}
}
.tabs {
display: flex;
justify-content: space-between;
margin-bottom: 32rpx;
li {
position: relative;
text-align: center;
font-size: 28rpx;
color: #333;
white-space: nowrap;
}
.active {
color: #007EFF;
&:after {
content: '';
position: absolute;
bottom: -12rpx;
left: 50%;
width: 116%;
height: 4rpx;
margin: 10rpx auto 0;
background-color: #007EFF;
transform: translateX(-50%);
}
}
}
.detail {
padding: 34rpx 32rpx;
background-color: #fff;
.chapters {
margin-top: 20rpx;
}
.chapter {
margin-bottom: 40rpx;
.chapterName {
display: flex;
justify-content: space-between;
font-size: 30rpx;
color: #333;
}
.arrow {
font-size: 28rpx;
}
.section {
margin: 20rpx 0;
}
.sectionName {
display: flex;
align-items: center;
margin: 20rpx 0;
font-size: 26rpx;
color: #333;
}
.ext {
width: 36rpx;
height: 36rpx;
margin-right: 10rpx;
}
}
.list {
.item {
position: relative;
padding: 20rpx 0;
border-bottom: 1px solid #e6e6e6;
}
.c-name {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.line {
margin-top: 14rpx;
font-size: 26rpx;
color: #828282;
}
.btn {
position: absolute;
bottom: 20rpx;
right: 0;
padding: 10rpx 30rpx;
font-size: 28rpx;
color: #fff;
background-color: #007EFF;
border-radius: 36rpx;
}
}
}
</style>

@ -0,0 +1,273 @@
<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>

@ -0,0 +1,504 @@
<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

@ -0,0 +1,285 @@
<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>

@ -0,0 +1,109 @@
<template>
<view class="page">
<view v-if="practices.length" class="list">
<view v-for="(item, i) in practices" :key="i" class="item" @click="toDetail(item)">
<view class="c-name">{{ item.projectName }}</view>
<view class="line">得分{{ item.score }}&emsp;&emsp;耗时{{ item.timeSum }}min</view>
<view class="line">练习开始时间{{ item.startTime }}</view>
<view class="line">练习结束时间{{ item.submitTime }}</view>
<view class="btn">成绩报告</view>
</view>
</view>
</view>
</template>
<script>
import { practiceByStudentDetail } from '@/apis/modules/course.js'
export default {
data() {
return {
cid: '',
projectId: '',
paperId: '',
practices: [],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
page: 1,
pageSize: 10,
}
},
//
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.cid = options.cid
this.projectId = options.projectId
this.paperId = options.paperId
this.getList()
},
methods: {
//
async getList () {
const { data } = await practiceByStudentDetail({
page: this.page,
pageSize: this.pageSize,
projectId: this.projectId,
paperId: this.paperId,
cid: this.cid
})
this.practices = this.reachBottom > 0 ? [...this.practices, ...data.records] : data.records
this.page++ // page+1
const noMore = this.practices.length === data.total //
this.status = noMore ? 'noMore' : 'more' // noMore
this.reachBottom = noMore ? -1 : 0 // -1
},
//
toDetail(row) {
// this.$util.to(path)
},
}
}
</script>
<style scoped lang="scss">
.page {
padding: 10rpx 30rpx;
background-color: #fff;
}
.list {
.item {
position: relative;
padding: 20rpx 0;
border-bottom: 1px solid #e6e6e6;
}
.c-name {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.line {
margin-top: 14rpx;
font-size: 26rpx;
color: #828282;
}
.btn {
position: absolute;
bottom: 20rpx;
right: 0;
padding: 10rpx 30rpx;
font-size: 28rpx;
color: #fff;
background-color: #007EFF;
border-radius: 36rpx;
}
}
</style>

@ -0,0 +1,107 @@
<template>
<view class="wrap">
<view class="title">用户隐私协议</view>
<view class="text">
我们非常重视对用户隐私的保护您在使用我们的服务时我们可能会收集和使用您的相关信息我们希望通过本用户隐私条款向您说明在使用我们的服务时我们如何收集使用披露存储这些信息本用户隐私条款系本平台保护用户个人隐私的承诺与您所使用的服务息息相关希望您仔细阅读
个人资料的收集
您在注册账户或使用我们的服务时向我们提供的相关个人信息例如电话号码电子邮件等您通过我们的服务向其他方提供的共享信息以及您使用我们的服务时所储存的信息我们收集数据是根据您与我们的互动和您所做出的选择包括您的隐私设置以及您使用的产品和功能我们收集的数据可能包括SDK/API/JS代码版本浏览器互联网服务提供商IP地址平台时间戳应用标识符应用程序版本应用分发渠道独立设备标识符iOS广告标识符IDFA)安卓广告主标识符网卡MAC地址国际移动设备识别码IMEI设备型号终端制造厂商终端设备操作系统版本会话启动/停止时间语言所在地时区和网络状态WiFi等硬盘CPU和电池使用情况等
个人资料的获取
您使用服务时我们可能收集如下信息
1日志信息指您使用我们的服务时系统可能通过cookieswebbeacon或其他方式自动采集的技术信息包括
1设备或软件信息例如您的移动设备网页浏览器或用于接入我们服务的其他程序所提供的配置信息您的IP地址和移动设备所用的版本和设备识别码等在使用我们服务时搜索或浏览的信息例如您使用的网页搜索词语访问的社交媒体页面url地址以及您在使用我们服务时浏览或要求提供的其他信息和内容详情
2有关您曾使用的移动应用APP和其他软件的信息以及您曾经使用该等移动应用和软件的信息
3您通过我们的服务进行通讯的信息例如曾通讯的账号以及通讯时间数据和时长
4您通过我们的服务分享的内容所包含的信息元数据例如拍摄或上传的共享照片或录像的日期时间或地点等
2位置信息指您开启设备定位功能并使用我们基于位置提供的相关服务时收集的有关您位置的信息包括
1您通过具有定位功能的移动设备使用我们的服务时通过GPS或WiFi等方式收集的您的地理位置信息
2您或其他用户提供的包含您所处地理位置的实时信息例如您提供的账户信息中包含的您所在地区信息
3您可以通过关闭定位功能停止对您的地理位置信息的收集
4我们的产品集成友盟+SDK友盟+SDK需要收集您的设备Mac地址唯一设备识别码IMEI/androidID/IDFA/OPENUDID/GUIDSIM卡IMSI信息以提供统计分析服务
APP涉及用户信息使用的SDK相关情况逐项列举详情如下
1华为推送/小米推送/vivo推送/oppo推送:
SDK类型推送通知
SDK描述用于实现消息推送(或其他推送)功能SDK
使用业务场景向用户推荐活动和提醒
收集个人信息的类型设备信息地理位置网络信息
设备信息设备标识符(IMEIIDFAAndroidIDMACOAID等相关信息)应用信息(应用崩溃信息通知开关状态软件列表等相关信息)设备参数及系统信息(设备类型设备型号操作系统及硬件相关信息)
网络信息IP地址WiFi信息基站信息等相关信息
使用目的/理由向用户推荐活动和提醒
2微信开放平台
SDK类型社交
SDK描述微信分享功能
SDK使用业务场景微信分享
SDK所需用户信息字段软件安装列表设备型号MAC地址IMEI号IMSI系统版本手机型号
使用目的/理由APP分享音频视频图片活动至微信客户端
3友盟分享
SDK类型社交
SDK描述分享功能
SDK使用业务场景分享到微信
SDK所需用户信息字段设备型号系统版本号手机型号分享信息
使用目的/理由APP分享图片活动至微信客户端
4友盟统计
SDK类型数据统计
SDK描述提供数据统计数据收集数据分析服务
SDK使用业务场景日活路径分析
SDK所需用户信息字段设备型号系统版本号手机型号发布渠道页面code数据
使用目的/理由数据收集进行数据分析提升产品体验
5Bugly
SDK类型性能监测
SDK描述提供移动端应用运行时崩溃卡顿监控服务
SDK使用业务场景对APP进行性能监控提升产品使用体验
SDK所需用户信息字段设备型号MAC地址IMEI号系统版本手机型号
使用目的/理由监控app使用过程中的奔溃信息分析提升用户体验
个人资料的披露
我们将采取合理的安全手段保护用户提供的个人及单位信息在未得到用户许可之前本平台不会擅自将用户信息披露给任何无关的第三方但涉及下列情形之一的除外
1法律强制规定或司法行政机关依照法定程序要求提供
2为保护用户的生命财产安全或为公共安全之需要
3为了保护本平台其他用户的合法权益或财产
4您出现违反中国有关法律法规或者本平台相关协议规则的情况需要向第三方披露
5其他特殊或紧急情况
由于用户对自身信息保密不当从而导致用户资料的泄露或由于网络线路黑客攻击计算机病毒等原因造成的资料泄露丢失被盗用或被篡改等本平台不承担任何责任
Cookies技术的使用
我们收集信息是为了向您提供更好更优更个性化的服务本公司将以合法的方式收集必要的用户个人资料本平台有可能收集的个人资料包括用户姓名身份证号地址电话号码电子邮件等信息用户在本平台注册时须依注册内容之提示提供用户本人及单位的真实准确完整信息并保证个人及单位资料的及时更新因用户提供个人及单位信息不准确不完整或未及时更新而可能遭受的任何损害本公司不承担任何责任
个人资料的存储
我们收集的有关您的信息和资料将保存在我们及其关联公司的服务器上
个人资料的保护
为保障您的信息安全我们将采取各种合理的安全措施来保护您的信息使您的信息不会被泄漏毁损或者丢失我们对可能接触到您的信息的员工也采取了严格管理包括但不限于根据岗位的不同采取不同的权限控制与他们签署保密协议监控他们的操作情况等措施我们会按现有技术提供相应的安全措施来保护您的信息提供合理的安全保障尽力做到使您的信息不被泄漏毁损或丢失您的账户均有安全保护功能请妥善保管您的账户及密码信息我们将通过向其它服务器备份对用户密码进行加密等安全措施确保您的信息不丢失不被滥用和变造
未成年人保护
我们重视未成年人的个人信息保护如您为未成年人建议您请您的监护人阅读本隐私权条款并在征得您的监护人同意的前提下使用我们的服务或向我们提供信息
联系我们
您可通过发送邮件至service@huorantech.cn与我们沟通我们将在15天内回复您的请求
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style scoped lang="scss">
.wrap {
padding: 30rpx;
.title {
margin-bottom: 30rpx;
font-size: 40rpx;
text-align: center;
}
.text {
font-size: 30rpx;
line-height: 1.6;
white-space: pre-wrap;
}
}
</style>

@ -0,0 +1,399 @@
<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>

@ -0,0 +1,88 @@
<template>
<view class="wrap">
<view class="title">服务协议</view>
<view class="text">我们提醒您在使用本平台的各项服务之前请您务必仔细阅读并透彻理解本声明如果您使用本平台服务的您的使用行为将被视为对本声明全部内容的认可若您不同意本声明中的全部或部分内容您应立即停止使用本平台服务</view>
<view class="text">知识产权声明</view>
<view class="text">1本平台内的所有产品技术软件程序数据及其他信息包括但不限于文字图像图片照片音频视频图表色彩版面设计电子文档的所有权利包括但不限于域名版权商标权专利权商业秘密及其他所有相关权利均归我们公司或其关联公司所有未经我司的许可任何人不得擅自使用</view>
<view class="text">2本平台的Logo等文字图形及其组合以及其他标识徵记产品和服务名称均为我司及其关联公司的注册商标未经我们的书面授权任何人不得以任何方式使用或作其他处理也不得向他人表明您有权使用或作其他处理</view>
<view class="text">3如果本平台内容无权利声明并不代表本平台对其不享有权利也不意味着本平台不主张权利您应根据诚信原则尊重该等内容的合法权益并进行合法使用您不得以任何方式修改复制公开展示公布或分发这些材料或者以其他方式把它们用于任何公开或商业目的禁止以任何目的把这些材料用于其他任何网站或其他平面媒体或网络计算机环境</view>
<view class="text">服务声明</view>
<view class="text">1我们向用户提供的所有产品或新增加的服务功能均适用本声明条款之规范</view>
<view class="text">2本平台所有信息软件均为按现状提供不带有任何明示或暗示的担保或条件包括但不限于准确性及时性和非侵权的默示担保或保证</view>
<view class="text">3本平台有权根据业务需要修订本服务声明并以平台公告的形式进行更新不再单独通知予您经修订的服务声明一经本平台公布即产生效力如您不同意相关修订请您立即停止使用本平台服务如您继续使用服务则将视为您已接受经修订的条款当您与本平台发生争议时应以最新的条款为准</view>
<view class="text">平台的使用</view>
<view class="text">1除法定许可或征得本公司同意本平台的信息及其任何组成部分不得被重新编辑复制抄袭或为任何未经本公司允许的商业目的所使用如果本公司确定用户行为违法或有损本平台和本公司的合法权益本公司将采取相关法律措施包括但不限于拒绝提供服务冻结或删除用户账号等</view>
<view class="text">2如果您从本站下载软件在使用软件时要遵守该软件附带的软件许可协议中所有的许可条款在您阅读并接受软件许可协议的各项条款之前不得下载或安装这一软件如果在适用的许可条款或协议中已经禁止复制或再分发这些软件您须遵照执行</view>
<view class="text">信息发布条款</view>
<view class="text">平台信息发布</view>
<view class="text">本平台所发布的信息由所有权人及其关联公司遵循真实原则发布发布人对平台信息不作任何保证或其它担保包括适销性适合于特定目的没有计算机病毒或不侵犯知识产权的保证</view>
<view class="text">用户信息发布</view>
<view class="text">1平台用户有权在本平台允许用户发布信息的版块发布信息用户在本平台发表或投递的信息回复必须遵守中华人民共和国各项法律法规条例不发布或链接有关政治破坏系统淫秽色情封建迷信人身攻击等违法信息不侵犯他人知识产权等</view>
<view class="text">2我们作为服务提供平台用户在使用时应当了解明白平台上所有信息均为用户自由发布用户应依法对其提供的任何信息承担全部责任我们会对信息进行必要的核查筛选但最终对信息的合法性准确性真实性不承担任何法律责任如用户发现某些信息中含有虚假违法内容请及时联系我们 待核实之后我们将根据中国法律法规和政府规范性文件采取措施移除相关内容或屏蔽相关链接我们不对用户所发布的信息之删除或储存失败负责若因用户发布内容引起任何刑事或民事纠纷发布者须自行承担该刑事民事或者经济法律责任同时本平台有权就发布者上述违法行为给予平台造成的任何损失要求赔偿</view>
<view class="text">隐私权政策</view>
<view class="text">我们非常重视对用户隐私的保护您在使用我们的服务时我们可能会收集和使用您的相关信息我们希望通过本用户隐私条款向您说明在使用我们的服务时我们如何收集使用披露存储这些信息本用户隐私条款系本平台保护用户个人隐私的承诺与您所使用的服务息息相关希望您仔细阅读</view>
<view class="text">个人资料的收集</view>
<view class="text">我们收集信息是为了向您提供更好更优更个性化的服务本公司将以合法的方式收集必要的用户个人资料本平台有可能收集的个人资料包括用户姓名身份证号地址电话号码电子邮件等信息用户在本平台注册时须依注册内容之提示提供用户本人及单位的真实准确完整信息并保证个人及单位资料的及时更新因用户提供个人及单位信息不准确不完整或未及时更新而可能遭受的任何损害本公司不承担任何责任</view>
<view class="text">个人资料的使用</view>
<view class="text">本公司有权为内部经营管理统计等目的使用您提供的个人及单位资料包括但不限于日常管理本公司提供给用户的服务及产品监控本平台的安全使用内部调研对来访数据进行统计和研究促进更新供用户享用的服务和产品确认核对联络名单为宣传推广目的为解决争议排除纠纷和执行本法律声明目的等</view>
<view class="text">个人资料的披露</view>
<view class="text">我们将采取合理的安全手段保护用户提供的个人及单位信息在未得到用户许可之前本平台不会擅自将用户信息披露给任何无关的第三方但涉及下列情形之一的除外</view>
<view class="text">1法律强制规定或司法行政机关依照法定程序要求提供</view>
<view class="text">2为保护用户的生命财产安全或为公共安全之需要</view>
<view class="text">3为了保护本平台其他用户的合法权益或财产</view>
<view class="text">4您出现违反中国有关法律法规或者本平台相关协议规则的情况需要向第三方披露</view>
<view class="text">5其他特殊或紧急情况</view>
<view class="text">由于用户对自身信息保密不当从而导致用户资料的泄露或由于网络线路黑客攻击计算机病毒等原因造成的资料泄露丢失被盗用或被篡改等本平台不承担任何责任</view>
<view class="text">Cookies技术的使用</view>
<view class="text">当用户访问设有Cookies装置的本平台时本平台服务器会自动发送Cookies至用户浏览器中同时储存进用户的电脑硬盘内此Cookies便负责记录日后用户访问本平台时的种种操作浏览习惯信用记录等运用Cookies技术我们能够为您提供更加周到的个性化服务我们将运用Cookies技术向用户提供其感兴趣的信息资料或为其储存密码</view>
<view class="text">个人资料的存储</view>
<view class="text">我们收集的有关您的信息和资料将保存在本公司及其关联公司的服务器上</view>
<view class="text">个人资料的保护</view>
<view class="text">为保障您的信息安全我们将采取各种合理的安全措施来保护您的信息使您的信息不会被泄漏毁损或者丢失我们对可能接触到您的信息的员工也采取了严格管理包括但不限于根据岗位的不同采取不同的权限控制与他们签署保密协议监控他们的操作情况等措施我们会按现有技术提供相应的安全措施来保护您的信息提供合理的安全保障尽力做到使您的信息不被泄漏毁损或丢失您的账户均有安全保护功能请妥善保管您的账户及密码信息我们将通过向其它服务器备份对用户密码进行加密等安全措施确保您的信息不丢失不被滥用和变造</view>
<view class="text">未成年人保护</view>
<view class="text">我们重视未成年人的个人信息保护如您为未成年人建议您请您的监护人阅读本隐私权条款并在征得您的监护人同意的前提下使用我们的服务或向我们提供信息</view>
<view class="text">免责条款</view>
<view class="text">1平台用户通过平台获取信息服务的过程中需务必遵守中国的相关法律法规平台不对用户达成协议过程中的任意纠纷承担法律责任</view>
<view class="text">2如买卖双方在交易过程中发生纠纷在当事人自愿平等的前提下买卖双方可提出要求平台协助调解平台会在查明事实分清是非的基础上严格遵守国家法律法规来给出建议不得因未经调解或者调解不成而阻止对方当事人向人民法院起诉经调解达成的协议具有法律效力但平台对此协议内容不承担任何法律责任</view>
<view class="text">3平台在此声明对您使用本平台与本平台相关的任何内容服务或其它链接至本平台的站点内容均不作直接间接法定约定的保证本平台对UGC用户原创内容的真实性不作保证也不承担因其非真实而造成的任何责任</view>
<view class="text">4本站到第三方平台的链接仅作为一种方便服务提供给您如果使用这些链接您将离开本站平台没有审查过任何第三方平台对这些平台及其内容不进行控制也不负任何责任如果您决定访问任何与本站链接的第三方平台其可能带来的结果和风险全部由您自己承担</view>
<view class="text">5用户应对使用平台得到的信息结果自行承担风险我们仅作为服务平台对本平台的使用即表明同意承担浏览本平台的全部风险本平台对任何使用或提供本网站信息的商业活动及其风险不承担任何责任用户自行发布的资源信息我们不对信息内容的安全性准确性真实性合法性负责也不承担任何法律责任</view>
<view class="text">6本平台如因线路硬件故障系统维护系统升级或其它不可抗力而导致暂停服务于暂停服务期间造成的一切不便与损失本平台不承担任何责任</view>
<view class="text">7本平台由于计算机黑客攻击计算机病毒侵入硬件设施损坏或因政府行为司法强制要求而造成个人资料泄露丢失被盗用或被篡改等本平台不承担任何责任</view>
<view class="text">8因不可抗力因素或第三方支付平台的系统漏洞故障造成交易环节中支付服务暂停或中断不稳定的本平台不承担任何责任</view>
<view class="text">9本平台上所有的增值服务或外包服务是为了方便用户更好地使用本平台而提供用户可自行选择接受与否您应在接受增值服务或外包服务之前阅读相关协议并按照您的需求和判断作出接受或不接受的意思表示若您选择接受增值服务及外包服务的视为您已经阅读相关协议并自行承担接受增值服务或外包服务的风险本平台不对任何提供给用户的增值服务及外包服务承担责任</view>
<view class="text">10任何单位或个人认为通过本平台网页内容可能涉嫌侵犯其知识产权应该及时向我们提出书面权利通知并提供身份证明权属证明及详细侵权情况证明我们收到上述法律文件后将会依法尽快处理</view>
<view class="text">法律管辖和适用</view>
<view class="text">任何有关本平台和本法律声明的争议纠纷均适用中华人民共和国法律任何有关本平台和本法律声明的争议应由有管辖权的人民法院管辖如中华人民共和国法律的修改使上述任何条款成为非法各方将同意由深圳智慧科技有限公司对上述条款作出修改</view>
<view class="text">本声明的解释权及对本平台及软件使用的解释权归结于本公司</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style scoped lang="scss">
.wrap {
padding: 30rpx;
.title {
margin-bottom: 30rpx;
font-size: 40rpx;
text-align: center;
}
.text {
font-size: 30rpx;
line-height: 1.6;
white-space: pre-wrap;
}
}
</style>

@ -0,0 +1,317 @@
<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>

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

@ -0,0 +1,135 @@
export const Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}

@ -0,0 +1,117 @@
var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let Crypto = {};
var util = Crypto.util = {
rotl: function (n, b) {
return (n << b) | (n >>> (32 - b));
},
rotr: function (n, b) {
return (n << (32 - b)) | (n >>> b);
},
endian: function (n) {
if (n.constructor == Number) {
return util.rotl(n, 8) & 0x00FF00FF |
util.rotl(n, 24) & 0xFF00FF00;
}
for (var i = 0; i < n.length; i++)
n[i] = util.endian(n[i]);
return n;
},
randomBytes: function (n) {
for (var bytes = []; n > 0; n--)
bytes.push(Math.floor(Math.random() * 256));
return bytes;
},
stringToBytes: function (str) {
var bytes = [];
for (var i = 0; i < str.length; i++)
bytes.push(str.charCodeAt(i));
return bytes;
},
bytesToString: function (bytes) {
var str = [];
for (var i = 0; i < bytes.length; i++)
str.push(String.fromCharCode(bytes[i]));
return str.join("");
},
stringToWords: function (str) {
var words = [];
for (var c = 0, b = 0; c < str.length; c++, b += 8)
words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);
return words;
},
bytesToWords: function (bytes) {
var words = [];
for (var i = 0, b = 0; i < bytes.length; i++, b += 8)
words[b >>> 5] |= bytes[i] << (24 - b % 32);
return words;
},
wordsToBytes: function (words) {
var bytes = [];
for (var b = 0; b < words.length * 32; b += 8)
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
return bytes;
},
bytesToHex: function (bytes) {
var hex = [];
for (var i = 0; i < bytes.length; i++) {
hex.push((bytes[i] >>> 4).toString(16));
hex.push((bytes[i] & 0xF).toString(16));
}
return hex.join("");
},
hexToBytes: function (hex) {
var bytes = [];
for (var c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return bytes;
},
bytesToBase64: function (bytes) {
if (typeof btoa == "function") return btoa(util.bytesToString(bytes));
var base64 = [],
overflow;
for (var i = 0; i < bytes.length; i++) {
switch (i % 3) {
case 0:
base64.push(base64map.charAt(bytes[i] >>> 2));
overflow = (bytes[i] & 0x3) << 4;
break;
case 1:
base64.push(base64map.charAt(overflow | (bytes[i] >>> 4)));
overflow = (bytes[i] & 0xF) << 2;
break;
case 2:
base64.push(base64map.charAt(overflow | (bytes[i] >>> 6)));
base64.push(base64map.charAt(bytes[i] & 0x3F));
overflow = -1;
}
}
if (overflow != undefined && overflow != -1)
base64.push(base64map.charAt(overflow));
while (base64.length % 4 != 0) base64.push("=");
return base64.join("");
},
base64ToBytes: function (base64) {
if (typeof atob == "function") return util.stringToBytes(atob(base64));
base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
var bytes = [];
for (var i = 0; i < base64.length; i++) {
switch (i % 4) {
case 1:
bytes.push((base64map.indexOf(base64.charAt(i - 1)) << 2) |
(base64map.indexOf(base64.charAt(i)) >>> 4));
break;
case 2:
bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0xF) << 4) |
(base64map.indexOf(base64.charAt(i)) >>> 2));
break;
case 3:
bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0x3) << 6) |
(base64map.indexOf(base64.charAt(i))));
break;
}
}
return bytes;
}
};
Crypto.mode = {};
export default Crypto;

@ -0,0 +1,37 @@
import Crypto from './crypto.js';
/*!
* Crypto-JS v1.1.0
* http://code.google.com/p/crypto-js/
* Copyright (c) 2009, Jeff Mott. All rights reserved.
* http://code.google.com/p/crypto-js/wiki/License
*/
(function(){
// Shortcut
var util = Crypto.util;
Crypto.HMAC = function (hasher, message, key, options) {
// Allow arbitrary length keys
key = key.length > hasher._blocksize * 4 ?
hasher(key, { asBytes: true }) :
util.stringToBytes(key);
// XOR keys with pad constants
var okey = key,
ikey = key.slice(0);
for (var i = 0; i < hasher._blocksize * 4; i++) {
okey[i] ^= 0x5C;
ikey[i] ^= 0x36;
}
var hmacbytes = hasher(util.bytesToString(okey) +
hasher(util.bytesToString(ikey) + message, { asString: true }),
{ asBytes: true });
return options && options.asBytes ? hmacbytes :
options && options.asString ? util.bytesToString(hmacbytes) :
util.bytesToHex(hmacbytes);
};
})();

@ -0,0 +1,82 @@
import Crypto from './crypto.js';
/*!
* Crypto-JS v1.1.0
* http://code.google.com/p/crypto-js/
* Copyright (c) 2009, Jeff Mott. All rights reserved.
* http://code.google.com/p/crypto-js/wiki/License
*/
(function(){
// Shortcut
var util = Crypto.util;
// Public API
var SHA1 = Crypto.SHA1 = function (message, options) {
var digestbytes = util.wordsToBytes(SHA1._sha1(message));
return options && options.asBytes ? digestbytes :
options && options.asString ? util.bytesToString(digestbytes) :
util.bytesToHex(digestbytes);
};
// The core
SHA1._sha1 = function (message) {
var m = util.stringToWords(message),
l = message.length * 8,
w = [],
H0 = 1732584193,
H1 = -271733879,
H2 = -1732584194,
H3 = 271733878,
H4 = -1009589776;
// Padding
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >>> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
var a = H0,
b = H1,
c = H2,
d = H3,
e = H4;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = m[i + j];
else {
var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
w[j] = (n << 1) | (n >>> 31);
}
var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
(H1 ^ H2 ^ H3) - 899497514);
H4 = H3;
H3 = H2;
H2 = (H1 << 30) | (H1 >>> 2);
H1 = H0;
H0 = t;
}
H0 += a;
H1 += b;
H2 += c;
H3 += d;
H4 += e;
}
return [H0, H1, H2, H3, H4];
};
// Package private blocksize
SHA1._blocksize = 16;
})();

@ -0,0 +1,71 @@
import Crypto from './crypto.js';
import './hmac.js';
import './sha1.js';
import Util from '@/libs/util'
import {Base64} from './base64.js';
let date=new Date()
date=date.setHours(date.getHours() + 24)
let extime=""+new Date(date).toISOString()
console.log(33, extime)
var policyText = {
"expiration": extime, //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了
"conditions": [
["content-length-range", 0, 1024*1024*100] // 设置上传文件的大小限制
]
};
var config={
accessid:'LTAI4FzqQHnk4rozqLZ8jCNj',
accesskey:'mveW7B1OyFoKUkHm8WsxmrjHmkJWHq',
osshost:'https://huoran.oss-cn-shenzhen.aliyuncs.com',
policyBase64:Base64.encode(JSON.stringify(policyText))
}
var message = config.policyBase64;
var bytes = Crypto.HMAC(Crypto.SHA1, message, config.accesskey, { asBytes: true }) ;
var signature = Crypto.util.bytesToBase64(bytes);
var timetamp = new Date().getTime();
function random_string(len) {
  len = len || 32;
  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
  var maxPos = chars.length;
  var pwd = '';
  for (let i = 0; i < len; i++) {
  pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
var OSS={
name:'aliyun',
host:config.osshost,
accessid:config.accessid,
signature:signature,
policyBase64:config.policyBase64,
}
export default function(tempFilePaths, callback) {
const ext = Util.getFileExt(tempFilePaths)
const fileName = Date.now() + '.' + ext
uni.uploadFile({
   url: OSS.host,
   filePath: tempFilePaths,
fileType: '',
name: 'file',
formData: {
name: fileName,
key: fileName,//文件名
  policy: OSS.policyBase64, // 输入你获取的的policy
OSSAccessKeyId: OSS.accessid, // 输入你的AccessKeyId
success_action_status: '200', // 让服务端返回200,不然,默认会返回204
signature: OSS.signature, // 输入你获取的的signature
},
success: (res) => {
callback({
name: fileName,
url: OSS.host + '/' + fileName,
ext
})
},
fail: (res) => {
console.log(res);
}
})
};

@ -0,0 +1,35 @@
var crypto = require('crypto')
function WXBizDataCrypt(appId, sessionKey) {
this.appId = appId
this.sessionKey = sessionKey
}
WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
// base64 decode
var sessionKey = new Buffer(this.sessionKey, 'base64')
encryptedData = new Buffer(encryptedData, 'base64')
iv = new Buffer(iv, 'base64')
try {
// 解密
var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
// 设置自动 padding 为 true,删除填充补位
decipher.setAutoPadding(true)
var decoded = decipher.update(encryptedData, 'binary', 'utf8')
decoded += decipher.final('utf8')
decoded = JSON.parse(decoded)
} catch (err) {
throw new Error('Illegal Buffer')
}
if (decoded.watermark.appid !== this.appId) {
throw new Error('Illegal Buffer')
}
return decoded
}
module.exports = WXBizDataCrypt

@ -0,0 +1,39 @@
/**
* @file 百度移动统计配置文件
*/
module.exports = {
/**
* 从百度移动统计获取的AppKey
* @type {string}
*/
appKey: 'ce2fa79380',
/**
* 是否使用了插件
* @type {boolean}
*/
hasPlugin: false,
/**
* 是否获取当前的地理位置和速度信息
* @type {boolean}
*/
getLocation: false,
/**
* 是否获取组件滚动信息
* @type {boolean}
*/
getComponentScroll: false,
/**
* 是否开启了A/B 测试
* @type {boolean}
*/
hasABTest: false,
/**
* 是否开启热力图功能
* @type {boolean}
*/
hasHeatmap: false,
};

File diff suppressed because one or more lines are too long

@ -0,0 +1,36 @@
export default{
// 监听用户点击右上角菜单的「转发」按钮时触发的事件
onShareAppMessage() {
// 设置转发的参数
return {
title: "职站商城",
// path: '',
imageUrl: "",
success: function(res) {
if (res.errMsg == 'shareAppMessage:ok') {
console.log("成功", res)
}
},
fail: function(res) {
console.log("失败", res)
}
}
},
// 分享到朋友圈
onShareTimeline:function(res){
return {
title: '职站商城',
// imageUrl:'/static/image/phone.png',
query:''
}
},
// 收藏
onAddToFavorites:function(res) {
return {
title: '职站商城',
// imageUrl:'/static/image/phone.png',
query: '',
}
}
}

@ -0,0 +1,18 @@
import uma from 'umtrack-wx';
uma.init({
appKey: '64cc98d5a1a164591b62da3e', // 由友盟分配的APP_KEY
useOpenid: true,
// 使用Openid进行统计,此项为false时将使用友盟+uuid进行用户统计。
// 使用Openid来统计微信小程序的用户,会使统计的指标更为准确,对系统准确性要求高的应用推荐使用Openid
autoGetOpenid: true,
// 使用openid进行统计时,是否授权友盟自动获取Openid,
// 如若需要,请到友盟后台"设置管理-应用信息"(https://mp.umeng.com/setting/appset)中设置appId及secret
debug: true,// 是否打开调试模式
uploadUserInfo: true, // 自动上传用户信息,设为false取消上传,默认为false
enableVerify: true
});
uma.install = function(Vue) {
Vue.prototype.$uma = uma;
}
export default uma;

@ -0,0 +1,129 @@
import Product from '@/config/product'
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/1709798668435.docx', // 人工智能
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798621083.docx', // 大数据
'https://huoran.oss-cn-shenzhen.aliyuncs.com/1709798646462.docx', // 金融科技
]
const docExts = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx']
export default {
// 路由跳转
to(url) {
uni.navigateTo({
url
})
},
// 成功提示
sucMsg(title, duration = 1500) {
uni.showToast({
title,
duration
})
},
// 错误提示
errMsg(title, duration = 1500) {
uni.showToast({
title,
icon: 'none',
duration
})
},
// 如果非数字,则返回0
handleNaN(val) {
return isNaN(val) || val == 0 ? '' : val
},
// 小于10,返回0+传入值
preZero(val) {
return val < 10 ? '0' + val : val
},
//返回格式化时间,传参例如:"yyyy-MM-dd hh:mm:ss"
formatDate(date, fmt = 'yyyy-MM-dd hh:mm:ss') {
var date = date ? date : new Date()
var o = {
"M+" : date.getMonth()+1, //月份
"d+" : date.getDate(), //日
"h+" : date.getHours(), //小时
"m+" : date.getMinutes(), //分
"s+" : date.getSeconds(), //秒
"q+" : Math.floor((date.getMonth()+3)/3), //季度
"S" : date.getMilliseconds() //毫秒
}
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length))
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)))
}
}
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) {
uni.showLoading({
title: '加载中',
mask: true
})
// 下载文件资源到本地
uni.downloadFile({
url: files[id],
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: 'pdf', // 文件类型,指定文件类型打开文件,有效值 doc, xls, ppt, pdf, docx, xlsx, pptx
showMenu: true, // 允许出现分享功能
success: res => {
uni.hideLoading()
},
fail: openError => {
uni.hideLoading()
}
})
},
fail: function(err) {
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 , '')
},
// 传入文件名获取文件后缀
getFileExt(fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
},
}

@ -0,0 +1,43 @@
// #ifndef VUE3
import Vue from 'vue'
import App from './App'
import util from '@/libs/util'
import uma from './libs/uma'
import share from './libs/share'
import mtjWxSdk from './libs/mtj-wx-sdk'
Vue.config.productionTip = false
Vue.prototype.$util = util
Vue.use(uma)
Vue.mixin(share)
App.mpType = 'app'
// 权限控制
Vue.prototype.auth = function(text){
const auth = uni.getStorageSync('auth')
if (text && auth && auth.length) {
const isPermission = auth.includes(text)
return auth.includes(text)
}
// return true
}
const app = new Vue({
...App,
share
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
import App from './App.vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif

@ -0,0 +1,73 @@
{
"name" : "职站商城",
"appid" : "__UNI__2E89BA6",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
/* 5+App */
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {},
/* */
"distribute" : {
/* */
"android" : {
/* android */
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
/* ios */
"sdkConfigs" : {}
}
},
/* SDK */
"sdkConfigs" : {},
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx2b506fdb0eeee65d",
"setting" : {
"urlCheck" : false,
"es6" : true,
"minified" : true
},
"usingComponents" : true,
"optimization" : {
"subPackages" : true
},
"uniStatistics" : {
"enable" : false
}
},
"vueVersion" : "2",
"uniStatistics" : {
"version" : "2"
},
"mp-toutiao" : {
"appid" : "tt2192572fbea04fe601"
}
}

777
package-lock.json generated

@ -0,0 +1,777 @@
{
"name": "筛选 菜单 筛选菜单 上拉筛选 ",
"version": "1.0.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ajv-errors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
"integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ=="
},
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
},
"ansi-colors": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
"integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA=="
},
"aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
},
"array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==",
"requires": {
"array-uniq": "^1.0.1"
}
},
"array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q=="
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
},
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"cacache": {
"version": "11.3.3",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz",
"integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==",
"requires": {
"bluebird": "^3.5.5",
"chownr": "^1.1.1",
"figgy-pudding": "^3.5.1",
"glob": "^7.1.4",
"graceful-fs": "^4.1.15",
"lru-cache": "^5.1.1",
"mississippi": "^3.0.0",
"mkdirp": "^0.5.1",
"move-concurrently": "^1.0.1",
"promise-inflight": "^1.0.1",
"rimraf": "^2.6.3",
"ssri": "^6.0.1",
"unique-filename": "^1.1.1",
"y18n": "^4.0.0"
}
},
"chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
},
"commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"concat-stream": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"requires": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^2.2.2",
"typedarray": "^0.0.6"
}
},
"copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
"integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
"requires": {
"aproba": "^1.1.1",
"fs-write-stream-atomic": "^1.0.8",
"iferr": "^0.1.5",
"mkdirp": "^0.5.1",
"rimraf": "^2.5.4",
"run-queue": "^1.0.0"
}
},
"copy-webpack-plugin": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.3.tgz",
"integrity": "sha512-PlZRs9CUMnAVylZq+vg2Juew662jWtwOXOqH4lbQD9ZFhRG9R7tVStOgHt21CBGVq7k5yIJaz8TXDLSjV+Lj8Q==",
"requires": {
"cacache": "^11.3.2",
"find-cache-dir": "^2.1.0",
"glob-parent": "^3.1.0",
"globby": "^7.1.1",
"is-glob": "^4.0.1",
"loader-utils": "^1.2.3",
"minimatch": "^3.0.4",
"normalize-path": "^3.0.0",
"p-limit": "^2.2.0",
"schema-utils": "^1.0.0",
"serialize-javascript": "^1.7.0",
"webpack-log": "^2.0.0"
}
},
"core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"cyclist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
"integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A=="
},
"dir-glob": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
"integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
"requires": {
"path-type": "^3.0.0"
}
},
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
"integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
"requires": {
"end-of-stream": "^1.0.0",
"inherits": "^2.0.1",
"readable-stream": "^2.0.0",
"stream-shift": "^1.0.0"
}
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"requires": {
"once": "^1.4.0"
}
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"figgy-pudding": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
"integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw=="
},
"find-cache-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
"integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
"requires": {
"commondir": "^1.0.1",
"make-dir": "^2.0.0",
"pkg-dir": "^3.0.0"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"requires": {
"locate-path": "^3.0.0"
}
},
"flush-write-stream": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
"integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
"requires": {
"inherits": "^2.0.3",
"readable-stream": "^2.3.6"
}
},
"from2": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
"integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==",
"requires": {
"inherits": "^2.0.1",
"readable-stream": "^2.0.0"
}
},
"fs-write-stream-atomic": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
"integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==",
"requires": {
"graceful-fs": "^4.1.2",
"iferr": "^0.1.5",
"imurmurhash": "^0.1.4",
"readable-stream": "1 || 2"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
"integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
"requires": {
"is-glob": "^3.1.0",
"path-dirname": "^1.0.0"
},
"dependencies": {
"is-glob": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
"integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
"requires": {
"is-extglob": "^2.1.0"
}
}
}
},
"globby": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
"integrity": "sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==",
"requires": {
"array-union": "^1.0.1",
"dir-glob": "^2.0.0",
"glob": "^7.1.2",
"ignore": "^3.3.5",
"pify": "^3.0.0",
"slash": "^1.0.0"
},
"dependencies": {
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
"integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="
}
}
},
"graceful-fs": {
"version": "4.2.10",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
},
"iferr": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
"integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA=="
},
"ignore": {
"version": "3.3.10",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
"integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug=="
},
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
},
"is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"requires": {
"is-extglob": "^2.1.1"
}
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"json5": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"requires": {
"minimist": "^1.2.0"
}
},
"loader-utils": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
"integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^1.0.1"
}
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
}
},
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"requires": {
"yallist": "^3.0.2"
}
},
"make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
"requires": {
"pify": "^4.0.1",
"semver": "^5.6.0"
}
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
},
"mississippi": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
"integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
"requires": {
"concat-stream": "^1.5.0",
"duplexify": "^3.4.2",
"end-of-stream": "^1.1.0",
"flush-write-stream": "^1.0.0",
"from2": "^2.1.0",
"parallel-transform": "^1.1.0",
"pump": "^3.0.0",
"pumpify": "^1.3.3",
"stream-each": "^1.1.0",
"through2": "^2.0.0"
}
},
"mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"requires": {
"minimist": "^1.2.6"
}
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
"integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==",
"requires": {
"aproba": "^1.1.1",
"copy-concurrently": "^1.0.0",
"fs-write-stream-atomic": "^1.0.8",
"mkdirp": "^0.5.1",
"rimraf": "^2.5.4",
"run-queue": "^1.0.3"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"requires": {
"wrappy": "1"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"requires": {
"p-limit": "^2.0.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"parallel-transform": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
"integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
"requires": {
"cyclist": "^1.0.1",
"inherits": "^2.0.3",
"readable-stream": "^2.1.5"
}
},
"path-dirname": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
"integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q=="
},
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
},
"path-type": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
"integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
"requires": {
"pify": "^3.0.0"
},
"dependencies": {
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
"integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="
}
}
},
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
},
"pkg-dir": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
"integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
"requires": {
"find-up": "^3.0.0"
}
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
"integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"pumpify": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
"integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
"requires": {
"duplexify": "^3.6.0",
"inherits": "^2.0.3",
"pump": "^2.0.0"
},
"dependencies": {
"pump": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
"integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
}
}
},
"punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"requires": {
"glob": "^7.1.3"
}
},
"run-queue": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
"integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==",
"requires": {
"aproba": "^1.1.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"schema-utils": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
"requires": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
"ajv-keywords": "^3.1.0"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"serialize-javascript": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz",
"integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A=="
},
"slash": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
"integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg=="
},
"ssri": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz",
"integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==",
"requires": {
"figgy-pudding": "^3.5.1"
}
},
"stream-each": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
"integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
"requires": {
"end-of-stream": "^1.1.0",
"stream-shift": "^1.0.0"
}
},
"stream-shift": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
},
"through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"requires": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
}
},
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
},
"umtrack-wx": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/umtrack-wx/-/umtrack-wx-2.8.0.tgz",
"integrity": "sha512-F5ul+Q7bDJ6MDrn9ysPAyB9nyP1vCxLGUBkSJ4uvknt8rjmX4tqy1IUnJuWKj9ZH2BtkjRFpldQXJSlLDOYfhQ=="
},
"unique-filename": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
"integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
"requires": {
"unique-slug": "^2.0.0"
}
},
"unique-slug": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
"integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
"requires": {
"imurmurhash": "^0.1.4"
}
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"requires": {
"punycode": "^2.1.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"webpack-log": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
"integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
"requires": {
"ansi-colors": "^3.0.0",
"uuid": "^3.3.2"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
}
}
}

@ -0,0 +1,16 @@
{
"id": "filter-popup",
"name": "筛选 菜单 筛选菜单 上拉筛选 ",
"version": "1.0.4",
"description": "筛选菜单,支持单选和多选 , 选择后的数据通过.sync双向绑定,全端支持 导入即用",
"keywords": [
"筛选",
"菜单",
"筛选菜单",
"上拉筛选"
],
"dependencies": {
"copy-webpack-plugin": "^5.0.3",
"umtrack-wx": "^2.8.0"
}
}

@ -0,0 +1,208 @@
{
"pages": [
{
"path" : "pages/login/login",
"style" :
{
"navigationBarTitleText": "登录",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/index/index",
"style" :
{"navigationBarTitleText": "课程",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/achievement/achievement",
"style" :
{
"navigationBarTitleText": "成绩",
"enablePullDownRefresh": true
}
},
{
"path" : "pages/person/person",
"style" :
{
"navigationBarTitleText": "我的",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
}
],
"subPackages": [
{
"root": "course",
"pages": [
{
"path" : "courseDetail/courseDetail",
"style" :
{
"navigationBarTitleText": "课程详情",
"enablePullDownRefresh": true
}
},
{
"path" : "practiceDetail/practiceDetail",
"style" :
{
"navigationBarTitleText": "练习情况",
"enablePullDownRefresh": true
}
}
]
},
{
"root": "user",
"pages": [
{
"path" : "reg/reg",
"style" :
{
"navigationBarTitleText": "绑定账号",
"enablePullDownRefresh": false
}
},
{
"path" : "selectAccount/selectAccount",
"style" :
{
"navigationBarTitleText": "选择账号",
"enablePullDownRefresh": false
}
},
{
"path" : "setting/setting",
"style" :
{
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false
}
},
{
"path" : "password/password",
"style" :
{
"navigationBarTitleText": "修改密码",
"enablePullDownRefresh": false
}
},
{
"path" : "addStaff/addStaff",
"style" :
{
"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" : "qrcode/qrcode",
"style" :
{
"navigationBarTitleText": "邀请加入",
"enablePullDownRefresh": false
}
}
,{
"path" : "article/article",
"style" :
{
"navigationBarTitleText": "学习",
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#fff",
"enablePullDownRefresh": false
}
}
,{
"path" : "scheme/scheme",
"style" :
{
"navigationBarTitleText": "方案详情",
"enablePullDownRefresh": false
}
},
{
"path" : "send/send",
"style" :
{
"navigationBarTitleText": "下载发送",
"enablePullDownRefresh": false
}
}
]
}
],
"preloadRule": {
"pages/index/index": {
"network": "all",
"packages": ["course"]
}
},
"condition": { //
"current": 0, //list
"list": [{
"name": "test", //
"path": "pages/login/login" //
}]
},
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "慧教云舟",
"navigationBarBackgroundColor": "#007EFF",
"backgroundColor": "#f5f5f5",
"app-plus": {
"background": "#efeff4"
}
},
"tabBar": {
"color": "#B8B9B8",
"selectedColor": "#007FFF",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"fontSize": "22px",
"iconWidth": "20px",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "static/image/tab1.png",
"selectedIconPath": "static/image/tab1-1.png",
"text": "课程"
}, {
"pagePath": "pages/achievement/achievement",
"iconPath": "static/image/tab2.png",
"selectedIconPath": "static/image/tab2-1.png",
"text": "成绩"
}, {
"pagePath": "pages/person/person",
"iconPath": "static/image/tab4.png",
"selectedIconPath": "static/image/tab4-1.png",
"text": "我的"
}]
}
}

@ -0,0 +1,216 @@
<template>
<view class="page">
<view class="wrap">
<view class="p-title">
<image class="icon" src="https://izhixinyun.com/images/record5.png" mode="widthFix"></image> 成绩概览
</view>
<view class="stat">
<view class="item">
<view class="val">{{ overview.userName }}</view>
<view class="name">姓名</view>
</view>
<view class="item">
<view class="val">{{ overview.experimentalNum }}</view>
<view class="name">实验次数()</view>
</view>
<view class="item">
<view class="val">{{ overview.duration ? overview.duration : 0 }}小时</view>
<view class="name">实验总时长()</view>
</view>
<view class="item">
<view class="val">{{ overview.avgScore ? overview.avgScore.toFixed(2) : overview.avgScore }}</view>
<view class="name">实验平均分</view>
</view>
</view>
</view>
<view class="wrap">
<view class="p-title">
<image class="icon" src="https://izhixinyun.com/images/record6.png" mode="widthFix"></image> 成绩记录明细
</view>
<ul class="tabs">
<li v-for="(item, i) in tabs" :key="i" :class="{active: curTab === item.id}" @click="tabChange(item.id)">{{ item.name }}</li>
</ul>
</view>
</view>
</template>
<script>
import { experimentOverview } from '@/apis/modules/course.js'
export default {
data() {
return {
overview: {},
curTab: 0,
tabs: [
{
id: 0,
name: '练习'
},
{
id: 1,
name: '考核'
},
],
list: [],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
page: 1,
pageSize: 10,
}
},
onShow() {
this.getOverview()
},
methods: {
//
async getOverview () {
const res = await experimentOverview()
this.overview = res.data
},
// tab
tabChange(id) {
this.curTab = id
},
//
toModule(i) {
this.$uma.trackEvent(i) //
let path = '/order/clients/clients'
if (i === 'plan') {
path = '/team/plans/plans'
} else if (i === 'study') {
path = '/team/study/study'
} else if (i === 'info') {
path = '/team/info/info'
}
this.$util.to(path, { type: i })
},
//
toPanel(i) {
this.$util.errMsg('功能暂未开放!')
}
}
}
</script>
<style scoped lang="scss">
.page {
.wrap {
padding: 30rpx;
margin-bottom: 30rpx;
background-color: #fff;
}
.p-title {
display: flex;
align-items: center;
margin-bottom: 20rpx;
font-size: 28rpx;
color: #333;
.icon {
width: 44rpx;
margin-right: 8rpx;
}
}
.tabs {
display: flex;
margin-bottom: 32rpx;
li {
position: relative;
margin-right: 40rpx;
text-align: center;
font-size: 28rpx;
color: #333;
}
.active {
color: #007EFF;
&:after {
content: '';
position: absolute;
bottom: -12rpx;
left: 50%;
width: 116%;
height: 4rpx;
margin: 10rpx auto 0;
background-color: #007EFF;
transform: translateX(-50%);
}
}
}
.stat {
display: flex;
flex-wrap: wrap;
gap: 32rpx;
.item:nth-child(1) {
background: url(https://izhixinyun.com/images/record1.png) (88% 25px) / auto no-repeat,
url(https://izhixinyun.com/images/record1.png) 0 0/100% 100% no-repeat;
}
.item:nth-child(2) {
background: url(https://izhixinyun.com/images/record2-1.png) (88% 15px) / auto no-repeat,
url(https://izhixinyun.com/images/record2.png) 0 0/100% 100% no-repeat;
}
.item:nth-child(3) {
background: url(https://izhixinyun.com/images/record3-1.png) (88% 20px) / auto no-repeat,
url(https://izhixinyun.com/images/record3.png) 0 0/100% 100% no-repeat;
}
.item:nth-child(4) {
margin-right: 0;
background: url(https://izhixinyun.com/images/record4-1.png) (88% 18px) / auto no-repeat,
url(https://izhixinyun.com/images/record4.png) 0 0/100% 100% no-repeat;
}
.item {
width: calc(50% - 16rpx);
padding: 30rpx;
border-radius: 8rpx;
box-sizing: border-box;
.name {
margin-top: 8rpx;
color: #fff;
font-size: 28rpx;
}
.val {
font-size: 42rpx;
color: #fff;
}
}
}
.list {
.item {
position: relative;
padding: 20rpx 0;
border-bottom: 1px solid #e6e6e6;
}
.c-name {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.line {
margin-top: 14rpx;
font-size: 26rpx;
color: #828282;
}
.btn {
position: absolute;
bottom: 20rpx;
right: 0;
padding: 10rpx 30rpx;
font-size: 28rpx;
color: #fff;
background-color: #007EFF;
border-radius: 36rpx;
}
}
}
</style>

@ -0,0 +1,166 @@
<template>
<view>
<view class="filter">
<uni-search-bar class="search" radius="30" placeholder="请输入课程名称" v-model="keyword" clearButton="auto" cancelButton="none" />
</view>
<ul class="tab-wrap">
<scroll-view scroll-x :scroll-left="scrollLeft" class="tab tab-scroll">
<li v-for="(tab, i) in tabs" :key="i" :class="{active: curTab === tab.classificationId}" @click="tabChange(tab.classificationId)">{{ tab.classificationName }}</li>
</scroll-view>
</ul>
<ul class="list">
<li v-for="(item, i) in list" :key="i" @click="toDetail(item)">
<image class="cover" :src="item.coverUrl"></image>
<view class="name">{{ item.goodsName }}</view>
<view class="entry">进入课程</view>
</li>
</ul>
</view>
</template>
<script>
import { schoolCourse, recentUse, getSchoolCourseAuthority } from '@/apis/modules/course.js'
export default {
data() {
return {
curTab: 0,
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)
},
onShow() {
// uni.setStorageSync('token', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjM5NTc2LCJyblN0ciI6Ik5vcTB1UlNEZ0V0UExOUzBSUWtSZHlVVGsxOFYycnpNIiwiYWNjb3VudElkIjozOTU3NiwidXNlcklkIjozOTU3NSwic2Nob29sSWQiOjI4NDYsInVzZXJOYW1lIjoiYWMiLCJwbGF0Zm9ybUlkIjoiMSJ9.-YiaJdr5H2j6TGezs1eDS1EX5bNYCWGGghRw6eD3jk4')
this.getTab()
},
methods: {
//
async getList() {
// 使
if (this.curTab === 0) {
const { page } = await recentUse({
pageNum: 1,
pageSize: 100,
goodsName: this.keyword,
})
this.list = page.records
} else {
const { data } = await schoolCourse({
authority: this.curTab === -1 ? '' : this.curTab,
goodsName: this.keyword,
})
this.list = data
}
},
// tab
async getTab () {
const { data } = await getSchoolCourseAuthority()
this.tabs = [
{
classificationId: 0,
classificationName: '最近使用',
},
{
classificationId: -1,
classificationName: '全部',
},
...data,
]
this.getList()
},
// tab
tabChange(id) {
this.curTab = id
this.initList()
},
//
toDetail(item) {
this.$util.to(`/course/courseDetail/courseDetail?cid=${item.cid}&mallId=${item.mallId}`)
},
}
}
</script>
<style scoped lang="scss">
.tab-wrap {
display: flex;
.tab-scroll {
white-space: nowrap;
li {
display: inline-block;
}
}
}
.list {
display: flex;
flex-wrap: wrap;
padding: 40rpx 30rpx 30rpx;
li {
width: calc(50% - 16rpx);
padding: 24rpx;
margin: 0 30rpx 52rpx 0;
border-radius: 16rpx;
background-color: #fff;
box-sizing: border-box;
&:nth-child(2n) {
margin-right: 0;
}
}
.cover {
width: 100%;
height: 160rpx;
margin-top: -50rpx;
border-radius: 20rpx;
object-fit: cover;
}
.name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
overflow: hidden;
height: 76rpx;
margin: 10rpx 0 16rpx;
font-size: 28rpx;
color: #333;
}
.entry {
font-size: 28rpx;
line-height: 1.9;
color: #333;
text-align: center;
border: 1px solid #dadada;
border-radius: 40rpx;
}
}
</style>

@ -0,0 +1,347 @@
<template>
<view class="page">
<view class="wrap">
<view class="logo">
<image class="icon" src="https://izhixinyun.com/images/hjyz-logo.png" mode="widthFix"></image>
<view class="texts">
<view class="cn">慧教云舟</view>
<view class="en">EduVessel</view>
</view>
</view>
<template v-if="isLogin">
<button class="btn phone" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber">
<image src="@/static/image/phone.png" mode="widthFix"></image>
{{ isReg ? '获取手机号' : '绑定手机'}}
</button>
<view class="tips">未注册或未绑定职站商城的手机号将帮你注册新账号</view>
</template>
<template v-else>
<view class="btn wechat" @click="login">
快捷登录
</view>
</template>
<view class="agree">
<uni-data-checkbox class="check" multiple v-model="agree" :localdata="agreeData"></uni-data-checkbox>
<text @click="toAgreement(0)">用户服务协议</text>
<text @click="toAgreement(1)">用户隐私协议</text>
</view>
</view>
</view>
</template>
<script>
import { studentWeChatAppletCallback, studentBinding, weChatToken } from '@/apis/modules/user.js'
import WXBizDataCrypt from '@/libs/WXBizDataCrypt'
export default {
data() {
return {
agree: [],
agreeData: [{
text: '同意',
value: 1
}],
isLogin: false, //
isReg: false, //
sessionKey: '',
openid: '',
unionid: '',
submiting: false
}
},
onShow() {
// uni.setStorageSync('token', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjM5NTc2LCJyblN0ciI6IjZXZUtCNTdOMU9ubGhBSG53RmJwMWN0c3VuVWlyR2l5IiwiYWNjb3VudElkIjozOTU3NiwidXNlcklkIjozOTU3NSwic2Nob29sSWQiOjI4NDYsInVzZXJOYW1lIjoiYWMiLCJwbGF0Zm9ybUlkIjoiMSJ9.hYkjwTUdMMYQLXJVRmqnw3tqRvGndNAzUiVh1ClyCec')
//
this.checkLogin()
},
methods: {
//
checkLogin() {
if (uni.getStorageSync('token')) {
this.toIndex()
} else {
uni.clearStorageSync()
this.isLogin = false
}
},
//
login() {
this.isReg = false
if (this.agree.length) {
if (this.submiting) return false
const that = this
uni.getUserProfile({
lang: 'zh_CN',
desc: '登录',
success: ({ userInfo }) => {
uni.login({
success: async ({ code }) => {
if (code) {
this.submiting = true
//
try {
const res = await studentWeChatAppletCallback({
code,
avatarUrl: userInfo.avatarUrl
})
const { data, status } = res
this.submiting = false
const e = data.sessionKey
this.sessionKey = e.session_key
this.openid = e.openid
// this.unionid = e.unionid
uni.setStorageSync('sessionKey', e.session_key)
uni.setStorageSync('openid', e.openid)
//
if (data.state === 'login') {
this.toIndex()
uni.setStorageSync('token', data.token)
} else {
//
// this.$util.to(`../reg/reg?openid=${this.openid}`)
this.isLogin = true
this.isReg = true
}
} catch (e) {
this.submiting = false
}
} else {
this.submiting = false
that.$util.errMsg('登录失败!')
}
}
})
},
fail(res) {
that.$util.errMsg('登录授权失败!')
}
})
} else {
this.$util.errMsg('请先阅读勾选协议!')
}
},
//
async onGetPhoneNumber(e){
if (this.submiting) return false
const { encryptedData, iv } = e.detail
// 1.使js2.使 ()
const appId = this.isDy ? 'tt2192572fbea04fe601' : uni.getAccountInfoSync().miniProgram.appId
const pc = new WXBizDataCrypt(appId , this.sessionKey)
const data = pc.decryptData(encryptedData , iv)
this.submiting = true
const phone = data.phoneNumber
if (this.isReg) { //
this.submiting = false
const { data } = await studentBinding({
openid: this.openid,
phone,
platformId: 1
})
const accounts = data.userAccounts
if (accounts instanceof Array) {
uni.setStorageSync('accounts', JSON.stringify(accounts))
this.$util.to(`/user/selectAccount/selectAccount?openid=${this.openid}&phone=${phone}`)
} else {
this.token = data.token
uni.setStorageSync('token', data.token)
this.toIndex()
}
} else { //
try {
const fn = this.isDy ? douYinUserBinding : userBinding
const res = await fn({
openid: this.openid,
phone,
unionid: this.unionid,
platformId: 4
})
const { token, status } = res
if (status == 10014) {
// unilogincode
uni.login({
success: ({ code }) => {
getSessionKey({
code,
}).then(({ sessionKey }) => {
this.sessionKey = sessionKey.session_key
this.openid = sessionKey.openid
this.$util.to(`../reg/reg?openid=${this.openid}&phone=${phone}`)
}).catch(e => {})
this.isReg = true
}
})
} else {
this.submiting = false
uni.setStorageSync('token', token)
this.toIndex()
}
} catch (e) {
this.submiting = false
uni.showToast({
title: e.message,
icon: 'none'
})
}
}
},
//
toReg() {
this.isReg = true
if (this.agree.length) {
const that = this
uni.getUserProfile({
lang: 'zh_CN',
desc: '登录',
success: ({ userInfo }) => {
uni.setStorageSync('userName', userInfo.nickName)
uni.setStorageSync('avatar', userInfo.avatarUrl)
uni.login({
success: ({ code }) => {
if (code) {
this.submiting = true
getSessionKey({
code,
}).then(({ sessionKey }) => {
this.sessionKey = sessionKey.session_key
this.openid = sessionKey.openid
this.submiting = false
this.isLogin = true
}).catch(e => {
this.submiting = false
})
} else {
this.submiting = false
that.$util.errMsg('登录失败!')
}
}
})
},
fail(res) {
that.$util.errMsg('登录授权失败!')
}
})
} else {
this.$util.errMsg('请先阅读勾选协议!')
}
},
toAgreement(id) {
this.$util.to(id ? `/order/privacyAgreement/privacyAgreement` : `/order/serviceAgreement/serviceAgreement`)
},
//
toIndex() {
uni.reLaunch({
url: '../index/index'
})
}
}
}
</script>
<style scoped lang="scss">
.page {
min-height: calc(100vh - 170rpx);
padding-top: 170rpx;
background: url(@/static/image/login1.png) 0 0/175rpx auto no-repeat,
url(@/static/image/login2.png) bottom right/123rpx auto no-repeat;
overflow: hidden;
}
.wrap {
position: relative;
height: 60vh;
padding: 214rpx 74rpx 28rpx;
margin: 0 61rpx;
background-color: #fff;
border-radius: 20rpx;
.logo {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 40rpx;
color: #333;
.icon {
width: 150rpx;
margin-right: 20rpx;
}
.cn {
margin-bottom: 10rpx;
font-size: 40rpx;
font-weight: 600;
}
.en {
font-size: 28rpx;
}
}
.hello {
margin: 36rpx 0;
font-size: 28rpx;
color: #333;
}
.tips {
margin-top: 30rpx;
font-size: 26rpx;
color: #adadad;
text-align: left;
}
.btn {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 88rpx;
font-size: 32rpx;
border-radius: 10rpx;
image {
width: 50rpx;
margin-right: 15rpx;
}
}
.wechat {
margin-bottom: 38rpx;
color: #fff;
background-color: #007EFF;
}
.phone {
color: #007EFF;
border: 1px solid #007EFF;
background-color: #fff;
image {
width: 40rpx;
}
}
.reg {
font-size: 28rpx;
color: #e61717;
text-align: right;
}
.agree {
position: absolute;
bottom: 28rpx;
left: 0%;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
text-align: center;
font-size: 24rpx;
color: #ccc;
text {
color: #007EFF;
}
}
/deep/.check {
.checklist-box {
margin: 0;
}
.checkbox__inner {
width: 40rpx !important;
height: 40rpx !important;
border-radius: 50% !important;
}
.checkbox__inner-icon {
top: 8rpx !important;
left: 14rpx !important;
}
}
}
</style>

@ -0,0 +1,360 @@
<template>
<view>
<view :class="[{'not-auth': !per}]">
<view class="filter">
<uni-search-bar class="search" radius="30" placeholder="请输入学校名称,商务经理,订单号" v-model="keyword" clearButton="auto" cancelButton="none" />
<view :class="['sort', sort]" @click="switchSort"></view>
<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">
<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.orderContent }}</view>
<view v-if="item.orderContent && item.orderContent.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('/order/orderDetail/orderDetail')"></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 { queryCustomer } from '@/apis/modules/client.js'
import { list, del } from '@/apis/modules/order.js'
export default {
data() {
return {
per: true, //
popup: false,
//
filterData: [
{
children: false,//
title: "订单状态",
key: "orderStatus", //
keyValue: "value", //
isRadio: true, //
data: [
{
title: "待发货",
value: 0
},
{
title: "已完成",
value: 1
},
{
title: "已取消",
value: 2
},
],
}
],
filterForm: {},
curTab: 0,
tabs: [
{
name: '我的订单',
id: 0
},
{
name: '团队全部订单',
id: 1
}
],
reachBottom: 0, // 0->,1->,-1->
status: 'more', // more|loading|noMore
searchTimer: null,
orderStatus: '',
sort: 'desc',
keyword: '',
list: [],
page: 1,
pageSize: 10,
delOption: [{
text: '删除',
style: {
backgroundColor: '#F56C6C'
}
}],
}
},
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
//
try {
uni.removeStorageSync('orderForm')
uni.removeStorageSync('courses')
} catch (e) {}
this.initRole()
this.$uma.trackEvent('order') //
},
methods: {
//
initRole() {
const auth = uni.getStorageSync('auth')
if (!auth.includes('订单')) {
this.per = false
this.list = [
{
businessManagerName: '智信云',
customerName: '智信云师资培训班',
orderContent: 'python实训系统',
createTime: '2023-08-08'
},
{
businessManagerName: '智信云智信云智信云',
customerName: '智信云师资培训班',
orderContent: 'python实训系统',
createTime: '2023-08-08'
},
{
businessManagerName: '智信云智信云',
customerName: '智信云师资培训班',
orderContent: 'python系统',
createTime: '2023-08-08'
},
{
businessManagerName: '智信云',
customerName: '智信云师资培训班智信云师资培训班',
orderContent: 'python实训系统,实训系统',
createTime: '2023-08-08'
},
{
businessManagerName: '智信云',
customerName: '智信云师资培训班',
orderContent: 'python实训系统',
createTime: '2023-08-08'
}
]
}
this.tabs = []
auth.includes('订单:我的订单') && this.tabs.push({
name: '我的订单',
id: 0
})
auth.includes('订单:团队全部订单') && this.tabs.push({
name: '团队全部订单',
id: 1
})
const len = this.tabs.length
// tab
if (len === 1) {
this.curTab = this.tabs[0].id
this.tabs = []
}
this.per && this.initList()
},
getList() {
const data = {
businessManagerId: this.$util.getBmId(),
teamId: uni.getStorageSync('team').id,
keywords: this.keyword,
pageNum: this.page,
pageSize: this.pageSize,
sort: this.sort,
orderStatus: this.orderStatus,
type: this.curTab
}
uni.showLoading({
title: '加载中'
})
list(data).then(({ data }) => {
uni.hideLoading()
// list
const list = data.records
list.map(e => {
if (e.orderContent) e.toggle = e.orderContent.length < 14 // 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()
},
//
toggle(item) {
item.toggle = !item.toggle
},
//
subFinsh(val) {
const { orderStatus } = val
this.orderStatus = orderStatus.length ? orderStatus[0] : ''
this.initList()
},
//
switchSort() {
this.sort = this.sort === 'desc' ? 'asc' : 'desc'
this.initList()
},
// tab
tabChange(tab) {
this.curTab = tab.id
this.initList()
},
//
toDetail(item) {
this.$util.to(`/order/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.initList()
}).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>

@ -0,0 +1,409 @@
<template>
<view class="page">
<view class="status-bar"></view>
<image class="bg" src="@/static/image/person-bg.png"></image>
<view class="wrap">
<view class="info">
<button class="avatar-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image class="avatar" :src="avatar" mode=""></image>
</button>
<view class="text">
<view class="name">{{ my.info.userName }}</view>
<view class="phone">{{ my.info.phone }}</view>
</view>
<view v-if="!disabled" class="tag">团队负责人</view>
</view>
<view class="list">
<view v-if="auth('我的:我的团队')" class="item" @click="$util.to('/team/teams/teams')">
<view class="left">
<image class="icon" src="@/static/image/person4.png" mode=""></image>
<text class="name">{{ disabled ? '所属团队' : '我的团队' }}</text>
</view>
<uni-icons type="right" size="15" color="#ccc"></uni-icons>
</view>
<view v-if="!hasOwnTeam && auth('我的:我的团队')" class="item" @click="createTeam">
<view class="left">
<image class="icon" src="@/static/image/person4.png" mode=""></image>
<text class="name">创建自己的团队</text>
</view>
<uni-icons type="right" size="15" color="#ccc"></uni-icons>
</view>
<view v-if="auth('我的:团队收益')" class="item">
<view class="left">
<image class="icon" src="@/static/image/person2.png" mode=""></image>
<text class="name">团队收益</text>
</view>
<text class="val">{{ my.teamIncome }}</text>
</view>
<view v-if="auth('我的:我的项目收益')" class="item">
<view class="left">
<image class="icon" src="@/static/image/person1.png" mode=""></image>
<text class="name">我的项目收益</text>
</view>
<text class="val">{{ my.myIncome }}</text>
</view>
<!-- <view class="item">
<view class="left">
<image class="icon" src="@/static/image/person5.png" mode=""></image>
<text class="name">我的收藏</text>
</view>
</view> -->
<view v-if="auth('我的:市场服务费')" class="item">
<view class="left">
<image class="icon" src="@/static/image/person26.png" mode=""></image>
<text class="name">市场服务费</text>
</view>
<text class="val">{{ my.teamInfo.annualMarketingFee ? '项目抽成' + my.teamInfo.annualMarketingFee + '%' :'-' }}</text>
</view>
<view v-if="auth('我的:团队年费')" class="item">
<view class="left">
<image class="icon" src="@/static/image/person27.png" mode=""></image>
<text class="name">团队年费</text>
</view>
<text class="val">{{ my.teamInfo.annualTeamFee ? '固定年费' + my.teamInfo.annualTeamFee + 'w' : '-' }}</text>
</view>
<view v-if="auth('我的:业务省份')" class="item">
<view class="left">
<image class="icon" src="@/static/image/person8.png" mode=""></image>
<text class="name">业务省份</text>
</view>
<view class="val">
<text v-if="disabled" class="name">{{ provinceName }}</text>
<uni-data-picker v-else class="picker-input" :clear-icon="false" :readonly="disabled" placeholder="请选择省份" popup-title="请选择省份" preload :localdata="provinces" :map="{text: 'provinceName', value: 'provinceId'}" v-model="provinceId" @change="getCity"></uni-data-picker>
</view>
</view>
<view v-if="auth('我的:业务城市')" class="item">
<view class="left">
<image class="icon" src="@/static/image/person9.png" mode=""></image>
<text class="name">业务城市</text>
</view>
<view class="val">
<text v-if="disabled" class="name">{{ cityName }}</text>
<uni-data-picker v-else class="picker-input" :clear-icon="false" :readonly="disabled" placeholder="请选择城市" popup-title="请选择城市" preload :localdata="cities" :map="{text: 'cityName', value: 'cityId'}" v-model="cityId" @change="submit"></uni-data-picker>
</view>
</view>
<view v-if="auth('我的:设置')" class="item" @click="toSet">
<view class="left">
<image class="icon" src="@/static/image/person3.png" mode=""></image>
<text class="name">设置</text>
</view>
</view>
</view>
</view>
<view v-if="!per" class="per-mask">功能升级中敬请期待...</view>
</view>
</template>
<script>
import { my, editProvinceCity } from '@/apis/modules/parner.js'
import { queryProvince, queryCity, updateAvatars, getUserRolesPermissionMenu } from '@/apis/modules/user.js'
import { getTeamsByAccountId } from '@/apis/modules/client.js'
import OSS from '@/libs/Oss/upload'
export default {
data() {
return {
per: true, //
teamId: uni.getStorageSync('teamId') || '',
teams: [],
my: {
info: {
phone: ''
},
teamInfo: {
annualMarketingFee: '',
annualTeamFee: '',
},
myIncome: 0,
teamIncome: 0
},
avatar: uni.getStorageSync('avatar') || '@/static/image/avatar.png',
userName: uni.getStorageSync('userName'),
hasOwnTeam: 0, //
disabled: true,
provinces: [],
cities: [],
provinceIcon: {
color: '#007eff',
size: '22',
type: 'location'
},
cityIcon: {
color: '#007eff',
size: '22',
type: 'map-pin-ellipse'
},
provinceId: '',
cityId: '',
provinceName: '',
cityName: ''
}
},
onShow() {
this.per = true
if (uni.getStorageSync('token')) {
this.getTeam()
} else {
uni.redirectTo({
url: '/pages/login/login'
})
}
},
methods: {
//
initRole() {
if (!uni.getStorageSync('auth').includes('我的')) {
this.per = false
} else {
this.getInfo()
}
},
//
getAuth() {
uni.showLoading({
title: '加载中'
})
getUserRolesPermissionMenu({
teamId: this.teams.find(e => e.teamId == this.teamId).partnerClassificationId,
platformId: 4
}).then(({ permissionMenu }) => {
uni.hideLoading()
const auth = []
//
const generateAuth = (list, parent) => {
list.map(e => {
const name = `${parent ? parent + ':' : ''}${e.name}`
auth.push(name)
generateAuth(e.children, name)
})
}
generateAuth(permissionMenu[0].children, '')
uni.setStorageSync('auth', auth)
this.initRole()
}).catch(e => {
uni.hideLoading()
uni.setStorageSync('auth', [])
this.initRole()
})
},
//
getTeam() {
uni.showLoading({
title: '加载中'
})
getTeamsByAccountId().then(({ data }) => {
let hasOwnTeam = 0 //
data.map(e => {
const n = e.partnerClassificationList
e.id = n.id
// parnerIdidteamIduni.getStorageSync('team').partnerId使
e.teamId = e.isTeam == 1 ? +e.partnerClassificationId : n.id
e.partnerClassificationName = n.partnerClassificationName
delete e.partnerClassificationList
if (e.isTeam == 1) hasOwnTeam = 1
})
this.hasOwnTeam = hasOwnTeam
const teamId = uni.getStorageSync('teamId')
if (data.length) {
/**
* @description 如果是第一次进则默认选中第一个团队并把该团队的信息存入缓存
* 或者团队列表里没有该id则说明超管已经被转让也需要重新选中团队
*/
const curTeam = data.find(e => e.teamId == teamId)
if (teamId && curTeam) {
uni.setStorageSync('team', curTeam)
} else if (!uni.getStorageSync('team') || !curTeam) {
this.teamId = data[0].teamId
uni.setStorageSync('teamId', data[0].teamId)
uni.setStorageSync('team', data[0])
}
} else {
// 退
uni.hideLoading()
uni.clearStorageSync()
uni.redirectTo({
url: '../index/index'
})
}
this.disabled = uni.getStorageSync('team').isTeam == 0 //
this.teams = data
this.getAuth()
}).catch(e => {
uni.hideLoading()
})
},
//
getInfo() {
const { partnerId, teamId } = uni.getStorageSync('team')
my({
partnerId,
teamId
}).then(({ my }) => {
this.my = my
const avatar = my.info.userAvatars || 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'
this.avatar = avatar
uni.setStorageSync('avatar', avatar)
this.provinceId = my.teamInfo.provinceId
this.cityId = my.teamInfo.cityId
uni.setStorageSync('provinceId', this.provinceId)
uni.setStorageSync('cityId', this.cityId)
this.getProvince()
this.provinceId && this.getCity()
}).catch(e => {})
},
//
onChooseAvatar(e) {
OSS(e.detail.avatarUrl, ({ url }) => {
updateAvatars(url).then(res => {
this.getInfo()
}).catch(e => {})
})
},
//
createTeam() {
this.$util.to(`../reg/reg?openid=${uni.getStorageSync('openid')}&phone=${this.my.info.phone}&my=1`)
},
//
toSet() {
this.$util.to(`/team/setting/setting`)
},
//
getProvince() {
queryProvince().then(({ list }) => {
if (this.disabled) {
const { provinceId } = this
this.provinceName = list.find(e => e.provinceId == provinceId).provinceName
} else {
this.provinces = list
}
}).catch(res => {})
},
//
getCity(val) {
if (this.provinceId) {
queryCity({
provinceId: this.provinceId
}).then(({ list }) => {
if (this.disabled) {
const { cityId } = this
this.cityName = list.find(e => e.cityId == cityId).cityName
} else {
this.cities = list
}
}).catch(res => {})
} else {
this.cities = []
}
if (val) this.cityId = ''
},
//
submit() {
const { partnerId, teamId } = uni.getStorageSync('team')
editProvinceCity({
provinceId: this.provinceId,
cityId: this.cityId,
classificationId: teamId,
partnerId
}).then(({ my }) => {
this.$util.sucMsg('修改成功')
}).catch(e => {})
},
}
}
</script>
<style scoped lang="scss">
.status-bar {
// width: 100%;
// height: calc(var(--status-bar-height) + 120rpx);
}
.bg {
width: 100%;
height: calc(var(--status-bar-height) + 250rpx);
// #ifdef MP-WEIXIN
height: calc(var(--status-bar-height) + 317rpx);
// #endif
}
.wrap {
position: relative;
padding: 0 24rpx;
margin-top: -150rpx;
}
.info {
display: flex;
align-items: center;
padding: 26rpx 34rpx;
background-color: #fff;
border-radius: 16rpx;
.avatar-btn {
padding: 0;
margin: 0 28rpx 0 0;
line-height: 0;
border: 0 !important;
background-color: transparent;
outline: none;
border-radius: 50%;
}
.avatar {
width: 120rpx;
height: 120rpx;
border: 0;
}
.text {
margin-right: 20rpx;
}
.name {
margin-bottom: 10rpx;
font-size: 40rpx;
color: #333;
}
.phone {
font-size: 28rpx;
color: #333;
}
.tag {
padding: 8rpx 16rpx;
margin-top: -50rpx;
font-size: 24rpx;
color: #fff;
background-color: #2979ff;
border-radius: 20px;
}
}
.list {
margin-top: 16rpx;
.item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 26rpx 28rpx;
margin-bottom: 16rpx;
background-color: #fff;
border-radius: 16rpx;
}
.left {
display: inline-flex;
align-items: center;
}
.icon {
width: 40rpx;
height: 40rpx;
margin-right: 16rpx;
}
text {
font-size: 28rpx;
color: #333;
}
}
.location {
margin-top: 30rpx;
}
.picker-wrap {
margin-top: 4px;
}
.name {
font-size: 24rpx;
}
</style>

@ -0,0 +1,32 @@
@font-face {
font-family: "iconfont"; src: url('/static/iconfont/iconfont.ttf') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-qrcode:before {
content: "\e7dd";
}
.icon-dingdan:before {
content: "\e601";
}
.icon-product:before {
content: "\e788";
}
.icon-edit:before {
content: "\e621";
}
.icon-filter:before {
content: "\e6b9";
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 B

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save