UNPKG

npm-cts-ui

Version:

UI KIT for Taro

967 lines (858 loc) 30.5 kB
// ======================================== 全局方法 ======================================== import Taro from '@tarojs/taro' import qs from 'qs' import dateformat from 'dateformat' export default { /** * 全局请求方法 * @param url 请求路径 * @param method 请求方法 * @param data 请求参数 * @param isLoading 是否显示加载 */ async requestBase(url: string, method: string = 'GET', data: object = {}, isLoading = true) { return this.request('/basic' + url, method, data, isLoading, true) }, /** * 全局请求方法 * @param url 请求路径 * @param method 请求方法 * @param data 请求参数 * @param isLoading 是否显示加载 * @param isBase 是否是基础服务 */ async request(url: string, method: string = 'GET', data: object = {}, isLoading = true, isBase = false) { let that = this return new Promise((resolve, reject) => { let type = 'application/json' //默认application/json if (this.useFormData.includes(url)) type = 'application/x-www-form-urlencoded' let header = { 'content-type': type, 'Accept-Language': 'zh-CN,zh;q=0.9' } // 是否使用登录服务 if (['/wxma/session', '/wxma/getUserInfo'].includes(url)) { url = this.authUrl + url } else { header['Authorization'] = 'Bearer ' + Taro.getStorageSync('access_token') if (isBase) { url = this.baseUrl + url } else { url = this.baseUrl + this.apiLink + url } } let timeout = 10000 if (isLoading) Taro.showLoading({ title: '加载中...', mask: true }) Taro.request({ url, method, header, data, timeout, success(res) { Taro.stopPullDownRefresh() if (res.statusCode === 200) { if (res.data.success) { if (isLoading) Taro.hideLoading() that.transformNullAndUndef(res.data) resolve(res.data) } else { Taro.showToast({ title: res.data.msg || res.data.message, icon: 'none' }) reject(res) } } else if (res.statusCode === 500) { Taro.showToast({ title: '服务器异常,请稍后重试', icon: 'none' }) reject() } else { Taro.showToast({ title: res.data.msg || res.data.message || '链接失败,请稍后重试', icon: 'none' }) reject() } }, fail(err) { Taro.stopPullDownRefresh() that.requestError(err.errMsg) } }) }) }, // 微信登录,手机验证码登录 login(url: string, method: string = 'POST', data: any = {}) { let that = this return new Promise((resolve, reject) => { let type = 'application/x-www-form-urlencoded' url = this.authUrl + url Taro.showLoading({ title: '加载中...', mask: true }) Taro.request({ url, method, header: { 'content-type': type }, data, async success(res) { console.log(res) switch (res.statusCode) { case 200: // 若success为true,则不是第一次登录,微信登录成功。若success为false,则是第一次登录,需要跳转到手机验证码登录 if (res.data.access_token) { // console.log('微信一键登录') // Taro.hideLoading() Taro.setStorageSync('access_token', res.data.access_token) // 获取用户权限(项目版,劳务版,监管版调用) if (['/cts', '/sgd', '/ggb'].includes(that.apiLink)) { await that.getUserPermissions() } // 用户个人信息接口 await that.getUserInfo() // 查询所有区域信息 await that.getArea() // 获取项目所有字典码 that.getAllDict() // 若是手机号登录,则缓存手机号 if (data.mobile) { Taro.setStorageSync('mobile', data.mobile) } Taro.hideLoading() } else { Taro.showToast({ title: res.data.message, icon: 'none' }) } that.transformNullAndUndef(res.data) resolve(res.data) break case 400: // 若是微信自动登录(小程序),则不提示错误信息 if (data.grant_type !== 'wxma') { Taro.showToast({ title: res.data.message.includes('username or password') ? '微信号未绑定手机号,请绑定手机号登录' : res.data.message, icon: 'none', duration: 2000 }) } else { Taro.hideLoading() } Taro.removeStorageSync('access_token') that.transformNullAndUndef(res.data) resolve(res.data) break; default: Taro.showToast({ title: res.data.msg || res.data.message, icon: 'none' }) break } }, fail(err) { that.requestError(err.errMsg) } }) }) }, // 获取微信用户信息,wechatScanParams中存在style,则是从扫描二维码进来或微信分享进来 getUserInfoApi(iv, encryptedData, wechatScanParams) { const { style } = wechatScanParams // 获取用户信息,判断 头像或昵称有一个为空,则getUserInfo接口,updateFlag 为true,否则为false this.request(`/user/account/info`, 'GET', {}, false).then(res => { console.log(res) let params = { acc: 'miniapp-team', open_id: Taro.getStorageSync('open_id'), iv, encrypted_data: encryptedData, updateFlag: (!res.data.headImg || !res.data.nickname) } console.log(params) // 获取微信用户信息,并更新至系统用户信息(选填) this.request('/wxma/getUserInfo', 'POST', params, false).then(res => { // 是否授权用户信息 Taro.setStorageSync('isUserInfo', true) // 存在style,则是从扫描二维码进来或者微信扫码进来,则跳转到对应的页面。否则跳转到首页 if (style) { Taro.navigateTo({ url: `${wechatScanParams.url}?${qs.stringify(wechatScanParams)}` }) } else { // 获取用户权限(项目版,劳务版,监管版使用navigateTo跳转到首页) if (['/cts', '/sgd', '/ggb'].includes(this.apiLink)) { Taro.navigateTo({ url: this.homePage }) } else { Taro.switchTab({ url: this.homePage }) } } }) }) }, // 请求失败提示函数 requestError(errMsg) { let errObj = { fail: '网络异常!请检查你的网络状态', timeout: '网络超时!请检查你的网络状况' } let timeoutReg = new RegExp('timeout|请求超时') if (timeoutReg.test(errMsg)) { Taro.showToast({ title: errObj.timeout, icon: 'none' }) return } if (errMsg.includes('request:fail')) { Taro.showToast({ title: errObj.fail, icon: 'none' }) return } Taro.showToast({ title: errMsg, icon: 'none' }) }, /** * 将响应数据的null和undefined转化为空 * @param obj 响应数据 */ transformNullAndUndef(obj: object) { for (let i in obj) { let val = obj[i] // 对象 if (val && Object.prototype.toString.call(val) === '[object Object]') { this.transformNullAndUndef(val) } // 数组 if (val && Object.prototype.toString.call(val) === '[object Array]') { for (let v of val) { this.transformNullAndUndef(v) } } // 基本数据类型null和undefined,转化为空 if (['[object Null]', '[object Undefined]'].includes(Object.prototype.toString.call(val))) { obj[i] = '' } } }, // 获取用户权限 async getUserPermissions() { if (!this.getPermission('user')) { return new Promise(resolve => { this.request(`/user/permission/listForUser`, 'GET', {}, false).then(res => { this.setPermission('user', res.data) resolve(res) }) }); } }, // 用户个人信息接口 getUserInfo() { return new Promise((resolve, reject) => { this.request(`/user/account/info`, 'GET', {}, false).then(res => { Taro.setStorageSync('userInfo', res.data) resolve(res.data) }) }) }, // 查询所有区域信息 async getArea() { if (!Taro.getStorageSync('region')) { let res = await this.requestBase('/area/lists', 'GET', {}, false) Taro.setStorageSync('region', res.data) } }, // 根据字典码,查询字典表数据 getDictCode(type: string) { return new Promise(resolve => { this.requestBase('/dict/listByCode', 'GET', { dictCode: type }, false).then(res => { // 根据返回数据计算字典码选中对象 let dictList = this.getListByCode(res.data) // 格式:[{ value: '', text: '' }] resolve({ dictData: res.data, dictList }) }) }) }, // 根据返回数据计算字典码选中对象 getListByCode(data) { let list: any[] = [] for (let i in data) { list.push({ value: i, text: data[i] }) } return list }, // 获取项目所有字典码 getAllDict() { return new Promise((resolve, reject) => { let promises: any[] = [] for (let i in this.dicts) { if (!this.getDictsStorage[this.dicts[i]]) { promises.push(this.setDictsStorage(this.dicts[i])) } } Promise.all(promises).then(res => { console.log('获取所有字典表成功') resolve(res) }) }) }, // 根据类型,存储相对应的数字字典数据 setDictsStorage(type: string) { return new Promise(resolve => { this.requestBase('/dict/listByCode', 'GET', { dictCode: type }, false).then(res => { Taro.setStorageSync('dictCode_' + type, res.data) resolve(res) }) }); }, // 根据类型,获取相对应的数字字典数据 getDictsStorage(type: string) { return Taro.getStorageSync('dictCode_' + type) }, // [TREE]根据字典码查询所有子字典项 treeGetByCode(params) { return new Promise((resolve, reject) => { Taro['common'].requestBase('/dict/v2/tree/getByCode', 'GET', params, false).then(res => { resolve(res.data) }) }) }, // [TREE]根据父ID查询所有子字典项 getTreeDictByPrarentId(params) { return new Promise((resolve, reject) => { Taro['common'].requestBase('/dict/v2/tree/getByParentId', 'GET', params, false).then(res => { resolve(res.data) }) }) }, // [ARRAY]根据字典码查询直属子字典项列表 getDictByCode(params) { return new Promise((resolve, reject) => { Taro['common'].requestBase('/dict/v2/list/getByCode', 'GET', params, false).then(res => { resolve(res.data) }) }) }, // [ARRAY]根据父ID查询直属子字典项列表 getDictByParentId(params) { return new Promise((resolve, reject) => { Taro['common'].requestBase('/dict/v2/list/getByParentId', 'GET', params, false).then(res => { resolve(res.data) }) }) }, // 根据返回数据计算字典码选中对象(返回value,name) getListByCodeData(data) { let obj: any = {} for (let item of data) { obj[item.value] = item.name } return obj }, // 根据省市区id,查询省市区详细地址 getAreaProvinceId(data) { return new Promise((resolve) => { const { provinceId, cityId, districtId } = data const params: any = { provinceId, cityId } if (districtId) params.districtId = districtId this.requestBase('/area/region', 'GET', params, false).then(res => { resolve(res) }) }) }, // 扫码 scanCode() { let that = this return new Promise((resolve, reject) => { // console.log(Taro.getSystemInfoSync()) const { platform, version } = Taro.getSystemInfoSync() if (platform === 'ios' && version === '7.0.5') { Taro.showToast({ title: '当前微信版本是7.0.5,不支持扫码功能,请升级微信版本', icon: 'none' }) reject() return } Taro.scanCode({ success(res) { console.log('扫码内容', res, that.envList) // 当前环境是开发环境,二维码是测试环境,扫描开发环境的二维码 // 判断是否是当前环境,如:开发环境,测试环境,生产环境 let paramsUrl = res.result.split('?')[1] let params = qs.parse(paramsUrl) let { env } = params if (env !== process.env.NODE_ENV) { Taro.showToast({ title: `当前环境为${that.envList[process.env.NODE_ENV]},该二维码为${that.envList[env]},请对应环境再操作!`, icon: 'none', duration: 3000 }) return } resolve(res.result) }, fail(err) { console.log(err) } }) }) }, /** * 上传附件返回url * @param params 上传参数 * @param flag 是否是多张图片上传,默认为false * @param loading 是否显示上传中... */ uploadFile(params, flag: boolean = false, loading = true) { // console.log(params) if (loading) { Taro.showLoading({ title: '上传中...', mask: true }) } return new Promise((resolve, reject) => { Taro.uploadFile({ url: this.baseUrl + '/basic/attachment/upload', filePath: params.file, // 本地图片转化为file对象 name: 'file', formData: { sysCode: params.sysCode, bizCode: params.bizCode }, success(res) { console.log('上传附件返回url: ', res) if (res.statusCode === 200) { let data = JSON.parse(res.data) if (data.success) { if (!flag && loading) { Taro.hideLoading() } resolve(data) } else { Taro.showToast({ title: res.data.msg, icon: 'none' }) } } else { Taro.showToast({ title: '服务器异常,请稍后重试', icon: 'none' }) } }, fail(err) { console.log('上传文件失败:', err) Taro.showToast({ title: err.errMsg.includes('timeout') ? '网络超时!请检查你的网络状况' : err.errMsg, icon: 'none' }) } }) }) }, /** * 时间格式化 * @param date 日期数据 * @param type 返回类型,如:yyyy年mm月dd日,如timeago:返回某个时间前 * @param agotime 几年前的当月或当天当天 */ dateFormat(date: any, type: string = 'yyyy年mm月dd日', agotime: number = 0) { // console.log(date) if (date) { switch (type) { case 'timeago': const timestamp = new Date(date).getTime() let minute = 1000 * 60 let hour = minute * 60 let days = hour * 24 let week = days * 7 let months = days * 15 let now = new Date().getTime() // 获取当前时间毫秒 let diffValue = now - timestamp; // 时间差 if (diffValue < 0) { return '' } // 计算时间差的分,时,天,周,月 let minC = diffValue / minute let hourC = diffValue / hour let dayC = diffValue / days let weekC = diffValue / week let monthC = diffValue / months if (diffValue >= 0 && diffValue <= minute) { return '刚刚' } else if (minC >= 1 && minC <= 59) { return `${Math.floor(minC)}分钟前` } else if (hourC >= 1 && hourC <= 23) { return `${Math.floor(hourC)}小时前` } else if (dayC >= 1 && dayC <= 6) { return `${Math.floor(dayC)}天前` } else if (weekC >= 1 && weekC <= 3) { return `${Math.floor(weekC)}周前` } else if (monthC >= 1 && monthC <= 12) { return `${Math.floor(monthC)}月前` } else { const d = new Date(date) const year = d.getFullYear() const month = this.timeAddZero(d.getMonth() + 1) const day = this.timeAddZero(d.getDate()) let time = `${year}${month}${day}日` return time } break default: const d = new Date(date) const year = agotime ? d.getFullYear() - agotime : d.getFullYear() const month = this.timeAddZero(d.getMonth() + 1) const day = this.timeAddZero(d.getDate()) let time = type.replace('yyyy', String(year)).replace('mm', String(month)).replace('dd', String(day)) return time break } } else { return '' } }, // 计算时间,date:时间数据,type:返回类型 timeFn(date: any, type: string = 'HH:mm:ss') { // console.log(date) if (date) { const d = new Date(date) const year = this.timeAddZero(d.getHours()) const month = this.timeAddZero(d.getMinutes()) const day = this.timeAddZero(d.getSeconds()) let time = type.replace('HH', String(year)).replace('mm', String(month)).replace('ss', String(day)) return time } else { return '无' } }, // 日期时间补0计算 timeAddZero(time) { return time >= 10 ? time : `0${time}` }, // 获取周几 getDay(val) { let d = new Date(val) return `周${this.getDayTransform(d.getDay())}` }, // 星期转化 getDayTransform(val) { let dayObj = ['日', '一', '二', '三', '四', '五', '六'] return dayObj[val] }, // 获取星期几 getDayNote(val) { let dayObj = ['天', '一', '二', '三', '四', '五', '六'] let d = new Date(val) return `星期${dayObj[d.getDay()]}` }, // 获取月份 getMonthNote(val) { let monthObj = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'] let d = new Date(val) return `${monthObj[d.getMonth()]}月` }, // 判断是否是当前年,当前月,当前天,年:'Y',月:'M',天:'D' isCurrentDate(date: any, type: string = 'D') { // console.log(date) const isCurrentYear = new Date(dateformat(date, 'yyyy/mm/dd')).getFullYear() === new Date().getFullYear() const isCurrentMonth = new Date(dateformat(date, 'yyyy/mm/dd')).getMonth() === new Date().getMonth() const isCurrentDate = new Date(dateformat(date, 'yyyy/mm/dd')).getDate() === new Date().getDate() // console.log(isCurrentYear, isCurrentMonth, isCurrentDate) switch (type) { case 'Y': return isCurrentYear break case 'M': return isCurrentYear && isCurrentMonth break case 'D': return isCurrentYear && isCurrentMonth && isCurrentDate break default: break } }, // 小程序转发功能 showShareMenu() { Taro.showShareMenu({ withShareTicket: true }) }, // 拨打电话 makePhoneCall(phoneNumber) { console.log('拨打电话', phoneNumber) Taro.makePhoneCall({ phoneNumber, success() { console.log('拨打电话成功') }, fail(err) { console.log('拨打电话失败', err) } }) }, // 开启小程序进入前台时接收位置消息 startLocationUpdate() { Taro.startLocationUpdate({ success(res) { console.log('开启小程序进入前台时接收位置消息-成功', res) }, fail(err) { console.log('开启小程序进入前台时接收位置消息-失败', err) } }) }, // 获取当前的地理位置 // getLocation() { // return new Promise((resolve, reject) => { // Taro.getLocation({ // type: 'gcj02', // isHighAccuracy: true, // success(res) { // console.log('获取当前的地理位置: ', res) // resolve(res) // }, // fail(err) { // console.error('获取当前的地理位置', err) // Taro.showToast({ title: '获取当前定位失败,请检查是否开启权限', icon: 'none' }) // reject(err) // } // }) // }) // }, // 地理位置授权 getLocationAuthorize() { return new Promise((resolve, reject) => { Taro.getSetting({ success(res) { console.log('getSetting', res) if (!res.authSetting['scope.userLocationBackground']) { // 未授权 // Taro.showToast({ // title: '请选择在"在使用小程序期间和离开小程序后",否则无法获取地理位置', // icon: 'none', // duration: 3000, // mask: false // }) // 提前向用户发起授权请求。调用后会立刻弹窗询问用户是否同意授权小程序使用某项功能或获取用户的某些数据,但不会实际调用对应接口。如果用户之前已经同意授权,则不会出现弹窗,直接返回成功。 Taro.authorize({ scope: 'scope.userLocationBackground', success() { // 授权成功 resolve(true) }, fail() { // 授权失败 Taro.showToast({ title: '授权失败,点击右上角设置"在使用小程序期间和离开小程序后"', icon: 'none', duration: 3000, mask: false }) reject() } }) } else { // 已授权 resolve(true) } } }) }) }, /** * 监听实时地理位置 * @param callback 监听实时地理位置回调函数(方便调用offLocationChange取消监听实时地理位置) */ startLocation(callback: any) { Taro.showLoading({ title: '定位中...', mask: true }) Taro.startLocationUpdateBackground({ success() { // 监听实时地理位置 // Taro.onLocationChange((res) => { // resolve(res) // }) // 监听实时地理位置 Taro.onLocationChange(callback) }, fail() { }, complete() { Taro.hideLoading() } }) }, /** * 获取当前位置,逆地址解析 * @param location 位置坐标 {latitude: 纬度,longitude:经度},不传时默认是当前位置 */ reverseGeocoder(location?: any) { return new Promise((resolve, reject) => { this.qqmapsdk.reverseGeocoder({ location, success(res) { console.log('逆地址解析', res) resolve(res) }, fail(err) { console.error('逆地址解析失败', err) Taro.showToast({ title: '获取当前定位失败,请检查是否开启权限', icon: 'none' }) reject(err) } }) }) }, /** * 预览图片,在新页面中全屏预览图片。预览的过程中用户可以进行保存图片、发送给朋友等操作,没有长按扫一扫二维码 * @param current 当前显示图片的链接 * @param urls 需要预览的图片链接列表 */ previewImage(current, urls) { Taro.previewImage({ current, urls }) }, // 预览PDF/WORD文件 previewFile(file) { Taro.showLoading({ title: '文件打开中...' }) // 下载文件资源到本地。客户端直接发起一个 HTTPS GET 请求,返回文件的本地临时路径 (本地路径),单次下载允许的最大文件为 50MB Taro.downloadFile({ url: file, success(res) { console.log('downloadFile:', res) let path = res.tempFilePath // 新开页面打开文档。微信客户端 7.0.12 版本前默认显示右上角菜单按钮,之后的版本默认不显示,需主动传入 showMenu Taro.openDocument({ filePath: path, showMenu: true, success(res) { Taro.hideLoading() console.log('新开页面打开文档成功:', res) } }) }, fail(err) { Taro.showToast({ title: '预览失败,请检查文件', icon: 'none' }) console.error('downloadFile失败:', err, file) } }) }, /** * 获取班组简易列表 * @param projectId 项目id * @param leader 是否需要返回领班 */ getGroupSimpleList(projectId, leader: boolean = false) { return new Promise((resolve, reject) => { Taro['common'].request(`/group/simple/list`, 'GET', { projectId }).then(res => { console.log('获取班组简易列表', res.data) res = res.data // 处理班组列表数据 let groupData: any = {} let groupList: any[] = [] for (let key in res) { groupData[res[key].groupId] = res[key].groupName + (leader ? `:${res[key].leaderName || '无'}` : '') groupList.push({ value: res[key].groupId, name: res[key].groupName }) } resolve({ groupData, groupList }) }) }) }, /** * 获取工程/维保的项目/监管成员角色字典表 * @param type 项目类型,1:工程,2:维保 * @param memberType 成员类型,p:项目成员,g:监管成员 */ getProjectPositionDict(type: string = '1', memberType: string = 'p') { return new Promise(async (resolve, reject) => { let codeData: object = {} if (memberType === 'p') { codeData = { 1: 'PROJECT_POST_CTS', 2: 'PROJECT_POST_WB' } } else if (memberType === 'g') { codeData = { 1: 'PROJECT_POST_GGB', 2: 'PROJECT_POST_WBGGB' } } // 获取工程/维保的项目/监管成员角色字典表 let params = { dictCode: 'ProjectDict', code: 'ProjectPosition' } let projectDict = await this.getDictByCode(params) let roleLists: any[] = [] let roleData: any = {} for (let item of projectDict) { if (item.code === codeData[type]) { roleLists = await this.getDictByParentId({ parentId: item.id }) console.log(type, memberType, roleLists) for (let item of roleLists) { roleData[item.value] = item.name } } } resolve({ roleLists, roleData }) }) }, /** * 金额格式化,返回10,000.00的格式 * @param v 金额 * @returns v 金额 */ moneyFormat(v) { if (isNaN(v)) { return 0.0; } v = Math.round((v - 0) * 100) / 100; v = v === Math.floor(v) ? v + ".00" : v * 10 === Math.floor(v * 10) ? v + "0" : v; v = String(v); var ps = v.split("."); var whole = ps[0]; var sub = ps[1] ? "." + ps[1] : ".00"; var r = /(\d+)(\d{3})/; while (r.test(whole)) { whole = whole.replace(r, "$1,$2"); } v = whole + sub; return v; }, /** * 权限判断 * @param {string[]} acls 权限对象 * @param {string ''} type 权限类型:用户user,团队team,项目project * @returns {Boolean} */ checkAcls(acls: any[] = [], type: string = '') { let pms; if (type) { pms = Taro.getStorageSync(type + 'Permission') } else { pms = [...Taro.getStorageSync('userPermission'), ...Taro.getStorageSync('teamPermission'), ...Taro.getStorageSync('projectPermission')] } if (!pms) { return false } for (let acl of acls) { if (pms.indexOf(acl) > -1) return true } return false }, /** * 权限数据存储 * @param data 权限数据 * @param type 权限类型:用户user,团队team,项目project */ setPermission(type: string = '', data: any,) { Taro.setStorageSync(type + 'Permission', data) }, /** * 获取权限数据 * @param type 权限类型:用户user,团队team,项目project */ getPermission(type: string = '') { return Taro.getStorageSync(type + 'Permission') }, /** * 检查当前项目状态是否为1:在场,返回true,否则是2:离场,返回false */ checkProjectStatus() { return Taro.getStorageSync('projectStatus') === 1 }, // toast封装 toast(title: any, option = { icon: null, duration: null }) { Taro.showToast({ title: title, icon: option.icon || 'none', duration: option.duration || 1500 // 提示的延迟时间,单位毫秒 }) }, // 延时返回上n级页面。 goBack(n: number = 1, time: number = 1000) { setTimeout(() => { Taro.navigateBack({ delta: n }) }, time) }, getRoleText(roleKeys = []) { let roleObj = { ...this.getDictsStorage('PositionForGGBProject'), ...this.getDictsStorage('PositionForWBProject') } let textArr = new Array() for (let i = 0; i < roleKeys.length; i++) { if (roleObj[roleKeys[i]]) { textArr.push(roleObj[roleKeys[i]]) } } return textArr } }