@ -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/ |
||||||
|
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 |
||||||
|
"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,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 {}; |
||||||
|
}, |
||||||
|
}, |
||||||
|
// 遮罩的动画样式, 是否使用使用zoom进行scale进行缩放 |
||||||
|
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) { |
||||||
|
// 当展示遮罩的时候,设置scale为1,达到缩小(原来为1.2)的效果 |
||||||
|
this.zoomStyle.transform = "scale(1, 1)"; |
||||||
|
} else if (!n && this.zoom) { |
||||||
|
// 当隐藏遮罩的时候,设置scale为1.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, |
||||||
|
}, |
||||||
|
// 此为内部参数,不在文档对外使用,为了解决Picker和keyboard等融合了弹窗的组件 |
||||||
|
// 对v-model双向绑定多层调用造成报错不能修改props值的问题 |
||||||
|
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-left为左上角,top-right为右上角,bottom-left为左下角,bottom-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-top,往上偏移,避免和键盘重合的情况,仅在mode=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() { |
||||||
|
// 组件渲染完成时,检查value是否为true,如果是,弹出popup |
||||||
|
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() { |
||||||
|
// 标记关闭是内部发生的,否则修改了value值,导致watch中对value检测,导致再执行一遍close |
||||||
|
// 造成@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.popup为false,意味着为picker,actionsheet等组件调用了popup组件 |
||||||
|
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"></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: 权限。0数据平台,1为课程,2职站增值模块,3实训课程(非集成),4实验工具 |
||||||
|
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) |
||||||
|
// 选中的情况下,该产品如果没有push到已选数组里,则push |
||||||
|
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) |
||||||
|
// 选中的情况下,该产品如果没有push到已选数组里,则push |
||||||
|
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, // 启用否:1启用,0禁用 |
||||||
|
ship: 0, // 发货否(0未发货,1已发货,默认不发货) |
||||||
|
authority, // 区分权限 0为数据平台权限,1为课程权限 |
||||||
|
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 = [] |
||||||
|
// 有5种产品,要传不同的authority调renew接口 |
||||||
|
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 }}  练习次数:{{ 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 }}  耗时:{{ 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> |
@ -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 }}  耗时:{{ 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、日志信息,指您使用我们的服务时,系统可能通过cookies、web、beacon或其他方式自动采集的技术信息,包括: |
||||||
|
1)设备或软件信息,例如您的移动设备、网页浏览器或用于接入我们服务的其他程序所提供的配置信息、您的IP地址和移动设备所用的版本和设备识别码等;在使用我们服务时搜索或浏览的信息,例如您使用的网页搜索词语、访问的社交媒体页面url地址,以及您在使用我们服务时浏览或要求提供的其他信息和内容详情; |
||||||
|
2)有关您曾使用的移动应用(APP)和其他软件的信息,以及您曾经使用该等移动应用和软件的信息; |
||||||
|
3)您通过我们的服务进行通讯的信息,例如曾通讯的账号,以及通讯时间、数据和时长; |
||||||
|
4)您通过我们的服务分享的内容所包含的信息(元数据),例如拍摄或上传的共享照片或录像的日期、时间或地点等。 |
||||||
|
|
||||||
|
2、位置信息,指您开启设备定位功能并使用我们基于位置提供的相关服务时,收集的有关您位置的信息,包括: |
||||||
|
1)您通过具有定位功能的移动设备使用我们的服务时,通过GPS或WiFi等方式收集的您的地理位置信息; |
||||||
|
2)您或其他用户提供的包含您所处地理位置的实时信息,例如您提供的账户信息中包含的您所在地区信息; |
||||||
|
3)您可以通过关闭定位功能,停止对您的地理位置信息的收集。 |
||||||
|
4)我们的产品集成友盟+SDK,友盟+SDK需要收集您的设备Mac地址、唯一设备识别码(IMEI/androidID/IDFA/OPENUDID/GUID、SIM卡IMSI信息)以提供统计分析服务。 |
||||||
|
(三)APP涉及用户信息使用的SDK相关情况逐项列举,详情如下: |
||||||
|
1、华为推送/小米推送/vivo推送/oppo推送: |
||||||
|
SDK类型:推送通知; |
||||||
|
SDK描述:用于实现消息推送(或其他推送)功能SDK; |
||||||
|
使用业务场景:向用户推荐活动和提醒; |
||||||
|
收集个人信息的类型:设备信息、地理位置、网络信息; |
||||||
|
设备信息:设备标识符(IMEI、IDFA、Android、ID、MAC、OAID等相关信息)、应用信息(应用崩溃信息、通知开关状态、软件列表等相关信息)、设备参数及系统信息(设备类型、设备型号、操作系统及硬件相关信息); |
||||||
|
网络信息:IP地址,WiFi信息,基站信息等相关信息; |
||||||
|
使用目的/理由:向用户推荐活动和提醒。 |
||||||
|
|
||||||
|
2、微信开放平台: |
||||||
|
SDK类型:社交; |
||||||
|
SDK描述:微信分享功能; |
||||||
|
SDK使用业务场景:微信分享; |
||||||
|
SDK所需用户信息字段:软件安装列表、设备型号、MAC地址、IMEI号、IMSI、系统版本、手机型号; |
||||||
|
使用目的/理由:APP分享音频、视频,图片,活动至微信客户端。 |
||||||
|
|
||||||
|
3、友盟分享: |
||||||
|
SDK类型:社交; |
||||||
|
SDK描述:分享功能; |
||||||
|
SDK使用业务场景:分享到微信; |
||||||
|
SDK所需用户信息字段:设备型号,系统版本号,手机型号,分享信息; |
||||||
|
使用目的/理由:APP分享图片,活动至微信客户端。 |
||||||
|
|
||||||
|
4、友盟统计: |
||||||
|
SDK类型:数据统计; |
||||||
|
SDK描述:提供数据统计,数据收集,数据分析服务; |
||||||
|
SDK使用业务场景:日活,路径分析; |
||||||
|
SDK所需用户信息字段:设备型号,系统版本号,手机型号,发布渠道,页面code数据; |
||||||
|
使用目的/理由:数据收集,进行数据分析,提升产品体验。 |
||||||
|
|
||||||
|
5、Bugly: |
||||||
|
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) |
||||||
|
// 选中的情况下,该产品如果没有push到已选数组里,则push |
||||||
|
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, // 启用否:1启用,0禁用 |
||||||
|
ship: 0, // 发货否(0未发货,1已发货,默认不发货) |
||||||
|
authority, // 区分权限 0为数据平台权限,1为课程权限 |
||||||
|
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,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, |
||||||
|
}; |
@ -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(/(<[^>]+>)|(( )+)/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" |
||||||
|
} |
||||||
|
} |
@ -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.前端使用js完成;2.使用接口完成 (抖音) |
||||||
|
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) { |
||||||
|
// 这里需要再调一次uni的login,因为code用过了一次,已经失效了 |
||||||
|
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 |
||||||
|
// parnerId是商务经理id,teamId则是下面这个,其他地方要用的话直接uni.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"; |
||||||
|
} |
||||||
|
|
After Width: | Height: | Size: 257 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 775 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 599 B |
After Width: | Height: | Size: 439 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 518 B |
After Width: | Height: | Size: 522 B |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 528 B |
After Width: | Height: | Size: 620 B |
After Width: | Height: | Size: 382 B |
After Width: | Height: | Size: 537 B |
After Width: | Height: | Size: 514 B |
After Width: | Height: | Size: 689 B |
After Width: | Height: | Size: 519 B |
After Width: | Height: | Size: 457 B |
After Width: | Height: | Size: 270 B |
After Width: | Height: | Size: 734 B |
After Width: | Height: | Size: 372 B |
After Width: | Height: | Size: 302 B |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 483 B |
After Width: | Height: | Size: 434 B |
After Width: | Height: | Size: 298 B |
After Width: | Height: | Size: 351 B |
After Width: | Height: | Size: 641 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 480 B |
After Width: | Height: | Size: 440 B |
After Width: | Height: | Size: 347 B |
After Width: | Height: | Size: 1007 B |