commit c033fc636169cecfc5ca054312a3e20e3effb22d Author: yujialong <479214531@qq.com> Date: Thu Nov 21 11:42:33 2024 +0800 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2857694 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +unpackage +node_modules diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..37af134 --- /dev/null +++ b/.hbuilderx/launch.json @@ -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" + } + ] +} diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..55be1b2 --- /dev/null +++ b/App.vue @@ -0,0 +1,36 @@ + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..2837dc6 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# 职站商城 \ No newline at end of file diff --git a/apis/modules/article.js b/apis/modules/article.js new file mode 100644 index 0000000..c67ac27 --- /dev/null +++ b/apis/modules/article.js @@ -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) +} \ No newline at end of file diff --git a/apis/modules/client.js b/apis/modules/client.js new file mode 100644 index 0000000..560370c --- /dev/null +++ b/apis/modules/client.js @@ -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}`) +} \ No newline at end of file diff --git a/apis/modules/course.js b/apis/modules/course.js new file mode 100644 index 0000000..7677fe6 --- /dev/null +++ b/apis/modules/course.js @@ -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') +} \ No newline at end of file diff --git a/apis/modules/order.js b/apis/modules/order.js new file mode 100644 index 0000000..e9a003d --- /dev/null +++ b/apis/modules/order.js @@ -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}`) +} \ No newline at end of file diff --git a/apis/modules/parner.js b/apis/modules/parner.js new file mode 100644 index 0000000..c3a3f0b --- /dev/null +++ b/apis/modules/parner.js @@ -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) +} \ No newline at end of file diff --git a/apis/modules/product.js b/apis/modules/product.js new file mode 100644 index 0000000..4726020 --- /dev/null +++ b/apis/modules/product.js @@ -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) +} \ No newline at end of file diff --git a/apis/modules/user.js b/apis/modules/user.js new file mode 100644 index 0000000..effec4a --- /dev/null +++ b/apis/modules/user.js @@ -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` \ No newline at end of file diff --git a/apis/request.js b/apis/request.js new file mode 100644 index 0000000..4ea0553 --- /dev/null +++ b/apis/request.js @@ -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 +} \ No newline at end of file diff --git a/components/empty/empty.vue b/components/empty/empty.vue new file mode 100644 index 0000000..42d2f06 --- /dev/null +++ b/components/empty/empty.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/components/filter-popup/components/mask.vue b/components/filter-popup/components/mask.vue new file mode 100644 index 0000000..521f0d9 --- /dev/null +++ b/components/filter-popup/components/mask.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/components/filter-popup/components/popup.vue b/components/filter-popup/components/popup.vue new file mode 100644 index 0000000..fffcfdc --- /dev/null +++ b/components/filter-popup/components/popup.vue @@ -0,0 +1,510 @@ + + + + + diff --git a/components/filter-popup/detail.md b/components/filter-popup/detail.md new file mode 100644 index 0000000..e704412 --- /dev/null +++ b/components/filter-popup/detail.md @@ -0,0 +1,155 @@ +## 导入即用 全端支持 + +### 有问题 + wx : zy597172583 标注来意 可评论 看到及时回复 +1.使用方式 + +```javascript + + + diff --git a/components/notAuth/notAuth.vue b/components/notAuth/notAuth.vue new file mode 100644 index 0000000..52f9d08 --- /dev/null +++ b/components/notAuth/notAuth.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/config/product.js b/config/product.js new file mode 100644 index 0000000..206e21d --- /dev/null +++ b/config/product.js @@ -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' // 数据图标 +} diff --git a/config/request.js b/config/request.js new file mode 100644 index 0000000..430eec3 --- /dev/null +++ b/config/request.js @@ -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 // 是否序列化表单数据 +} diff --git a/course/addCourse/addCourse.vue b/course/addCourse/addCourse.vue new file mode 100644 index 0000000..40c3996 --- /dev/null +++ b/course/addCourse/addCourse.vue @@ -0,0 +1,399 @@ + + + + + diff --git a/course/clients/clients.vue b/course/clients/clients.vue new file mode 100644 index 0000000..3612133 --- /dev/null +++ b/course/clients/clients.vue @@ -0,0 +1,280 @@ + + + + + diff --git a/course/courseDetail/courseDetail.vue b/course/courseDetail/courseDetail.vue new file mode 100644 index 0000000..d2a1b3e --- /dev/null +++ b/course/courseDetail/courseDetail.vue @@ -0,0 +1,334 @@ + + + + + diff --git a/course/curClient/curClient.vue b/course/curClient/curClient.vue new file mode 100644 index 0000000..f02cfdc --- /dev/null +++ b/course/curClient/curClient.vue @@ -0,0 +1,273 @@ + + + + + diff --git a/course/editCourse/editCourse.vue b/course/editCourse/editCourse.vue new file mode 100644 index 0000000..2eb2a5d --- /dev/null +++ b/course/editCourse/editCourse.vue @@ -0,0 +1,504 @@ + + + + + diff --git a/course/orderDetail/orderDetail.vue b/course/orderDetail/orderDetail.vue new file mode 100644 index 0000000..74f3fd0 --- /dev/null +++ b/course/orderDetail/orderDetail.vue @@ -0,0 +1,1201 @@ + + + + + diff --git a/course/ordered/ordered.vue b/course/ordered/ordered.vue new file mode 100644 index 0000000..85e08f0 --- /dev/null +++ b/course/ordered/ordered.vue @@ -0,0 +1,285 @@ + + + + + diff --git a/course/practiceDetail/practiceDetail.vue b/course/practiceDetail/practiceDetail.vue new file mode 100644 index 0000000..b1967d4 --- /dev/null +++ b/course/practiceDetail/practiceDetail.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/course/privacyAgreement/privacyAgreement.vue b/course/privacyAgreement/privacyAgreement.vue new file mode 100644 index 0000000..f8dfd12 --- /dev/null +++ b/course/privacyAgreement/privacyAgreement.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/course/products/products.vue b/course/products/products.vue new file mode 100644 index 0000000..33058e9 --- /dev/null +++ b/course/products/products.vue @@ -0,0 +1,399 @@ + + + + + diff --git a/course/serviceAgreement/serviceAgreement.vue b/course/serviceAgreement/serviceAgreement.vue new file mode 100644 index 0000000..391b6d7 --- /dev/null +++ b/course/serviceAgreement/serviceAgreement.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/course/shopCart/shopCart.vue b/course/shopCart/shopCart.vue new file mode 100644 index 0000000..40fe190 --- /dev/null +++ b/course/shopCart/shopCart.vue @@ -0,0 +1,317 @@ + + + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..9efb733 --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + + + + + +
+ + + diff --git a/libs/Oss/base64.js b/libs/Oss/base64.js new file mode 100644 index 0000000..4535327 --- /dev/null +++ b/libs/Oss/base64.js @@ -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; + } + +} \ No newline at end of file diff --git a/libs/Oss/crypto.js b/libs/Oss/crypto.js new file mode 100644 index 0000000..7807ea4 --- /dev/null +++ b/libs/Oss/crypto.js @@ -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; \ No newline at end of file diff --git a/libs/Oss/hmac.js b/libs/Oss/hmac.js new file mode 100644 index 0000000..1918f4c --- /dev/null +++ b/libs/Oss/hmac.js @@ -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); + +}; + +})(); \ No newline at end of file diff --git a/libs/Oss/sha1.js b/libs/Oss/sha1.js new file mode 100644 index 0000000..5632fd7 --- /dev/null +++ b/libs/Oss/sha1.js @@ -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; + +})(); \ No newline at end of file diff --git a/libs/Oss/upload.js b/libs/Oss/upload.js new file mode 100644 index 0000000..a673826 --- /dev/null +++ b/libs/Oss/upload.js @@ -0,0 +1,71 @@ +import Crypto from './crypto.js'; +import './hmac.js'; +import './sha1.js'; +import Util from '@/libs/util' +import {Base64} from './base64.js'; + +let date=new Date() +date=date.setHours(date.getHours() + 24) +let extime=""+new Date(date).toISOString() +console.log(33, extime) +var policyText = { + "expiration": extime, //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了 + "conditions": [ + ["content-length-range", 0, 1024*1024*100] // 设置上传文件的大小限制 + ] +}; +var config={ + accessid:'LTAI4FzqQHnk4rozqLZ8jCNj', + accesskey:'mveW7B1OyFoKUkHm8WsxmrjHmkJWHq', + osshost:'https://huoran.oss-cn-shenzhen.aliyuncs.com', + policyBase64:Base64.encode(JSON.stringify(policyText)) +} +var message = config.policyBase64; +var bytes = Crypto.HMAC(Crypto.SHA1, message, config.accesskey, { asBytes: true }) ; +var signature = Crypto.util.bytesToBase64(bytes); +var timetamp = new Date().getTime(); +function random_string(len) { +  len = len || 32; +  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; +  var maxPos = chars.length; +  var pwd = ''; +  for (let i = 0; i < len; i++) { +   pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} +var OSS={ + name:'aliyun', + host:config.osshost, + accessid:config.accessid, + signature:signature, + policyBase64:config.policyBase64, +} +export default function(tempFilePaths, callback) { + const ext = Util.getFileExt(tempFilePaths) + const fileName = Date.now() + '.' + ext + uni.uploadFile({ +   url: OSS.host, +   filePath: tempFilePaths, + fileType: '', + name: 'file', + formData: { + name: fileName, + key: fileName,//文件名 +  policy: OSS.policyBase64, // 输入你获取的的policy + OSSAccessKeyId: OSS.accessid, // 输入你的AccessKeyId + success_action_status: '200', // 让服务端返回200,不然,默认会返回204 + signature: OSS.signature, // 输入你获取的的signature + }, + success: (res) => { + callback({ + name: fileName, + url: OSS.host + '/' + fileName, + ext + }) + }, + fail: (res) => { + console.log(res); + } +}) +}; \ No newline at end of file diff --git a/libs/WXBizDataCrypt.js b/libs/WXBizDataCrypt.js new file mode 100644 index 0000000..36b3de1 --- /dev/null +++ b/libs/WXBizDataCrypt.js @@ -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 \ No newline at end of file diff --git a/libs/mtj-wx-sdk.config.js b/libs/mtj-wx-sdk.config.js new file mode 100644 index 0000000..e1d7474 --- /dev/null +++ b/libs/mtj-wx-sdk.config.js @@ -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, +}; diff --git a/libs/mtj-wx-sdk.js b/libs/mtj-wx-sdk.js new file mode 100644 index 0000000..b908aa2 --- /dev/null +++ b/libs/mtj-wx-sdk.js @@ -0,0 +1 @@ +var mtjwxsdk=function(t){"use strict";var e,n,r="1.10.23",o="https://hmma.baidu.com/mini.gif",a={app:["onShow","onHide","onError"],page:["onShow","onReady","onHide","onPageScroll"],share:["onShareAppMessage"],behavior:["tap"]},i="mtj_uuid",c="mtj_user",s="mtj_user_property",u="mtj_track_status",f="mtj_remote_config",l="mtj_ab_experiment_list",h="mtj_ab_active_experiment_ids",p={},d={type:1},g={aso:{}},m={},y=function(t){if(!1!==p.trackStatus){var n=t.data.et?{mtj_ii:t.data.uuid||"",mtj_et:t.data.et,mtj_en:t.data.en}:{};return e.request({url:t.url,data:t.data,header:Object.assign({"content-type":"application/json"},n,t.header),method:t.method||"POST",dataType:t.dataType||"json",success:function(e){t.success&&t.success(e)},fail:function(e){t.fail&&t.fail(e)}})}},v=function(){return"undefined"!=typeof crypto&&crypto.getRandomValues?crypto.getRandomValues(new Uint32Array(1))[0]:Math.floor(4294967295*Math.random())},b=function(t,e){return"[object "+e+"]"==={}.toString.call(t)},j=function(t,e,n){var r=(t=t.replace(new RegExp(e+"=[^&]*","g"),"").replace(/(\?|&)&/g,"$1").replace(/(\?|&)$/g,"")).indexOf("?")>0?"&":"?";return t+r+e+"="+encodeURIComponent(n)},S=function t(e){return b(e,"Object")||b(e,"Array")?(Object.keys(e).forEach((function(n){var r=e[n];b(r,"Object")||b(r,"Array")?e[n]=t(r):e[n]=""+r})),e):e},O=function(t){return b(t,"String")&&/^[a-z][a-z0-9_]{0,31}$/.test(t)},w=function(t){return b(t,"String")&&/^[a-z0-9_]{1,32}$/.test(t)},k=function(t){return b(t,"String")||b(t,"Number")},x=function(t){return b(t,"String")&&/^\d{11}$/.test(t)},P=function(t){return b(t,"String")&&28===t.length},_=0,T=function(t){return new Promise((function(e,n){return t.data=t.data||{},p.blacklist&&(p.blacklist.indexOf("all")>-1&&t.data.et||p.blacklist.indexOf("behavior")>-1&&"behavior"===t.data.et)?e():(t.data.v=r,t.data.rqc=++_,o=t.data,JSON.stringify(o).length<=204800?(t.success=function(t){return e(t)},t.fail=function(t){return n(t)},void y(t)):(_--,n(new Error("invalid data"))));var o}))},I=function(t,e){var n=b(e,"Object")?JSON.stringify(e):""+e;T({url:o,dataType:"string",data:Object.assign({},d,{et:"error",en:t,ep:{ex:n},rid:v()})})},A=function(t){t.rid=v(),t.aso=t.aso||{};var e={url:o,dataType:"string",data:Object.assign({},d,t)};T(e),(m.circleToken||m.circleByThreeFingers)&&("page"===t.et&&"show"===t.en||"behavior"===t.et&&"tap"===t.en)&&(e.url="https://hmma.baidu.com/mini.gif?circle=1",e.data.token=m.circleToken,T(e).catch((function(t){return console.error(t)})))};function E(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=t&&("undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"]);if(null==n)return;var r,o,a=[],i=!0,c=!1;try{for(n=n.call(t);!(i=(r=n.next()).done)&&(a.push(r.value),!e||a.length!==e);i=!0);}catch(t){c=!0,o=t}finally{try{i||null==n.return||n.return()}finally{if(c)throw o}}return a}(t,e)||function(t,e){if(!t)return;if("string"==typeof t)return N(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return N(t,e)}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function N(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n>t/4).toString(16)})),q(i,t),p.hasABTest&&(U(l),U(h))),t}))},B=function(t){return new Promise((function(n){if(!t)return n();e.getShareInfo({shareTicket:t,success:function(t){delete t.errMsg,n(t)},fail:function(){n({})}})}))},M=function(){return n||(d.sid=v(),d.rqc=0,n=Promise.all([D(),new Promise((function(t){e.getSystemInfo({success:function(e){delete e.errMsg,t(e)},fail:function(){t({})}})})),new Promise((function(t){e.getNetworkType({success:function(e){delete e.errMsg,t(e)},fail:function(){t({})}})})),Promise.resolve().then((function(){var t=C(c),n=b(t,"Object")?t:{};return new Promise((function(t){e.getSetting({success:function(r){r.authSetting&&r.authSetting["scope.userInfo"]?e.getUserInfo({success:function(e){delete e.userInfo.errMsg,t(Object.assign(n,e.userInfo))},fail:function(){t(n)}}):t(n)},fail:function(){t(n)}})}))})),new Promise((function(t){if(!p.getLocation)return t({});e.getLocation({type:"wgs84",success:function(e){delete e.errMsg,t(e)},fail:function(){t({})}})})),Promise.resolve().then((function(){var t=C(s);return b(t,"Object")?t:{}}))]).then((function(t){var e=E(t,6),n=e[0],o=e[1],a=e[2],i=e[3],c=e[4],s=e[5];d.uuid=n,g.system=S(o),g.network=S(a),Object.keys(i).length>0&&(g.user=S(i)),Object.keys(c).length>0&&(g.location=S(c)),Object.keys(s).length>0&&(g.userProperty=JSON.stringify(s)),"devtools"===g.system.platform&&p.latestVersion&&function(t,e){for(var n=t.split("."),r=e.split("."),o=0;o<3;o++){var a=+n[o]||0,i=+r[o]||0;if(a>i)return 1;if(i>a)return-1}return 0}(r,p.latestVersion)<0&&console.warn("百度移动统计微信小程序SDK已更新,为不影响您的正常使用,请到SDK下载中心 https://mtj.baidu.com/web/sdk/index 下载最新版本")})))},R={onShow:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=(g.aso.query||[]).filter((function(t){return 0===t.key.indexOf("mtj_")}));return g.aso.scene=""+(t.scene||""),t.referrerInfo&&t.referrerInfo.appId?g.aso.referrerInfo=t.referrerInfo:delete g.aso.referrerInfo,g.aso.path=t.path||"",g.aso.query=Object.keys(t.query||{}).map((function(e){return{key:e,value:t.query[e]}})),e.length>0&&!/(^|,)mtj_/.test(Object.keys(t.query||{}).join(","))&&(g.aso.query=g.aso.query.concat(e)),(t.query||{}).mtj_ctoken&&!p.disableCircling&&(m.circleToken=t.query.mtj_ctoken),(t.query||{}).mtj_htoken&&p.hasHeatmap&&(m.heatmapToken=t.query.mtj_htoken),M().then((function(){return B(t.shareTicket)})).then((function(t){t?g.aso.shareInfo=t:delete g.aso.shareInfo,A(Object.assign({et:"app",en:"show"},g))})).catch((function(t){I("app.onShow",t)}))},onHide:function(){A({et:"app",en:"hide"})},onError:function(t){var e=b(t,"Object")?JSON.stringify(S(t)):""+t;A({et:"app",en:"error",ep:{ex:e}})}};function F(){this.options={opacity:100,radius:30,bshadow:1.5,boundVal:15e3,shadowBlur:15,points:{max:100,data:[]},gradient:{.45:"rgb(0,0,255)",.55:"rgb(0,255,255)",.65:"rgb(0,255,0)",.95:"yellow",1:"rgb(255,0,0)"}}}F.prototype={getCanvas:function(t){return new Promise((function(n,r){e.createSelectorQuery().select(t).fields({node:!0,size:!0}).exec((function(t){n(t[0].node)}))}))},getPageClientRect:function(){return new Promise((function(t,n){e.createSelectorQuery().select(".hm-container").boundingClientRect((function(e){t([e.width,e.height])})).exec()}))},init:function(){var t=this;return Promise.all([this.getPageClientRect(),this.getCanvas("#cvs"),this.getCanvas("#cvd")]).then((function(e){var n=E(e,3),r=n[0],o=n[1],a=n[2];t.options.width=r[0],t.options.height=r[1],o.width=t.options.width,o.height=t.options.height,t.options.context.setData({p_width:t.options.width,p_height:t.options.height});var i=o.getContext("2d");t.options.ctx=i,a.width=1,a.height=256;var c=a.getContext("2d");t.options.pctx=c}))},renderShadow:function(t,e,n,r){var o=this.options.ctx,a=this.options.boundVal,i=parseFloat(n/this.options.points.max,10);o.shadowColor="rgba(0, 0, 0, "+i+")",o.shadowOffsetX=a,o.shadowOffsetY=a,o.shadowBlur=this.options.shadowBlur,o.beginPath(),o.arc(t-a,e-a,this.options.radius,0,2*Math.PI,!0),o.closePath(),o.fill(),r||this.cachePoint(t,e,n)},colorize:function(){for(var t=this.options.width,e=this.options.height,n=this.options.ctx,r=n.getImageData(0,0,t,e),o=r.data,a=o.length,i=this.getPalette(),c=this.options.opacity,s=3;sr.max&&(r.max=n),o.push([t,e,n])},addPoint:function(t,e,n){this.options.ctx.clearRect(0,0,this.options.width,this.options.height),this.options.pctx.clearRect(0,0,1,256);for(var r=this.options.points.data,o=r.length,a=0;a0&&A(Object.assign({et:"page",en:"scroll",ep:S(t[0])},a))}))}catch(t){I("page.trackComponentScrollEvent",t)}},onPageScroll:function(t){(!m.pageScrollTop||t.scrollTop>m.pageScrollTop)&&(m.pageScrollTop=t.scrollTop)},onShareAppMessage:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n={from:t.from,path:e.path};if(!n.path){var r=d.query.map((function(t){return t.key+"="+t.value})).join("&");n.path=d.path+(r?"?"+r:"")}e.title&&(n.title=""+e.title),t.target&&(n.target=JSON.stringify(t.target)),A(Object.assign({et:"share",en:"action",ep:n},g));var o=g.aso.query.filter((function(t){return"mtj_shuuid"===t.key})),a=o[0]?o[0].value.split("_"):[];d.uuid!==a[a.length-1]&&a.push(d.uuid);var i=a.slice(Math.max(0,a.length-3)).join("_");return e.path=j(n.path,"mtj_shuuid",i),e},onAction:function(t,e){if(t&&t.type&&t.currentTarget){var n="#"+(t.currentTarget.id||e);if("tap"===t.type){var r=[{key:"xpath",value:n}],o=t.detail,a=o.x,i=o.y,c={};return void 0!==a&&void 0!==i&&(c={x:Math.floor(a),y:Math.floor(i)}),void A(Object.assign({et:"behavior",en:"tap",ep:{data:r},posi:c},g))}if("touchmove"===t.type&&-1===J&&t.touches instanceof Array&&3===t.touches.length){if(z+=1,clearTimeout(V),3===z)return m.circleByThreeFingers=!0,m.circleToken=void 0,void A(Object.assign({et:"page",en:"show"},g));J=setTimeout((function(){J=-1,V=setTimeout((function(){z=0}),500)}),1e3)}}}},L={trackEvent:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!O(t))return Promise.reject(new Error("事件名称不合法"));var n=Object.keys(e).filter((function(t){return w(t)&&k(e[t])})).map((function(t){return{key:""+t,value:""+e[t],type:b(e[t],"String")?"string":"number"}}));return M().then((function(){A(Object.assign({et:"event",en:""+t,ep:{data:n}},g))})).catch((function(t){I("trackEvent",t)}))},setTrackStatus:function(t){b(t,"Boolean")&&(p.trackStatus=t,q(u,t))},setUserInfo:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.tel,n=t.openId;return M().then((function(){var t=C(c),r=b(t,"Object")?t:{};x(e)&&(r.tel=g.user.tel=e.substr(e.length-11)),P(n)&&(r.openId=g.user.openId=n),(r.tel||r.openId)&&q(c,r),b(e,"Undefined")||x(e)||console.error("手机号 ".concat(e," 不合法")),b(n,"Undefined")||P(n)||console.error("openid ".concat(n," 不合法"))})).catch((function(t){I("setUserInfo",t)}))},setUserId:function(t){return Promise.resolve().then((function(){if(!(b(t,"String")||b(t,"Number")&&Number.isFinite(t)))return Promise.reject(new Error("userId只能是字符串或数字"));var e=""+t,n=C(s),r=b(n,"Object")?n:{};if(!r.uid_||r.uid_[0]!==e){r.uid_=[e,"1"],q(s,r),g.userProperty=JSON.stringify(r);var o=[{key:"uid",value:e}];return M().then((function(){A(Object.assign({et:"api",en:"setUserId",ep:{data:o}},g))})).catch((function(t){I("setUserId",t)}))}}))},setUserProperty:function(t){return Promise.resolve().then((function(){var e=C(s),n=b(e,"Object")?e:{};if(b(t,"Null"))Object.keys(n).forEach((function(t){"_"!==t.charAt(0)&&"_"!==t.charAt(t.length-1)&&delete n[t]}));else if(!b(t,"Object"))return Promise.reject(new Error("userProperty必须是对象"));var r=Object.keys(n).filter((function(t){return"_"!==t.charAt(0)&&"_"!==t.charAt(t.length-1)})).length;Object.keys(t||{}).forEach((function(e){var o=t[e];""===e||"_"===e.charAt(0)||"_"===e.charAt(e.length-1)&&"ab_"!==e&&"ab_filter_"!==e||(b(o,"Null")?n[e]&&(delete n[e],r--):!(b(o,"String")||b(o,"Number")&&Number.isFinite(o))||e.length>256||(""+o).length>256||!n[e]&&r>=100||(n[e]||r++,n[e]=[o,"1"]))})),q(s,n),g.userProperty=JSON.stringify(n)}))}},$={data:[],init:function(){var t=this,e=d.uuid;e?this.startFetch(e):D().then((function(e){d.uuid=e,t.startFetch(e)}))},startFetch:function(t){console.log("---您的设备ID---",t),this.fetchTest()},getExpDataByParamName:function(t){var e=C(l);if(this.setLocalData(e),!e||!b(e,"Array"))return{};var n=e.find((function(e){return e&&b(e.params,"Object")&&!b(e.params[t],"Undefined")}));return n&&n.params?{expValue:n.params[t],expId:n.e}:{}},fetchTest:function(t,e,n){var r=this,o=d.uuid,a=d.key;y({url:"https://hm.baidu.com/v1/diversion/",data:{cid:o,tid:a},method:"GET",success:function(o){b(o,"Object")&&200===o.statusCode&&b(o.data,"Object")&&0===o.data.status?r.handleFetchResponse(o.data,t,e,n):n&&n(e)},fail:function(){console.error("请求分流实验失败"),n&&n(e)}})},handleFetchResponse:function(t,e,n,r){var o=[];if(b(t,"Object")&&b(t.data,"Object")&&b(t.data.expr,"Array")&&(o=t.data.expr),this.updateStorage(o),this.setLocalData(o),r){var a=this.getExpDataByParamName(e),i=a.expValue,c=a.expId;b(i,"Null")||b(i,"Undefined")?r(n):this.handleInTest(i,c,r)}},handleInTest:function(t,e,n){n(t),this.updateUserProperty(e)},updateStorage:function(t){q(l,t)},setLocalData:function(t){this.data=t||[]},updateUserProperty:function(t){var e=this,n=this.getActiveExpIds(t)||[],r={ab_:null,ab_filter_:null},o={},a=[];if(n.forEach((function(t){var n=e.getExpDataFromId(t);b(n,"Object")&&(o[n.e]=n.g,a.push(n.h||0))})),a.length){var i=0;a.forEach((function(t){i=function(t,e){var n="00000000000000000000000000000000";function r(t){var e=(n+n+Number(t).toString(2)).slice(-64);return[parseInt(e.slice(0,32),2),parseInt(e.slice(-32),2)]}function o(t){return(n+t.toString(2)).slice(-32)}var a=r(t),i=r(e);return parseInt(o((a[0]|i[0])>>>0)+o((a[1]|i[1])>>>0),2)}(i,t)})),r={ab_:JSON.stringify(o),ab_filter_:i}}L.setUserProperty(r)},getExpDataFromId:function(t){return C(l).find((function(e){return String(e.e)===String(t)}))},setActiveExperimentIds:function(t){q(h,t)},getActiveExpIds:function(t){var e=this,n=C(h)||[];return b(t,"Undefined")||-1!==n.indexOf(t)||n.push(t),n=(n=n.filter((function(t){return!!e.getExpDataFromId(t)}))).filter((function(t,e){return n.indexOf(t)===e})),this.setActiveExperimentIds(n),n}},K=function(t){if(p.hasABTest)if(b(t,"Object")){var e=t.paramName;if(null!=e){var n=t.defaultValue;if(b(n,"Undefined"))console.error("请设置参数默认值");else{var r=t.callback;if(b(r,"Function")){var o=$.getExpDataByParamName(e),a=o.expValue,i=o.expId;b(a,"Null")||b(a,"Undefined")?$.fetchTest(e,n,r):$.handleInTest(a,i,r)}else console.error("callback必须为函数")}}else console.error("请设置实验参数名称")}else console.error("传递参数请设置为对象")},Q=function(t,e,n){var r=e[t];e[t]=function(e){if(n.call(this,e,t),r)return r.apply(this,arguments)}},G=App,W=function(t){a.app.forEach((function(e){Q(e,t,R[e])})),t.mtj=L,t.mtj.pageEvent=H,t.mtj.fetchABTest=K,G(t)},X=Page,Y=function(t){a.page.forEach((function(e){Q(e,t,H[e])})),a.share.forEach((function(e){!function(t,e,n){var r=e[t];e[t]=function(t){var e=r&&r.apply(this,arguments);return n.call(this,t,e)}}(e,t,H[e])})),Object.keys(t).forEach((function(e){"function"==typeof t[e]&&-1===a.page.indexOf(e)&&-1===a.share.indexOf(e)&&Q(e,t,H.onAction)})),X(t)},Z=Behavior,tt=function(t){return a.page.forEach((function(e){Q(e,t.methods,H[e])})),Z(t)};tt.prototype.constructor=Behavior;var et=Component,nt=function(t){return a.page.forEach((function(e){Q(e,t.methods,H[e])})),et(t)},rt=function(){var t,n;t=wx,e=t;try{n=require("./mtj-wx-sdk.config")}catch(t){return void console.error("请把mtj-wx-sdk.config.js文件拷贝到utils目录中")}n&&n.appKey?(d.key=n.appKey,p.getLocation=n.getLocation||!1,p.getComponentScroll=n.getComponentScroll||!1,p.disableCircling=n.disableCircling||!1,p.trackStatus=!(!1===C(u)),p.hasABTest=n.hasABTest||!1,p.hasHeatmap=n.hasHeatmap||!1,p.hasABTest&&$.init(),function(){var t=C(f);if(t){Object.keys(t).forEach((function(e){p[e]=t[e]}));var e=t.updateTimestamp||0;if(+new Date-e<864e5)return Promise.resolve()}T({url:"https://hmma.baidu.com/mini.conf",method:"POST",header:{"content-type":"application/x-www-form-urlencoded"},data:{type:"wx",key:d.key}}).then((function(t){if(t&&t.data){var e=t.data;Object.keys(e).forEach((function(t){p[t]=e[t]})),e.updateTimestamp=+new Date,q(f,e)}else I("remoteConfig",t)})).catch((function(t){I("sendRequest",t)}))}(),n.hasPlugin||(App=W,Page=Y),module.exports={App:W,Page:Y,Behavior:tt,Component:nt}):console.error("请设置mtj-wx-sdk.config.js文件中的appKey字段")};return rt(),t.init=rt,Object.defineProperty(t,"__esModule",{value:!0}),t}({}); diff --git a/libs/share.js b/libs/share.js new file mode 100644 index 0000000..a8d0166 --- /dev/null +++ b/libs/share.js @@ -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: '', + } + } + +} \ No newline at end of file diff --git a/libs/uma.js b/libs/uma.js new file mode 100644 index 0000000..a688ffd --- /dev/null +++ b/libs/uma.js @@ -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; diff --git a/libs/util.js b/libs/util.js new file mode 100644 index 0000000..8e72d90 --- /dev/null +++ b/libs/util.js @@ -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); + }, +} \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..589448c --- /dev/null +++ b/main.js @@ -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 \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..4d126fb --- /dev/null +++ b/manifest.json @@ -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" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "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" + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..eb2ff65 --- /dev/null +++ b/package-lock.json @@ -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==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..569edcd --- /dev/null +++ b/package.json @@ -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" + } +} diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..72681b0 --- /dev/null +++ b/pages.json @@ -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": "我的" + }] + } +} diff --git a/pages/achievement/achievement.vue b/pages/achievement/achievement.vue new file mode 100644 index 0000000..3fbf5e8 --- /dev/null +++ b/pages/achievement/achievement.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/pages/index/index.vue b/pages/index/index.vue new file mode 100644 index 0000000..55d2f97 --- /dev/null +++ b/pages/index/index.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/pages/login/login.vue b/pages/login/login.vue new file mode 100644 index 0000000..963efbd --- /dev/null +++ b/pages/login/login.vue @@ -0,0 +1,347 @@ + + + + + diff --git a/pages/orders/orders.vue b/pages/orders/orders.vue new file mode 100644 index 0000000..b188f73 --- /dev/null +++ b/pages/orders/orders.vue @@ -0,0 +1,360 @@ + + + + + diff --git a/pages/person/person.vue b/pages/person/person.vue new file mode 100644 index 0000000..5e27982 --- /dev/null +++ b/pages/person/person.vue @@ -0,0 +1,409 @@ + + + + + diff --git a/static/iconfont/iconfont.css b/static/iconfont/iconfont.css new file mode 100644 index 0000000..3a65ec5 --- /dev/null +++ b/static/iconfont/iconfont.css @@ -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"; +} + diff --git a/static/iconfont/iconfont.ttf b/static/iconfont/iconfont.ttf new file mode 100644 index 0000000..9db285d Binary files /dev/null and b/static/iconfont/iconfont.ttf differ diff --git a/static/image/arrow-down.png b/static/image/arrow-down.png new file mode 100644 index 0000000..1369211 Binary files /dev/null and b/static/image/arrow-down.png differ diff --git a/static/image/avatar.png b/static/image/avatar.png new file mode 100644 index 0000000..01dee60 Binary files /dev/null and b/static/image/avatar.png differ diff --git a/static/image/index/1.png b/static/image/index/1.png new file mode 100644 index 0000000..2a7a8ff Binary files /dev/null and b/static/image/index/1.png differ diff --git a/static/image/index/2.png b/static/image/index/2.png new file mode 100644 index 0000000..e6f6b81 Binary files /dev/null and b/static/image/index/2.png differ diff --git a/static/image/index/3.png b/static/image/index/3.png new file mode 100644 index 0000000..b7b66ce Binary files /dev/null and b/static/image/index/3.png differ diff --git a/static/image/index/4.png b/static/image/index/4.png new file mode 100644 index 0000000..0af3c84 Binary files /dev/null and b/static/image/index/4.png differ diff --git a/static/image/index/5.png b/static/image/index/5.png new file mode 100644 index 0000000..d65619e Binary files /dev/null and b/static/image/index/5.png differ diff --git a/static/image/index/6.png b/static/image/index/6.png new file mode 100644 index 0000000..d416b91 Binary files /dev/null and b/static/image/index/6.png differ diff --git a/static/image/index/7.png b/static/image/index/7.png new file mode 100644 index 0000000..8fc2b6e Binary files /dev/null and b/static/image/index/7.png differ diff --git a/static/image/index/8.png b/static/image/index/8.png new file mode 100644 index 0000000..fd81395 Binary files /dev/null and b/static/image/index/8.png differ diff --git a/static/image/index/9.png b/static/image/index/9.png new file mode 100644 index 0000000..f6fcd88 Binary files /dev/null and b/static/image/index/9.png differ diff --git a/static/image/index/banner.png b/static/image/index/banner.png new file mode 100644 index 0000000..5e12e76 Binary files /dev/null and b/static/image/index/banner.png differ diff --git a/static/image/index/banner1.png b/static/image/index/banner1.png new file mode 100644 index 0000000..96f920c Binary files /dev/null and b/static/image/index/banner1.png differ diff --git a/static/image/info-bg.jpg b/static/image/info-bg.jpg new file mode 100644 index 0000000..bf0bd0c Binary files /dev/null and b/static/image/info-bg.jpg differ diff --git a/static/image/info.png b/static/image/info.png new file mode 100644 index 0000000..cc48896 Binary files /dev/null and b/static/image/info.png differ diff --git a/static/image/login1.png b/static/image/login1.png new file mode 100644 index 0000000..3696454 Binary files /dev/null and b/static/image/login1.png differ diff --git a/static/image/login2.png b/static/image/login2.png new file mode 100644 index 0000000..bba9df6 Binary files /dev/null and b/static/image/login2.png differ diff --git a/static/image/logo.png b/static/image/logo.png new file mode 100644 index 0000000..54001c1 Binary files /dev/null and b/static/image/logo.png differ diff --git a/static/image/logo1.png b/static/image/logo1.png new file mode 100644 index 0000000..24e9c5f Binary files /dev/null and b/static/image/logo1.png differ diff --git a/static/image/none.png b/static/image/none.png new file mode 100644 index 0000000..7f26edd Binary files /dev/null and b/static/image/none.png differ diff --git a/static/image/person-bg.png b/static/image/person-bg.png new file mode 100644 index 0000000..c7053ab Binary files /dev/null and b/static/image/person-bg.png differ diff --git a/static/image/person1.png b/static/image/person1.png new file mode 100644 index 0000000..fca1656 Binary files /dev/null and b/static/image/person1.png differ diff --git a/static/image/person2.png b/static/image/person2.png new file mode 100644 index 0000000..9d67572 Binary files /dev/null and b/static/image/person2.png differ diff --git a/static/image/person26.png b/static/image/person26.png new file mode 100644 index 0000000..8ecb59c Binary files /dev/null and b/static/image/person26.png differ diff --git a/static/image/person27.png b/static/image/person27.png new file mode 100644 index 0000000..da9f936 Binary files /dev/null and b/static/image/person27.png differ diff --git a/static/image/person3.png b/static/image/person3.png new file mode 100644 index 0000000..5ff5353 Binary files /dev/null and b/static/image/person3.png differ diff --git a/static/image/person4.png b/static/image/person4.png new file mode 100644 index 0000000..f4be28c Binary files /dev/null and b/static/image/person4.png differ diff --git a/static/image/person5.png b/static/image/person5.png new file mode 100644 index 0000000..7867860 Binary files /dev/null and b/static/image/person5.png differ diff --git a/static/image/person6.png b/static/image/person6.png new file mode 100644 index 0000000..f2e1025 Binary files /dev/null and b/static/image/person6.png differ diff --git a/static/image/person7.png b/static/image/person7.png new file mode 100644 index 0000000..b3639c3 Binary files /dev/null and b/static/image/person7.png differ diff --git a/static/image/person8.png b/static/image/person8.png new file mode 100644 index 0000000..404ca7b Binary files /dev/null and b/static/image/person8.png differ diff --git a/static/image/person9.png b/static/image/person9.png new file mode 100644 index 0000000..3b1ae92 Binary files /dev/null and b/static/image/person9.png differ diff --git a/static/image/phone.png b/static/image/phone.png new file mode 100644 index 0000000..b67616a Binary files /dev/null and b/static/image/phone.png differ diff --git a/static/image/product.png b/static/image/product.png new file mode 100644 index 0000000..5c32c3c Binary files /dev/null and b/static/image/product.png differ diff --git a/static/image/product/1.png b/static/image/product/1.png new file mode 100644 index 0000000..70f05e9 Binary files /dev/null and b/static/image/product/1.png differ diff --git a/static/image/product/2.png b/static/image/product/2.png new file mode 100644 index 0000000..b69e84b Binary files /dev/null and b/static/image/product/2.png differ diff --git a/static/image/product/3.png b/static/image/product/3.png new file mode 100644 index 0000000..f4fe323 Binary files /dev/null and b/static/image/product/3.png differ diff --git a/static/image/product/4.png b/static/image/product/4.png new file mode 100644 index 0000000..1d975c6 Binary files /dev/null and b/static/image/product/4.png differ diff --git a/static/image/product/5.png b/static/image/product/5.png new file mode 100644 index 0000000..5c98aac Binary files /dev/null and b/static/image/product/5.png differ diff --git a/static/image/product/6.png b/static/image/product/6.png new file mode 100644 index 0000000..bf93532 Binary files /dev/null and b/static/image/product/6.png differ diff --git a/static/image/product/excel.png b/static/image/product/excel.png new file mode 100644 index 0000000..778174a Binary files /dev/null and b/static/image/product/excel.png differ diff --git a/static/image/product/pdf.png b/static/image/product/pdf.png new file mode 100644 index 0000000..d04fdc3 Binary files /dev/null and b/static/image/product/pdf.png differ diff --git a/static/image/product/ppt.png b/static/image/product/ppt.png new file mode 100644 index 0000000..ddd6b10 Binary files /dev/null and b/static/image/product/ppt.png differ diff --git a/static/image/product/shop-blue.png b/static/image/product/shop-blue.png new file mode 100644 index 0000000..e1f55c1 Binary files /dev/null and b/static/image/product/shop-blue.png differ diff --git a/static/image/product/shop.png b/static/image/product/shop.png new file mode 100644 index 0000000..a698eff Binary files /dev/null and b/static/image/product/shop.png differ diff --git a/static/image/product/word.png b/static/image/product/word.png new file mode 100644 index 0000000..bedc504 Binary files /dev/null and b/static/image/product/word.png differ diff --git a/static/image/qrcode.png b/static/image/qrcode.png new file mode 100644 index 0000000..8654e2c Binary files /dev/null and b/static/image/qrcode.png differ diff --git a/static/image/school.png b/static/image/school.png new file mode 100644 index 0000000..af4535f Binary files /dev/null and b/static/image/school.png differ diff --git a/static/image/study-bg.jpg b/static/image/study-bg.jpg new file mode 100644 index 0000000..afe399f Binary files /dev/null and b/static/image/study-bg.jpg differ diff --git a/static/image/tab1-1.png b/static/image/tab1-1.png new file mode 100644 index 0000000..819c915 Binary files /dev/null and b/static/image/tab1-1.png differ diff --git a/static/image/tab1.png b/static/image/tab1.png new file mode 100644 index 0000000..6b1255d Binary files /dev/null and b/static/image/tab1.png differ diff --git a/static/image/tab2-1.png b/static/image/tab2-1.png new file mode 100644 index 0000000..5dd59cc Binary files /dev/null and b/static/image/tab2-1.png differ diff --git a/static/image/tab2.png b/static/image/tab2.png new file mode 100644 index 0000000..a343fd8 Binary files /dev/null and b/static/image/tab2.png differ diff --git a/static/image/tab3-1.png b/static/image/tab3-1.png new file mode 100644 index 0000000..72ae725 Binary files /dev/null and b/static/image/tab3-1.png differ diff --git a/static/image/tab3.png b/static/image/tab3.png new file mode 100644 index 0000000..b8560b2 Binary files /dev/null and b/static/image/tab3.png differ diff --git a/static/image/tab4-1.png b/static/image/tab4-1.png new file mode 100644 index 0000000..e889467 Binary files /dev/null and b/static/image/tab4-1.png differ diff --git a/static/image/tab4.png b/static/image/tab4.png new file mode 100644 index 0000000..e444b25 Binary files /dev/null and b/static/image/tab4.png differ diff --git a/static/image/trash.png b/static/image/trash.png new file mode 100644 index 0000000..eda986d Binary files /dev/null and b/static/image/trash.png differ diff --git a/static/image/unfold.png b/static/image/unfold.png new file mode 100644 index 0000000..62ca6e5 Binary files /dev/null and b/static/image/unfold.png differ diff --git a/static/image/wechat.png b/static/image/wechat.png new file mode 100644 index 0000000..9f8d946 Binary files /dev/null and b/static/image/wechat.png differ diff --git a/static/image/workbench/index1.png b/static/image/workbench/index1.png new file mode 100644 index 0000000..bdbfa67 Binary files /dev/null and b/static/image/workbench/index1.png differ diff --git a/static/image/workbench/index10.png b/static/image/workbench/index10.png new file mode 100644 index 0000000..2153a6f Binary files /dev/null and b/static/image/workbench/index10.png differ diff --git a/static/image/workbench/index11.png b/static/image/workbench/index11.png new file mode 100644 index 0000000..415c90c Binary files /dev/null and b/static/image/workbench/index11.png differ diff --git a/static/image/workbench/index12.png b/static/image/workbench/index12.png new file mode 100644 index 0000000..076af33 Binary files /dev/null and b/static/image/workbench/index12.png differ diff --git a/static/image/workbench/index2.png b/static/image/workbench/index2.png new file mode 100644 index 0000000..dd10c1b Binary files /dev/null and b/static/image/workbench/index2.png differ diff --git a/static/image/workbench/index3.png b/static/image/workbench/index3.png new file mode 100644 index 0000000..abe9779 Binary files /dev/null and b/static/image/workbench/index3.png differ diff --git a/static/image/workbench/index4.png b/static/image/workbench/index4.png new file mode 100644 index 0000000..029d403 Binary files /dev/null and b/static/image/workbench/index4.png differ diff --git a/static/image/workbench/index5.png b/static/image/workbench/index5.png new file mode 100644 index 0000000..a33fdb7 Binary files /dev/null and b/static/image/workbench/index5.png differ diff --git a/static/image/workbench/index6.png b/static/image/workbench/index6.png new file mode 100644 index 0000000..aee4959 Binary files /dev/null and b/static/image/workbench/index6.png differ diff --git a/static/image/workbench/index7.png b/static/image/workbench/index7.png new file mode 100644 index 0000000..1fbd6c4 Binary files /dev/null and b/static/image/workbench/index7.png differ diff --git a/static/image/workbench/index8.png b/static/image/workbench/index8.png new file mode 100644 index 0000000..df914cf Binary files /dev/null and b/static/image/workbench/index8.png differ diff --git a/static/image/workbench/index9.png b/static/image/workbench/index9.png new file mode 100644 index 0000000..186de65 Binary files /dev/null and b/static/image/workbench/index9.png differ diff --git a/styles/common.scss b/styles/common.scss new file mode 100644 index 0000000..8a817e6 --- /dev/null +++ b/styles/common.scss @@ -0,0 +1,305 @@ +button[type=primary] { + background-color: #007eff; +} +.bg-wh { + background-color: #fff; +} +page { + height: 100%; + background-color: #f5f5f5; +} +ul { + padding-left: 0; + li { + list-style: none; + } +} +.block { + padding: 0 24rpx; + margin: 20rpx 24rpx; + border-radius: 16rpx; + background-color: #fff; +} +.ell { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} +.l-title { + display: flex; + align-items: center; + padding: 28rpx 0; + font-size: 28rpx; + color: #333; + &:before { + content: ''; + width: 6rpx; + height: 28rpx; + margin-right: 12rpx; + vertical-align: middle; + background-color: #4876F9; + } +} +@mixin sort { + margin: 0 20rpx 0 10rpx; + &:before { + content: ''; + display: block; + margin-bottom: 5rpx; + border: 15rpx solid transparent; + border-bottom-color: #B9B9B9; + } + &:after { + content: ''; + display: block; + border: 15rpx solid transparent; + border-top-color: #B9B9B9; + } + &.desc:before { + border-bottom-color: #007EFF; + } + &.asc:after { + border-top-color: #007EFF; + } +} +.filter { + display: flex; + align-items: center; + padding: 10rpx 30rpx 10rpx 10rpx; + background-color: #fff; + .search { + flex: 1; + } + .uni-searchbar__box { + height: 70rpx; + } + .sort { + @include sort; + } +} +.form-list { + border-top: 1px solid #E6E8ED; + .line { + display: flex; + justify-content: space-between; + align-items: center; + padding: 28rpx 0; + border-bottom: 1px solid #E6E8ED; + &:last-child { + border-bottom: 0; + } + } + .ph { + font-size: 28rpx; + color: #999; + } + .name, .val, input { + font-size: 28rpx; + color: #333; + } + input { + flex: 1; + margin-left: 20rpx; + text-align: right; + } + .req { + .name:after { + content: '*'; + margin-left: 6rpx; + color: #F53232; + vertical-align: middle; + } + } + .err { + .name { + color: #f00; + } + } + .inline { + display: inline-flex; + align-items: center; + @extend input; + input { + margin-right: 10rpx; + } + } +} +.picker-input .input-value-border { + line-height: 1; + border: 0; +} +.tab { + display: flex; + justify-content: space-around; + margin-bottom: 20rpx; + background-color: #fff; + li { + padding: 0 20rpx; + font-size: 28rpx; + white-space: nowrap; + line-height: 100rpx; + border-bottom: 3px solid transparent; + } + .active { + color: $uni-primary; + border-bottom-color: $uni-primary; + } + .sort { + @include sort; + } +} +.plus { + position: fixed; + bottom: 40rpx; + right: 40rpx; +} + +.popup-mask { + z-index: 9; + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + background-color: rgba(0, 0, 0, .5); +} +.popup { + z-index: 10; + position: fixed; + bottom: 0%; + width: 100%; + height: 90vh; + background-color: #fff; + border-top-left-radius: 8px; + border-top-right-radius: 8px; + .top { + text-align: center; + line-height: 100rpx; + font-size: 28rpx; + color: #333; + border-bottom: 1px solid #f1f1f1; + } + .close { + position: absolute; + top: 30rpx; + right: 30rpx; + } + .list { + max-height: calc(90vh - 206rpx); + padding: 0 30rpx; + overflow: auto; + .item { + line-height: 80rpx; + font-size: 24rpx; + } + } +} +.type-popup { + z-index: 10; + position: fixed; + top: 100%; + left: 0; + width: 100%; + height: 100%; + padding: 10rpx; + background-color: #fff; + transition: .3s; + overflow: auto; + &.active { + top: 0; + } + .close { + position: absolute; + top: 50rpx; + right: 50rpx; + } + .title { + margin: 150rpx 20rpx 30rpx; + font-size: 30rpx; + color: #333; + } + .types { + display: flex; + flex-wrap: wrap; + } + .item { + width: calc((100% - 80rpx) / 3); + margin: 10rpx; + font-size: 28rpx; + line-height: 3; + text-align: center; + color: #1f1f1f; + background-color: #dbebff; + border-radius: 2px; + &.active { + color: #fff; + background-color: #007EFF; + } + } +} +.btn-wrap { + z-index: 10; + position: fixed; + bottom: env(safe-area-inset-bottom); + bottom: 0; + display: flex; + justify-content: flex-end; + align-items: center; + width: 100%; + padding: 20rpx 24rpx 20rpx 40rpx; + background-color: #fff; + box-shadow: 0px 0px 7rpx 0px rgba(203, 203, 203, 0.55); + box-sizing: border-box; + .btn { + width: 100%; + line-height: 80rpx; + font-size: 30rpx; + text-align: center; + color: #fff; + border-radius: 10rpx; + background-color: #007EFF; + } +} +.per-mask { + z-index: 1000; + position: fixed; + top: 0; + left: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + -webkit-user-drag: none; + -webkit-user-select: none; + user-select: none; + .mask { + position: relative; + width: 100%; + height: 100%; + filter: blur(10px); + } + .texts { + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 100%; + text-align: center; + } + .text { + margin-bottom: 40rpx; + font-size: 28rpx; + color: #333; + } + .qrcode { + width: 78%; + } +} + +.not-auth { + height: 100vh; + padding-bottom: 0 !important; + overflow: hidden; + filter: blur(10px); +} \ No newline at end of file diff --git a/uni.scss b/uni.scss new file mode 100644 index 0000000..0bbb54a --- /dev/null +++ b/uni.scss @@ -0,0 +1,3 @@ +@import '@/uni_modules/uni-scss/variables.scss'; +@import '@/styles/common.scss'; +@import '@/static/iconfont/iconfont.css'; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/changelog.md b/uni_modules/Sansnn-uQRCode/changelog.md new file mode 100644 index 0000000..de28dde --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/changelog.md @@ -0,0 +1,44 @@ +## 3.2.2(2022-05-12) +3.2.2 + +修复vue3引入js报错问题; +增加draw可选项,可在每一阶段绘制前后扩展自定义方法,详见文档draw(options); +其他优化。 +## 3.2.1(2022-05-09) +3.2.1 + +已实现导入临时文件方法`toTempFilePath`; +已实现保存二维码到本地或相册方法`save`; +已实现生成完成回调事件`complete`; +文档补充。 +## 3.2.0(2022-05-07) +3.2.0 + +适用所有支持canvas的前端应用和Node.js服务端; +微信小程序端切换为canvas2d; +支持绘制背景图片和前景图片,也就是说可以绘制背景和logo了; +支持对定位角进行样式设置; +支持对分割图案进行样式设置; +支持对对齐图案进行样式设置; +支持对时序图案进行样式设置; +支持对暗块进行样式设置; +支持对版本信息进行样式设置; +解决小块之间出现白线问题。 +## 3.0.1(2022-01-05) +3.0.1 gcanvas引用目录调整。 +## 3.0.0(2022-01-04) +3.0.0 uQRCode 3.0 全新版本来袭。 +## 2.0.4(2021-11-19) +2.0.4 新增绘制模式;新增绘制延时、canvas导入文件延时属性。 +## 2.0.3(2021-10-18) +2.0.3 修复在部分安卓设备生成异常;移除延迟绘制;新增批量生成示例。 +## 2.0.23(2021-08-09) + +## 2.0.22(2021-08-09) + +## 2.0.21(2021-07-28) + +## 2.0.2(2021-07-28) +2.0.2 新增延迟绘制。 +## 2.0.1(2021-07-26) +2.0.1 调整为uni_modules目录规范。 diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/bridge/bridge-weex.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/bridge/bridge-weex.js new file mode 100644 index 0000000..27086ec --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/bridge/bridge-weex.js @@ -0,0 +1,241 @@ +const isWeex = typeof WXEnvironment !== 'undefined'; +const isWeexIOS = isWeex && /ios/i.test(WXEnvironment.platform); +const isWeexAndroid = isWeex && !isWeexIOS; + +import GLmethod from '../context-webgl/GLmethod'; + +const GCanvasModule = + (typeof weex !== 'undefined' && weex.requireModule) ? (weex.requireModule('gcanvas')) : + (typeof __weex_require__ !== 'undefined') ? (__weex_require__('@weex-module/gcanvas')) : {}; + +let isDebugging = false; + +let isComboDisabled = false; + +const logCommand = (function () { + const methodQuery = []; + Object.keys(GLmethod).forEach(key => { + methodQuery[GLmethod[key]] = key; + }) + const queryMethod = (id) => { + return methodQuery[parseInt(id)] || 'NotFoundMethod'; + } + const logCommand = (id, cmds) => { + const mId = cmds.split(',')[0]; + const mName = queryMethod(mId); + console.log(`=== callNative - componentId:${id}; method: ${mName}; cmds: ${cmds}`); + } + return logCommand; +})(); + +function joinArray(arr, sep) { + let res = ''; + for (let i = 0; i < arr.length; i++) { + if (i !== 0) { + res += sep; + } + res += arr[i]; + } + return res; +} + +const commandsCache = {} + +const GBridge = { + + callEnable: (ref, configArray) => { + + commandsCache[ref] = []; + + return GCanvasModule.enable({ + componentId: ref, + config: configArray + }); + }, + + callEnableDebug: () => { + isDebugging = true; + }, + + callEnableDisableCombo: () => { + isComboDisabled = true; + }, + + callSetContextType: function (componentId, context_type) { + GCanvasModule.setContextType(context_type, componentId); + }, + + callReset: function(id){ + GCanvasModule.resetComponent && canvasModule.resetComponent(componentId); + }, + + render: isWeexIOS ? function (componentId) { + return GCanvasModule.extendCallNative({ + contextId: componentId, + type: 0x60000001 + }); + } : function (componentId) { + return callGCanvasLinkNative(componentId, 0x60000001, 'render'); + }, + + render2d: isWeexIOS ? function (componentId, commands, callback) { + + if (isDebugging) { + console.log('>>> >>> render2d ==='); + console.log('>>> commands: ' + commands); + } + + GCanvasModule.render([commands, callback?true:false], componentId, callback); + + } : function (componentId, commands,callback) { + + if (isDebugging) { + console.log('>>> >>> render2d ==='); + console.log('>>> commands: ' + commands); + } + + callGCanvasLinkNative(componentId, 0x20000001, commands); + if(callback){ + callback(); + } + }, + + callExtendCallNative: isWeexIOS ? function (componentId, cmdArgs) { + + throw 'should not be here anymore ' + cmdArgs; + + } : function (componentId, cmdArgs) { + + throw 'should not be here anymore ' + cmdArgs; + + }, + + + flushNative: isWeexIOS ? function (componentId) { + + const cmdArgs = joinArray(commandsCache[componentId], ';'); + commandsCache[componentId] = []; + + if (isDebugging) { + console.log('>>> >>> flush native ==='); + console.log('>>> commands: ' + cmdArgs); + } + + const result = GCanvasModule.extendCallNative({ + "contextId": componentId, + "type": 0x60000000, + "args": cmdArgs + }); + + const res = result && result.result; + + if (isDebugging) { + console.log('>>> result: ' + res); + } + + return res; + + } : function (componentId) { + + const cmdArgs = joinArray(commandsCache[componentId], ';'); + commandsCache[componentId] = []; + + if (isDebugging) { + console.log('>>> >>> flush native ==='); + console.log('>>> commands: ' + cmdArgs); + } + + const result = callGCanvasLinkNative(componentId, 0x60000000, cmdArgs); + + if (isDebugging) { + console.log('>>> result: ' + result); + } + + return result; + }, + + callNative: function (componentId, cmdArgs, cache) { + + if (isDebugging) { + logCommand(componentId, cmdArgs); + } + + commandsCache[componentId].push(cmdArgs); + + if (!cache || isComboDisabled) { + return GBridge.flushNative(componentId); + } else { + return undefined; + } + }, + + texImage2D(componentId, ...args) { + if (isWeexIOS) { + if (args.length === 6) { + const [target, level, internalformat, format, type, image] = args; + GBridge.callNative( + componentId, + GLmethod.texImage2D + ',' + 6 + ',' + target + ',' + level + ',' + internalformat + ',' + format + ',' + type + ',' + image.src + ) + } else if (args.length === 9) { + const [target, level, internalformat, width, height, border, format, type, image] = args; + GBridge.callNative( + componentId, + GLmethod.texImage2D + ',' + 9 + ',' + target + ',' + level + ',' + internalformat + ',' + width + ',' + height + ',' + border + ',' + + + format + ',' + type + ',' + (image ? image.src : 0) + ) + } + } else if (isWeexAndroid) { + if (args.length === 6) { + const [target, level, internalformat, format, type, image] = args; + GCanvasModule.texImage2D(componentId, target, level, internalformat, format, type, image.src); + } else if (args.length === 9) { + const [target, level, internalformat, width, height, border, format, type, image] = args; + GCanvasModule.texImage2D(componentId, target, level, internalformat, width, height, border, format, type, (image ? image.src : 0)); + } + } + }, + + texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image) { + if (isWeexIOS) { + if (arguments.length === 8) { + GBridge.callNative( + componentId, + GLmethod.texSubImage2D + ',' + 6 + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset, + ',' + format + ',' + type + ',' + image.src + ) + } + } else if (isWeexAndroid) { + GCanvasModule.texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image.src); + } + }, + + bindImageTexture(componentId, src, imageId) { + GCanvasModule.bindImageTexture([src, imageId], componentId); + }, + + perloadImage([url, id], callback) { + GCanvasModule.preLoadImage([url, id], function (image) { + image.url = url; + image.id = id; + callback(image); + }); + }, + + measureText(text, fontStyle, componentId) { + return GCanvasModule.measureText([text, fontStyle], componentId); + }, + + getImageData (componentId, x, y, w, h, callback) { + GCanvasModule.getImageData([x, y,w,h],componentId,callback); + }, + + putImageData (componentId, data, x, y, w, h, callback) { + GCanvasModule.putImageData([x, y,w,h,data],componentId,callback); + }, + + toTempFilePath(componentId, x, y, width, height, destWidth, destHeight, fileType, quality, callback){ + GCanvasModule.toTempFilePath([x, y, width,height, destWidth, destHeight, fileType, quality], componentId, callback); + } +} + +export default GBridge; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js new file mode 100644 index 0000000..3e7f03a --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js @@ -0,0 +1,18 @@ +class FillStyleLinearGradient { + + constructor(x0, y0, x1, y1) { + this._start_pos = { _x: x0, _y: y0 }; + this._end_pos = { _x: x1, _y: y1 }; + this._stop_count = 0; + this._stops = [0, 0, 0, 0, 0]; + } + + addColorStop = function (pos, color) { + if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) { + this._stops[this._stop_count] = { _pos: pos, _color: color }; + this._stop_count++; + } + } +} + +export default FillStyleLinearGradient; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStylePattern.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStylePattern.js new file mode 100644 index 0000000..6e4f646 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStylePattern.js @@ -0,0 +1,8 @@ +class FillStylePattern { + constructor(img, pattern) { + this._style = pattern; + this._img = img; + } +} + +export default FillStylePattern; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js new file mode 100644 index 0000000..7790596 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js @@ -0,0 +1,17 @@ +class FillStyleRadialGradient { + constructor(x0, y0, r0, x1, y1, r1) { + this._start_pos = { _x: x0, _y: y0, _r: r0 }; + this._end_pos = { _x: x1, _y: y1, _r: r1 }; + this._stop_count = 0; + this._stops = [0, 0, 0, 0, 0]; + } + + addColorStop(pos, color) { + if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) { + this._stops[this._stop_count] = { _pos: pos, _color: color }; + this._stop_count++; + } + } +} + +export default FillStyleRadialGradient; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/RenderingContext.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/RenderingContext.js new file mode 100644 index 0000000..e6b8f48 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-2d/RenderingContext.js @@ -0,0 +1,666 @@ +import FillStylePattern from './FillStylePattern'; +import FillStyleLinearGradient from './FillStyleLinearGradient'; +import FillStyleRadialGradient from './FillStyleRadialGradient'; +import GImage from '../env/image.js'; +import { + ArrayBufferToBase64, + Base64ToUint8ClampedArray +} from '../env/tool.js'; + +export default class CanvasRenderingContext2D { + + _drawCommands = ''; + + _globalAlpha = 1.0; + + _fillStyle = 'rgb(0,0,0)'; + _strokeStyle = 'rgb(0,0,0)'; + + _lineWidth = 1; + _lineCap = 'butt'; + _lineJoin = 'miter'; + + _miterLimit = 10; + + _globalCompositeOperation = 'source-over'; + + _textAlign = 'start'; + _textBaseline = 'alphabetic'; + + _font = '10px sans-serif'; + + _savedGlobalAlpha = []; + + timer = null; + componentId = null; + + _notCommitDrawImageCache = []; + _needRedrawImageCache = []; + _redrawCommands = ''; + _autoSaveContext = true; + // _imageMap = new GHashMap(); + // _textureMap = new GHashMap(); + + constructor() { + this.className = 'CanvasRenderingContext2D'; + //this.save() + } + + setFillStyle(value) { + this.fillStyle = value; + } + + set fillStyle(value) { + this._fillStyle = value; + + if (typeof(value) == 'string') { + this._drawCommands = this._drawCommands.concat("F" + value + ";"); + } else if (value instanceof FillStylePattern) { + const image = value._img; + if (!image.complete) { + image.onload = () => { + var index = this._needRedrawImageCache.indexOf(image); + if (index > -1) { + this._needRedrawImageCache.splice(index, 1); + CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id); + this._redrawflush(true); + } + } + this._notCommitDrawImageCache.push(image); + } else { + CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id); + } + + //CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id); + this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";"); + } else if (value instanceof FillStyleLinearGradient) { + var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + + value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + + value._stop_count; + for (var i = 0; i < value._stop_count; ++i) { + command += ("," + value._stops[i]._pos + "," + value._stops[i]._color); + } + this._drawCommands = this._drawCommands.concat(command + ";"); + } else if (value instanceof FillStyleRadialGradient) { + var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r + .toFixed(2) + "," + + value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + value._end_pos._r.toFixed(2) + "," + + value._stop_count; + for (var i = 0; i < value._stop_count; ++i) { + command += ("," + value._stops[i]._pos + "," + value._stops[i]._color); + } + this._drawCommands = this._drawCommands.concat(command + ";"); + } + } + + get fillStyle() { + return this._fillStyle; + } + + get globalAlpha() { + return this._globalAlpha; + } + + setGlobalAlpha(value) { + this.globalAlpha = value; + } + + set globalAlpha(value) { + this._globalAlpha = value; + this._drawCommands = this._drawCommands.concat("a" + value.toFixed(2) + ";"); + } + + + get strokeStyle() { + return this._strokeStyle; + } + + setStrokeStyle(value) { + this.strokeStyle = value; + } + + set strokeStyle(value) { + + this._strokeStyle = value; + + if (typeof(value) == 'string') { + this._drawCommands = this._drawCommands.concat("S" + value + ";"); + } else if (value instanceof FillStylePattern) { + CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id); + this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";"); + } else if (value instanceof FillStyleLinearGradient) { + var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + + value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + + value._stop_count; + + for (var i = 0; i < value._stop_count; ++i) { + command += ("," + value._stops[i]._pos + "," + value._stops[i]._color); + } + this._drawCommands = this._drawCommands.concat(command + ";"); + } else if (value instanceof FillStyleRadialGradient) { + var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r + .toFixed(2) + "," + + value._end_pos._x.toFixed(2) + "," + value._end_pos._y + ",".toFixed(2) + value._end_pos._r.toFixed(2) + "," + + value._stop_count; + + for (var i = 0; i < value._stop_count; ++i) { + command += ("," + value._stops[i]._pos + "," + value._stops[i]._color); + } + this._drawCommands = this._drawCommands.concat(command + ";"); + } + } + + get lineWidth() { + return this._lineWidth; + } + + setLineWidth(value) { + this.lineWidth = value; + } + + set lineWidth(value) { + this._lineWidth = value; + this._drawCommands = this._drawCommands.concat("W" + value + ";"); + } + + get lineCap() { + return this._lineCap; + } + + setLineCap(value) { + this.lineCap = value; + } + + set lineCap(value) { + this._lineCap = value; + this._drawCommands = this._drawCommands.concat("C" + value + ";"); + } + + get lineJoin() { + return this._lineJoin; + } + + setLineJoin(value) { + this.lineJoin = value + } + + set lineJoin(value) { + this._lineJoin = value; + this._drawCommands = this._drawCommands.concat("J" + value + ";"); + } + + get miterLimit() { + return this._miterLimit; + } + + setMiterLimit(value) { + this.miterLimit = value + } + + set miterLimit(value) { + this._miterLimit = value; + this._drawCommands = this._drawCommands.concat("M" + value + ";"); + } + + get globalCompositeOperation() { + return this._globalCompositeOperation; + } + + set globalCompositeOperation(value) { + + this._globalCompositeOperation = value; + let mode = 0; + switch (value) { + case "source-over": + mode = 0; + break; + case "source-atop": + mode = 5; + break; + case "source-in": + mode = 0; + break; + case "source-out": + mode = 2; + break; + case "destination-over": + mode = 4; + break; + case "destination-atop": + mode = 4; + break; + case "destination-in": + mode = 4; + break; + case "destination-out": + mode = 3; + break; + case "lighter": + mode = 1; + break; + case "copy": + mode = 2; + break; + case "xor": + mode = 6; + break; + default: + mode = 0; + } + + this._drawCommands = this._drawCommands.concat("B" + mode + ";"); + } + + get textAlign() { + return this._textAlign; + } + + setTextAlign(value) { + this.textAlign = value + } + + set textAlign(value) { + + this._textAlign = value; + let Align = 0; + switch (value) { + case "start": + Align = 0; + break; + case "end": + Align = 1; + break; + case "left": + Align = 2; + break; + case "center": + Align = 3; + break; + case "right": + Align = 4; + break; + default: + Align = 0; + } + + this._drawCommands = this._drawCommands.concat("A" + Align + ";"); + } + + get textBaseline() { + return this._textBaseline; + } + + setTextBaseline(value) { + this.textBaseline = value + } + + set textBaseline(value) { + this._textBaseline = value; + let baseline = 0; + switch (value) { + case "alphabetic": + baseline = 0; + break; + case "middle": + baseline = 1; + break; + case "top": + baseline = 2; + break; + case "hanging": + baseline = 3; + break; + case "bottom": + baseline = 4; + break; + case "ideographic": + baseline = 5; + break; + default: + baseline = 0; + break; + } + + this._drawCommands = this._drawCommands.concat("E" + baseline + ";"); + } + + get font() { + return this._font; + } + + setFontSize(size) { + var str = this._font; + var strs = str.trim().split(/\s+/); + for (var i = 0; i < strs.length; i++) { + var values = ["normal", "italic", "oblique", "normal", "small-caps", "normal", "bold", + "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", + "normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", + "semi-expanded", "expanded", "extra-expanded", "ultra-expanded" + ]; + + if (-1 == values.indexOf(strs[i].trim())) { + if (typeof size === 'string') { + strs[i] = size; + } else if (typeof size === 'number') { + strs[i] = String(size) + 'px'; + } + break; + } + } + this.font = strs.join(" "); + } + + set font(value) { + this._font = value; + this._drawCommands = this._drawCommands.concat("j" + value + ";"); + } + + setTransform(a, b, c, d, tx, ty) { + this._drawCommands = this._drawCommands.concat("t" + + (a === 1 ? "1" : a.toFixed(2)) + "," + + (b === 0 ? "0" : b.toFixed(2)) + "," + + (c === 0 ? "0" : c.toFixed(2)) + "," + + (d === 1 ? "1" : d.toFixed(2)) + "," + tx.toFixed(2) + "," + ty.toFixed(2) + ";"); + } + + transform(a, b, c, d, tx, ty) { + this._drawCommands = this._drawCommands.concat("f" + + (a === 1 ? "1" : a.toFixed(2)) + "," + + (b === 0 ? "0" : b.toFixed(2)) + "," + + (c === 0 ? "0" : c.toFixed(2)) + "," + + (d === 1 ? "1" : d.toFixed(2)) + "," + tx + "," + ty + ";"); + } + + resetTransform() { + this._drawCommands = this._drawCommands.concat("m;"); + } + + scale(a, d) { + this._drawCommands = this._drawCommands.concat("k" + a.toFixed(2) + "," + + d.toFixed(2) + ";"); + } + + rotate(angle) { + this._drawCommands = this._drawCommands + .concat("r" + angle.toFixed(6) + ";"); + } + + translate(tx, ty) { + this._drawCommands = this._drawCommands.concat("l" + tx.toFixed(2) + "," + ty.toFixed(2) + ";"); + } + + save() { + this._savedGlobalAlpha.push(this._globalAlpha); + this._drawCommands = this._drawCommands.concat("v;"); + } + + restore() { + this._drawCommands = this._drawCommands.concat("e;"); + this._globalAlpha = this._savedGlobalAlpha.pop(); + } + + createPattern(img, pattern) { + if (typeof img === 'string') { + var imgObj = new GImage(); + imgObj.src = img; + img = imgObj; + } + return new FillStylePattern(img, pattern); + } + + createLinearGradient(x0, y0, x1, y1) { + return new FillStyleLinearGradient(x0, y0, x1, y1); + } + + createRadialGradient = function(x0, y0, r0, x1, y1, r1) { + return new FillStyleRadialGradient(x0, y0, r0, x1, y1, r1); + }; + + createCircularGradient = function(x0, y0, r0) { + return new FillStyleRadialGradient(x0, y0, 0, x0, y0, r0); + }; + + strokeRect(x, y, w, h) { + this._drawCommands = this._drawCommands.concat("s" + x + "," + y + "," + w + "," + h + ";"); + } + + + clearRect(x, y, w, h) { + this._drawCommands = this._drawCommands.concat("c" + x + "," + y + "," + w + + "," + h + ";"); + } + + clip() { + this._drawCommands = this._drawCommands.concat("p;"); + } + + resetClip() { + this._drawCommands = this._drawCommands.concat("q;"); + } + + closePath() { + this._drawCommands = this._drawCommands.concat("o;"); + } + + moveTo(x, y) { + this._drawCommands = this._drawCommands.concat("g" + x.toFixed(2) + "," + y.toFixed(2) + ";"); + } + + lineTo(x, y) { + this._drawCommands = this._drawCommands.concat("i" + x.toFixed(2) + "," + y.toFixed(2) + ";"); + } + + quadraticCurveTo = function(cpx, cpy, x, y) { + this._drawCommands = this._drawCommands.concat("u" + cpx + "," + cpy + "," + x + "," + y + ";"); + } + + bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, ) { + this._drawCommands = this._drawCommands.concat( + "z" + cp1x.toFixed(2) + "," + cp1y.toFixed(2) + "," + cp2x.toFixed(2) + "," + cp2y.toFixed(2) + "," + + x.toFixed(2) + "," + y.toFixed(2) + ";"); + } + + arcTo(x1, y1, x2, y2, radius) { + this._drawCommands = this._drawCommands.concat("h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";"); + } + + beginPath() { + this._drawCommands = this._drawCommands.concat("b;"); + } + + + fillRect(x, y, w, h) { + this._drawCommands = this._drawCommands.concat("n" + x + "," + y + "," + w + + "," + h + ";"); + } + + rect(x, y, w, h) { + this._drawCommands = this._drawCommands.concat("w" + x + "," + y + "," + w + "," + h + ";"); + } + + fill() { + this._drawCommands = this._drawCommands.concat("L;"); + } + + stroke(path) { + this._drawCommands = this._drawCommands.concat("x;"); + } + + arc(x, y, radius, startAngle, endAngle, anticlockwise) { + + let ianticlockwise = 0; + if (anticlockwise) { + ianticlockwise = 1; + } + + this._drawCommands = this._drawCommands.concat( + "y" + x.toFixed(2) + "," + y.toFixed(2) + "," + + radius.toFixed(2) + "," + startAngle + "," + endAngle + "," + ianticlockwise + + ";" + ); + } + + fillText(text, x, y) { + let tmptext = text.replace(/!/g, "!!"); + tmptext = tmptext.replace(/,/g, "!,"); + tmptext = tmptext.replace(/;/g, "!;"); + this._drawCommands = this._drawCommands.concat("T" + tmptext + "," + x + "," + y + ",0.0;"); + } + + strokeText = function(text, x, y) { + let tmptext = text.replace(/!/g, "!!"); + tmptext = tmptext.replace(/,/g, "!,"); + tmptext = tmptext.replace(/;/g, "!;"); + this._drawCommands = this._drawCommands.concat("U" + tmptext + "," + x + "," + y + ",0.0;"); + } + + measureText(text) { + return CanvasRenderingContext2D.GBridge.measureText(text, this.font, this.componentId); + } + + isPointInPath = function(x, y) { + throw new Error('GCanvas not supported yet'); + } + + drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) { + if (typeof image === 'string') { + var imgObj = new GImage(); + imgObj.src = image; + image = imgObj; + } + if (image instanceof GImage) { + if (!image.complete) { + imgObj.onload = () => { + var index = this._needRedrawImageCache.indexOf(image); + if (index > -1) { + this._needRedrawImageCache.splice(index, 1); + CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id); + this._redrawflush(true); + } + } + this._notCommitDrawImageCache.push(image); + } else { + CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id); + } + var srcArgs = [image, sx, sy, sw, sh, dx, dy, dw, dh]; + var args = []; + for (var arg in srcArgs) { + if (typeof(srcArgs[arg]) != 'undefined') { + args.push(srcArgs[arg]); + } + } + this.__drawImage.apply(this, args); + //this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh); + } + } + + __drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) { + const numArgs = arguments.length; + + function drawImageCommands() { + + if (numArgs === 3) { + const x = parseFloat(sx) || 0.0; + const y = parseFloat(sy) || 0.0; + + return ("d" + image._id + ",0,0," + + image.width + "," + image.height + "," + + x + "," + y + "," + image.width + "," + image.height + ";"); + } else if (numArgs === 5) { + const x = parseFloat(sx) || 0.0; + const y = parseFloat(sy) || 0.0; + const width = parseInt(sw) || image.width; + const height = parseInt(sh) || image.height; + + return ("d" + image._id + ",0,0," + + image.width + "," + image.height + "," + + x + "," + y + "," + width + "," + height + ";"); + } else if (numArgs === 9) { + sx = parseFloat(sx) || 0.0; + sy = parseFloat(sy) || 0.0; + sw = parseInt(sw) || image.width; + sh = parseInt(sh) || image.height; + dx = parseFloat(dx) || 0.0; + dy = parseFloat(dy) || 0.0; + dw = parseInt(dw) || image.width; + dh = parseInt(dh) || image.height; + + return ("d" + image._id + "," + + sx + "," + sy + "," + sw + "," + sh + "," + + dx + "," + dy + "," + dw + "," + dh + ";"); + } + } + this._drawCommands += drawImageCommands(); + } + + _flush(reserve, callback) { + const commands = this._drawCommands; + this._drawCommands = ''; + CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback); + this._needRender = false; + } + + _redrawflush(reserve, callback) { + const commands = this._redrawCommands; + CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback); + if (this._needRedrawImageCache.length == 0) { + this._redrawCommands = ''; + } + } + + draw(reserve, callback) { + if (!reserve) { + this._globalAlpha = this._savedGlobalAlpha.pop(); + this._savedGlobalAlpha.push(this._globalAlpha); + this._redrawCommands = this._drawCommands; + this._needRedrawImageCache = this._notCommitDrawImageCache; + if (this._autoSaveContext) { + this._drawCommands = ("v;" + this._drawCommands); + this._autoSaveContext = false; + } else { + this._drawCommands = ("e;X;v;" + this._drawCommands); + } + } else { + this._needRedrawImageCache = this._needRedrawImageCache.concat(this._notCommitDrawImageCache); + this._redrawCommands += this._drawCommands; + if (this._autoSaveContext) { + this._drawCommands = ("v;" + this._drawCommands); + this._autoSaveContext = false; + } + } + this._notCommitDrawImageCache = []; + if (this._flush) { + this._flush(reserve, callback); + } + } + + getImageData(x, y, w, h, callback) { + CanvasRenderingContext2D.GBridge.getImageData(this.componentId, x, y, w, h, function(res) { + res.data = Base64ToUint8ClampedArray(res.data); + if (typeof(callback) == 'function') { + callback(res); + } + }); + } + + putImageData(data, x, y, w, h, callback) { + if (data instanceof Uint8ClampedArray) { + data = ArrayBufferToBase64(data); + CanvasRenderingContext2D.GBridge.putImageData(this.componentId, data, x, y, w, h, function(res) { + if (typeof(callback) == 'function') { + callback(res); + } + }); + } + } + + toTempFilePath(x, y, width, height, destWidth, destHeight, fileType, quality, callback) { + CanvasRenderingContext2D.GBridge.toTempFilePath(this.componentId, x, y, width, height, destWidth, destHeight, + fileType, quality, + function(res) { + if (typeof(callback) == 'function') { + callback(res); + } + }); + } +} diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/ActiveInfo.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/ActiveInfo.js new file mode 100644 index 0000000..b495129 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/ActiveInfo.js @@ -0,0 +1,11 @@ +export default class WebGLActiveInfo { + className = 'WebGLActiveInfo'; + + constructor({ + type, name, size + }) { + this.type = type; + this.name = name; + this.size = size; + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Buffer.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Buffer.js new file mode 100644 index 0000000..4800f67 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Buffer.js @@ -0,0 +1,21 @@ +import {getTransferedObjectUUID} from './classUtils'; + +const name = 'WebGLBuffer'; + +function uuid(id) { + return getTransferedObjectUUID(name, id); +} + +export default class WebGLBuffer { + className = name; + + constructor(id) { + this.id = id; + } + + static uuid = uuid; + + uuid() { + return uuid(this.id); + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Framebuffer.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Framebuffer.js new file mode 100644 index 0000000..28b46d3 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Framebuffer.js @@ -0,0 +1,21 @@ +import {getTransferedObjectUUID} from './classUtils'; + +const name = 'WebGLFrameBuffer'; + +function uuid(id) { + return getTransferedObjectUUID(name, id); +} + +export default class WebGLFramebuffer { + className = name; + + constructor(id) { + this.id = id; + } + + static uuid = uuid; + + uuid() { + return uuid(this.id); + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLenum.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLenum.js new file mode 100644 index 0000000..ac5544d --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLenum.js @@ -0,0 +1,298 @@ +export default { + "DEPTH_BUFFER_BIT": 256, + "STENCIL_BUFFER_BIT": 1024, + "COLOR_BUFFER_BIT": 16384, + "POINTS": 0, + "LINES": 1, + "LINE_LOOP": 2, + "LINE_STRIP": 3, + "TRIANGLES": 4, + "TRIANGLE_STRIP": 5, + "TRIANGLE_FAN": 6, + "ZERO": 0, + "ONE": 1, + "SRC_COLOR": 768, + "ONE_MINUS_SRC_COLOR": 769, + "SRC_ALPHA": 770, + "ONE_MINUS_SRC_ALPHA": 771, + "DST_ALPHA": 772, + "ONE_MINUS_DST_ALPHA": 773, + "DST_COLOR": 774, + "ONE_MINUS_DST_COLOR": 775, + "SRC_ALPHA_SATURATE": 776, + "FUNC_ADD": 32774, + "BLEND_EQUATION": 32777, + "BLEND_EQUATION_RGB": 32777, + "BLEND_EQUATION_ALPHA": 34877, + "FUNC_SUBTRACT": 32778, + "FUNC_REVERSE_SUBTRACT": 32779, + "BLEND_DST_RGB": 32968, + "BLEND_SRC_RGB": 32969, + "BLEND_DST_ALPHA": 32970, + "BLEND_SRC_ALPHA": 32971, + "CONSTANT_COLOR": 32769, + "ONE_MINUS_CONSTANT_COLOR": 32770, + "CONSTANT_ALPHA": 32771, + "ONE_MINUS_CONSTANT_ALPHA": 32772, + "BLEND_COLOR": 32773, + "ARRAY_BUFFER": 34962, + "ELEMENT_ARRAY_BUFFER": 34963, + "ARRAY_BUFFER_BINDING": 34964, + "ELEMENT_ARRAY_BUFFER_BINDING": 34965, + "STREAM_DRAW": 35040, + "STATIC_DRAW": 35044, + "DYNAMIC_DRAW": 35048, + "BUFFER_SIZE": 34660, + "BUFFER_USAGE": 34661, + "CURRENT_VERTEX_ATTRIB": 34342, + "FRONT": 1028, + "BACK": 1029, + "FRONT_AND_BACK": 1032, + "TEXTURE_2D": 3553, + "CULL_FACE": 2884, + "BLEND": 3042, + "DITHER": 3024, + "STENCIL_TEST": 2960, + "DEPTH_TEST": 2929, + "SCISSOR_TEST": 3089, + "POLYGON_OFFSET_FILL": 32823, + "SAMPLE_ALPHA_TO_COVERAGE": 32926, + "SAMPLE_COVERAGE": 32928, + "NO_ERROR": 0, + "INVALID_ENUM": 1280, + "INVALID_VALUE": 1281, + "INVALID_OPERATION": 1282, + "OUT_OF_MEMORY": 1285, + "CW": 2304, + "CCW": 2305, + "LINE_WIDTH": 2849, + "ALIASED_POINT_SIZE_RANGE": 33901, + "ALIASED_LINE_WIDTH_RANGE": 33902, + "CULL_FACE_MODE": 2885, + "FRONT_FACE": 2886, + "DEPTH_RANGE": 2928, + "DEPTH_WRITEMASK": 2930, + "DEPTH_CLEAR_VALUE": 2931, + "DEPTH_FUNC": 2932, + "STENCIL_CLEAR_VALUE": 2961, + "STENCIL_FUNC": 2962, + "STENCIL_FAIL": 2964, + "STENCIL_PASS_DEPTH_FAIL": 2965, + "STENCIL_PASS_DEPTH_PASS": 2966, + "STENCIL_REF": 2967, + "STENCIL_VALUE_MASK": 2963, + "STENCIL_WRITEMASK": 2968, + "STENCIL_BACK_FUNC": 34816, + "STENCIL_BACK_FAIL": 34817, + "STENCIL_BACK_PASS_DEPTH_FAIL": 34818, + "STENCIL_BACK_PASS_DEPTH_PASS": 34819, + "STENCIL_BACK_REF": 36003, + "STENCIL_BACK_VALUE_MASK": 36004, + "STENCIL_BACK_WRITEMASK": 36005, + "VIEWPORT": 2978, + "SCISSOR_BOX": 3088, + "COLOR_CLEAR_VALUE": 3106, + "COLOR_WRITEMASK": 3107, + "UNPACK_ALIGNMENT": 3317, + "PACK_ALIGNMENT": 3333, + "MAX_TEXTURE_SIZE": 3379, + "MAX_VIEWPORT_DIMS": 3386, + "SUBPIXEL_BITS": 3408, + "RED_BITS": 3410, + "GREEN_BITS": 3411, + "BLUE_BITS": 3412, + "ALPHA_BITS": 3413, + "DEPTH_BITS": 3414, + "STENCIL_BITS": 3415, + "POLYGON_OFFSET_UNITS": 10752, + "POLYGON_OFFSET_FACTOR": 32824, + "TEXTURE_BINDING_2D": 32873, + "SAMPLE_BUFFERS": 32936, + "SAMPLES": 32937, + "SAMPLE_COVERAGE_VALUE": 32938, + "SAMPLE_COVERAGE_INVERT": 32939, + "COMPRESSED_TEXTURE_FORMATS": 34467, + "DONT_CARE": 4352, + "FASTEST": 4353, + "NICEST": 4354, + "GENERATE_MIPMAP_HINT": 33170, + "BYTE": 5120, + "UNSIGNED_BYTE": 5121, + "SHORT": 5122, + "UNSIGNED_SHORT": 5123, + "INT": 5124, + "UNSIGNED_INT": 5125, + "FLOAT": 5126, + "DEPTH_COMPONENT": 6402, + "ALPHA": 6406, + "RGB": 6407, + "RGBA": 6408, + "LUMINANCE": 6409, + "LUMINANCE_ALPHA": 6410, + "UNSIGNED_SHORT_4_4_4_4": 32819, + "UNSIGNED_SHORT_5_5_5_1": 32820, + "UNSIGNED_SHORT_5_6_5": 33635, + "FRAGMENT_SHADER": 35632, + "VERTEX_SHADER": 35633, + "MAX_VERTEX_ATTRIBS": 34921, + "MAX_VERTEX_UNIFORM_VECTORS": 36347, + "MAX_VARYING_VECTORS": 36348, + "MAX_COMBINED_TEXTURE_IMAGE_UNITS": 35661, + "MAX_VERTEX_TEXTURE_IMAGE_UNITS": 35660, + "MAX_TEXTURE_IMAGE_UNITS": 34930, + "MAX_FRAGMENT_UNIFORM_VECTORS": 36349, + "SHADER_TYPE": 35663, + "DELETE_STATUS": 35712, + "LINK_STATUS": 35714, + "VALIDATE_STATUS": 35715, + "ATTACHED_SHADERS": 35717, + "ACTIVE_UNIFORMS": 35718, + "ACTIVE_ATTRIBUTES": 35721, + "SHADING_LANGUAGE_VERSION": 35724, + "CURRENT_PROGRAM": 35725, + "NEVER": 512, + "LESS": 513, + "EQUAL": 514, + "LEQUAL": 515, + "GREATER": 516, + "NOTEQUAL": 517, + "GEQUAL": 518, + "ALWAYS": 519, + "KEEP": 7680, + "REPLACE": 7681, + "INCR": 7682, + "DECR": 7683, + "INVERT": 5386, + "INCR_WRAP": 34055, + "DECR_WRAP": 34056, + "VENDOR": 7936, + "RENDERER": 7937, + "VERSION": 7938, + "NEAREST": 9728, + "LINEAR": 9729, + "NEAREST_MIPMAP_NEAREST": 9984, + "LINEAR_MIPMAP_NEAREST": 9985, + "NEAREST_MIPMAP_LINEAR": 9986, + "LINEAR_MIPMAP_LINEAR": 9987, + "TEXTURE_MAG_FILTER": 10240, + "TEXTURE_MIN_FILTER": 10241, + "TEXTURE_WRAP_S": 10242, + "TEXTURE_WRAP_T": 10243, + "TEXTURE": 5890, + "TEXTURE_CUBE_MAP": 34067, + "TEXTURE_BINDING_CUBE_MAP": 34068, + "TEXTURE_CUBE_MAP_POSITIVE_X": 34069, + "TEXTURE_CUBE_MAP_NEGATIVE_X": 34070, + "TEXTURE_CUBE_MAP_POSITIVE_Y": 34071, + "TEXTURE_CUBE_MAP_NEGATIVE_Y": 34072, + "TEXTURE_CUBE_MAP_POSITIVE_Z": 34073, + "TEXTURE_CUBE_MAP_NEGATIVE_Z": 34074, + "MAX_CUBE_MAP_TEXTURE_SIZE": 34076, + "TEXTURE0": 33984, + "TEXTURE1": 33985, + "TEXTURE2": 33986, + "TEXTURE3": 33987, + "TEXTURE4": 33988, + "TEXTURE5": 33989, + "TEXTURE6": 33990, + "TEXTURE7": 33991, + "TEXTURE8": 33992, + "TEXTURE9": 33993, + "TEXTURE10": 33994, + "TEXTURE11": 33995, + "TEXTURE12": 33996, + "TEXTURE13": 33997, + "TEXTURE14": 33998, + "TEXTURE15": 33999, + "TEXTURE16": 34000, + "TEXTURE17": 34001, + "TEXTURE18": 34002, + "TEXTURE19": 34003, + "TEXTURE20": 34004, + "TEXTURE21": 34005, + "TEXTURE22": 34006, + "TEXTURE23": 34007, + "TEXTURE24": 34008, + "TEXTURE25": 34009, + "TEXTURE26": 34010, + "TEXTURE27": 34011, + "TEXTURE28": 34012, + "TEXTURE29": 34013, + "TEXTURE30": 34014, + "TEXTURE31": 34015, + "ACTIVE_TEXTURE": 34016, + "REPEAT": 10497, + "CLAMP_TO_EDGE": 33071, + "MIRRORED_REPEAT": 33648, + "FLOAT_VEC2": 35664, + "FLOAT_VEC3": 35665, + "FLOAT_VEC4": 35666, + "INT_VEC2": 35667, + "INT_VEC3": 35668, + "INT_VEC4": 35669, + "BOOL": 35670, + "BOOL_VEC2": 35671, + "BOOL_VEC3": 35672, + "BOOL_VEC4": 35673, + "FLOAT_MAT2": 35674, + "FLOAT_MAT3": 35675, + "FLOAT_MAT4": 35676, + "SAMPLER_2D": 35678, + "SAMPLER_CUBE": 35680, + "VERTEX_ATTRIB_ARRAY_ENABLED": 34338, + "VERTEX_ATTRIB_ARRAY_SIZE": 34339, + "VERTEX_ATTRIB_ARRAY_STRIDE": 34340, + "VERTEX_ATTRIB_ARRAY_TYPE": 34341, + "VERTEX_ATTRIB_ARRAY_NORMALIZED": 34922, + "VERTEX_ATTRIB_ARRAY_POINTER": 34373, + "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING": 34975, + "IMPLEMENTATION_COLOR_READ_TYPE": 35738, + "IMPLEMENTATION_COLOR_READ_FORMAT": 35739, + "COMPILE_STATUS": 35713, + "LOW_FLOAT": 36336, + "MEDIUM_FLOAT": 36337, + "HIGH_FLOAT": 36338, + "LOW_INT": 36339, + "MEDIUM_INT": 36340, + "HIGH_INT": 36341, + "FRAMEBUFFER": 36160, + "RENDERBUFFER": 36161, + "RGBA4": 32854, + "RGB5_A1": 32855, + "RGB565": 36194, + "DEPTH_COMPONENT16": 33189, + "STENCIL_INDEX8": 36168, + "DEPTH_STENCIL": 34041, + "RENDERBUFFER_WIDTH": 36162, + "RENDERBUFFER_HEIGHT": 36163, + "RENDERBUFFER_INTERNAL_FORMAT": 36164, + "RENDERBUFFER_RED_SIZE": 36176, + "RENDERBUFFER_GREEN_SIZE": 36177, + "RENDERBUFFER_BLUE_SIZE": 36178, + "RENDERBUFFER_ALPHA_SIZE": 36179, + "RENDERBUFFER_DEPTH_SIZE": 36180, + "RENDERBUFFER_STENCIL_SIZE": 36181, + "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE": 36048, + "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME": 36049, + "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL": 36050, + "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE": 36051, + "COLOR_ATTACHMENT0": 36064, + "DEPTH_ATTACHMENT": 36096, + "STENCIL_ATTACHMENT": 36128, + "DEPTH_STENCIL_ATTACHMENT": 33306, + "NONE": 0, + "FRAMEBUFFER_COMPLETE": 36053, + "FRAMEBUFFER_INCOMPLETE_ATTACHMENT": 36054, + "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT": 36055, + "FRAMEBUFFER_INCOMPLETE_DIMENSIONS": 36057, + "FRAMEBUFFER_UNSUPPORTED": 36061, + "FRAMEBUFFER_BINDING": 36006, + "RENDERBUFFER_BINDING": 36007, + "MAX_RENDERBUFFER_SIZE": 34024, + "INVALID_FRAMEBUFFER_OPERATION": 1286, + "UNPACK_FLIP_Y_WEBGL": 37440, + "UNPACK_PREMULTIPLY_ALPHA_WEBGL": 37441, + "CONTEXT_LOST_WEBGL": 37442, + "UNPACK_COLORSPACE_CONVERSION_WEBGL": 37443, + "BROWSER_DEFAULT_WEBGL": 37444 +}; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLmethod.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLmethod.js new file mode 100644 index 0000000..f2659be --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLmethod.js @@ -0,0 +1,142 @@ +let i = 1; + +const GLmethod = {}; + +GLmethod.activeTexture = i++; //1 +GLmethod.attachShader = i++; +GLmethod.bindAttribLocation = i++; +GLmethod.bindBuffer = i++; +GLmethod.bindFramebuffer = i++; +GLmethod.bindRenderbuffer = i++; +GLmethod.bindTexture = i++; +GLmethod.blendColor = i++; +GLmethod.blendEquation = i++; +GLmethod.blendEquationSeparate = i++; //10 +GLmethod.blendFunc = i++; +GLmethod.blendFuncSeparate = i++; +GLmethod.bufferData = i++; +GLmethod.bufferSubData = i++; +GLmethod.checkFramebufferStatus = i++; +GLmethod.clear = i++; +GLmethod.clearColor = i++; +GLmethod.clearDepth = i++; +GLmethod.clearStencil = i++; +GLmethod.colorMask = i++; //20 +GLmethod.compileShader = i++; +GLmethod.compressedTexImage2D = i++; +GLmethod.compressedTexSubImage2D = i++; +GLmethod.copyTexImage2D = i++; +GLmethod.copyTexSubImage2D = i++; +GLmethod.createBuffer = i++; +GLmethod.createFramebuffer = i++; +GLmethod.createProgram = i++; +GLmethod.createRenderbuffer = i++; +GLmethod.createShader = i++; //30 +GLmethod.createTexture = i++; +GLmethod.cullFace = i++; +GLmethod.deleteBuffer = i++; +GLmethod.deleteFramebuffer = i++; +GLmethod.deleteProgram = i++; +GLmethod.deleteRenderbuffer = i++; +GLmethod.deleteShader = i++; +GLmethod.deleteTexture = i++; +GLmethod.depthFunc = i++; +GLmethod.depthMask = i++; //40 +GLmethod.depthRange = i++; +GLmethod.detachShader = i++; +GLmethod.disable = i++; +GLmethod.disableVertexAttribArray = i++; +GLmethod.drawArrays = i++; +GLmethod.drawArraysInstancedANGLE = i++; +GLmethod.drawElements = i++; +GLmethod.drawElementsInstancedANGLE = i++; +GLmethod.enable = i++; +GLmethod.enableVertexAttribArray = i++; //50 +GLmethod.flush = i++; +GLmethod.framebufferRenderbuffer = i++; +GLmethod.framebufferTexture2D = i++; +GLmethod.frontFace = i++; +GLmethod.generateMipmap = i++; +GLmethod.getActiveAttrib = i++; +GLmethod.getActiveUniform = i++; +GLmethod.getAttachedShaders = i++; +GLmethod.getAttribLocation = i++; +GLmethod.getBufferParameter = i++; //60 +GLmethod.getContextAttributes = i++; +GLmethod.getError = i++; +GLmethod.getExtension = i++; +GLmethod.getFramebufferAttachmentParameter = i++; +GLmethod.getParameter = i++; +GLmethod.getProgramInfoLog = i++; +GLmethod.getProgramParameter = i++; +GLmethod.getRenderbufferParameter = i++; +GLmethod.getShaderInfoLog = i++; +GLmethod.getShaderParameter = i++; //70 +GLmethod.getShaderPrecisionFormat = i++; +GLmethod.getShaderSource = i++; +GLmethod.getSupportedExtensions = i++; +GLmethod.getTexParameter = i++; +GLmethod.getUniform = i++; +GLmethod.getUniformLocation = i++; +GLmethod.getVertexAttrib = i++; +GLmethod.getVertexAttribOffset = i++; +GLmethod.isBuffer = i++; +GLmethod.isContextLost = i++; //80 +GLmethod.isEnabled = i++; +GLmethod.isFramebuffer = i++; +GLmethod.isProgram = i++; +GLmethod.isRenderbuffer = i++; +GLmethod.isShader = i++; +GLmethod.isTexture = i++; +GLmethod.lineWidth = i++; +GLmethod.linkProgram = i++; +GLmethod.pixelStorei = i++; +GLmethod.polygonOffset = i++; //90 +GLmethod.readPixels = i++; +GLmethod.renderbufferStorage = i++; +GLmethod.sampleCoverage = i++; +GLmethod.scissor = i++; +GLmethod.shaderSource = i++; +GLmethod.stencilFunc = i++; +GLmethod.stencilFuncSeparate = i++; +GLmethod.stencilMask = i++; +GLmethod.stencilMaskSeparate = i++; +GLmethod.stencilOp = i++; //100 +GLmethod.stencilOpSeparate = i++; +GLmethod.texImage2D = i++; +GLmethod.texParameterf = i++; +GLmethod.texParameteri = i++; +GLmethod.texSubImage2D = i++; +GLmethod.uniform1f = i++; +GLmethod.uniform1fv = i++; +GLmethod.uniform1i = i++; +GLmethod.uniform1iv = i++; +GLmethod.uniform2f = i++; //110 +GLmethod.uniform2fv = i++; +GLmethod.uniform2i = i++; +GLmethod.uniform2iv = i++; +GLmethod.uniform3f = i++; +GLmethod.uniform3fv = i++; +GLmethod.uniform3i = i++; +GLmethod.uniform3iv = i++; +GLmethod.uniform4f = i++; +GLmethod.uniform4fv = i++; +GLmethod.uniform4i = i++; //120 +GLmethod.uniform4iv = i++; +GLmethod.uniformMatrix2fv = i++; +GLmethod.uniformMatrix3fv = i++; +GLmethod.uniformMatrix4fv = i++; +GLmethod.useProgram = i++; +GLmethod.validateProgram = i++; +GLmethod.vertexAttrib1f = i++; //new +GLmethod.vertexAttrib2f = i++; //new +GLmethod.vertexAttrib3f = i++; //new +GLmethod.vertexAttrib4f = i++; //new //130 +GLmethod.vertexAttrib1fv = i++; //new +GLmethod.vertexAttrib2fv = i++; //new +GLmethod.vertexAttrib3fv = i++; //new +GLmethod.vertexAttrib4fv = i++; //new +GLmethod.vertexAttribPointer = i++; +GLmethod.viewport = i++; + +export default GLmethod; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLtype.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLtype.js new file mode 100644 index 0000000..695abcb --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/GLtype.js @@ -0,0 +1,23 @@ +const GLtype = {}; + +[ + "GLbitfield", + "GLboolean", + "GLbyte", + "GLclampf", + "GLenum", + "GLfloat", + "GLint", + "GLintptr", + "GLsizei", + "GLsizeiptr", + "GLshort", + "GLubyte", + "GLuint", + "GLushort" +].sort().map((typeName, i) => GLtype[typeName] = 1 >> (i + 1)); + +export default GLtype; + + + diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Program.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Program.js new file mode 100644 index 0000000..6f5691c --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Program.js @@ -0,0 +1,21 @@ +import {getTransferedObjectUUID} from './classUtils'; + +const name = 'WebGLProgram'; + +function uuid(id) { + return getTransferedObjectUUID(name, id); +} + +export default class WebGLProgram { + className = name; + + constructor(id) { + this.id = id; + } + + static uuid = uuid; + + uuid() { + return uuid(this.id); + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Renderbuffer.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Renderbuffer.js new file mode 100644 index 0000000..d3182ae --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Renderbuffer.js @@ -0,0 +1,21 @@ +import {getTransferedObjectUUID} from './classUtils'; + +const name = 'WebGLRenderBuffer'; + +function uuid(id) { + return getTransferedObjectUUID(name, id); +} + +export default class WebGLRenderbuffer { + className = name; + + constructor(id) { + this.id = id; + } + + static uuid = uuid; + + uuid() { + return uuid(this.id); + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/RenderingContext.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/RenderingContext.js new file mode 100644 index 0000000..5f9608f --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/RenderingContext.js @@ -0,0 +1,1191 @@ +import GLenum from './GLenum'; +import ActiveInfo from './ActiveInfo'; +import Buffer from './Buffer'; +import Framebuffer from './Framebuffer'; +import Renderbuffer from './Renderbuffer'; +import Texture from './Texture'; +import Program from './Program'; +import Shader from './Shader'; +import ShaderPrecisionFormat from './ShaderPrecisionFormat'; +import UniformLocation from './UniformLocation'; +import GLmethod from './GLmethod'; + +const processArray = (array, checkArrayType = false) => { + + function joinArray(arr, sep) { + let res = ''; + for (let i = 0; i < arr.length; i++) { + if (i !== 0) { + res += sep; + } + res += arr[i]; + } + return res; + } + + let type = 'Float32Array'; + if (checkArrayType) { + if (array instanceof Uint8Array) { + type = 'Uint8Array' + } else if (array instanceof Uint16Array) { + type = 'Uint16Array'; + } else if (array instanceof Uint32Array) { + type = 'Uint32Array'; + } else if (array instanceof Float32Array) { + type = 'Float32Array'; + } else { + throw new Error('Check array type failed. Array type is ' + typeof array); + } + } + + const ArrayTypes = { + Uint8Array: 1, + Uint16Array: 2, + Uint32Array: 4, + Float32Array: 14 + }; + return ArrayTypes[type] + ',' + btoa(joinArray(array, ',')) +} + +export default class WebGLRenderingContext { + + // static GBridge = null; + + className = 'WebGLRenderingContext'; + + constructor(canvas, type, attrs) { + this._canvas = canvas; + this._type = type; + this._version = 'WebGL 1.0'; + this._attrs = attrs; + this._map = new Map(); + + Object.keys(GLenum) + .forEach(name => Object.defineProperty(this, name, { + value: GLenum[name] + })); + } + + get canvas() { + return this._canvas; + } + + activeTexture = function (textureUnit) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.activeTexture + ',' + textureUnit, + true + ); + } + + attachShader = function (progarm, shader) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.attachShader + ',' + progarm.id + ',' + shader.id, + true + ); + } + + bindAttribLocation = function (program, index, name) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.bindAttribLocation + ',' + program.id + ',' + index + ',' + name, + true + ) + } + + bindBuffer = function (target, buffer) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.bindBuffer + ',' + target + ',' + (buffer ? buffer.id : 0), + true + ); + } + + bindFramebuffer = function (target, framebuffer) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.bindFramebuffer + ',' + target + ',' + (framebuffer ? framebuffer.id : 0), + true + ) + } + + bindRenderbuffer = function (target, renderBuffer) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.bindRenderbuffer + ',' + target + ',' + (renderBuffer ? renderBuffer.id : 0), + true + ) + } + + bindTexture = function (target, texture) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.bindTexture + ',' + target + ',' + (texture ? texture.id : 0), + true + ) + } + + blendColor = function (r, g, b, a) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.blendColor + ',' + target + ',' + r + ',' + g + ',' + b + ',' + a, + true + ) + } + + blendEquation = function (mode) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.blendEquation + ',' + mode, + true + ) + } + + blendEquationSeparate = function (modeRGB, modeAlpha) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.blendEquationSeparate + ',' + modeRGB + ',' + modeAlpha, + true + ) + } + + + blendFunc = function (sfactor, dfactor) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.blendFunc + ',' + sfactor + ',' + dfactor, + true + ); + } + + blendFuncSeparate = function (srcRGB, dstRGB, srcAlpha, dstAlpha) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.blendFuncSeparate + ',' + srcRGB + ',' + dstRGB + ',' + srcAlpha + ',' + dstAlpha, + true + ); + } + + bufferData = function (target, data, usage) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.bufferData + ',' + target + ',' + processArray(data, true) + ',' + usage, + true + ) + } + + bufferSubData = function (target, offset, data) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.bufferSubData + ',' + target + ',' + offset + ',' + processArray(data, true), + true + ) + } + + checkFramebufferStatus = function (target) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.checkFramebufferStatus + ',' + target + ); + return Number(result); + } + + clear = function (mask) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.clear + ',' + mask + ); + this._canvas._needRender = true; + } + + clearColor = function (r, g, b, a) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.clearColor + ',' + r + ',' + g + ',' + b, + true + ) + } + + clearDepth = function (depth) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.clearDepth + ',' + depth, + true + ) + } + + clearStencil = function (s) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.clearStencil + ',' + s + ); + } + + colorMask = function (r, g, b, a) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.colorMask + ',' + r + ',' + g + ',' + b + ',' + a + ) + } + + compileShader = function (shader) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.compileShader + ',' + shader.id, + true + ) + } + + compressedTexImage2D = function (target, level, internalformat, width, height, border, pixels) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.compressedTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' + + width + ',' + height + ',' + border + ',' + processArray(pixels), + true + ) + } + + compressedTexSubImage2D = function (target, level, xoffset, yoffset, width, height, format, pixels) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.compressedTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' + + width + ',' + height + ',' + format + ',' + processArray(pixels), + true + ) + } + + + copyTexImage2D = function (target, level, internalformat, x, y, width, height, border) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.copyTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' + x + ',' + y + ',' + + width + ',' + height + ',' + border, + true + ); + } + + copyTexSubImage2D = function (target, level, xoffset, yoffset, x, y, width, height) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.copyTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' + x + ',' + y + ',' + + width + ',' + height + ); + } + + createBuffer = function () { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.createBuffer + '' + ); + const buffer = new Buffer(result); + this._map.set(buffer.uuid(), buffer); + return buffer; + } + + createFramebuffer = function () { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.createFramebuffer + '' + ); + const framebuffer = new Framebuffer(result); + this._map.set(framebuffer.uuid(), framebuffer); + return framebuffer; + } + + + createProgram = function () { + const id = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.createProgram + '' + ); + const program = new Program(id); + this._map.set(program.uuid(), program); + return program; + } + + createRenderbuffer = function () { + const id = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.createRenderbuffer + '' + ) + const renderBuffer = new Renderbuffer(id); + this._map.set(renderBuffer.uuid(), renderBuffer); + return renderBuffer; + } + + createShader = function (type) { + const id = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.createShader + ',' + type + ) + const shader = new Shader(id, type); + this._map.set(shader.uuid(), shader); + return shader; + } + + createTexture = function () { + const id = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.createTexture + '' + ); + const texture = new Texture(id); + this._map.set(texture.uuid(), texture); + return texture; + } + + cullFace = function (mode) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.cullFace + ',' + mode, + true + ) + } + + + deleteBuffer = function (buffer) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.deleteBuffer + ',' + buffer.id, + true + ) + } + + deleteFramebuffer = function (framebuffer) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.deleteFramebuffer + ',' + framebuffer.id, + true + ) + } + + deleteProgram = function (program) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.deleteProgram + ',' + program.id, + true + ) + } + + deleteRenderbuffer = function (renderbuffer) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.deleteRenderbuffer + ',' + renderbuffer.id, + true + ) + } + + deleteShader = function (shader) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.deleteShader + ',' + shader.id, + true + ) + } + + deleteTexture = function (texture) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.deleteTexture + ',' + texture.id, + true + ) + } + + depthFunc = function (func) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.depthFunc + ',' + func + ) + } + + depthMask = function (flag) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.depthMask + ',' + Number(flag), + true + ) + } + + depthRange = function (zNear, zFar) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.depthRange + ',' + zNear + ',' + zFar, + true + ) + } + + detachShader = function (program, shader) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.detachShader + ',' + program.id + ',' + shader.id, + true + ) + } + + disable = function (cap) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.disable + ',' + cap, + true + ) + } + + disableVertexAttribArray = function (index) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.disableVertexAttribArray + ',' + index, + true + ); + } + + drawArrays = function (mode, first, count) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.drawArrays + ',' + mode + ',' + first + ',' + count + ) + this._canvas._needRender = true; + } + + drawElements = function (mode, count, type, offset) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.drawElements + ',' + mode + ',' + count + ',' + type + ',' + offset + ';' + ); + this._canvas._needRender = true; + } + + enable = function (cap) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.enable + ',' + cap, + true + ); + } + + enableVertexAttribArray = function (index) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.enableVertexAttribArray + ',' + index, + true + ) + } + + + flush = function () { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.flush + '' + ) + } + + framebufferRenderbuffer = function (target, attachment, textarget, texture, level) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.framebufferRenderbuffer + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level, + true + ) + } + + framebufferTexture2D = function (target, attachment, textarget, texture, level) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.framebufferTexture2D + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level, + true + ) + } + + frontFace = function (mode) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.frontFace + ',' + mode, + true + ) + } + + generateMipmap = function (target) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.generateMipmap + ',' + target, + true + ) + } + + getActiveAttrib = function (progarm, index) { + const resultString = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getActiveAttrib + ',' + progarm.id + ',' + index + ) + const [type, size, name] = resultString.split(','); + return new ActiveInfo({ + type: Number(type), + size: Number(size), + name + }); + } + + getActiveUniform = function (progarm, index) { + const resultString = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getActiveUniform + ',' + progarm.id + ',' + index + ); + const [type, size, name] = resultString.split(','); + return new ActiveInfo({ + type: Number(type), + size: Number(size), + name + }) + } + + getAttachedShaders = function (progarm) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getAttachedShaders + ',' + progarm.id + ); + const [type, ...ids] = result; + return ids.map(id => this._map.get(Shader.uuid(id))); + } + + getAttribLocation = function (progarm, name) { + return WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getAttribLocation + ',' + progarm.id + ',' + name + ) + } + + getBufferParameter = function (target, pname) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getBufferParameter + ',' + target + ',' + pname + ); + const [type, res] = getBufferParameter; + return res; + } + + getError = function () { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getError + '' + ) + return result; + } + + getExtension = function (name) { + return null; + } + + getFramebufferAttachmentParameter = function (target, attachment, pname) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getFramebufferAttachmentParameter + ',' + target + ',' + attachment + ',' + pname + ) + switch (pname) { + case GLenum.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + return this._map.get(Renderbuffer.uuid(result)) || this._map.get(Texture.uuid(result)) || null; + default: + return result; + } + } + + getParameter = function (pname) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getParameter + ',' + pname + ) + switch (pname) { + case GLenum.VERSION: + return this._version; + case GLenum.ARRAY_BUFFER_BINDING: // buffer + case GLenum.ELEMENT_ARRAY_BUFFER_BINDING: // buffer + return this._map.get(Buffer.uuid(result)) || null; + case GLenum.CURRENT_PROGRAM: // program + return this._map.get(Program.uuid(result)) || null; + case GLenum.FRAMEBUFFER_BINDING: // framebuffer + return this._map.get(Framebuffer.uuid(result)) || null; + case GLenum.RENDERBUFFER_BINDING: // renderbuffer + return this._map.get(Renderbuffer.uuid(result)) || null; + case GLenum.TEXTURE_BINDING_2D: // texture + case GLenum.TEXTURE_BINDING_CUBE_MAP: // texture + return this._map.get(Texture.uuid(result)) || null; + case GLenum.ALIASED_LINE_WIDTH_RANGE: // Float32Array + case GLenum.ALIASED_POINT_SIZE_RANGE: // Float32Array + case GLenum.BLEND_COLOR: // Float32Array + case GLenum.COLOR_CLEAR_VALUE: // Float32Array + case GLenum.DEPTH_RANGE: // Float32Array + case GLenum.MAX_VIEWPORT_DIMS: // Int32Array + case GLenum.SCISSOR_BOX: // Int32Array + case GLenum.VIEWPORT: // Int32Array + case GLenum.COMPRESSED_TEXTURE_FORMATS: // Uint32Array + default: + const [type, ...res] = result.split(','); + if (res.length === 1) { + return Number(res[0]); + } else { + return res.map(Number); + } + } + } + + getProgramInfoLog = function (progarm) { + return WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getProgramInfoLog + ',' + progarm.id + ) + } + + getProgramParameter = function (program, pname) { + const res = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getProgramParameter + ',' + program.id + ',' + pname + ); + + const [type, result] = res.split(',').map(i => parseInt(i)); + + if (type === 1) { + return Boolean(result); + } else if (type === 2) { + return result; + } else { + throw new Error('Unrecongized program paramater ' + res + ', type: ' + typeof res); + } + } + + + getRenderbufferParameter = function (target, pname) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getRenderbufferParameter + ',' + target + ',' + pname + ) + return result; + } + + + getShaderInfoLog = function (shader) { + return WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getShaderInfoLog + ',' + shader.id + ); + } + + getShaderParameter = function (shader, pname) { + return WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getShaderParameter + ',' + shader.id + ',' + pname + ) + } + + getShaderPrecisionFormat = function (shaderType, precisionType) { + const [rangeMin, rangeMax, precision] = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getShaderPrecisionFormat + ',' + shaderType + ',' + precisionType + ); + const shaderPrecisionFormat = new ShaderPrecisionFormat({ + rangeMin: Number(rangeMin), + rangeMax: Number(rangeMax), + precision: Number(precision) + }); + return shaderPrecisionFormat; + } + + getShaderSource = function (shader) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getShaderSource + ',' + shader.id + ); + return result; + } + + getSupportedExtensions = function () { + return Object.keys({}); + } + + getTexParameter = function (target, pname) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getTexParameter + ',' + target + ',' + pname + ) + return result; + } + + getUniformLocation = function (program, name) { + const id = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getUniformLocation + ',' + program.id + ',' + name + ); + if (id === -1) { + return null; + } else { + return new UniformLocation(Number(id)); + } + } + + getVertexAttrib = function (index, pname) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getVertexAttrib + ',' + index + ',' + pname + ); + switch (pname) { + case GLenum.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + return this._map.get(Buffer.uuid(result)) || null; + case GLenum.CURRENT_VERTEX_ATTRIB: // Float32Array + default: + return result; + } + } + + getVertexAttribOffset = function (index, pname) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.getVertexAttribOffset + ',' + index + ',' + pname + ) + return Number(result); + } + + isBuffer = function (buffer) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.isBuffer + ',' + buffer.id + ) + return Boolean(result); + } + + isContextLost = function () { + return false; + } + + isEnabled = function (cap) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.isEnabled + ',' + cap + ) + return Boolean(result); + } + + isFramebuffer = function (framebuffer) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.isFramebuffer + ',' + framebuffer.id + ) + return Boolean(result); + } + + isProgram = function (program) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.isProgram + ',' + program.id + ) + return Boolean(result); + } + + isRenderbuffer = function (renderBuffer) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.isRenderbuffer + ',' + renderbuffer.id + ) + return Boolean(result); + } + + isShader = function (shader) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.isShader + ',' + shader.id + ) + return Boolean(result); + } + + isTexture = function (texture) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.isTexture + ',' + texture.id + ); + return Boolean(result); + } + + lineWidth = function (width) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.lineWidth + ',' + width, + true + ) + } + + linkProgram = function (program) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.linkProgram + ',' + program.id, + true + ); + } + + + pixelStorei = function (pname, param) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.pixelStorei + ',' + pname + ',' + Number(param) + ) + } + + polygonOffset = function (factor, units) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.polygonOffset + ',' + factor + ',' + units + ) + } + + readPixels = function (x, y, width, height, format, type, pixels) { + const result = WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.readPixels + ',' + x + ',' + y + ',' + width + ',' + height + ',' + format + ',' + type + ) + return result; + } + + renderbufferStorage = function (target, internalFormat, width, height) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.renderbufferStorage + ',' + target + ',' + internalFormat + ',' + width + ',' + height, + true + ) + } + + sampleCoverage = function (value, invert) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.sampleCoverage + ',' + value + ',' + Number(invert), + true + ) + } + + scissor = function (x, y, width, height) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.scissor + ',' + x + ',' + y + ',' + width + ',' + height, + true + ) + } + + shaderSource = function (shader, source) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.shaderSource + ',' + shader.id + ',' + source + ) + } + + stencilFunc = function (func, ref, mask) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.stencilFunc + ',' + func + ',' + ref + ',' + mask, + true + ) + } + + stencilFuncSeparate = function (face, func, ref, mask) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.stencilFuncSeparate + ',' + face + ',' + func + ',' + ref + ',' + mask, + true + ) + } + + stencilMask = function (mask) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.stencilMask + ',' + mask, + true + ) + } + + stencilMaskSeparate = function (face, mask) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.stencilMaskSeparate + ',' + face + ',' + mask, + true + ) + } + + stencilOp = function (fail, zfail, zpass) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.stencilOp + ',' + fail + ',' + zfail + ',' + zpass + ) + } + + stencilOpSeparate = function (face, fail, zfail, zpass) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.stencilOp + ',' + face + ',' + fail + ',' + zfail + ',' + zpass, + true + ) + } + + texImage2D = function (...args) { + WebGLRenderingContext.GBridge.texImage2D(this._canvas.id, ...args); + } + + + texParameterf = function (target, pname, param) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.texParameterf + ',' + target + ',' + pname + ',' + param, + true + ) + } + + texParameteri = function (target, pname, param) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.texParameteri + ',' + target + ',' + pname + ',' + param + ) + } + + texSubImage2D = function (...args) { + WebGLRenderingContext.GBridge.texSubImage2D(this._canvas.id, ...args); + } + + uniform1f = function (location, v0) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform1f + ',' + location.id + ',' + v0 + ) + } + + uniform1fv = function (location, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform1fv + ',' + location.id + ',' + processArray(value), + true + ) + } + + uniform1i = function (location, v0) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform1i + ',' + location.id + ',' + v0, + // true + ) + } + + uniform1iv = function (location, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform1iv + ',' + location.id + ',' + processArray(value), + true + ) + } + + uniform2f = function (location, v0, v1) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform2f + ',' + location.id + ',' + v0 + ',' + v1, + true + ) + } + + uniform2fv = function (location, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform2fv + ',' + location.id + ',' + processArray(value), + true + ) + } + + uniform2i = function (location, v0, v1) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform2i + ',' + location.id + ',' + v0 + ',' + v1, + true + ) + } + + uniform2iv = function (location, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform2iv + ',' + location.id + ',' + processArray(value), + true + ) + } + + uniform3f = function (location, v0, v1, v2) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform3f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2, + true + ) + } + + uniform3fv = function (location, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform3fv + ',' + location.id + ',' + processArray(value), + true + ) + } + + uniform3i = function (location, v0, v1, v2) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform3i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2, + true + ) + } + + uniform3iv = function (location, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform3iv + ',' + location.id + ',' + processArray(value), + true + ) + } + + uniform4f = function (location, v0, v1, v2, v3) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform4f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3, + true + ) + } + + uniform4fv = function (location, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform4fv + ',' + location.id + ',' + processArray(value), + true + ) + } + + uniform4i = function (location, v0, v1, v2, v3) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform4i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3, + true + ) + } + + uniform4iv = function (location, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniform4iv + ',' + location.id + ',' + processArray(value, true), + true + ) + } + + uniformMatrix2fv = function (location, transpose, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniformMatrix2fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value), + true + ) + } + + uniformMatrix3fv = function (location, transpose, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniformMatrix3fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value), + true + ) + } + + uniformMatrix4fv = function (location, transpose, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.uniformMatrix4fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value), + true + ); + } + + useProgram = function (progarm) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.useProgram + ',' + progarm.id + '', + true + ) + } + + + validateProgram = function (program) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.validateProgram + ',' + program.id, + true + ) + } + + vertexAttrib1f = function (index, v0) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttrib1f + ',' + index + ',' + v0, + true + ) + } + + vertexAttrib2f = function (index, v0, v1) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttrib2f + ',' + index + ',' + v0 + ',' + v1, + true + ) + } + + vertexAttrib3f = function (index, v0, v1, v2) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttrib3f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2, + true + ) + } + + vertexAttrib4f = function (index, v0, v1, v2, v3) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttrib4f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3, + true + ) + } + + vertexAttrib1fv = function (index, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttrib1fv + ',' + index + ',' + processArray(value), + true + ) + } + + vertexAttrib2fv = function (index, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttrib2fv + ',' + index + ',' + processArray(value), + true + ) + } + + vertexAttrib3fv = function (index, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttrib3fv + ',' + index + ',' + processArray(value), + true + ) + } + + vertexAttrib4fv = function (index, value) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttrib4fv + ',' + index + ',' + processArray(value), + true + ) + } + + vertexAttribPointer = function (index, size, type, normalized, stride, offset) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.vertexAttribPointer + ',' + index + ',' + size + ',' + type + ',' + Number(normalized) + ',' + stride + ',' + offset, + true + ) + } + + viewport = function (x, y, width, height) { + WebGLRenderingContext.GBridge.callNative( + this._canvas.id, + GLmethod.viewport + ',' + x + ',' + y + ',' + width + ',' + height, + true + ) + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Shader.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Shader.js new file mode 100644 index 0000000..a763886 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Shader.js @@ -0,0 +1,22 @@ +import {getTransferedObjectUUID} from './classUtils'; + +const name = 'WebGLShader'; + +function uuid(id) { + return getTransferedObjectUUID(name, id); +} + +export default class WebGLShader { + className = name; + + constructor(id, type) { + this.id = id; + this.type = type; + } + + static uuid = uuid; + + uuid() { + return uuid(this.id); + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js new file mode 100644 index 0000000..208d6c1 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js @@ -0,0 +1,11 @@ +export default class WebGLShaderPrecisionFormat { + className = 'WebGLShaderPrecisionFormat'; + + constructor({ + rangeMin, rangeMax, precision + }) { + this.rangeMin = rangeMin; + this.rangeMax = rangeMax; + this.precision = precision; + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Texture.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Texture.js new file mode 100644 index 0000000..de4d806 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/Texture.js @@ -0,0 +1,22 @@ +import {getTransferedObjectUUID} from './classUtils'; + +const name = 'WebGLTexture'; + +function uuid(id) { + return getTransferedObjectUUID(name, id); +} + +export default class WebGLTexture { + className = name; + + constructor(id, type) { + this.id = id; + this.type = type; + } + + static uuid = uuid; + + uuid() { + return uuid(this.id); + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/UniformLocation.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/UniformLocation.js new file mode 100644 index 0000000..f5e99dc --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/UniformLocation.js @@ -0,0 +1,22 @@ +import {getTransferedObjectUUID} from './classUtils'; + +const name = 'WebGLUniformLocation'; + +function uuid(id) { + return getTransferedObjectUUID(name, id); +} + +export default class WebGLUniformLocation { + className = name; + + constructor(id, type) { + this.id = id; + this.type = type; + } + + static uuid = uuid; + + uuid() { + return uuid(this.id); + } +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/classUtils.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/classUtils.js new file mode 100644 index 0000000..88716be --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/context-webgl/classUtils.js @@ -0,0 +1,3 @@ +export function getTransferedObjectUUID(name, id) { + return `${name.toLowerCase()}-${id}`; +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/canvas.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/canvas.js new file mode 100644 index 0000000..a8d9bb9 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/canvas.js @@ -0,0 +1,74 @@ +import GContext2D from '../context-2d/RenderingContext'; +import GContextWebGL from '../context-webgl/RenderingContext'; + +export default class GCanvas { + + // static GBridge = null; + + id = null; + + _needRender = true; + + constructor(id, { disableAutoSwap }) { + this.id = id; + + this._disableAutoSwap = disableAutoSwap; + if (disableAutoSwap) { + this._swapBuffers = () => { + GCanvas.GBridge.render(this.id); + } + } + } + + getContext(type) { + + let context = null; + + if (type.match(/webgl/i)) { + context = new GContextWebGL(this); + + context.componentId = this.id; + + if (!this._disableAutoSwap) { + const render = () => { + if (this._needRender) { + GCanvas.GBridge.render(this.id); + this._needRender = false; + } + } + setInterval(render, 16); + } + + GCanvas.GBridge.callSetContextType(this.id, 1); // 0 for 2d; 1 for webgl + } else if (type.match(/2d/i)) { + context = new GContext2D(this); + + context.componentId = this.id; + +// const render = ( callback ) => { +// +// const commands = context._drawCommands; +// context._drawCommands = ''; +// +// GCanvas.GBridge.render2d(this.id, commands, callback); +// this._needRender = false; +// } +// //draw方法触发 +// context._flush = render; +// //setInterval(render, 16); + + GCanvas.GBridge.callSetContextType(this.id, 0); + } else { + throw new Error('not supported context ' + type); + } + + return context; + + } + + reset() { + GCanvas.GBridge.callReset(this.id); + } + + +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/image.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/image.js new file mode 100644 index 0000000..9499a51 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/image.js @@ -0,0 +1,96 @@ +let incId = 1; + +const noop = function () { }; + +class GImage { + + static GBridge = null; + + constructor() { + this._id = incId++; + this._width = 0; + this._height = 0; + this._src = undefined; + this._onload = noop; + this._onerror = noop; + this.complete = false; + } + + get width() { + return this._width; + } + set width(v) { + this._width = v; + } + + get height() { + return this._height; + } + + set height(v) { + this._height = v; + } + + get src() { + return this._src; + } + + set src(v) { + + if (v.startsWith('//')) { + v = 'http:' + v; + } + + this._src = v; + + GImage.GBridge.perloadImage([this._src, this._id], (data) => { + if (typeof data === 'string') { + data = JSON.parse(data); + } + if (data.error) { + var evt = { type: 'error', target: this }; + this.onerror(evt); + } else { + this.complete = true; + this.width = typeof data.width === 'number' ? data.width : 0; + this.height = typeof data.height === 'number' ? data.height : 0; + var evt = { type: 'load', target: this }; + this.onload(evt); + } + }); + } + + addEventListener(name, listener) { + if (name === 'load') { + this.onload = listener; + } else if (name === 'error') { + this.onerror = listener; + } + } + + removeEventListener(name, listener) { + if (name === 'load') { + this.onload = noop; + } else if (name === 'error') { + this.onerror = noop; + } + } + + get onload() { + return this._onload; + } + + set onload(v) { + this._onload = v; + } + + get onerror() { + return this._onerror; + } + + set onerror(v) { + this._onerror = v; + } +} + +export default GImage; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/tool.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/tool.js new file mode 100644 index 0000000..d3fb398 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/env/tool.js @@ -0,0 +1,24 @@ + +export function ArrayBufferToBase64 (buffer) { + var binary = ''; + var bytes = new Uint8ClampedArray(buffer); + for (var len = bytes.byteLength, i = 0; i < len; i++) { + binary += String.fromCharCode(bytes[i]); + } + return btoa(binary); +} + +export function Base64ToUint8ClampedArray(base64String) { + const padding = '='.repeat((4 - base64String.length % 4) % 4); + const base64 = (base64String + padding) + .replace(/\-/g, '+') + .replace(/_/g, '/'); + + const rawData = atob(base64); + const outputArray = new Uint8ClampedArray(rawData.length); + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; +} \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/index.js b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/index.js new file mode 100644 index 0000000..a34ad58 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/gcanvas/index.js @@ -0,0 +1,39 @@ +import GCanvas from './env/canvas'; +import GImage from './env/image'; + +import GWebGLRenderingContext from './context-webgl/RenderingContext'; +import GContext2D from './context-2d/RenderingContext'; + +import GBridgeWeex from './bridge/bridge-weex'; + +export let Image = GImage; + +export let WeexBridge = GBridgeWeex; + +export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommands } = {}) { + + const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge; + + GBridge.callEnable(el.ref, [ + 0, // renderMode: 0--RENDERMODE_WHEN_DIRTY, 1--RENDERMODE_CONTINUOUSLY + -1, // hybridLayerType: 0--LAYER_TYPE_NONE 1--LAYER_TYPE_SOFTWARE 2--LAYER_TYPE_HARDWARE + false, // supportScroll + false, // newCanvasMode + 1, // compatible + 'white',// clearColor + false // sameLevel: newCanvasMode = true && true => GCanvasView and Webview is same level + ]); + + if (debug === true) { + GBridge.callEnableDebug(); + } + if (disableComboCommands) { + GBridge.callEnableDisableCombo(); + } + + var canvas = new GCanvas(el.ref, { disableAutoSwap }); + canvas.width = el.style.width; + canvas.height = el.style.height; + + return canvas; +}; \ No newline at end of file diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue b/uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue new file mode 100644 index 0000000..d9e7ad2 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue @@ -0,0 +1,684 @@ + + + + + + diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/license.md b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/license.md new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/license.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/module.js b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/module.js new file mode 100644 index 0000000..a3cbfca --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/module.js @@ -0,0 +1,2285 @@ +//--------------------------------------------------------------------- +// uQRCode 二维码生成插件 v3.2.2 +// +// uQRCode 是一款使用方式简单,高扩展的二维码生成插件。支持全端生成,支持canvas的地方就可以使用uQRCode。 +// +// Copyright (c) Sansnn uQRCode All rights reserved. +// Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// 复制使用请保留本段注释,感谢支持开源! +// +// 开源地址: +// https://github.com/Sansnn/uQRCode +// +// uni-app插件市场地址: +// https://ext.dcloud.net.cn/plugin?id=1287 +//--------------------------------------------------------------------- + +"use strict"; + +function uQRCode(options, canvasContext, loadImage) { + this.options = uQRCode.getOptions(options); + this.canvasContext = uQRCode.getCanvasContext(canvasContext); + this.loadImage = uQRCode.getLoadImage(loadImage); +} + +(function() { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + // QR8bitByte + //--------------------------------------------------------------------- + + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + } + + QR8bitByte.prototype = { + + getLength: function(buffer) { + return this.data.length; + }, + + write: function(buffer) { + for (var i = 0; i < this.data.length; i++) { + // not JIS ... + buffer.put(this.data.charCodeAt(i), 8); + } + } + }; + + //--------------------------------------------------------------------- + // QRCode + //--------------------------------------------------------------------- + + function QRCode(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = new Array(); + } + + QRCode.prototype = { + + addData: function(data) { + var newData = new QR8bitByte(data); + this.dataList.push(newData); + this.dataCache = null; + }, + + isDark: function(row, col) { + if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { + throw new Error(row + "," + col); + } + return this.modules[row][col]; + }, + + getModuleCount: function() { + return this.moduleCount; + }, + + make: function() { + // Calculate automatically typeNumber if provided is < 1 + if (this.typeNumber < 1) { + var typeNumber = 1; + for (typeNumber = 1; typeNumber < 40; typeNumber++) { + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel); + + var buffer = new QRBitBuffer(); + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount; + } + + for (var i = 0; i < this.dataList.length; i++) { + var data = this.dataList[i]; + buffer.put(data.mode, 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber)); + data.write(buffer); + } + if (buffer.getLengthInBits() <= totalDataCount * 8) + break; + } + this.typeNumber = typeNumber; + } + this.makeImpl(false, this.getBestMaskPattern()); + }, + + makeImpl: function(test, maskPattern) { + + this.moduleCount = this.typeNumber * 4 + 17; + this.modules = new Array(this.moduleCount); + + for (var row = 0; row < this.moduleCount; row++) { + + this.modules[row] = new Array(this.moduleCount); + + for (var col = 0; col < this.moduleCount; col++) { + this.modules[row][col] = null; //(col + row) % 3; + } + } + + this.setupPositionProbePattern(0, 0); + this.setupPositionProbePattern(this.moduleCount - 7, 0); + this.setupPositionProbePattern(0, this.moduleCount - 7); + this.setupPositionAdjustPattern(); + this.setupTimingPattern(); + this.setupTypeInfo(test, maskPattern); + + if (this.typeNumber >= 7) { + this.setupTypeNumber(test); + } + + if (this.dataCache == null) { + this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); + } + + this.mapData(this.dataCache, maskPattern); + }, + + setupPositionProbePattern: function(row, col) { + + for (var r = -1; r <= 7; r++) { + + if (row + r <= -1 || this.moduleCount <= row + r) continue; + + for (var c = -1; c <= 7; c++) { + + if (col + c <= -1 || this.moduleCount <= col + c) continue; + + if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || + (0 <= c && c <= 6 && (r == 0 || r == 6)) || + (2 <= r && r <= 4 && 2 <= c && c <= 4)) { + this.modules[row + r][col + c] = true; + } else { + this.modules[row + r][col + c] = false; + } + } + } + }, + + getBestMaskPattern: function() { + + var minLostPoint = 0; + var pattern = 0; + + for (var i = 0; i < 8; i++) { + + this.makeImpl(true, i); + + var lostPoint = QRUtil.getLostPoint(this); + + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint; + pattern = i; + } + } + + return pattern; + }, + + createMovieClip: function(target_mc, instance_name, depth) { + + var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); + var cs = 1; + + this.make(); + + for (var row = 0; row < this.modules.length; row++) { + + var y = row * cs; + + for (var col = 0; col < this.modules[row].length; col++) { + + var x = col * cs; + var dark = this.modules[row][col]; + + if (dark) { + qr_mc.beginFill(0, 100); + qr_mc.moveTo(x, y); + qr_mc.lineTo(x + cs, y); + qr_mc.lineTo(x + cs, y + cs); + qr_mc.lineTo(x, y + cs); + qr_mc.endFill(); + } + } + } + + return qr_mc; + }, + + setupTimingPattern: function() { + + for (var r = 8; r < this.moduleCount - 8; r++) { + if (this.modules[r][6] != null) { + continue; + } + this.modules[r][6] = (r % 2 == 0); + } + + for (var c = 8; c < this.moduleCount - 8; c++) { + if (this.modules[6][c] != null) { + continue; + } + this.modules[6][c] = (c % 2 == 0); + } + }, + + setupPositionAdjustPattern: function() { + + var pos = QRUtil.getPatternPosition(this.typeNumber); + + for (var i = 0; i < pos.length; i++) { + + for (var j = 0; j < pos.length; j++) { + + var row = pos[i]; + var col = pos[j]; + + if (this.modules[row][col] != null) { + continue; + } + + for (var r = -2; r <= 2; r++) { + + for (var c = -2; c <= 2; c++) { + + if (r == -2 || r == 2 || c == -2 || c == 2 || + (r == 0 && c == 0)) { + this.modules[row + r][col + c] = true; + } else { + this.modules[row + r][col + c] = false; + } + } + } + } + } + }, + + setupTypeNumber: function(test) { + + var bits = QRUtil.getBCHTypeNumber(this.typeNumber); + + for (var i = 0; i < 18; i++) { + var mod = (!test && ((bits >> i) & 1) == 1); + this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; + } + + for (var i = 0; i < 18; i++) { + var mod = (!test && ((bits >> i) & 1) == 1); + this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; + } + }, + + setupTypeInfo: function(test, maskPattern) { + + var data = (this.errorCorrectLevel << 3) | maskPattern; + var bits = QRUtil.getBCHTypeInfo(data); + + // vertical + for (var i = 0; i < 15; i++) { + + var mod = (!test && ((bits >> i) & 1) == 1); + + if (i < 6) { + this.modules[i][8] = mod; + } else if (i < 8) { + this.modules[i + 1][8] = mod; + } else { + this.modules[this.moduleCount - 15 + i][8] = mod; + } + } + + // horizontal + for (var i = 0; i < 15; i++) { + + var mod = (!test && ((bits >> i) & 1) == 1); + + if (i < 8) { + this.modules[8][this.moduleCount - i - 1] = mod; + } else if (i < 9) { + this.modules[8][15 - i - 1 + 1] = mod; + } else { + this.modules[8][15 - i - 1] = mod; + } + } + + // fixed module + this.modules[this.moduleCount - 8][8] = (!test); + + }, + + mapData: function(data, maskPattern) { + + var inc = -1; + var row = this.moduleCount - 1; + var bitIndex = 7; + var byteIndex = 0; + + for (var col = this.moduleCount - 1; col > 0; col -= 2) { + + if (col == 6) col--; + + while (true) { + + for (var c = 0; c < 2; c++) { + + if (this.modules[row][col - c] == null) { + + var dark = false; + + if (byteIndex < data.length) { + dark = (((data[byteIndex] >>> bitIndex) & 1) == 1); + } + + var mask = QRUtil.getMask(maskPattern, row, col - c); + + if (mask) { + dark = !dark; + } + + this.modules[row][col - c] = dark; + bitIndex--; + + if (bitIndex == -1) { + byteIndex++; + bitIndex = 7; + } + } + } + + row += inc; + + if (row < 0 || this.moduleCount <= row) { + row -= inc; + inc = -inc; + break; + } + } + } + + } + + }; + + QRCode.PAD0 = 0xEC; + QRCode.PAD1 = 0x11; + + QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { + + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); + + var buffer = new QRBitBuffer(); + + for (var i = 0; i < dataList.length; i++) { + var data = dataList[i]; + buffer.put(data.mode, 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber)); + data.write(buffer); + } + + // calc num max data. + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount; + } + + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error("code length overflow. (" + + buffer.getLengthInBits() + + ">" + + totalDataCount * 8 + + ")"); + } + + // end code + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4); + } + + // padding + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false); + } + + // padding + while (true) { + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(QRCode.PAD0, 8); + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(QRCode.PAD1, 8); + } + + return QRCode.createBytes(buffer, rsBlocks); + } + + QRCode.createBytes = function(buffer, rsBlocks) { + + var offset = 0; + + var maxDcCount = 0; + var maxEcCount = 0; + + var dcdata = new Array(rsBlocks.length); + var ecdata = new Array(rsBlocks.length); + + for (var r = 0; r < rsBlocks.length; r++) { + + var dcCount = rsBlocks[r].dataCount; + var ecCount = rsBlocks[r].totalCount - dcCount; + + maxDcCount = Math.max(maxDcCount, dcCount); + maxEcCount = Math.max(maxEcCount, ecCount); + + dcdata[r] = new Array(dcCount); + + for (var i = 0; i < dcdata[r].length; i++) { + dcdata[r][i] = 0xff & buffer.buffer[i + offset]; + } + offset += dcCount; + + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); + var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1); + + var modPoly = rawPoly.mod(rsPoly); + ecdata[r] = new Array(rsPoly.getLength() - 1); + for (var i = 0; i < ecdata[r].length; i++) { + var modIndex = i + modPoly.getLength() - ecdata[r].length; + ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0; + } + + } + + var totalCodeCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalCodeCount += rsBlocks[i].totalCount; + } + + var data = new Array(totalCodeCount); + var index = 0; + + for (var i = 0; i < maxDcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < dcdata[r].length) { + data[index++] = dcdata[r][i]; + } + } + } + + for (var i = 0; i < maxEcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < ecdata[r].length) { + data[index++] = ecdata[r][i]; + } + } + } + + return data; + + } + + //--------------------------------------------------------------------- + // QRMode + //--------------------------------------------------------------------- + + var QRMode = { + MODE_NUMBER: 1 << 0, + MODE_ALPHA_NUM: 1 << 1, + MODE_8BIT_BYTE: 1 << 2, + MODE_KANJI: 1 << 3 + }; + + //--------------------------------------------------------------------- + // QRErrorCorrectLevel + //--------------------------------------------------------------------- + + var QRErrorCorrectLevel = { + L: 1, + M: 0, + Q: 3, + H: 2 + }; + + //--------------------------------------------------------------------- + // QRMaskPattern + //--------------------------------------------------------------------- + + var QRMaskPattern = { + PATTERN000: 0, + PATTERN001: 1, + PATTERN010: 2, + PATTERN011: 3, + PATTERN100: 4, + PATTERN101: 5, + PATTERN110: 6, + PATTERN111: 7 + }; + + //--------------------------------------------------------------------- + // QRUtil + //--------------------------------------------------------------------- + + var QRUtil = { + + PATTERN_POSITION_TABLE: [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ], + + G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), + G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), + G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), + + getBCHTypeInfo: function(data) { + var d = data << 10; + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { + d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))); + } + return ((data << 10) | d) ^ QRUtil.G15_MASK; + }, + + getBCHTypeNumber: function(data) { + var d = data << 12; + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { + d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))); + } + return (data << 12) | d; + }, + + getBCHDigit: function(data) { + + var digit = 0; + + while (data != 0) { + digit++; + data >>>= 1; + } + + return digit; + }, + + getPatternPosition: function(typeNumber) { + return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; + }, + + getMask: function(maskPattern, i, j) { + + switch (maskPattern) { + + case QRMaskPattern.PATTERN000: + return (i + j) % 2 == 0; + case QRMaskPattern.PATTERN001: + return i % 2 == 0; + case QRMaskPattern.PATTERN010: + return j % 3 == 0; + case QRMaskPattern.PATTERN011: + return (i + j) % 3 == 0; + case QRMaskPattern.PATTERN100: + return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0; + case QRMaskPattern.PATTERN101: + return (i * j) % 2 + (i * j) % 3 == 0; + case QRMaskPattern.PATTERN110: + return ((i * j) % 2 + (i * j) % 3) % 2 == 0; + case QRMaskPattern.PATTERN111: + return ((i * j) % 3 + (i + j) % 2) % 2 == 0; + + default: + throw new Error("bad maskPattern:" + maskPattern); + } + }, + + getErrorCorrectPolynomial: function(errorCorrectLength) { + + var a = new QRPolynomial([1], 0); + + for (var i = 0; i < errorCorrectLength; i++) { + a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0)); + } + + return a; + }, + + getLengthInBits: function(mode, type) { + + if (1 <= type && type < 10) { + + // 1 - 9 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 10; + case QRMode.MODE_ALPHA_NUM: + return 9; + case QRMode.MODE_8BIT_BYTE: + return 8; + case QRMode.MODE_KANJI: + return 8; + default: + throw new Error("mode:" + mode); + } + + } else if (type < 27) { + + // 10 - 26 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 12; + case QRMode.MODE_ALPHA_NUM: + return 11; + case QRMode.MODE_8BIT_BYTE: + return 16; + case QRMode.MODE_KANJI: + return 10; + default: + throw new Error("mode:" + mode); + } + + } else if (type < 41) { + + // 27 - 40 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 14; + case QRMode.MODE_ALPHA_NUM: + return 13; + case QRMode.MODE_8BIT_BYTE: + return 16; + case QRMode.MODE_KANJI: + return 12; + default: + throw new Error("mode:" + mode); + } + + } else { + throw new Error("type:" + type); + } + }, + + getLostPoint: function(qrCode) { + + var moduleCount = qrCode.getModuleCount(); + + var lostPoint = 0; + + // LEVEL1 + + for (var row = 0; row < moduleCount; row++) { + + for (var col = 0; col < moduleCount; col++) { + + var sameCount = 0; + var dark = qrCode.isDark(row, col); + + for (var r = -1; r <= 1; r++) { + + if (row + r < 0 || moduleCount <= row + r) { + continue; + } + + for (var c = -1; c <= 1; c++) { + + if (col + c < 0 || moduleCount <= col + c) { + continue; + } + + if (r == 0 && c == 0) { + continue; + } + + if (dark == qrCode.isDark(row + r, col + c)) { + sameCount++; + } + } + } + + if (sameCount > 5) { + lostPoint += (3 + sameCount - 5); + } + } + } + + // LEVEL2 + + for (var row = 0; row < moduleCount - 1; row++) { + for (var col = 0; col < moduleCount - 1; col++) { + var count = 0; + if (qrCode.isDark(row, col)) count++; + if (qrCode.isDark(row + 1, col)) count++; + if (qrCode.isDark(row, col + 1)) count++; + if (qrCode.isDark(row + 1, col + 1)) count++; + if (count == 0 || count == 4) { + lostPoint += 3; + } + } + } + + // LEVEL3 + + for (var row = 0; row < moduleCount; row++) { + for (var col = 0; col < moduleCount - 6; col++) { + if (qrCode.isDark(row, col) && + !qrCode.isDark(row, col + 1) && + qrCode.isDark(row, col + 2) && + qrCode.isDark(row, col + 3) && + qrCode.isDark(row, col + 4) && + !qrCode.isDark(row, col + 5) && + qrCode.isDark(row, col + 6)) { + lostPoint += 40; + } + } + } + + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount - 6; row++) { + if (qrCode.isDark(row, col) && + !qrCode.isDark(row + 1, col) && + qrCode.isDark(row + 2, col) && + qrCode.isDark(row + 3, col) && + qrCode.isDark(row + 4, col) && + !qrCode.isDark(row + 5, col) && + qrCode.isDark(row + 6, col)) { + lostPoint += 40; + } + } + } + + // LEVEL4 + + var darkCount = 0; + + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount; row++) { + if (qrCode.isDark(row, col)) { + darkCount++; + } + } + } + + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; + lostPoint += ratio * 10; + + return lostPoint; + } + + }; + + + //--------------------------------------------------------------------- + // QRMath + //--------------------------------------------------------------------- + + var QRMath = { + + glog: function(n) { + + if (n < 1) { + throw new Error("glog(" + n + ")"); + } + + return QRMath.LOG_TABLE[n]; + }, + + gexp: function(n) { + + while (n < 0) { + n += 255; + } + + while (n >= 256) { + n -= 255; + } + + return QRMath.EXP_TABLE[n]; + }, + + EXP_TABLE: new Array(256), + + LOG_TABLE: new Array(256) + + }; + + for (var i = 0; i < 8; i++) { + QRMath.EXP_TABLE[i] = 1 << i; + } + for (var i = 8; i < 256; i++) { + QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ + QRMath.EXP_TABLE[i - 5] ^ + QRMath.EXP_TABLE[i - 6] ^ + QRMath.EXP_TABLE[i - 8]; + } + for (var i = 0; i < 255; i++) { + QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i; + } + + //--------------------------------------------------------------------- + // QRPolynomial + //--------------------------------------------------------------------- + + function QRPolynomial(num, shift) { + + if (num.length == undefined) { + throw new Error(num.length + "/" + shift); + } + + var offset = 0; + + while (offset < num.length && num[offset] == 0) { + offset++; + } + + this.num = new Array(num.length - offset + shift); + for (var i = 0; i < num.length - offset; i++) { + this.num[i] = num[i + offset]; + } + } + + QRPolynomial.prototype = { + + get: function(index) { + return this.num[index]; + }, + + getLength: function() { + return this.num.length; + }, + + multiply: function(e) { + + var num = new Array(this.getLength() + e.getLength() - 1); + + for (var i = 0; i < this.getLength(); i++) { + for (var j = 0; j < e.getLength(); j++) { + num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j))); + } + } + + return new QRPolynomial(num, 0); + }, + + mod: function(e) { + + if (this.getLength() - e.getLength() < 0) { + return this; + } + + var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0)); + + var num = new Array(this.getLength()); + + for (var i = 0; i < this.getLength(); i++) { + num[i] = this.get(i); + } + + for (var i = 0; i < e.getLength(); i++) { + num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio); + } + + // recursive call + return new QRPolynomial(num, 0).mod(e); + } + }; + + //--------------------------------------------------------------------- + // QRRSBlock + //--------------------------------------------------------------------- + + function QRRSBlock(totalCount, dataCount) { + this.totalCount = totalCount; + this.dataCount = dataCount; + } + + QRRSBlock.RS_BLOCK_TABLE = [ + + // L + // M + // Q + // H + + // 1 + [1, 26, 19], + [1, 26, 16], + [1, 26, 13], + [1, 26, 9], + + // 2 + [1, 44, 34], + [1, 44, 28], + [1, 44, 22], + [1, 44, 16], + + // 3 + [1, 70, 55], + [1, 70, 44], + [2, 35, 17], + [2, 35, 13], + + // 4 + [1, 100, 80], + [2, 50, 32], + [2, 50, 24], + [4, 25, 9], + + // 5 + [1, 134, 108], + [2, 67, 43], + [2, 33, 15, 2, 34, 16], + [2, 33, 11, 2, 34, 12], + + // 6 + [2, 86, 68], + [4, 43, 27], + [4, 43, 19], + [4, 43, 15], + + // 7 + [2, 98, 78], + [4, 49, 31], + [2, 32, 14, 4, 33, 15], + [4, 39, 13, 1, 40, 14], + + // 8 + [2, 121, 97], + [2, 60, 38, 2, 61, 39], + [4, 40, 18, 2, 41, 19], + [4, 40, 14, 2, 41, 15], + + // 9 + [2, 146, 116], + [3, 58, 36, 2, 59, 37], + [4, 36, 16, 4, 37, 17], + [4, 36, 12, 4, 37, 13], + + // 10 + [2, 86, 68, 2, 87, 69], + [4, 69, 43, 1, 70, 44], + [6, 43, 19, 2, 44, 20], + [6, 43, 15, 2, 44, 16], + + // 11 + [4, 101, 81], + [1, 80, 50, 4, 81, 51], + [4, 50, 22, 4, 51, 23], + [3, 36, 12, 8, 37, 13], + + // 12 + [2, 116, 92, 2, 117, 93], + [6, 58, 36, 2, 59, 37], + [4, 46, 20, 6, 47, 21], + [7, 42, 14, 4, 43, 15], + + // 13 + [4, 133, 107], + [8, 59, 37, 1, 60, 38], + [8, 44, 20, 4, 45, 21], + [12, 33, 11, 4, 34, 12], + + // 14 + [3, 145, 115, 1, 146, 116], + [4, 64, 40, 5, 65, 41], + [11, 36, 16, 5, 37, 17], + [11, 36, 12, 5, 37, 13], + + // 15 + [5, 109, 87, 1, 110, 88], + [5, 65, 41, 5, 66, 42], + [5, 54, 24, 7, 55, 25], + [11, 36, 12], + + // 16 + [5, 122, 98, 1, 123, 99], + [7, 73, 45, 3, 74, 46], + [15, 43, 19, 2, 44, 20], + [3, 45, 15, 13, 46, 16], + + // 17 + [1, 135, 107, 5, 136, 108], + [10, 74, 46, 1, 75, 47], + [1, 50, 22, 15, 51, 23], + [2, 42, 14, 17, 43, 15], + + // 18 + [5, 150, 120, 1, 151, 121], + [9, 69, 43, 4, 70, 44], + [17, 50, 22, 1, 51, 23], + [2, 42, 14, 19, 43, 15], + + // 19 + [3, 141, 113, 4, 142, 114], + [3, 70, 44, 11, 71, 45], + [17, 47, 21, 4, 48, 22], + [9, 39, 13, 16, 40, 14], + + // 20 + [3, 135, 107, 5, 136, 108], + [3, 67, 41, 13, 68, 42], + [15, 54, 24, 5, 55, 25], + [15, 43, 15, 10, 44, 16], + + // 21 + [4, 144, 116, 4, 145, 117], + [17, 68, 42], + [17, 50, 22, 6, 51, 23], + [19, 46, 16, 6, 47, 17], + + // 22 + [2, 139, 111, 7, 140, 112], + [17, 74, 46], + [7, 54, 24, 16, 55, 25], + [34, 37, 13], + + // 23 + [4, 151, 121, 5, 152, 122], + [4, 75, 47, 14, 76, 48], + [11, 54, 24, 14, 55, 25], + [16, 45, 15, 14, 46, 16], + + // 24 + [6, 147, 117, 4, 148, 118], + [6, 73, 45, 14, 74, 46], + [11, 54, 24, 16, 55, 25], + [30, 46, 16, 2, 47, 17], + + // 25 + [8, 132, 106, 4, 133, 107], + [8, 75, 47, 13, 76, 48], + [7, 54, 24, 22, 55, 25], + [22, 45, 15, 13, 46, 16], + + // 26 + [10, 142, 114, 2, 143, 115], + [19, 74, 46, 4, 75, 47], + [28, 50, 22, 6, 51, 23], + [33, 46, 16, 4, 47, 17], + + // 27 + [8, 152, 122, 4, 153, 123], + [22, 73, 45, 3, 74, 46], + [8, 53, 23, 26, 54, 24], + [12, 45, 15, 28, 46, 16], + + // 28 + [3, 147, 117, 10, 148, 118], + [3, 73, 45, 23, 74, 46], + [4, 54, 24, 31, 55, 25], + [11, 45, 15, 31, 46, 16], + + // 29 + [7, 146, 116, 7, 147, 117], + [21, 73, 45, 7, 74, 46], + [1, 53, 23, 37, 54, 24], + [19, 45, 15, 26, 46, 16], + + // 30 + [5, 145, 115, 10, 146, 116], + [19, 75, 47, 10, 76, 48], + [15, 54, 24, 25, 55, 25], + [23, 45, 15, 25, 46, 16], + + // 31 + [13, 145, 115, 3, 146, 116], + [2, 74, 46, 29, 75, 47], + [42, 54, 24, 1, 55, 25], + [23, 45, 15, 28, 46, 16], + + // 32 + [17, 145, 115], + [10, 74, 46, 23, 75, 47], + [10, 54, 24, 35, 55, 25], + [19, 45, 15, 35, 46, 16], + + // 33 + [17, 145, 115, 1, 146, 116], + [14, 74, 46, 21, 75, 47], + [29, 54, 24, 19, 55, 25], + [11, 45, 15, 46, 46, 16], + + // 34 + [13, 145, 115, 6, 146, 116], + [14, 74, 46, 23, 75, 47], + [44, 54, 24, 7, 55, 25], + [59, 46, 16, 1, 47, 17], + + // 35 + [12, 151, 121, 7, 152, 122], + [12, 75, 47, 26, 76, 48], + [39, 54, 24, 14, 55, 25], + [22, 45, 15, 41, 46, 16], + + // 36 + [6, 151, 121, 14, 152, 122], + [6, 75, 47, 34, 76, 48], + [46, 54, 24, 10, 55, 25], + [2, 45, 15, 64, 46, 16], + + // 37 + [17, 152, 122, 4, 153, 123], + [29, 74, 46, 14, 75, 47], + [49, 54, 24, 10, 55, 25], + [24, 45, 15, 46, 46, 16], + + // 38 + [4, 152, 122, 18, 153, 123], + [13, 74, 46, 32, 75, 47], + [48, 54, 24, 14, 55, 25], + [42, 45, 15, 32, 46, 16], + + // 39 + [20, 147, 117, 4, 148, 118], + [40, 75, 47, 7, 76, 48], + [43, 54, 24, 22, 55, 25], + [10, 45, 15, 67, 46, 16], + + // 40 + [19, 148, 118, 6, 149, 119], + [18, 75, 47, 31, 76, 48], + [34, 54, 24, 34, 55, 25], + [20, 45, 15, 61, 46, 16] + ]; + + QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { + + var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); + + if (rsBlock == undefined) { + throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + + errorCorrectLevel); + } + + var length = rsBlock.length / 3; + + var list = new Array(); + + for (var i = 0; i < length; i++) { + + var count = rsBlock[i * 3 + 0]; + var totalCount = rsBlock[i * 3 + 1]; + var dataCount = rsBlock[i * 3 + 2]; + + for (var j = 0; j < count; j++) { + list.push(new QRRSBlock(totalCount, dataCount)); + } + } + + return list; + } + + QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) { + + switch (errorCorrectLevel) { + case QRErrorCorrectLevel.L: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; + case QRErrorCorrectLevel.M: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; + case QRErrorCorrectLevel.Q: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; + case QRErrorCorrectLevel.H: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; + default: + return undefined; + } + } + + //--------------------------------------------------------------------- + // QRBitBuffer + //--------------------------------------------------------------------- + + function QRBitBuffer() { + this.buffer = new Array(); + this.length = 0; + } + + QRBitBuffer.prototype = { + + get: function(index) { + var bufIndex = Math.floor(index / 8); + return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1; + }, + + put: function(num, length) { + for (var i = 0; i < length; i++) { + this.putBit(((num >>> (length - i - 1)) & 1) == 1); + } + }, + + getLengthInBits: function() { + return this.length; + }, + + putBit: function(bit) { + + var bufIndex = Math.floor(this.length / 8); + if (this.buffer.length <= bufIndex) { + this.buffer.push(0); + } + + if (bit) { + this.buffer[bufIndex] |= (0x80 >>> (this.length % 8)); + } + + this.length++; + } + }; + + //--------------------------------------------------------------------- + // Support Chinese 字符编码支持中文 + // 使用mode 4 8bit + //--------------------------------------------------------------------- + function utf16To8(text) { + var result = ''; + var c; + for (var i = 0; i < text.length; i++) { + c = text.charCodeAt(i); + if (c >= 0x0001 && c <= 0x007F) { + result += text.charAt(i); + } else if (c > 0x07FF) { + result += String.fromCharCode(0xE0 | c >> 12 & 0x0F); + result += String.fromCharCode(0x80 | c >> 6 & 0x3F); + result += String.fromCharCode(0x80 | c >> 0 & 0x3F); + } else { + result += String.fromCharCode(0xC0 | c >> 6 & 0x1F); + result += String.fromCharCode(0x80 | c >> 0 & 0x3F); + } + } + return result; + } + + /** + * 队列 + */ + class Queue { + constructor() { + let waitingQueue = []; + let isRunning = false; //记录是否有未完成的任务 + function execute(task, resolve, reject) { + task() + .then((data) => { + resolve(data); + }) + .catch((e) => { + reject(e); + }) + .finally(() => { + //等待任务队列中如果有任务,则触发它;否则设置isRunning = false,表示无任务状态 + if (waitingQueue.length) { + const next = waitingQueue.shift(); + execute(next.task, next.resolve, next.reject); + } else { + isRunning = false; + } + }); + } + return function(task) { + return new Promise((resolve, reject) => { + if (isRunning) { + waitingQueue.push({ + task, + resolve, + reject + }); + } else { + isRunning = true; + execute(task, resolve, reject); + } + }); + }; + } + } + // const queue = new Queue(); + // queue(() => new Promise((resolve, reject) => { + // setTimeout(() => { + // resolve('task1'); + // }, 1000); + // })).then(data => console.log(data)); + // queue(() => new Promise((resolve, reject) => { + // setTimeout(() => { + // resolve('task2'); + // }, 100); + // })).then(data => console.log(data)); + // queue(() => new Promise((resolve, reject) => { + // setTimeout(() => { + // resolve('task3'); + // }, 300); + // })).then(data => console.log(data)); + + /** + * 纠错等级 + */ + uQRCode.errorCorrectLevel = QRErrorCorrectLevel; + + /** + * 预设默认值(基本,不包含各部分和艺术码参数) + */ + uQRCode.defaults = { + typeNumber: -1, // 版本,-1为自动计算,字符越多,版本越高 + errorCorrectLevel: QRErrorCorrectLevel.H, // 纠错等级 + text: '', // 二维码内容 + size: 354, // 大小 + useDynamicSize: false, // 使用动态尺寸,可以去掉方块小数点,绘制出来后没有白色细线 + margin: 0, // 边距 + background: { + color: '#FFFFFF' // 背景色 + }, + foreground: { + color: '#000000' // 前景色 + } + } + + /** + * 对象属性深度替换 + * @param {Object} o 原始对象/默认对象/被替换的对象 + * @param {Object} r 从这个对象里取值替换到o对象里 + * @return {Object} 替换后的新对象 + */ + uQRCode.deepReplace = function(o = {}, r = {}) { + let obj = { + ...o + } + for (let k in r) { + var vr = r[k]; + if (vr.constructor == Object) { + obj[k] = this.deepReplace(obj[k], vr); + } else if (vr.constructor == String && !vr) { + obj[k] = obj[k]; + } else { + obj[k] = vr; + } + } + return obj; + } + + /** + * 获取选项值 + */ + uQRCode.getOptions = function(options) { + options = uQRCode.deepReplace(uQRCode.defaults, options); + + /* 背景 */ + options.background = uQRCode.deepReplace({ + color: options.background.color, // 背景色 + image: { + src: '', + width: 1, // 图片宽 + height: 1, // 图片高 + align: ['center', 'center'], // 图片对齐方式水平,垂直 + anchor: [0, 0], // 图片位置,X坐标,Y坐标 + alpha: 1 // 透明度 + } + }, options.background); + /* 前景 */ + options.foreground = uQRCode.deepReplace({ + color: options.foreground.color, // 前景色 + image: { + src: '', + width: 1 / 4, // 图片宽 + height: 1 / 4, // 图片高 + align: ['center', 'center'], // 图片对齐方式水平,垂直 + anchor: [0, 0] // 图片位置,X坐标,Y坐标 + } + }, options.foreground); + /* 定位角 */ + options.positionDetection = uQRCode.deepReplace({ + backgroundColor: options.background.color, // 定位角区域背景色,默认值跟随背景色 + foregroundColor: options.foreground.color // 定位角小块颜色,默认值跟随前景色 + }, options.positionDetection); + /* 分割图案 */ + options.separator = uQRCode.deepReplace({ + color: options.background.color // 分割区域颜色,默认值跟随背景色 + }, options.separator); + /* 对齐图案 */ + options.alignment = uQRCode.deepReplace({ + backgroundColor: options.background.color, // 对齐区域背景色,默认值跟随背景色 + foregroundColor: options.foreground.color // 对齐小块颜色,默认值跟随前景色 + }, options.alignment); + /* 时序图案 */ + options.timing = uQRCode.deepReplace({ + backgroundColor: options.background.color, // 时序区域背景色,默认值跟随背景色 + foregroundColor: options.foreground.color // 时序小块颜色,默认值跟随前景色 + }, options.timing); + /* 暗块 */ + options.darkBlock = uQRCode.deepReplace({ + color: options.foreground.color // 暗块颜色 + }, options.darkBlock); + /* 版本信息 */ + options.versionInformation = uQRCode.deepReplace({ + backgroundColor: options.background.color, // 版本信息区域背景色,默认值跟随背景色 + foregroundColor: options.foreground.color // 版本信息小块颜色,默认值跟随前景色 + }, options.versionInformation); + + return options; + } + + /** + * 获取canvas实例 + */ + uQRCode.getCanvasContext = function(ctx) { + /* 兼容setFillStyle写法,主要在uni-app nvue gcanvas */ + ctx.setFillStyle = ctx.setFillStyle || function(color) { + ctx.fillStyle = color; + } + /* 兼容setFontSize写法,主要在微信小程序canvas2d */ + ctx.setFontSize = ctx.setFontSize || function(fontSize) { + ctx.font = `${fontSize}px`; + } + /* 兼容setTextAlign写法,主要在微信小程序canvas2d */ + ctx.setTextAlign = ctx.setTextAlign || function(align) { + ctx.textAlign = align; + } + /* 兼容setTextBaseline写法,主要在微信小程序canvas2d */ + ctx.setTextBaseline = ctx.setTextBaseline || function(textBaseline) { + ctx.textBaseline = textBaseline; + } + /* 若实例不包含draw方法则创建一个 */ + ctx.draw = ctx.draw || function(reserve, callback) { + callback && callback(); + } + return ctx; + } + + /* 队列实例,某些平台一起使用多个组件时需要通过队列逐一绘制,否则部分绘制方法异常,nvue端的iOS gcanvas尤其明显,在不通过队列绘制时会出现图片丢失的情况 */ + uQRCode.Queue = new Queue(); + uQRCode.QueueLoadImage = new Queue(); + + /* 缓存loadImage图片 */ + uQRCode.loadImageCache = []; + + /** + * 获取加载图片方法 + */ + uQRCode.getLoadImage = function(loadImage) { + if (typeof loadImage == 'function') { + return function(src) { + /* 解决iOS APP||NVUE同时绘制多个二维码导致图片丢失需使用队列 */ + return uQRCode.QueueLoadImage(() => new Promise((resolve, reject) => { + setTimeout(() => { + const cache = uQRCode.loadImageCache.find(x => x.src == src); + if (cache) { + resolve(cache.img); + } else { + loadImage(src).then(img => { + uQRCode.loadImageCache.push({ + src, + img + }); + resolve(img); + }); + } + }, 150); + })); + } + } else { + return function(src) { + return Promise.resolve(src); + } + } + } + + uQRCode.prototype = { + /** + * 实例化传入的选项值 + */ + options: {}, + + /** + * 画布实例 + */ + canvasContext: {}, + + /** + * 制作二维码全部数据 + */ + makeData: {}, + + /** + * 制作二维码主要模块数据,基于makeData的modules但数据格式不一致,这里的modules是定制过的 + */ + modules: [], + + /** + * 模块数量 + */ + moduleCount: 0, + + /** + * 获取制作二维码数据 + */ + getMakeData() { + let { + typeNumber, + errorCorrectLevel, + text + } = this.options; + var qrcode = new QRCode(typeNumber, errorCorrectLevel); + qrcode.addData(utf16To8(text.toString())); + qrcode.make(); + return qrcode; + }, + + /** + * 制作二维码方法 + */ + make() { + let makeData = this.makeData = this.getMakeData(); + this.modules = JSON.parse(JSON.stringify(makeData.modules)); + this.moduleCount = makeData.moduleCount; + this.options.typeNumber = makeData.typeNumber; + + /* 数据码 data */ + this.paintData(); + /* 定位图案 position detection */ + this.paintPositionDetection(); + /* 分隔图案 separator */ + this.paintSeparator(); + /* 对齐图案 alignment */ + this.paintAlignment(); + /* 时序图案 timing */ + this.paintTiming(); + /* 暗块 darkBlock */ + this.paintDarkBlock(); + /* 预留版本信息 version information */ + this.paintVersionInformation(); + }, + + paintData() { + let modules = this.modules; + let moduleCount = this.moduleCount; + let { + size, + margin, + background, + foreground, + useDynamicSize + } = this.options; + + /* dynamicSize自动计算出最适合绘制的尺寸,并按这个尺寸去绘制,可以解决canvas绘制小块间产生白线的问题(其实就是小数点精度问题),useDynamicSize=false可以取消这个设定 */ + // let dynamicSize = this.options.dynamicSize = Math.floor((size - margin * 2) / moduleCount) * moduleCount + margin * 2; // Math.floor向下取整缩放会模糊 + let dynamicSize = this.options.dynamicSize = Math.ceil((size - margin * 2) / moduleCount) * moduleCount + margin * 2; // Math.ceil向上取整缩放效果比floor清晰 + if (!useDynamicSize) { + dynamicSize = this.options.dynamicSize = size; + } + let tileSize = (dynamicSize - margin * 2) / moduleCount; + + for (var rowI = 0; rowI < modules.length; rowI++) { + for (var colI = 0; colI < modules.length; colI++) { + var tile = modules[rowI][colI]; + if (tile) { + modules[rowI][colI] = { + size: tileSize, + x: colI * tileSize + margin, + y: rowI * tileSize + margin, + type: ['foreground'], + color: foreground.color, + isBlack: true, + isDrawn: false + }; + } else { + modules[rowI][colI] = { + size: tileSize, + x: colI * tileSize + margin, + y: rowI * tileSize + margin, + type: ['background'], + color: background.color, + isBlack: false, + isDrawn: false + }; + } + } + } + }, + + paintPositionDetection() { + let modules = this.modules; + let size = this.moduleCount; + let { + positionDetection + } = this.options; + + //1) 定义基础图形索引(左上角)x ,y,v + let basePart = [ + [0, 0, 1], + [1, 0, 1], + [2, 0, 1], + [3, 0, 1], + [4, 0, 1], + [5, 0, 1], + [6, 0, 1], + [0, 1, 1], + [1, 1, 0], + [2, 1, 0], + [3, 1, 0], + [4, 1, 0], + [5, 1, 0], + [6, 1, 1], + [0, 2, 1], + [1, 2, 0], + [2, 2, 1], + [3, 2, 1], + [4, 2, 1], + [5, 2, 0], + [6, 2, 1], + [0, 3, 1], + [1, 3, 0], + [2, 3, 1], + [3, 3, 1], + [4, 3, 1], + [5, 3, 0], + [6, 3, 1], + [0, 4, 1], + [1, 4, 0], + [2, 4, 1], + [3, 4, 1], + [4, 4, 1], + [5, 4, 0], + [6, 4, 1], + [0, 5, 1], + [1, 5, 0], + [2, 5, 0], + [3, 5, 0], + [4, 5, 0], + [5, 5, 0], + [6, 5, 1], + [0, 6, 1], + [1, 6, 1], + [2, 6, 1], + [3, 6, 1], + [4, 6, 1], + [5, 6, 1], + [6, 6, 1] + ]; + let disc = size - 7; //size -7 + basePart.forEach(d => { + var ltItem = modules[d[0]][d[1]]; + var rtItem = modules[d[0] + disc][d[1]]; + var lbItem = modules[d[0]][d[1] + disc]; + lbItem.type.push('positionDetection'); + rtItem.type.push('positionDetection'); + ltItem.type.push('positionDetection'); + //绘制左上角 + ltItem.color = d[2] == 1 ? positionDetection.foregroundColor : positionDetection.backgroundColor; + //绘制右 + rtItem.color = d[2] == 1 ? positionDetection.foregroundColor : positionDetection.backgroundColor; + //绘制左 + lbItem.color = d[2] == 1 ? positionDetection.foregroundColor : positionDetection.backgroundColor; + }); + }, + + paintSeparator() { + let modules = this.modules; + let size = this.moduleCount; + let { + separator + } = this.options; + + //1) 定义基础图形索引(左上角) + [ + [7, 0], + [7, 1], + [7, 2], + [7, 3], + [7, 4], + [7, 5], + [7, 6], + [7, 7], + [0, 7], + [1, 7], + [2, 7], + [3, 7], + [4, 7], + [5, 7], + [6, 7] + ].forEach(d => { + var ltItem = modules[d[0]][d[1]]; + var rtItem = modules[size - d[0] - 1][d[1]]; + var lbItem = modules[d[0]][size - d[1] - 1]; + lbItem.type.push('separator'); + rtItem.type.push('separator'); + ltItem.type.push('separator'); + //绘制左上 + ltItem.color = separator.color; + //绘制右 + rtItem.color = separator.color; + //绘制左 + lbItem.color = separator.color; + }); + }, + + paintAlignment() { + let modules = this.modules; + let size = this.moduleCount; + let { + alignment, + typeNumber + } = this.options; + + //不同版本的对齐图案组合位置 + const ALIGNMENT_OF_VERSION = [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ]; + // 对齐图案数量和中心位置根据版本定义 + const alignments = ALIGNMENT_OF_VERSION[typeNumber - 1]; + if (alignments) { + const calcMatrix = [ + [-2, -2, 1], + [-1, -2, 1], + [0, -2, 1], + [1, -2, 1], + [2, -2, 1], + [-2, -1, 1], + [-1, -1, 0], + [0, -1, 0], + [1, -1, 0], + [2, -1, 1], + [-2, 0, 1], + [-1, 0, 0], + [0, 0, 1], + [1, 0, 0], + [2, 0, 1], + [-2, 1, 1], + [-1, 1, 0], + [0, 1, 0], + [1, 1, 0], + [2, 1, 1], + [-2, 2, 1], + [-1, 2, 1], + [0, 2, 1], + [1, 2, 1], + [2, 2, 1] + ]; + const group_len = alignments.length; + for (let i = 0; i < group_len; i++) { + for (let j = 0; j < group_len; j++) { + //对齐图案不能污染 定位器和分隔器 + let { + x, + y + } = { + x: alignments[i], + y: alignments[j] + }; + if (!((x < 9 && y < 9) || (x > size - 9 - 1 && y < 9) || (y > size - 9 - 1 && x < 9))) { + calcMatrix.forEach(d => { + var alignmentItem = modules[x + d[0]][y + d[1]]; + alignmentItem.type.push('alignment'); + alignmentItem.color = d[2] == 1 ? alignment.foregroundColor : alignment.backgroundColor; + }); + } + } + } + } + }, + + paintTiming() { + let modules = this.modules; + let { + timing + } = this.options; + + let timingPartLen = modules.length - 16; + for (let i = 0; i < timingPartLen; i++) { + var xItem = modules[6][8 + i]; + var yItem = modules[8 + i][6]; + xItem.type.push('timing'); + yItem.type.push('timing'); + xItem.color = (1 & i) ^ 1 ? timing.foregroundColor : timing.backgroundColor; + yItem.color = (1 & i) ^ 1 ? timing.foregroundColor : timing.backgroundColor; + } + }, + + paintDarkBlock() { + let modules = this.modules; + let size = this.moduleCount; + let { + darkBlock + } = this.options; + + //创建暗模块 + var darkBlockItem = modules[size - 7 - 1][8]; + darkBlockItem.type.push('darkBlock'); + darkBlockItem.color = darkBlock.color; + }, + + paintVersionInformation() { + let modules = this.modules; + let size = this.moduleCount; + let { + versionInformation, + typeNumber: version + } = this.options; + + if (version < 7) { + return modules; + } + //预留版本信息 0 为补位,预留版本信息 是从索引7开始 + const VERSIONS = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + '000111110010010100', + '001000010110111100', + '001001101010011001', + '001010010011010011', + '001011101111110110', + '001100011101100010', + '001101100001000111', + '001110011000001101', + '001111100100101000', + '010000101101111000', + '010001010001011101', + '010010101000010111', + '010011010100110010', + '010100100110100110', + '010101011010000011', + '010110100011001001', + '010111011111101100', + '011000111011000100', + '011001000111100001', + '011010111110101011', + '011011000010001110', + '011100110000011010', + '011101001100111111', + '011110110101110101', + '011111001001010000', + '100000100111010101', + '100001011011110000', + '100010100010111010', + '100011011110011111', + '100100101100001011', + '100101010000101110', + '100110101001100100', + '100111010101000001', + '101000110001101001' + ]; + + //两种方式获取预留格式信息,临时计算或者查字典 + //let version_codes = _v.correctVersionData(_v.version); + let version_codes = VERSIONS[version] + VERSIONS[version]; + //创建预留版本信息 + let disc = [size - 11, size - 10, size - 9]; + // 左+右 + let version_cells = [ + //左 + [5, disc[2]], + [5, disc[1]], + [5, disc[0]], + [4, disc[2]], + [4, disc[1]], + [4, disc[0]], + [3, disc[2]], + [3, disc[1]], + [3, disc[0]], + [2, disc[2]], + [2, disc[1]], + [2, disc[0]], + [1, disc[2]], + [1, disc[1]], + [1, disc[0]], + [0, disc[2]], + [0, disc[1]], + [0, disc[0]], + //右 + [disc[2], 5], + [disc[1], 5], + [disc[0], 5], + [disc[2], 4], + [disc[1], 4], + [disc[0], 4], + [disc[2], 3], + [disc[1], 3], + [disc[0], 3], + [disc[2], 2], + [disc[1], 2], + [disc[0], 2], + [disc[2], 1], + [disc[1], 1], + [disc[0], 1], + [disc[2], 0], + [disc[1], 0], + [disc[0], 0] + ]; + version_cells.forEach((d, index) => { + var versionInformationItem = modules[d[0]][d[1]]; + versionInformationItem.type.push('versionInformation'); + versionInformationItem.color = version_codes[index] == '1' ? versionInformation.foregroundColor : versionInformation.backgroundColor; + }); + }, + + /** + * 绘制二维码方法 + */ + draw(options) { + options = uQRCode.deepReplace({ + drawBackground: { + before: () => {}, + after: () => {} + }, + drawBackgroundImage: { + before: () => {}, + after: () => {} + }, + drawForeground: { + before: () => {}, + after: () => {} + }, + drawForegroundImage: { + before: () => {}, + after: () => {} + } + }, options); + + /* 绘制层级关系,最底层背景 -> 背景图片 -> 前景 -> 最顶层前景图片 */ + return new Promise((resolve, reject) => { + let ctx = this.canvasContext; + + const startup = () => { + /* 同时绘制多个二维码时使用队列绘制,防止内部方法冲突导致绘制失败 */ + return uQRCode.Queue(() => new Promise((queueResolve, queueReject) => { + setTimeout(() => { + ctx.draw(false); // 第一个draw false可以清空画布 + queueResolve(); + }, 150); + })); + } + startup() + .then(() => { + /* 绘制背景 */ + return this.drawBackground({ + before: options.drawBackground.before, + after: options.drawBackground.after + }); + }) + .then(() => { + /* 绘制背景图片 */ + return this.drawBackgroundImage({ + before: options.drawBackgroundImage.before, + after: options.drawBackgroundImage.after + }); + }) + .then(() => { + /* 绘制前景 */ + return this.drawForeground({ + before: options.drawForeground.before, + after: options.drawForeground.after + }); + }) + .then(() => { + /* 绘制前景图片 */ + return this.drawForegroundImage({ + before: options.drawForegroundImage.before, + after: options.drawForegroundImage.after + }); + }) + .then(() => { + /* 完成绘制 */ + resolve(); + }); + }); + }, + + drawBackground({ + before, + after + }) { + let { + dynamicSize: size, + background + } = this.options; + let ctx = this.canvasContext; + + return new Promise((resolve, reject) => { + (async () => { + await before(this); + + ctx.save(); + /* 填充背景色 */ + ctx.setFillStyle(background.color); + ctx.fillRect(0, 0, size, size); + ctx.restore(); + ctx.draw(true); // gcanvas需要每一阶段都draw一下,否则重绘有问题,例如uni-app nvue绘制图片会失败 + + await after(this); + resolve(); + })(); + }); + }, + + drawBackgroundImage({ + before, + after + }) { + let { + dynamicSize: size, + background + } = this.options; + let ctx = this.canvasContext; + + return new Promise((resolve, reject) => { + (async () => { + await before(this); + + if (background.image.src) { + ctx.save(); + + let x = 0; + let y = 0; + + let w = background.image.width * size; + let h = background.image.height * size; + let align = background.image.align; + let anchor = background.image.anchor; + let alpha = background.image.alpha; + + switch (align[0]) { + case 'left': + x = 0; + break; + case 'center': + x = size / 2 - w / 2; + break; + case 'right': + x = size - w; + break; + } + x += Number(anchor[0]); + + switch (align[1]) { + case 'top': + y = 0; + break; + case 'center': + y = size / 2 - h / 2; + break; + case 'bottom': + y = size - h; + break; + } + y += Number(anchor[1]); + + /* 设置透明度 */ + ctx.globalAlpha = alpha; + + /* 绘制图片 */ + const img = await this.loadImage(background.image.src); + ctx.drawImage(img, x, y, w, h); + ctx.restore(); + ctx.draw(true); // gcanvas需要每一阶段都draw一下,否则重绘有问题,例如uni-app nvue绘制图片会失败 + } + + await after(this); + resolve(); + })(); + }); + }, + + drawForeground({ + before, + after + }) { + let { + background + } = this.options; + let modules = this.modules; + let moduleCount = this.moduleCount; + let ctx = this.canvasContext; + + return new Promise((resolve, reject) => { + (async () => { + await before(this); + + ctx.save(); + for (var rowI = 0; rowI < moduleCount; rowI++) { + for (var colI = 0; colI < moduleCount; colI++) { + var tile = modules[rowI][colI]; + if (!tile.isDrawn && tile.color != background.color) { // 颜色不能与背景色一致,否则可能发生颜色重叠 + var color = tile.color; + ctx.setFillStyle(color); + ctx.fillRect(tile.x, tile.y, tile.size, tile.size); + tile.isDrawn = true; + } + } + } + ctx.restore(); + ctx.draw(true); // gcanvas需要每一阶段都draw一下,否则重绘有问题,例如uni-app nvue绘制图片会失败 + + await after(this); + resolve(); + })(); + }); + }, + + drawForegroundImage({ + before, + after + }) { + let { + dynamicSize: size, + foreground + } = this.options; + let ctx = this.canvasContext; + + return new Promise((resolve, reject) => { + (async () => { + await before(this); + + if (foreground.image.src) { + ctx.save(); + + // 绘制前景图 + let x = 0; + let y = 0; + + let w = foreground.image.width * size; + let h = foreground.image.height * size; + let align = foreground.image.align; + let anchor = foreground.image.anchor; + let alpha = foreground.image.alpha; + let shadow = foreground.image.shadow; + let border = foreground.image.border; + + switch (align[0]) { + case 'left': + x = 0; + break; + case 'center': + x = size / 2 - w / 2; + break; + case 'right': + x = size - w; + break; + } + x += Number(anchor[0]); + + switch (align[1]) { + case 'top': + y = 0; + break; + case 'center': + y = size / 2 - h / 2; + break; + case 'bottom': + y = size - h; + break; + } + y += Number(anchor[1]); + + /* 绘制图片 */ + const img = await this.loadImage(foreground.image.src); + ctx.drawImage(img, x, y, w, h); + ctx.restore(); + ctx.draw(true); // gcanvas需要每一阶段都draw一下,否则重绘有问题,例如uni-app nvue绘制图片会失败 + } + + await after(this); + resolve(); + })(); + }); + } + + } + +})(); + +module.exports = uQRCode; diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/package.json b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/package.json new file mode 100644 index 0000000..86328da --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/package.json @@ -0,0 +1,24 @@ +{ + "name": "u-qrcode", + "version": "3.2.2", + "description": "uQRCode 二维码生成插件", + "main": "u-qrcode.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Sansnn/uQRCode.git" + }, + "keywords": [ + "QR", + "QRCode", + "uQRCode" + ], + "author": "Sansnn", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/Sansnn/uQRCode/issues" + }, + "homepage": "https://github.com/Sansnn/uQRCode#readme" +} diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/readme.md b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/readme.md new file mode 100644 index 0000000..e5935be --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/readme.md @@ -0,0 +1,274 @@ +# uQRCode + +**点击群号加入群聊【uQRCode交流群】:[695070434](https://jq.qq.com/?_wv=1027&k=JRjzDqiw)** + +uQRCode 生成方式简单,可扩展性高,适用所有前端应用和Node.js服务端,可运行到所有支持canvas的平台。支持NVUE(NVUE中使用GCanvas)。 + +支持自定义二维码渲染规则,可通过uQRCode API得到矩阵信息后,自行实现canvas或view+css渲染二维码,如随机颜色、圆点、方块、块与块之间的间距等,详情参考示例项目。 + +### 插件市场 +[https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287) + +### github +[https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode) + +### npm +[https://www.npmjs.com/package/u-qrcode](https://www.npmjs.com/package/u-qrcode) + +### 示例预览 +[https://static-c15f4b57-ef97-4d2b-b939-f580f910d7e2.bspapp.com](https://static-c15f4b57-ef97-4d2b-b939-f580f910d7e2.bspapp.com) + +### 二维码 +**什么是QR码** + +QR码属于矩阵式二维码中的一个种类,由DENSO(日本电装)公司开发,由JIS和ISO将其标准化。 + +**QR码的特点** + +一是高速读取(QR就是取自“Quick Response”的首字母),通过摄像头从拍摄到解码到显示内容也就三秒左右,对摄像的角度也没有什么要求; + +二是高容量、高密度,理论上内容经过压缩处理后可以存7089个数字,4296个字母和数字混合字符,2953个8位字节数据,1817个汉字; + +三是支持纠错处理,按照QR码的标准文档说明,QR码的纠错分为4个级别,分别是: +- level L : 最大 7% 的错误能够被纠正; +- level M : 最大 15% 的错误能够被纠正; +- level Q : 最大 25% 的错误能够被纠正; +- level H : 最大 30% 的错误能够被纠正; + +四是结构化,看似无规则的图形,其实对区域有严格的定义。 + +更多二维码介绍及原理:[https://blog.csdn.net/jason_ldh/article/details/11801355](https://blog.csdn.net/jason_ldh/article/details/11801355) + +### 组件使用 + +导入`u-qrcode`组件后,在 `template` 中创建 `` 组件 + +```html + +``` + +### 属性说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|canvasId |String |- |- |是 |组件标识/canvasId | +|value |String |- |- |是 |二维码内容 | +|size |Number |- |354 |否 |二维码大小,默认单位px,rpx需要使用uni.upx2px()转换| +|options |Object |- |- |否 |参数可选项,详见下方options说明 | + +### 事件说明 +|事件名 |参数 |返回值 |说明 | +|--- |--- |--- |:--- | +|click |- |void |点击事件 | +|complete |- |Object |生成完成事件,返回值success: true表示生成成功,false生成失败 | + +### 方法说明 +|方法名 |参数 |返回值 |说明 | +|--- |--- |--- |:--- | +|remake |- |void |重新生成 | +|toTempFilePath |Object:callback|void |导出临时路径 | +|save |Object:callback|void |保存 | + +#### options说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|typeNumber |Number |- |-1 |否 |二维码版本 | +|errorCorrectLevel |String/Number|L/M/Q/H/1/0/3/2|H |否 |纠错等级L/M/Q/H分别对应1/0/3/2 | +|useDynamicSize |Boolean |- |false |否 |是否使用动态尺寸,可以去除二维码小块白色细线 | +|margin |Number |- |0 |否 |填充边距,默认单位px | +|background |Object |- |- |否 |背景设置,详见下方options.background说明 | +|foreground |Object |- |- |否 |前景设置,详见下方options.foreground说明 | +|positionDetection |Object |- |- |否 |定位角设置,详见下方options.positionDetection说明 | +|separator |Object |- |- |否 |分割图案设置,详见下方options.separator说明 | +|alignment |Object |- |- |否 |对齐图案设置,详见下方options.alignment说明 | +|timing |Object |- |- |否 |时序图案设置,详见下方options.timing说明 | +|darkBlock |Object |- |- |否 |暗块设置,详见下方options.darkBlock说明 | +|versionInformation |Object |- |- |否 |版本信息设置,详见下方options.versionInformation说明 | + +#### options.background说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|color |String |- |#FFFFFF|否 |背景色,若需要透明背景可设置为rgba(0,0,0,0)| +|image |Object |- |- |否 |背景图片设置,详见下方options.background.image说明| + +#### options.background.image说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|src |String |- |- |否 |背景图片路径 | +|width |Number |- |1 |否 |指定背景图片宽度,1为二维码size的100% | +|height |Number |- |1 |否 |指定背景图片高度,1为二维码size的100% | +|align |Array|['left'/'center'/'right', 'top'/'center'/'bottom'] |['center', 'center'] |否 |指定背景图片对齐方式,[0]为水平方位,[1]为垂直方位 | +|anchor |Array|- |[0, 0] |否 |指定背景图片锚点,[0]为X轴偏移量,[1]为Y轴偏移量 | +|alpha |Number |0-1 |1 |否 |指定背景图片透明度 | + +#### options.foreground说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|color |String |- |#FFFFFF|否 |前景色 | +|image |Object |- |- |否 |前景图片设置,详见下方options.foreground.image说明 | + +#### options.foreground.image说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|src |String |- |- |否 |前景图片路径 | +|width |Number |- |1/4 |否 |指定前景图片宽度,1为二维码size的100% | +|height |Number |- |1/4 |否 |指定前景图片高度,1为二维码size的100% | +|align |Array|['left'/'center'/'right', 'top'/'center'/'bottom'] |['center', 'center'] |否 |指定前景图片对齐方式,[0]为水平方位,[1]为垂直方位 | +|anchor |Array|- |[0, 0] |否 |指定前景图片锚点,[0]为X轴偏移量,[1]为Y轴偏移量 | + +#### options.positionDetection说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|backgroundColor|String |- |options.background.color |否 |定位角区域背景色,默认值跟随背景色 | +|foregroundColor|String |- |options.foreground.color |否 |定位角小块颜色,默认值跟随前景色 | + +#### options.separator说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|color |String |- |options.background.color |否 |分割区域颜色,默认值跟随背景色 | + +#### options.alignment说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|backgroundColor|String |- |options.background.color |否 |对齐区域背景色,默认值跟随背景色 | +|foregroundColor|String |- |options.foreground.color |否 |对齐小块颜色,默认值跟随前景色 | + +#### options.timing说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|backgroundColor|String |- |options.background.color |否 |时序区域背景色,默认值跟随背景色 | +|foregroundColor|String |- |options.foreground.color |否 |时序小块颜色,默认值跟随前景色 | + +#### options.darkBlock说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|color |String |- |options.foreground.color |否 |暗块颜色,默认值跟随前景色 | + +#### options.versionInformation说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|backgroundColor|String |- |options.background.color |否 |版本信息区域背景色,默认值跟随背景色 | +|foregroundColor|String |- |options.foreground.color |否 |版本信息小块颜色,默认值跟随前景色 | + +### u-qrcode.js使用 + +引入u-qrcode.js + +``` javascript +import uQRCode from '../../uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode'; +``` + +或者使用npm安装 + +> npm i u-qrcode + +``` javascript +import uQRCode from 'u-qrcode'; +``` + +nodejs引入 + +``` javascript +import uQRCode from 'u-qrcode/module'; +``` + +在 `template` 中创建 `` 组件并设置 `id`,画布宽高 + +```html + +``` + +在 `script` 中调用生成方法 + +```javascript +import uQRCode from '../../uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode'; + +export default { + data() { + return { + text: 'uQRCode', + size: 256 + } + }, + onReady() { + const ctx = uni.createCanvasContext('qrcode'); + const uqrcode = new uQRCode( + { + text: this.text, + size: this.size + }, + ctx + ); + uqrcode.make(); + uqrcode.draw(); + } +} +``` + +### new uQRCode(options, canvasContext, loadImage)说明 + +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|options |Object |- |- |是 |包含组件属性中的options的所有属性,详见下方options说明 | +|canvasContext|Object |- |- |是 |canvas绘画上下文 | +|loadImage |Promise|- |- |否 |绘制图片时,某些平台必传,例如微信小程序2d绘图需要创建Image对象,不能直接使用路径,这时就需要传入canvas.createImage给loadImage方法,否则无法绘制图片 | + +#### options说明,包含组件属性中的options的所有属性,下方仅列举未包含的属性,其余属性请移步到组件属性options说明查看 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|text |String |- |- |是 |二维码内容 | +|size |Number |- |354 |否 |二维码大小 | + +### uQRCode实例属性 +|属性名 |类型 |说明 | +|--- |--- |:--- | +|options |Object |实例化传入的选项值 | +|canvasContext|Object |画布实例 | +|makeData |Object |制作二维码全部数据 | +|modules |Array |制作二维码主要模块数据 | +|moduleCount |Number |模块数量 | + +### uQRCode实例方法 +|方法名 |参数 |返回值 |说明 | +|--- |--- |--- |:--- | +|make |- |void |制作二维码方法 | +|draw |options|Promise|绘制二维码方法,绘制层级关系,最底层背景 -> 背景图片 -> 前景 -> 最顶层前景图片,options见下方说明 | + +#### draw(options)说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|drawBackground |Object: {before, after}|- |- |否 |绘制背景前后可执行自定义方法before,after | +|drawBackgroundImage|Object: {before, after}|- |- |否 |绘制背景图前后可执行自定义方法before,after| +|drawForeground |Object: {before, after}|- |- |否 |绘制前景前后可执行自定义方法before,after | +|drawForegroundImage|Object: {before, after}|- |- |否 |绘制前景图前后可执行自定义方法before,after| + +### uQRCode静态属性 +|属性名 |类型 |说明 | +|--- |--- |:--- | +|errorCorrectLevel|Object |纠错等级 | +|defaults |Object |预设默认值 | + +### uQRCode静态方法 +|方法名 |参数 |返回值 |说明 | +|--- |--- |--- |:--- | +|deepReplace|o, r |替换后的新对象 |对象属性深度替换 | + +### 常见问题 + +**如何扫码跳转指定网页** + +二维码内容直接放入完整的网页地址即可,例如:`https://ext.dcloud.net.cn/plugin?id=1287`。微信客户端不能是ip地址。 + +**nvue打包后生成失败** + +Canvas是作为独立的模块,打包时需要选择使用Canvas模块才能正常使用相关的功能。 需要在manifest.json的代码视图中配置如下(暂时还不支持可视化界面操作): +```javascript +"app-plus" : { + /* 模块配置 */ + "modules" : { + "Canvas" : "nvue canvas" //使用Canvas模块 + }, + //... +}, +//... +``` +保存好提交云端打包。 diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/u-qrcode.js b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/u-qrcode.js new file mode 100644 index 0000000..fa67ceb --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode/u-qrcode.js @@ -0,0 +1,2285 @@ +//--------------------------------------------------------------------- +// uQRCode 二维码生成插件 v3.2.2 +// +// uQRCode 是一款使用方式简单,高扩展的二维码生成插件。支持全端生成,支持canvas的地方就可以使用uQRCode。 +// +// Copyright (c) Sansnn uQRCode All rights reserved. +// Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// 复制使用请保留本段注释,感谢支持开源! +// +// 开源地址: +// https://github.com/Sansnn/uQRCode +// +// uni-app插件市场地址: +// https://ext.dcloud.net.cn/plugin?id=1287 +//--------------------------------------------------------------------- + +"use strict"; + +function uQRCode(options, canvasContext, loadImage) { + this.options = uQRCode.getOptions(options); + this.canvasContext = uQRCode.getCanvasContext(canvasContext); + this.loadImage = uQRCode.getLoadImage(loadImage); +} + +(function() { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + // QR8bitByte + //--------------------------------------------------------------------- + + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + } + + QR8bitByte.prototype = { + + getLength: function(buffer) { + return this.data.length; + }, + + write: function(buffer) { + for (var i = 0; i < this.data.length; i++) { + // not JIS ... + buffer.put(this.data.charCodeAt(i), 8); + } + } + }; + + //--------------------------------------------------------------------- + // QRCode + //--------------------------------------------------------------------- + + function QRCode(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = new Array(); + } + + QRCode.prototype = { + + addData: function(data) { + var newData = new QR8bitByte(data); + this.dataList.push(newData); + this.dataCache = null; + }, + + isDark: function(row, col) { + if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { + throw new Error(row + "," + col); + } + return this.modules[row][col]; + }, + + getModuleCount: function() { + return this.moduleCount; + }, + + make: function() { + // Calculate automatically typeNumber if provided is < 1 + if (this.typeNumber < 1) { + var typeNumber = 1; + for (typeNumber = 1; typeNumber < 40; typeNumber++) { + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel); + + var buffer = new QRBitBuffer(); + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount; + } + + for (var i = 0; i < this.dataList.length; i++) { + var data = this.dataList[i]; + buffer.put(data.mode, 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber)); + data.write(buffer); + } + if (buffer.getLengthInBits() <= totalDataCount * 8) + break; + } + this.typeNumber = typeNumber; + } + this.makeImpl(false, this.getBestMaskPattern()); + }, + + makeImpl: function(test, maskPattern) { + + this.moduleCount = this.typeNumber * 4 + 17; + this.modules = new Array(this.moduleCount); + + for (var row = 0; row < this.moduleCount; row++) { + + this.modules[row] = new Array(this.moduleCount); + + for (var col = 0; col < this.moduleCount; col++) { + this.modules[row][col] = null; //(col + row) % 3; + } + } + + this.setupPositionProbePattern(0, 0); + this.setupPositionProbePattern(this.moduleCount - 7, 0); + this.setupPositionProbePattern(0, this.moduleCount - 7); + this.setupPositionAdjustPattern(); + this.setupTimingPattern(); + this.setupTypeInfo(test, maskPattern); + + if (this.typeNumber >= 7) { + this.setupTypeNumber(test); + } + + if (this.dataCache == null) { + this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); + } + + this.mapData(this.dataCache, maskPattern); + }, + + setupPositionProbePattern: function(row, col) { + + for (var r = -1; r <= 7; r++) { + + if (row + r <= -1 || this.moduleCount <= row + r) continue; + + for (var c = -1; c <= 7; c++) { + + if (col + c <= -1 || this.moduleCount <= col + c) continue; + + if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || + (0 <= c && c <= 6 && (r == 0 || r == 6)) || + (2 <= r && r <= 4 && 2 <= c && c <= 4)) { + this.modules[row + r][col + c] = true; + } else { + this.modules[row + r][col + c] = false; + } + } + } + }, + + getBestMaskPattern: function() { + + var minLostPoint = 0; + var pattern = 0; + + for (var i = 0; i < 8; i++) { + + this.makeImpl(true, i); + + var lostPoint = QRUtil.getLostPoint(this); + + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint; + pattern = i; + } + } + + return pattern; + }, + + createMovieClip: function(target_mc, instance_name, depth) { + + var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); + var cs = 1; + + this.make(); + + for (var row = 0; row < this.modules.length; row++) { + + var y = row * cs; + + for (var col = 0; col < this.modules[row].length; col++) { + + var x = col * cs; + var dark = this.modules[row][col]; + + if (dark) { + qr_mc.beginFill(0, 100); + qr_mc.moveTo(x, y); + qr_mc.lineTo(x + cs, y); + qr_mc.lineTo(x + cs, y + cs); + qr_mc.lineTo(x, y + cs); + qr_mc.endFill(); + } + } + } + + return qr_mc; + }, + + setupTimingPattern: function() { + + for (var r = 8; r < this.moduleCount - 8; r++) { + if (this.modules[r][6] != null) { + continue; + } + this.modules[r][6] = (r % 2 == 0); + } + + for (var c = 8; c < this.moduleCount - 8; c++) { + if (this.modules[6][c] != null) { + continue; + } + this.modules[6][c] = (c % 2 == 0); + } + }, + + setupPositionAdjustPattern: function() { + + var pos = QRUtil.getPatternPosition(this.typeNumber); + + for (var i = 0; i < pos.length; i++) { + + for (var j = 0; j < pos.length; j++) { + + var row = pos[i]; + var col = pos[j]; + + if (this.modules[row][col] != null) { + continue; + } + + for (var r = -2; r <= 2; r++) { + + for (var c = -2; c <= 2; c++) { + + if (r == -2 || r == 2 || c == -2 || c == 2 || + (r == 0 && c == 0)) { + this.modules[row + r][col + c] = true; + } else { + this.modules[row + r][col + c] = false; + } + } + } + } + } + }, + + setupTypeNumber: function(test) { + + var bits = QRUtil.getBCHTypeNumber(this.typeNumber); + + for (var i = 0; i < 18; i++) { + var mod = (!test && ((bits >> i) & 1) == 1); + this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; + } + + for (var i = 0; i < 18; i++) { + var mod = (!test && ((bits >> i) & 1) == 1); + this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; + } + }, + + setupTypeInfo: function(test, maskPattern) { + + var data = (this.errorCorrectLevel << 3) | maskPattern; + var bits = QRUtil.getBCHTypeInfo(data); + + // vertical + for (var i = 0; i < 15; i++) { + + var mod = (!test && ((bits >> i) & 1) == 1); + + if (i < 6) { + this.modules[i][8] = mod; + } else if (i < 8) { + this.modules[i + 1][8] = mod; + } else { + this.modules[this.moduleCount - 15 + i][8] = mod; + } + } + + // horizontal + for (var i = 0; i < 15; i++) { + + var mod = (!test && ((bits >> i) & 1) == 1); + + if (i < 8) { + this.modules[8][this.moduleCount - i - 1] = mod; + } else if (i < 9) { + this.modules[8][15 - i - 1 + 1] = mod; + } else { + this.modules[8][15 - i - 1] = mod; + } + } + + // fixed module + this.modules[this.moduleCount - 8][8] = (!test); + + }, + + mapData: function(data, maskPattern) { + + var inc = -1; + var row = this.moduleCount - 1; + var bitIndex = 7; + var byteIndex = 0; + + for (var col = this.moduleCount - 1; col > 0; col -= 2) { + + if (col == 6) col--; + + while (true) { + + for (var c = 0; c < 2; c++) { + + if (this.modules[row][col - c] == null) { + + var dark = false; + + if (byteIndex < data.length) { + dark = (((data[byteIndex] >>> bitIndex) & 1) == 1); + } + + var mask = QRUtil.getMask(maskPattern, row, col - c); + + if (mask) { + dark = !dark; + } + + this.modules[row][col - c] = dark; + bitIndex--; + + if (bitIndex == -1) { + byteIndex++; + bitIndex = 7; + } + } + } + + row += inc; + + if (row < 0 || this.moduleCount <= row) { + row -= inc; + inc = -inc; + break; + } + } + } + + } + + }; + + QRCode.PAD0 = 0xEC; + QRCode.PAD1 = 0x11; + + QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { + + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); + + var buffer = new QRBitBuffer(); + + for (var i = 0; i < dataList.length; i++) { + var data = dataList[i]; + buffer.put(data.mode, 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber)); + data.write(buffer); + } + + // calc num max data. + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount; + } + + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error("code length overflow. (" + + buffer.getLengthInBits() + + ">" + + totalDataCount * 8 + + ")"); + } + + // end code + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4); + } + + // padding + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false); + } + + // padding + while (true) { + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(QRCode.PAD0, 8); + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(QRCode.PAD1, 8); + } + + return QRCode.createBytes(buffer, rsBlocks); + } + + QRCode.createBytes = function(buffer, rsBlocks) { + + var offset = 0; + + var maxDcCount = 0; + var maxEcCount = 0; + + var dcdata = new Array(rsBlocks.length); + var ecdata = new Array(rsBlocks.length); + + for (var r = 0; r < rsBlocks.length; r++) { + + var dcCount = rsBlocks[r].dataCount; + var ecCount = rsBlocks[r].totalCount - dcCount; + + maxDcCount = Math.max(maxDcCount, dcCount); + maxEcCount = Math.max(maxEcCount, ecCount); + + dcdata[r] = new Array(dcCount); + + for (var i = 0; i < dcdata[r].length; i++) { + dcdata[r][i] = 0xff & buffer.buffer[i + offset]; + } + offset += dcCount; + + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); + var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1); + + var modPoly = rawPoly.mod(rsPoly); + ecdata[r] = new Array(rsPoly.getLength() - 1); + for (var i = 0; i < ecdata[r].length; i++) { + var modIndex = i + modPoly.getLength() - ecdata[r].length; + ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0; + } + + } + + var totalCodeCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalCodeCount += rsBlocks[i].totalCount; + } + + var data = new Array(totalCodeCount); + var index = 0; + + for (var i = 0; i < maxDcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < dcdata[r].length) { + data[index++] = dcdata[r][i]; + } + } + } + + for (var i = 0; i < maxEcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < ecdata[r].length) { + data[index++] = ecdata[r][i]; + } + } + } + + return data; + + } + + //--------------------------------------------------------------------- + // QRMode + //--------------------------------------------------------------------- + + var QRMode = { + MODE_NUMBER: 1 << 0, + MODE_ALPHA_NUM: 1 << 1, + MODE_8BIT_BYTE: 1 << 2, + MODE_KANJI: 1 << 3 + }; + + //--------------------------------------------------------------------- + // QRErrorCorrectLevel + //--------------------------------------------------------------------- + + var QRErrorCorrectLevel = { + L: 1, + M: 0, + Q: 3, + H: 2 + }; + + //--------------------------------------------------------------------- + // QRMaskPattern + //--------------------------------------------------------------------- + + var QRMaskPattern = { + PATTERN000: 0, + PATTERN001: 1, + PATTERN010: 2, + PATTERN011: 3, + PATTERN100: 4, + PATTERN101: 5, + PATTERN110: 6, + PATTERN111: 7 + }; + + //--------------------------------------------------------------------- + // QRUtil + //--------------------------------------------------------------------- + + var QRUtil = { + + PATTERN_POSITION_TABLE: [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ], + + G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), + G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), + G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), + + getBCHTypeInfo: function(data) { + var d = data << 10; + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { + d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))); + } + return ((data << 10) | d) ^ QRUtil.G15_MASK; + }, + + getBCHTypeNumber: function(data) { + var d = data << 12; + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { + d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))); + } + return (data << 12) | d; + }, + + getBCHDigit: function(data) { + + var digit = 0; + + while (data != 0) { + digit++; + data >>>= 1; + } + + return digit; + }, + + getPatternPosition: function(typeNumber) { + return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; + }, + + getMask: function(maskPattern, i, j) { + + switch (maskPattern) { + + case QRMaskPattern.PATTERN000: + return (i + j) % 2 == 0; + case QRMaskPattern.PATTERN001: + return i % 2 == 0; + case QRMaskPattern.PATTERN010: + return j % 3 == 0; + case QRMaskPattern.PATTERN011: + return (i + j) % 3 == 0; + case QRMaskPattern.PATTERN100: + return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0; + case QRMaskPattern.PATTERN101: + return (i * j) % 2 + (i * j) % 3 == 0; + case QRMaskPattern.PATTERN110: + return ((i * j) % 2 + (i * j) % 3) % 2 == 0; + case QRMaskPattern.PATTERN111: + return ((i * j) % 3 + (i + j) % 2) % 2 == 0; + + default: + throw new Error("bad maskPattern:" + maskPattern); + } + }, + + getErrorCorrectPolynomial: function(errorCorrectLength) { + + var a = new QRPolynomial([1], 0); + + for (var i = 0; i < errorCorrectLength; i++) { + a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0)); + } + + return a; + }, + + getLengthInBits: function(mode, type) { + + if (1 <= type && type < 10) { + + // 1 - 9 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 10; + case QRMode.MODE_ALPHA_NUM: + return 9; + case QRMode.MODE_8BIT_BYTE: + return 8; + case QRMode.MODE_KANJI: + return 8; + default: + throw new Error("mode:" + mode); + } + + } else if (type < 27) { + + // 10 - 26 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 12; + case QRMode.MODE_ALPHA_NUM: + return 11; + case QRMode.MODE_8BIT_BYTE: + return 16; + case QRMode.MODE_KANJI: + return 10; + default: + throw new Error("mode:" + mode); + } + + } else if (type < 41) { + + // 27 - 40 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 14; + case QRMode.MODE_ALPHA_NUM: + return 13; + case QRMode.MODE_8BIT_BYTE: + return 16; + case QRMode.MODE_KANJI: + return 12; + default: + throw new Error("mode:" + mode); + } + + } else { + throw new Error("type:" + type); + } + }, + + getLostPoint: function(qrCode) { + + var moduleCount = qrCode.getModuleCount(); + + var lostPoint = 0; + + // LEVEL1 + + for (var row = 0; row < moduleCount; row++) { + + for (var col = 0; col < moduleCount; col++) { + + var sameCount = 0; + var dark = qrCode.isDark(row, col); + + for (var r = -1; r <= 1; r++) { + + if (row + r < 0 || moduleCount <= row + r) { + continue; + } + + for (var c = -1; c <= 1; c++) { + + if (col + c < 0 || moduleCount <= col + c) { + continue; + } + + if (r == 0 && c == 0) { + continue; + } + + if (dark == qrCode.isDark(row + r, col + c)) { + sameCount++; + } + } + } + + if (sameCount > 5) { + lostPoint += (3 + sameCount - 5); + } + } + } + + // LEVEL2 + + for (var row = 0; row < moduleCount - 1; row++) { + for (var col = 0; col < moduleCount - 1; col++) { + var count = 0; + if (qrCode.isDark(row, col)) count++; + if (qrCode.isDark(row + 1, col)) count++; + if (qrCode.isDark(row, col + 1)) count++; + if (qrCode.isDark(row + 1, col + 1)) count++; + if (count == 0 || count == 4) { + lostPoint += 3; + } + } + } + + // LEVEL3 + + for (var row = 0; row < moduleCount; row++) { + for (var col = 0; col < moduleCount - 6; col++) { + if (qrCode.isDark(row, col) && + !qrCode.isDark(row, col + 1) && + qrCode.isDark(row, col + 2) && + qrCode.isDark(row, col + 3) && + qrCode.isDark(row, col + 4) && + !qrCode.isDark(row, col + 5) && + qrCode.isDark(row, col + 6)) { + lostPoint += 40; + } + } + } + + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount - 6; row++) { + if (qrCode.isDark(row, col) && + !qrCode.isDark(row + 1, col) && + qrCode.isDark(row + 2, col) && + qrCode.isDark(row + 3, col) && + qrCode.isDark(row + 4, col) && + !qrCode.isDark(row + 5, col) && + qrCode.isDark(row + 6, col)) { + lostPoint += 40; + } + } + } + + // LEVEL4 + + var darkCount = 0; + + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount; row++) { + if (qrCode.isDark(row, col)) { + darkCount++; + } + } + } + + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; + lostPoint += ratio * 10; + + return lostPoint; + } + + }; + + + //--------------------------------------------------------------------- + // QRMath + //--------------------------------------------------------------------- + + var QRMath = { + + glog: function(n) { + + if (n < 1) { + throw new Error("glog(" + n + ")"); + } + + return QRMath.LOG_TABLE[n]; + }, + + gexp: function(n) { + + while (n < 0) { + n += 255; + } + + while (n >= 256) { + n -= 255; + } + + return QRMath.EXP_TABLE[n]; + }, + + EXP_TABLE: new Array(256), + + LOG_TABLE: new Array(256) + + }; + + for (var i = 0; i < 8; i++) { + QRMath.EXP_TABLE[i] = 1 << i; + } + for (var i = 8; i < 256; i++) { + QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ + QRMath.EXP_TABLE[i - 5] ^ + QRMath.EXP_TABLE[i - 6] ^ + QRMath.EXP_TABLE[i - 8]; + } + for (var i = 0; i < 255; i++) { + QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i; + } + + //--------------------------------------------------------------------- + // QRPolynomial + //--------------------------------------------------------------------- + + function QRPolynomial(num, shift) { + + if (num.length == undefined) { + throw new Error(num.length + "/" + shift); + } + + var offset = 0; + + while (offset < num.length && num[offset] == 0) { + offset++; + } + + this.num = new Array(num.length - offset + shift); + for (var i = 0; i < num.length - offset; i++) { + this.num[i] = num[i + offset]; + } + } + + QRPolynomial.prototype = { + + get: function(index) { + return this.num[index]; + }, + + getLength: function() { + return this.num.length; + }, + + multiply: function(e) { + + var num = new Array(this.getLength() + e.getLength() - 1); + + for (var i = 0; i < this.getLength(); i++) { + for (var j = 0; j < e.getLength(); j++) { + num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j))); + } + } + + return new QRPolynomial(num, 0); + }, + + mod: function(e) { + + if (this.getLength() - e.getLength() < 0) { + return this; + } + + var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0)); + + var num = new Array(this.getLength()); + + for (var i = 0; i < this.getLength(); i++) { + num[i] = this.get(i); + } + + for (var i = 0; i < e.getLength(); i++) { + num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio); + } + + // recursive call + return new QRPolynomial(num, 0).mod(e); + } + }; + + //--------------------------------------------------------------------- + // QRRSBlock + //--------------------------------------------------------------------- + + function QRRSBlock(totalCount, dataCount) { + this.totalCount = totalCount; + this.dataCount = dataCount; + } + + QRRSBlock.RS_BLOCK_TABLE = [ + + // L + // M + // Q + // H + + // 1 + [1, 26, 19], + [1, 26, 16], + [1, 26, 13], + [1, 26, 9], + + // 2 + [1, 44, 34], + [1, 44, 28], + [1, 44, 22], + [1, 44, 16], + + // 3 + [1, 70, 55], + [1, 70, 44], + [2, 35, 17], + [2, 35, 13], + + // 4 + [1, 100, 80], + [2, 50, 32], + [2, 50, 24], + [4, 25, 9], + + // 5 + [1, 134, 108], + [2, 67, 43], + [2, 33, 15, 2, 34, 16], + [2, 33, 11, 2, 34, 12], + + // 6 + [2, 86, 68], + [4, 43, 27], + [4, 43, 19], + [4, 43, 15], + + // 7 + [2, 98, 78], + [4, 49, 31], + [2, 32, 14, 4, 33, 15], + [4, 39, 13, 1, 40, 14], + + // 8 + [2, 121, 97], + [2, 60, 38, 2, 61, 39], + [4, 40, 18, 2, 41, 19], + [4, 40, 14, 2, 41, 15], + + // 9 + [2, 146, 116], + [3, 58, 36, 2, 59, 37], + [4, 36, 16, 4, 37, 17], + [4, 36, 12, 4, 37, 13], + + // 10 + [2, 86, 68, 2, 87, 69], + [4, 69, 43, 1, 70, 44], + [6, 43, 19, 2, 44, 20], + [6, 43, 15, 2, 44, 16], + + // 11 + [4, 101, 81], + [1, 80, 50, 4, 81, 51], + [4, 50, 22, 4, 51, 23], + [3, 36, 12, 8, 37, 13], + + // 12 + [2, 116, 92, 2, 117, 93], + [6, 58, 36, 2, 59, 37], + [4, 46, 20, 6, 47, 21], + [7, 42, 14, 4, 43, 15], + + // 13 + [4, 133, 107], + [8, 59, 37, 1, 60, 38], + [8, 44, 20, 4, 45, 21], + [12, 33, 11, 4, 34, 12], + + // 14 + [3, 145, 115, 1, 146, 116], + [4, 64, 40, 5, 65, 41], + [11, 36, 16, 5, 37, 17], + [11, 36, 12, 5, 37, 13], + + // 15 + [5, 109, 87, 1, 110, 88], + [5, 65, 41, 5, 66, 42], + [5, 54, 24, 7, 55, 25], + [11, 36, 12], + + // 16 + [5, 122, 98, 1, 123, 99], + [7, 73, 45, 3, 74, 46], + [15, 43, 19, 2, 44, 20], + [3, 45, 15, 13, 46, 16], + + // 17 + [1, 135, 107, 5, 136, 108], + [10, 74, 46, 1, 75, 47], + [1, 50, 22, 15, 51, 23], + [2, 42, 14, 17, 43, 15], + + // 18 + [5, 150, 120, 1, 151, 121], + [9, 69, 43, 4, 70, 44], + [17, 50, 22, 1, 51, 23], + [2, 42, 14, 19, 43, 15], + + // 19 + [3, 141, 113, 4, 142, 114], + [3, 70, 44, 11, 71, 45], + [17, 47, 21, 4, 48, 22], + [9, 39, 13, 16, 40, 14], + + // 20 + [3, 135, 107, 5, 136, 108], + [3, 67, 41, 13, 68, 42], + [15, 54, 24, 5, 55, 25], + [15, 43, 15, 10, 44, 16], + + // 21 + [4, 144, 116, 4, 145, 117], + [17, 68, 42], + [17, 50, 22, 6, 51, 23], + [19, 46, 16, 6, 47, 17], + + // 22 + [2, 139, 111, 7, 140, 112], + [17, 74, 46], + [7, 54, 24, 16, 55, 25], + [34, 37, 13], + + // 23 + [4, 151, 121, 5, 152, 122], + [4, 75, 47, 14, 76, 48], + [11, 54, 24, 14, 55, 25], + [16, 45, 15, 14, 46, 16], + + // 24 + [6, 147, 117, 4, 148, 118], + [6, 73, 45, 14, 74, 46], + [11, 54, 24, 16, 55, 25], + [30, 46, 16, 2, 47, 17], + + // 25 + [8, 132, 106, 4, 133, 107], + [8, 75, 47, 13, 76, 48], + [7, 54, 24, 22, 55, 25], + [22, 45, 15, 13, 46, 16], + + // 26 + [10, 142, 114, 2, 143, 115], + [19, 74, 46, 4, 75, 47], + [28, 50, 22, 6, 51, 23], + [33, 46, 16, 4, 47, 17], + + // 27 + [8, 152, 122, 4, 153, 123], + [22, 73, 45, 3, 74, 46], + [8, 53, 23, 26, 54, 24], + [12, 45, 15, 28, 46, 16], + + // 28 + [3, 147, 117, 10, 148, 118], + [3, 73, 45, 23, 74, 46], + [4, 54, 24, 31, 55, 25], + [11, 45, 15, 31, 46, 16], + + // 29 + [7, 146, 116, 7, 147, 117], + [21, 73, 45, 7, 74, 46], + [1, 53, 23, 37, 54, 24], + [19, 45, 15, 26, 46, 16], + + // 30 + [5, 145, 115, 10, 146, 116], + [19, 75, 47, 10, 76, 48], + [15, 54, 24, 25, 55, 25], + [23, 45, 15, 25, 46, 16], + + // 31 + [13, 145, 115, 3, 146, 116], + [2, 74, 46, 29, 75, 47], + [42, 54, 24, 1, 55, 25], + [23, 45, 15, 28, 46, 16], + + // 32 + [17, 145, 115], + [10, 74, 46, 23, 75, 47], + [10, 54, 24, 35, 55, 25], + [19, 45, 15, 35, 46, 16], + + // 33 + [17, 145, 115, 1, 146, 116], + [14, 74, 46, 21, 75, 47], + [29, 54, 24, 19, 55, 25], + [11, 45, 15, 46, 46, 16], + + // 34 + [13, 145, 115, 6, 146, 116], + [14, 74, 46, 23, 75, 47], + [44, 54, 24, 7, 55, 25], + [59, 46, 16, 1, 47, 17], + + // 35 + [12, 151, 121, 7, 152, 122], + [12, 75, 47, 26, 76, 48], + [39, 54, 24, 14, 55, 25], + [22, 45, 15, 41, 46, 16], + + // 36 + [6, 151, 121, 14, 152, 122], + [6, 75, 47, 34, 76, 48], + [46, 54, 24, 10, 55, 25], + [2, 45, 15, 64, 46, 16], + + // 37 + [17, 152, 122, 4, 153, 123], + [29, 74, 46, 14, 75, 47], + [49, 54, 24, 10, 55, 25], + [24, 45, 15, 46, 46, 16], + + // 38 + [4, 152, 122, 18, 153, 123], + [13, 74, 46, 32, 75, 47], + [48, 54, 24, 14, 55, 25], + [42, 45, 15, 32, 46, 16], + + // 39 + [20, 147, 117, 4, 148, 118], + [40, 75, 47, 7, 76, 48], + [43, 54, 24, 22, 55, 25], + [10, 45, 15, 67, 46, 16], + + // 40 + [19, 148, 118, 6, 149, 119], + [18, 75, 47, 31, 76, 48], + [34, 54, 24, 34, 55, 25], + [20, 45, 15, 61, 46, 16] + ]; + + QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { + + var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); + + if (rsBlock == undefined) { + throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + + errorCorrectLevel); + } + + var length = rsBlock.length / 3; + + var list = new Array(); + + for (var i = 0; i < length; i++) { + + var count = rsBlock[i * 3 + 0]; + var totalCount = rsBlock[i * 3 + 1]; + var dataCount = rsBlock[i * 3 + 2]; + + for (var j = 0; j < count; j++) { + list.push(new QRRSBlock(totalCount, dataCount)); + } + } + + return list; + } + + QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) { + + switch (errorCorrectLevel) { + case QRErrorCorrectLevel.L: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; + case QRErrorCorrectLevel.M: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; + case QRErrorCorrectLevel.Q: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; + case QRErrorCorrectLevel.H: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; + default: + return undefined; + } + } + + //--------------------------------------------------------------------- + // QRBitBuffer + //--------------------------------------------------------------------- + + function QRBitBuffer() { + this.buffer = new Array(); + this.length = 0; + } + + QRBitBuffer.prototype = { + + get: function(index) { + var bufIndex = Math.floor(index / 8); + return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1; + }, + + put: function(num, length) { + for (var i = 0; i < length; i++) { + this.putBit(((num >>> (length - i - 1)) & 1) == 1); + } + }, + + getLengthInBits: function() { + return this.length; + }, + + putBit: function(bit) { + + var bufIndex = Math.floor(this.length / 8); + if (this.buffer.length <= bufIndex) { + this.buffer.push(0); + } + + if (bit) { + this.buffer[bufIndex] |= (0x80 >>> (this.length % 8)); + } + + this.length++; + } + }; + + //--------------------------------------------------------------------- + // Support Chinese 字符编码支持中文 + // 使用mode 4 8bit + //--------------------------------------------------------------------- + function utf16To8(text) { + var result = ''; + var c; + for (var i = 0; i < text.length; i++) { + c = text.charCodeAt(i); + if (c >= 0x0001 && c <= 0x007F) { + result += text.charAt(i); + } else if (c > 0x07FF) { + result += String.fromCharCode(0xE0 | c >> 12 & 0x0F); + result += String.fromCharCode(0x80 | c >> 6 & 0x3F); + result += String.fromCharCode(0x80 | c >> 0 & 0x3F); + } else { + result += String.fromCharCode(0xC0 | c >> 6 & 0x1F); + result += String.fromCharCode(0x80 | c >> 0 & 0x3F); + } + } + return result; + } + + /** + * 队列 + */ + class Queue { + constructor() { + let waitingQueue = []; + let isRunning = false; //记录是否有未完成的任务 + function execute(task, resolve, reject) { + task() + .then((data) => { + resolve(data); + }) + .catch((e) => { + reject(e); + }) + .finally(() => { + //等待任务队列中如果有任务,则触发它;否则设置isRunning = false,表示无任务状态 + if (waitingQueue.length) { + const next = waitingQueue.shift(); + execute(next.task, next.resolve, next.reject); + } else { + isRunning = false; + } + }); + } + return function(task) { + return new Promise((resolve, reject) => { + if (isRunning) { + waitingQueue.push({ + task, + resolve, + reject + }); + } else { + isRunning = true; + execute(task, resolve, reject); + } + }); + }; + } + } + // const queue = new Queue(); + // queue(() => new Promise((resolve, reject) => { + // setTimeout(() => { + // resolve('task1'); + // }, 1000); + // })).then(data => console.log(data)); + // queue(() => new Promise((resolve, reject) => { + // setTimeout(() => { + // resolve('task2'); + // }, 100); + // })).then(data => console.log(data)); + // queue(() => new Promise((resolve, reject) => { + // setTimeout(() => { + // resolve('task3'); + // }, 300); + // })).then(data => console.log(data)); + + /** + * 纠错等级 + */ + uQRCode.errorCorrectLevel = QRErrorCorrectLevel; + + /** + * 预设默认值(基本,不包含各部分和艺术码参数) + */ + uQRCode.defaults = { + typeNumber: -1, // 版本,-1为自动计算,字符越多,版本越高 + errorCorrectLevel: QRErrorCorrectLevel.H, // 纠错等级 + text: '', // 二维码内容 + size: 354, // 大小 + useDynamicSize: false, // 使用动态尺寸,可以去掉方块小数点,绘制出来后没有白色细线 + margin: 0, // 边距 + background: { + color: '#FFFFFF' // 背景色 + }, + foreground: { + color: '#000000' // 前景色 + } + } + + /** + * 对象属性深度替换 + * @param {Object} o 原始对象/默认对象/被替换的对象 + * @param {Object} r 从这个对象里取值替换到o对象里 + * @return {Object} 替换后的新对象 + */ + uQRCode.deepReplace = function(o = {}, r = {}) { + let obj = { + ...o + } + for (let k in r) { + var vr = r[k]; + if (vr.constructor == Object) { + obj[k] = this.deepReplace(obj[k], vr); + } else if (vr.constructor == String && !vr) { + obj[k] = obj[k]; + } else { + obj[k] = vr; + } + } + return obj; + } + + /** + * 获取选项值 + */ + uQRCode.getOptions = function(options) { + options = uQRCode.deepReplace(uQRCode.defaults, options); + + /* 背景 */ + options.background = uQRCode.deepReplace({ + color: options.background.color, // 背景色 + image: { + src: '', + width: 1, // 图片宽 + height: 1, // 图片高 + align: ['center', 'center'], // 图片对齐方式水平,垂直 + anchor: [0, 0], // 图片位置,X坐标,Y坐标 + alpha: 1 // 透明度 + } + }, options.background); + /* 前景 */ + options.foreground = uQRCode.deepReplace({ + color: options.foreground.color, // 前景色 + image: { + src: '', + width: 1 / 4, // 图片宽 + height: 1 / 4, // 图片高 + align: ['center', 'center'], // 图片对齐方式水平,垂直 + anchor: [0, 0] // 图片位置,X坐标,Y坐标 + } + }, options.foreground); + /* 定位角 */ + options.positionDetection = uQRCode.deepReplace({ + backgroundColor: options.background.color, // 定位角区域背景色,默认值跟随背景色 + foregroundColor: options.foreground.color // 定位角小块颜色,默认值跟随前景色 + }, options.positionDetection); + /* 分割图案 */ + options.separator = uQRCode.deepReplace({ + color: options.background.color // 分割区域颜色,默认值跟随背景色 + }, options.separator); + /* 对齐图案 */ + options.alignment = uQRCode.deepReplace({ + backgroundColor: options.background.color, // 对齐区域背景色,默认值跟随背景色 + foregroundColor: options.foreground.color // 对齐小块颜色,默认值跟随前景色 + }, options.alignment); + /* 时序图案 */ + options.timing = uQRCode.deepReplace({ + backgroundColor: options.background.color, // 时序区域背景色,默认值跟随背景色 + foregroundColor: options.foreground.color // 时序小块颜色,默认值跟随前景色 + }, options.timing); + /* 暗块 */ + options.darkBlock = uQRCode.deepReplace({ + color: options.foreground.color // 暗块颜色 + }, options.darkBlock); + /* 版本信息 */ + options.versionInformation = uQRCode.deepReplace({ + backgroundColor: options.background.color, // 版本信息区域背景色,默认值跟随背景色 + foregroundColor: options.foreground.color // 版本信息小块颜色,默认值跟随前景色 + }, options.versionInformation); + + return options; + } + + /** + * 获取canvas实例 + */ + uQRCode.getCanvasContext = function(ctx) { + /* 兼容setFillStyle写法,主要在uni-app nvue gcanvas */ + ctx.setFillStyle = ctx.setFillStyle || function(color) { + ctx.fillStyle = color; + } + /* 兼容setFontSize写法,主要在微信小程序canvas2d */ + ctx.setFontSize = ctx.setFontSize || function(fontSize) { + ctx.font = `${fontSize}px`; + } + /* 兼容setTextAlign写法,主要在微信小程序canvas2d */ + ctx.setTextAlign = ctx.setTextAlign || function(align) { + ctx.textAlign = align; + } + /* 兼容setTextBaseline写法,主要在微信小程序canvas2d */ + ctx.setTextBaseline = ctx.setTextBaseline || function(textBaseline) { + ctx.textBaseline = textBaseline; + } + /* 若实例不包含draw方法则创建一个 */ + ctx.draw = ctx.draw || function(reserve, callback) { + callback && callback(); + } + return ctx; + } + + /* 队列实例,某些平台一起使用多个组件时需要通过队列逐一绘制,否则部分绘制方法异常,nvue端的iOS gcanvas尤其明显,在不通过队列绘制时会出现图片丢失的情况 */ + uQRCode.Queue = new Queue(); + uQRCode.QueueLoadImage = new Queue(); + + /* 缓存loadImage图片 */ + uQRCode.loadImageCache = []; + + /** + * 获取加载图片方法 + */ + uQRCode.getLoadImage = function(loadImage) { + if (typeof loadImage == 'function') { + return function(src) { + /* 解决iOS APP||NVUE同时绘制多个二维码导致图片丢失需使用队列 */ + return uQRCode.QueueLoadImage(() => new Promise((resolve, reject) => { + setTimeout(() => { + const cache = uQRCode.loadImageCache.find(x => x.src == src); + if (cache) { + resolve(cache.img); + } else { + loadImage(src).then(img => { + uQRCode.loadImageCache.push({ + src, + img + }); + resolve(img); + }); + } + }, 150); + })); + } + } else { + return function(src) { + return Promise.resolve(src); + } + } + } + + uQRCode.prototype = { + /** + * 实例化传入的选项值 + */ + options: {}, + + /** + * 画布实例 + */ + canvasContext: {}, + + /** + * 制作二维码全部数据 + */ + makeData: {}, + + /** + * 制作二维码主要模块数据,基于makeData的modules但数据格式不一致,这里的modules是定制过的 + */ + modules: [], + + /** + * 模块数量 + */ + moduleCount: 0, + + /** + * 获取制作二维码数据 + */ + getMakeData() { + let { + typeNumber, + errorCorrectLevel, + text + } = this.options; + var qrcode = new QRCode(typeNumber, errorCorrectLevel); + qrcode.addData(utf16To8(text.toString())); + qrcode.make(); + return qrcode; + }, + + /** + * 制作二维码方法 + */ + make() { + let makeData = this.makeData = this.getMakeData(); + this.modules = JSON.parse(JSON.stringify(makeData.modules)); + this.moduleCount = makeData.moduleCount; + this.options.typeNumber = makeData.typeNumber; + + /* 数据码 data */ + this.paintData(); + /* 定位图案 position detection */ + this.paintPositionDetection(); + /* 分隔图案 separator */ + this.paintSeparator(); + /* 对齐图案 alignment */ + this.paintAlignment(); + /* 时序图案 timing */ + this.paintTiming(); + /* 暗块 darkBlock */ + this.paintDarkBlock(); + /* 预留版本信息 version information */ + this.paintVersionInformation(); + }, + + paintData() { + let modules = this.modules; + let moduleCount = this.moduleCount; + let { + size, + margin, + background, + foreground, + useDynamicSize + } = this.options; + + /* dynamicSize自动计算出最适合绘制的尺寸,并按这个尺寸去绘制,可以解决canvas绘制小块间产生白线的问题(其实就是小数点精度问题),useDynamicSize=false可以取消这个设定 */ + // let dynamicSize = this.options.dynamicSize = Math.floor((size - margin * 2) / moduleCount) * moduleCount + margin * 2; // Math.floor向下取整缩放会模糊 + let dynamicSize = this.options.dynamicSize = Math.ceil((size - margin * 2) / moduleCount) * moduleCount + margin * 2; // Math.ceil向上取整缩放效果比floor清晰 + if (!useDynamicSize) { + dynamicSize = this.options.dynamicSize = size; + } + let tileSize = (dynamicSize - margin * 2) / moduleCount; + + for (var rowI = 0; rowI < modules.length; rowI++) { + for (var colI = 0; colI < modules.length; colI++) { + var tile = modules[rowI][colI]; + if (tile) { + modules[rowI][colI] = { + size: tileSize, + x: colI * tileSize + margin, + y: rowI * tileSize + margin, + type: ['foreground'], + color: foreground.color, + isBlack: true, + isDrawn: false + }; + } else { + modules[rowI][colI] = { + size: tileSize, + x: colI * tileSize + margin, + y: rowI * tileSize + margin, + type: ['background'], + color: background.color, + isBlack: false, + isDrawn: false + }; + } + } + } + }, + + paintPositionDetection() { + let modules = this.modules; + let size = this.moduleCount; + let { + positionDetection + } = this.options; + + //1) 定义基础图形索引(左上角)x ,y,v + let basePart = [ + [0, 0, 1], + [1, 0, 1], + [2, 0, 1], + [3, 0, 1], + [4, 0, 1], + [5, 0, 1], + [6, 0, 1], + [0, 1, 1], + [1, 1, 0], + [2, 1, 0], + [3, 1, 0], + [4, 1, 0], + [5, 1, 0], + [6, 1, 1], + [0, 2, 1], + [1, 2, 0], + [2, 2, 1], + [3, 2, 1], + [4, 2, 1], + [5, 2, 0], + [6, 2, 1], + [0, 3, 1], + [1, 3, 0], + [2, 3, 1], + [3, 3, 1], + [4, 3, 1], + [5, 3, 0], + [6, 3, 1], + [0, 4, 1], + [1, 4, 0], + [2, 4, 1], + [3, 4, 1], + [4, 4, 1], + [5, 4, 0], + [6, 4, 1], + [0, 5, 1], + [1, 5, 0], + [2, 5, 0], + [3, 5, 0], + [4, 5, 0], + [5, 5, 0], + [6, 5, 1], + [0, 6, 1], + [1, 6, 1], + [2, 6, 1], + [3, 6, 1], + [4, 6, 1], + [5, 6, 1], + [6, 6, 1] + ]; + let disc = size - 7; //size -7 + basePart.forEach(d => { + var ltItem = modules[d[0]][d[1]]; + var rtItem = modules[d[0] + disc][d[1]]; + var lbItem = modules[d[0]][d[1] + disc]; + lbItem.type.push('positionDetection'); + rtItem.type.push('positionDetection'); + ltItem.type.push('positionDetection'); + //绘制左上角 + ltItem.color = d[2] == 1 ? positionDetection.foregroundColor : positionDetection.backgroundColor; + //绘制右 + rtItem.color = d[2] == 1 ? positionDetection.foregroundColor : positionDetection.backgroundColor; + //绘制左 + lbItem.color = d[2] == 1 ? positionDetection.foregroundColor : positionDetection.backgroundColor; + }); + }, + + paintSeparator() { + let modules = this.modules; + let size = this.moduleCount; + let { + separator + } = this.options; + + //1) 定义基础图形索引(左上角) + [ + [7, 0], + [7, 1], + [7, 2], + [7, 3], + [7, 4], + [7, 5], + [7, 6], + [7, 7], + [0, 7], + [1, 7], + [2, 7], + [3, 7], + [4, 7], + [5, 7], + [6, 7] + ].forEach(d => { + var ltItem = modules[d[0]][d[1]]; + var rtItem = modules[size - d[0] - 1][d[1]]; + var lbItem = modules[d[0]][size - d[1] - 1]; + lbItem.type.push('separator'); + rtItem.type.push('separator'); + ltItem.type.push('separator'); + //绘制左上 + ltItem.color = separator.color; + //绘制右 + rtItem.color = separator.color; + //绘制左 + lbItem.color = separator.color; + }); + }, + + paintAlignment() { + let modules = this.modules; + let size = this.moduleCount; + let { + alignment, + typeNumber + } = this.options; + + //不同版本的对齐图案组合位置 + const ALIGNMENT_OF_VERSION = [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ]; + // 对齐图案数量和中心位置根据版本定义 + const alignments = ALIGNMENT_OF_VERSION[typeNumber - 1]; + if (alignments) { + const calcMatrix = [ + [-2, -2, 1], + [-1, -2, 1], + [0, -2, 1], + [1, -2, 1], + [2, -2, 1], + [-2, -1, 1], + [-1, -1, 0], + [0, -1, 0], + [1, -1, 0], + [2, -1, 1], + [-2, 0, 1], + [-1, 0, 0], + [0, 0, 1], + [1, 0, 0], + [2, 0, 1], + [-2, 1, 1], + [-1, 1, 0], + [0, 1, 0], + [1, 1, 0], + [2, 1, 1], + [-2, 2, 1], + [-1, 2, 1], + [0, 2, 1], + [1, 2, 1], + [2, 2, 1] + ]; + const group_len = alignments.length; + for (let i = 0; i < group_len; i++) { + for (let j = 0; j < group_len; j++) { + //对齐图案不能污染 定位器和分隔器 + let { + x, + y + } = { + x: alignments[i], + y: alignments[j] + }; + if (!((x < 9 && y < 9) || (x > size - 9 - 1 && y < 9) || (y > size - 9 - 1 && x < 9))) { + calcMatrix.forEach(d => { + var alignmentItem = modules[x + d[0]][y + d[1]]; + alignmentItem.type.push('alignment'); + alignmentItem.color = d[2] == 1 ? alignment.foregroundColor : alignment.backgroundColor; + }); + } + } + } + } + }, + + paintTiming() { + let modules = this.modules; + let { + timing + } = this.options; + + let timingPartLen = modules.length - 16; + for (let i = 0; i < timingPartLen; i++) { + var xItem = modules[6][8 + i]; + var yItem = modules[8 + i][6]; + xItem.type.push('timing'); + yItem.type.push('timing'); + xItem.color = (1 & i) ^ 1 ? timing.foregroundColor : timing.backgroundColor; + yItem.color = (1 & i) ^ 1 ? timing.foregroundColor : timing.backgroundColor; + } + }, + + paintDarkBlock() { + let modules = this.modules; + let size = this.moduleCount; + let { + darkBlock + } = this.options; + + //创建暗模块 + var darkBlockItem = modules[size - 7 - 1][8]; + darkBlockItem.type.push('darkBlock'); + darkBlockItem.color = darkBlock.color; + }, + + paintVersionInformation() { + let modules = this.modules; + let size = this.moduleCount; + let { + versionInformation, + typeNumber: version + } = this.options; + + if (version < 7) { + return modules; + } + //预留版本信息 0 为补位,预留版本信息 是从索引7开始 + const VERSIONS = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + '000111110010010100', + '001000010110111100', + '001001101010011001', + '001010010011010011', + '001011101111110110', + '001100011101100010', + '001101100001000111', + '001110011000001101', + '001111100100101000', + '010000101101111000', + '010001010001011101', + '010010101000010111', + '010011010100110010', + '010100100110100110', + '010101011010000011', + '010110100011001001', + '010111011111101100', + '011000111011000100', + '011001000111100001', + '011010111110101011', + '011011000010001110', + '011100110000011010', + '011101001100111111', + '011110110101110101', + '011111001001010000', + '100000100111010101', + '100001011011110000', + '100010100010111010', + '100011011110011111', + '100100101100001011', + '100101010000101110', + '100110101001100100', + '100111010101000001', + '101000110001101001' + ]; + + //两种方式获取预留格式信息,临时计算或者查字典 + //let version_codes = _v.correctVersionData(_v.version); + let version_codes = VERSIONS[version] + VERSIONS[version]; + //创建预留版本信息 + let disc = [size - 11, size - 10, size - 9]; + // 左+右 + let version_cells = [ + //左 + [5, disc[2]], + [5, disc[1]], + [5, disc[0]], + [4, disc[2]], + [4, disc[1]], + [4, disc[0]], + [3, disc[2]], + [3, disc[1]], + [3, disc[0]], + [2, disc[2]], + [2, disc[1]], + [2, disc[0]], + [1, disc[2]], + [1, disc[1]], + [1, disc[0]], + [0, disc[2]], + [0, disc[1]], + [0, disc[0]], + //右 + [disc[2], 5], + [disc[1], 5], + [disc[0], 5], + [disc[2], 4], + [disc[1], 4], + [disc[0], 4], + [disc[2], 3], + [disc[1], 3], + [disc[0], 3], + [disc[2], 2], + [disc[1], 2], + [disc[0], 2], + [disc[2], 1], + [disc[1], 1], + [disc[0], 1], + [disc[2], 0], + [disc[1], 0], + [disc[0], 0] + ]; + version_cells.forEach((d, index) => { + var versionInformationItem = modules[d[0]][d[1]]; + versionInformationItem.type.push('versionInformation'); + versionInformationItem.color = version_codes[index] == '1' ? versionInformation.foregroundColor : versionInformation.backgroundColor; + }); + }, + + /** + * 绘制二维码方法 + */ + draw(options) { + options = uQRCode.deepReplace({ + drawBackground: { + before: () => {}, + after: () => {} + }, + drawBackgroundImage: { + before: () => {}, + after: () => {} + }, + drawForeground: { + before: () => {}, + after: () => {} + }, + drawForegroundImage: { + before: () => {}, + after: () => {} + } + }, options); + + /* 绘制层级关系,最底层背景 -> 背景图片 -> 前景 -> 最顶层前景图片 */ + return new Promise((resolve, reject) => { + let ctx = this.canvasContext; + + const startup = () => { + /* 同时绘制多个二维码时使用队列绘制,防止内部方法冲突导致绘制失败 */ + return uQRCode.Queue(() => new Promise((queueResolve, queueReject) => { + setTimeout(() => { + ctx.draw(false); // 第一个draw false可以清空画布 + queueResolve(); + }, 150); + })); + } + startup() + .then(() => { + /* 绘制背景 */ + return this.drawBackground({ + before: options.drawBackground.before, + after: options.drawBackground.after + }); + }) + .then(() => { + /* 绘制背景图片 */ + return this.drawBackgroundImage({ + before: options.drawBackgroundImage.before, + after: options.drawBackgroundImage.after + }); + }) + .then(() => { + /* 绘制前景 */ + return this.drawForeground({ + before: options.drawForeground.before, + after: options.drawForeground.after + }); + }) + .then(() => { + /* 绘制前景图片 */ + return this.drawForegroundImage({ + before: options.drawForegroundImage.before, + after: options.drawForegroundImage.after + }); + }) + .then(() => { + /* 完成绘制 */ + resolve(); + }); + }); + }, + + drawBackground({ + before, + after + }) { + let { + dynamicSize: size, + background + } = this.options; + let ctx = this.canvasContext; + + return new Promise((resolve, reject) => { + (async () => { + await before(this); + + ctx.save(); + /* 填充背景色 */ + ctx.setFillStyle(background.color); + ctx.fillRect(0, 0, size, size); + ctx.restore(); + ctx.draw(true); // gcanvas需要每一阶段都draw一下,否则重绘有问题,例如uni-app nvue绘制图片会失败 + + await after(this); + resolve(); + })(); + }); + }, + + drawBackgroundImage({ + before, + after + }) { + let { + dynamicSize: size, + background + } = this.options; + let ctx = this.canvasContext; + + return new Promise((resolve, reject) => { + (async () => { + await before(this); + + if (background.image.src) { + ctx.save(); + + let x = 0; + let y = 0; + + let w = background.image.width * size; + let h = background.image.height * size; + let align = background.image.align; + let anchor = background.image.anchor; + let alpha = background.image.alpha; + + switch (align[0]) { + case 'left': + x = 0; + break; + case 'center': + x = size / 2 - w / 2; + break; + case 'right': + x = size - w; + break; + } + x += Number(anchor[0]); + + switch (align[1]) { + case 'top': + y = 0; + break; + case 'center': + y = size / 2 - h / 2; + break; + case 'bottom': + y = size - h; + break; + } + y += Number(anchor[1]); + + /* 设置透明度 */ + ctx.globalAlpha = alpha; + + /* 绘制图片 */ + const img = await this.loadImage(background.image.src); + ctx.drawImage(img, x, y, w, h); + ctx.restore(); + ctx.draw(true); // gcanvas需要每一阶段都draw一下,否则重绘有问题,例如uni-app nvue绘制图片会失败 + } + + await after(this); + resolve(); + })(); + }); + }, + + drawForeground({ + before, + after + }) { + let { + background + } = this.options; + let modules = this.modules; + let moduleCount = this.moduleCount; + let ctx = this.canvasContext; + + return new Promise((resolve, reject) => { + (async () => { + await before(this); + + ctx.save(); + for (var rowI = 0; rowI < moduleCount; rowI++) { + for (var colI = 0; colI < moduleCount; colI++) { + var tile = modules[rowI][colI]; + if (!tile.isDrawn && tile.color != background.color) { // 颜色不能与背景色一致,否则可能发生颜色重叠 + var color = tile.color; + ctx.setFillStyle(color); + ctx.fillRect(tile.x, tile.y, tile.size, tile.size); + tile.isDrawn = true; + } + } + } + ctx.restore(); + ctx.draw(true); // gcanvas需要每一阶段都draw一下,否则重绘有问题,例如uni-app nvue绘制图片会失败 + + await after(this); + resolve(); + })(); + }); + }, + + drawForegroundImage({ + before, + after + }) { + let { + dynamicSize: size, + foreground + } = this.options; + let ctx = this.canvasContext; + + return new Promise((resolve, reject) => { + (async () => { + await before(this); + + if (foreground.image.src) { + ctx.save(); + + // 绘制前景图 + let x = 0; + let y = 0; + + let w = foreground.image.width * size; + let h = foreground.image.height * size; + let align = foreground.image.align; + let anchor = foreground.image.anchor; + let alpha = foreground.image.alpha; + let shadow = foreground.image.shadow; + let border = foreground.image.border; + + switch (align[0]) { + case 'left': + x = 0; + break; + case 'center': + x = size / 2 - w / 2; + break; + case 'right': + x = size - w; + break; + } + x += Number(anchor[0]); + + switch (align[1]) { + case 'top': + y = 0; + break; + case 'center': + y = size / 2 - h / 2; + break; + case 'bottom': + y = size - h; + break; + } + y += Number(anchor[1]); + + /* 绘制图片 */ + const img = await this.loadImage(foreground.image.src); + ctx.drawImage(img, x, y, w, h); + ctx.restore(); + ctx.draw(true); // gcanvas需要每一阶段都draw一下,否则重绘有问题,例如uni-app nvue绘制图片会失败 + } + + await after(this); + resolve(); + })(); + }); + } + + } + +})(); + +export default uQRCode; diff --git a/uni_modules/Sansnn-uQRCode/package.json b/uni_modules/Sansnn-uQRCode/package.json new file mode 100644 index 0000000..5966ddd --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/package.json @@ -0,0 +1,83 @@ +{ + "id": "Sansnn-uQRCode", + "displayName": "uQRCode 二维码生成插件 支持nvue 支持nodejs服务端", + "version": "3.2.2", + "description": "uQRCode 是一款使用方式简单,高扩展的二维码生成插件。支持全端生成,支持canvas的地方就可以使用uQRCode。", + "keywords": [ + "uQRCode", + "二维码", + "qrcode", + "qr" +], + "repository": "https://github.com/Sansnn/uQRCode", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "JS SDK", + "通用 SDK" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/u-qrcode" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/uni_modules/Sansnn-uQRCode/readme.md b/uni_modules/Sansnn-uQRCode/readme.md new file mode 100644 index 0000000..e5935be --- /dev/null +++ b/uni_modules/Sansnn-uQRCode/readme.md @@ -0,0 +1,274 @@ +# uQRCode + +**点击群号加入群聊【uQRCode交流群】:[695070434](https://jq.qq.com/?_wv=1027&k=JRjzDqiw)** + +uQRCode 生成方式简单,可扩展性高,适用所有前端应用和Node.js服务端,可运行到所有支持canvas的平台。支持NVUE(NVUE中使用GCanvas)。 + +支持自定义二维码渲染规则,可通过uQRCode API得到矩阵信息后,自行实现canvas或view+css渲染二维码,如随机颜色、圆点、方块、块与块之间的间距等,详情参考示例项目。 + +### 插件市场 +[https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287) + +### github +[https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode) + +### npm +[https://www.npmjs.com/package/u-qrcode](https://www.npmjs.com/package/u-qrcode) + +### 示例预览 +[https://static-c15f4b57-ef97-4d2b-b939-f580f910d7e2.bspapp.com](https://static-c15f4b57-ef97-4d2b-b939-f580f910d7e2.bspapp.com) + +### 二维码 +**什么是QR码** + +QR码属于矩阵式二维码中的一个种类,由DENSO(日本电装)公司开发,由JIS和ISO将其标准化。 + +**QR码的特点** + +一是高速读取(QR就是取自“Quick Response”的首字母),通过摄像头从拍摄到解码到显示内容也就三秒左右,对摄像的角度也没有什么要求; + +二是高容量、高密度,理论上内容经过压缩处理后可以存7089个数字,4296个字母和数字混合字符,2953个8位字节数据,1817个汉字; + +三是支持纠错处理,按照QR码的标准文档说明,QR码的纠错分为4个级别,分别是: +- level L : 最大 7% 的错误能够被纠正; +- level M : 最大 15% 的错误能够被纠正; +- level Q : 最大 25% 的错误能够被纠正; +- level H : 最大 30% 的错误能够被纠正; + +四是结构化,看似无规则的图形,其实对区域有严格的定义。 + +更多二维码介绍及原理:[https://blog.csdn.net/jason_ldh/article/details/11801355](https://blog.csdn.net/jason_ldh/article/details/11801355) + +### 组件使用 + +导入`u-qrcode`组件后,在 `template` 中创建 `` 组件 + +```html + +``` + +### 属性说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|canvasId |String |- |- |是 |组件标识/canvasId | +|value |String |- |- |是 |二维码内容 | +|size |Number |- |354 |否 |二维码大小,默认单位px,rpx需要使用uni.upx2px()转换| +|options |Object |- |- |否 |参数可选项,详见下方options说明 | + +### 事件说明 +|事件名 |参数 |返回值 |说明 | +|--- |--- |--- |:--- | +|click |- |void |点击事件 | +|complete |- |Object |生成完成事件,返回值success: true表示生成成功,false生成失败 | + +### 方法说明 +|方法名 |参数 |返回值 |说明 | +|--- |--- |--- |:--- | +|remake |- |void |重新生成 | +|toTempFilePath |Object:callback|void |导出临时路径 | +|save |Object:callback|void |保存 | + +#### options说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|typeNumber |Number |- |-1 |否 |二维码版本 | +|errorCorrectLevel |String/Number|L/M/Q/H/1/0/3/2|H |否 |纠错等级L/M/Q/H分别对应1/0/3/2 | +|useDynamicSize |Boolean |- |false |否 |是否使用动态尺寸,可以去除二维码小块白色细线 | +|margin |Number |- |0 |否 |填充边距,默认单位px | +|background |Object |- |- |否 |背景设置,详见下方options.background说明 | +|foreground |Object |- |- |否 |前景设置,详见下方options.foreground说明 | +|positionDetection |Object |- |- |否 |定位角设置,详见下方options.positionDetection说明 | +|separator |Object |- |- |否 |分割图案设置,详见下方options.separator说明 | +|alignment |Object |- |- |否 |对齐图案设置,详见下方options.alignment说明 | +|timing |Object |- |- |否 |时序图案设置,详见下方options.timing说明 | +|darkBlock |Object |- |- |否 |暗块设置,详见下方options.darkBlock说明 | +|versionInformation |Object |- |- |否 |版本信息设置,详见下方options.versionInformation说明 | + +#### options.background说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|color |String |- |#FFFFFF|否 |背景色,若需要透明背景可设置为rgba(0,0,0,0)| +|image |Object |- |- |否 |背景图片设置,详见下方options.background.image说明| + +#### options.background.image说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|src |String |- |- |否 |背景图片路径 | +|width |Number |- |1 |否 |指定背景图片宽度,1为二维码size的100% | +|height |Number |- |1 |否 |指定背景图片高度,1为二维码size的100% | +|align |Array|['left'/'center'/'right', 'top'/'center'/'bottom'] |['center', 'center'] |否 |指定背景图片对齐方式,[0]为水平方位,[1]为垂直方位 | +|anchor |Array|- |[0, 0] |否 |指定背景图片锚点,[0]为X轴偏移量,[1]为Y轴偏移量 | +|alpha |Number |0-1 |1 |否 |指定背景图片透明度 | + +#### options.foreground说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|color |String |- |#FFFFFF|否 |前景色 | +|image |Object |- |- |否 |前景图片设置,详见下方options.foreground.image说明 | + +#### options.foreground.image说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|src |String |- |- |否 |前景图片路径 | +|width |Number |- |1/4 |否 |指定前景图片宽度,1为二维码size的100% | +|height |Number |- |1/4 |否 |指定前景图片高度,1为二维码size的100% | +|align |Array|['left'/'center'/'right', 'top'/'center'/'bottom'] |['center', 'center'] |否 |指定前景图片对齐方式,[0]为水平方位,[1]为垂直方位 | +|anchor |Array|- |[0, 0] |否 |指定前景图片锚点,[0]为X轴偏移量,[1]为Y轴偏移量 | + +#### options.positionDetection说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|backgroundColor|String |- |options.background.color |否 |定位角区域背景色,默认值跟随背景色 | +|foregroundColor|String |- |options.foreground.color |否 |定位角小块颜色,默认值跟随前景色 | + +#### options.separator说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|color |String |- |options.background.color |否 |分割区域颜色,默认值跟随背景色 | + +#### options.alignment说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|backgroundColor|String |- |options.background.color |否 |对齐区域背景色,默认值跟随背景色 | +|foregroundColor|String |- |options.foreground.color |否 |对齐小块颜色,默认值跟随前景色 | + +#### options.timing说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|backgroundColor|String |- |options.background.color |否 |时序区域背景色,默认值跟随背景色 | +|foregroundColor|String |- |options.foreground.color |否 |时序小块颜色,默认值跟随前景色 | + +#### options.darkBlock说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|color |String |- |options.foreground.color |否 |暗块颜色,默认值跟随前景色 | + +#### options.versionInformation说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|backgroundColor|String |- |options.background.color |否 |版本信息区域背景色,默认值跟随背景色 | +|foregroundColor|String |- |options.foreground.color |否 |版本信息小块颜色,默认值跟随前景色 | + +### u-qrcode.js使用 + +引入u-qrcode.js + +``` javascript +import uQRCode from '../../uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode'; +``` + +或者使用npm安装 + +> npm i u-qrcode + +``` javascript +import uQRCode from 'u-qrcode'; +``` + +nodejs引入 + +``` javascript +import uQRCode from 'u-qrcode/module'; +``` + +在 `template` 中创建 `` 组件并设置 `id`,画布宽高 + +```html + +``` + +在 `script` 中调用生成方法 + +```javascript +import uQRCode from '../../uni_modules/Sansnn-uQRCode/js_sdk/u-qrcode'; + +export default { + data() { + return { + text: 'uQRCode', + size: 256 + } + }, + onReady() { + const ctx = uni.createCanvasContext('qrcode'); + const uqrcode = new uQRCode( + { + text: this.text, + size: this.size + }, + ctx + ); + uqrcode.make(); + uqrcode.draw(); + } +} +``` + +### new uQRCode(options, canvasContext, loadImage)说明 + +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|options |Object |- |- |是 |包含组件属性中的options的所有属性,详见下方options说明 | +|canvasContext|Object |- |- |是 |canvas绘画上下文 | +|loadImage |Promise|- |- |否 |绘制图片时,某些平台必传,例如微信小程序2d绘图需要创建Image对象,不能直接使用路径,这时就需要传入canvas.createImage给loadImage方法,否则无法绘制图片 | + +#### options说明,包含组件属性中的options的所有属性,下方仅列举未包含的属性,其余属性请移步到组件属性options说明查看 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|text |String |- |- |是 |二维码内容 | +|size |Number |- |354 |否 |二维码大小 | + +### uQRCode实例属性 +|属性名 |类型 |说明 | +|--- |--- |:--- | +|options |Object |实例化传入的选项值 | +|canvasContext|Object |画布实例 | +|makeData |Object |制作二维码全部数据 | +|modules |Array |制作二维码主要模块数据 | +|moduleCount |Number |模块数量 | + +### uQRCode实例方法 +|方法名 |参数 |返回值 |说明 | +|--- |--- |--- |:--- | +|make |- |void |制作二维码方法 | +|draw |options|Promise|绘制二维码方法,绘制层级关系,最底层背景 -> 背景图片 -> 前景 -> 最顶层前景图片,options见下方说明 | + +#### draw(options)说明 +|属性名 |类型 |可选值 |默认值 |是否必填 |说明 | +|--- |--- |--- |--- |--- |:--- | +|drawBackground |Object: {before, after}|- |- |否 |绘制背景前后可执行自定义方法before,after | +|drawBackgroundImage|Object: {before, after}|- |- |否 |绘制背景图前后可执行自定义方法before,after| +|drawForeground |Object: {before, after}|- |- |否 |绘制前景前后可执行自定义方法before,after | +|drawForegroundImage|Object: {before, after}|- |- |否 |绘制前景图前后可执行自定义方法before,after| + +### uQRCode静态属性 +|属性名 |类型 |说明 | +|--- |--- |:--- | +|errorCorrectLevel|Object |纠错等级 | +|defaults |Object |预设默认值 | + +### uQRCode静态方法 +|方法名 |参数 |返回值 |说明 | +|--- |--- |--- |:--- | +|deepReplace|o, r |替换后的新对象 |对象属性深度替换 | + +### 常见问题 + +**如何扫码跳转指定网页** + +二维码内容直接放入完整的网页地址即可,例如:`https://ext.dcloud.net.cn/plugin?id=1287`。微信客户端不能是ip地址。 + +**nvue打包后生成失败** + +Canvas是作为独立的模块,打包时需要选择使用Canvas模块才能正常使用相关的功能。 需要在manifest.json的代码视图中配置如下(暂时还不支持可视化界面操作): +```javascript +"app-plus" : { + /* 模块配置 */ + "modules" : { + "Canvas" : "nvue canvas" //使用Canvas模块 + }, + //... +}, +//... +``` +保存好提交云端打包。 diff --git a/uni_modules/hpy-form-select/changelog.md b/uni_modules/hpy-form-select/changelog.md new file mode 100644 index 0000000..01f2a3e --- /dev/null +++ b/uni_modules/hpy-form-select/changelog.md @@ -0,0 +1,2 @@ +## 0.0.10(2022-04-26) +- 适配uni-forms校验 diff --git a/uni_modules/hpy-form-select/components/hpy-form-select/hpy-form-select.vue b/uni_modules/hpy-form-select/components/hpy-form-select/hpy-form-select.vue new file mode 100644 index 0000000..78de734 --- /dev/null +++ b/uni_modules/hpy-form-select/components/hpy-form-select/hpy-form-select.vue @@ -0,0 +1,255 @@ + + + + + diff --git a/uni_modules/hpy-form-select/package.json b/uni_modules/hpy-form-select/package.json new file mode 100644 index 0000000..c40ce8a --- /dev/null +++ b/uni_modules/hpy-form-select/package.json @@ -0,0 +1,87 @@ +{ + "id": "hpy-form-select", + "displayName": "picker选择器、下拉框,选择器", + "version": "0.0.10", + "description": "下拉选择器 基于 picker 简单封装", + "keywords": [ + "picker", + "选择器", + "下拉选择" +], + "repository": "", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uni-load-more" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "y", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/hpy-form-select/readme.md b/uni_modules/hpy-form-select/readme.md new file mode 100644 index 0000000..30f721e --- /dev/null +++ b/uni_modules/hpy-form-select/readme.md @@ -0,0 +1,169 @@ + +## hpy-form-select 下拉选择器 基于 [picker](https://uniapp.dcloud.io/component/picker?id=picker) 简单封装 + +> **组件名:hpy-form-select + +从底部弹起的滚动选择器。支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器 + +## API + +### FilePicker Props + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性名类型默认值说明
islotBoolean | Stringfalse是否使用插槽
titleString请选择默认标题
modeString选择模式selector | multiSelector
startString表示有效日期范围的开始,字符串格式为"YYYY-MM-DD"
endString表示有效日期范围的结束,字符串格式为"YYYY-MM-DD"
fieldsStringday有效值 year、month、day,表示选择器的粒度,默认为 day,App 端未配置此项时使用系统 UI
customItemString可为每一列的顶部添加一个自定义的项
dataListArray选择器数据
textString显示值的key
nameString保存值的key
v-model | valueArray | Object绑定的数据
disabledBoolean | Stringfalse是否禁用
hideBorderBoolean | Stringfalse是否隐藏边框
hideArrowBoolean | Stringfalse是否隐藏箭头
+ + +## 使用示例 +## dataList 为对象数组时,name为实际保存的value值,text为显示的值 +## dataList 为对象数组[{name:'张三', age:'18'}, {name:'李四', age:'19'}]时,需要设置name、text属性,name为实际保存的value值,text为显示的值 +## +## ====================================================================================================== +## dataList 为普通数组['张三', '李四'] name、text可不设置 +## +## 类似: +## + + +```html + + + + + + + + + + + + + + 可自定义显示 + + + + + + + +``` + +```javascript +export default { + data() { + return { + formData:{ + hobbySelect:'' + }, + hobbyList: [{ + text: '足球', + value: 1 + }, { + text: '篮球', + value: 2 + }, { + text: '游泳', + value: 3 + }], + } + }, + methods:{ + change(e){ + console.log(e.index); + console.log(e.value); + console.log(e.data); + } + } +} + +``` \ No newline at end of file diff --git a/uni_modules/mp-html/README.md b/uni_modules/mp-html/README.md new file mode 100644 index 0000000..f825383 --- /dev/null +++ b/uni_modules/mp-html/README.md @@ -0,0 +1,191 @@ +## 为减小组件包的大小,默认组件包中不包含编辑、latex 公式等扩展功能,需要使用扩展功能的请参考下方的 插件扩展 栏的说明 + +## 功能介绍 +- 全端支持(含 `v3、NVUE`) +- 支持丰富的标签(包括 `table`、`video`、`svg` 等) +- 支持丰富的事件效果(自动预览图片、链接处理等) +- 支持设置占位图(加载中、出错时、预览时) +- 支持锚点跳转、长按复制等丰富功能 +- 支持大部分 *html* 实体 +- 丰富的插件(关键词搜索、内容编辑、`latex` 公式等) +- 效率高、容错性强且轻量化 + +查看 [功能介绍](https://jin-yufeng.gitee.io/mp-html/#/overview/feature) 了解更多 + +## 使用方法 +- `uni_modules` 方式 + 1. 点击右上角的 `使用 HBuilder X 导入插件` 按钮直接导入项目或点击 `下载插件 ZIP` 按钮下载插件包并解压到项目的 `uni_modules/mp-html` 目录下 + 2. 在需要使用页面的 `(n)vue` 文件中添加 + ```html + + + ``` + ```javascript + export default { + data() { + return { + html: '
Hello World!
' + } + } + } + ``` + 3. 需要更新版本时在 `HBuilder X` 中右键 `uni_modules/mp-html` 目录选择 `从插件市场更新` 即可 + +- 源码方式 + 1. 从 [github](https://github.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 或 [gitee](https://gitee.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 下载源码 + 插件市场的 **非 uni_modules 版本** 无法更新,不建议从插件市场获取 + 2. 在需要使用页面的 `(n)vue` 文件中添加 + ```html + + ``` + ```javascript + import mpHtml from '@/components/mp-html/mp-html' + export default { + // HBuilderX 2.5.5+ 可以通过 easycom 自动引入 + components: { + mpHtml + }, + data() { + return { + html: '
Hello World!
' + } + } + } + ``` + +- npm 方式 + 1. 在项目根目录下执行 + ```bash + npm install mp-html + ``` + 2. 在需要使用页面的 `(n)vue` 文件中添加 + ```html + + ``` + ```javascript + import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html' + export default { + // 不可省略 + components: { + mpHtml + }, + data() { + return { + html: '
Hello World!
' + } + } + } + ``` + 3. 需要更新版本时执行以下命令即可 + ```bash + npm update mp-html + ``` + + 使用 *cli* 方式运行的项目,通过 *npm* 方式引入时,需要在 *vue.config.js* 中配置 *transpileDependencies*,详情可见 [#330](https://github.com/jin-yufeng/mp-html/issues/330#issuecomment-913617687) + 如果在 **nvue** 中使用还要将 `dist/uni-app/static` 目录下的内容拷贝到项目的 `static` 目录下,否则无法运行 + +查看 [快速开始](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart) 了解更多 + +## 组件属性 + +| 属性 | 类型 | 默认值 | 说明 | +|:---:|:---:|:---:|---| +| container-style | String | | 容器的样式([2.1.0+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v210)) | +| content | String | | 用于渲染的 html 字符串 | +| copy-link | Boolean | true | 是否允许外部链接被点击时自动复制 | +| domain | String | | 主域名(用于链接拼接) | +| error-img | String | | 图片出错时的占位图链接 | +| lazy-load | Boolean | false | 是否开启图片懒加载 | +| loading-img | String | | 图片加载过程中的占位图链接 | +| pause-video | Boolean | true | 是否在播放一个视频时自动暂停其他视频 | +| preview-img | Boolean | true | 是否允许图片被点击时自动预览 | +| scroll-table | Boolean | false | 是否给每个表格添加一个滚动层使其能单独横向滚动 | +| selectable | Boolean | false | 是否开启文本长按复制 | +| set-title | Boolean | true | 是否将 title 标签的内容设置到页面标题 | +| show-img-menu | Boolean | true | 是否允许图片被长按时显示菜单 | +| tag-style | Object | | 设置标签的默认样式 | +| use-anchor | Boolean | false | 是否使用锚点链接 | + +查看 [属性](https://jin-yufeng.gitee.io/mp-html/#/basic/prop) 了解更多 + +## 组件事件 + +| 名称 | 触发时机 | +|:---:|---| +| load | dom 树加载完毕时 | +| ready | 图片加载完毕时 | +| error | 发生渲染错误时 | +| imgtap | 图片被点击时 | +| linktap | 链接被点击时 | +| play | 音视频播放时 | + +查看 [事件](https://jin-yufeng.gitee.io/mp-html/#/basic/event) 了解更多 + +## api +组件实例上提供了一些 `api` 方法可供调用 + +| 名称 | 作用 | +|:---:|---| +| in | 将锚点跳转的范围限定在一个 scroll-view 内 | +| navigateTo | 锚点跳转 | +| getText | 获取文本内容 | +| getRect | 获取富文本内容的位置和大小 | +| setContent | 设置富文本内容 | +| imgList | 获取所有图片的数组 | +| pauseMedia | 暂停播放音视频([2.2.2+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v222)) | +| setPlaybackRate | 设置音视频播放速率([2.4.0+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v240)) | + +查看 [api](https://jin-yufeng.gitee.io/mp-html/#/advanced/api) 了解更多 + +## 插件扩展 +除基本功能外,本组件还提供了丰富的扩展,可按照需要选用 + +| 名称 | 作用 | +|:---:|---| +| audio | 音乐播放器 | +| editable | 富文本 **编辑**([示例项目](https://mp-html.oss-cn-hangzhou.aliyuncs.com/editable.zip)) | +| emoji | 解析 emoji | +| highlight | 代码块高亮显示 | +| markdown | 渲染 markdown | +| search | 关键词搜索 | +| style | 匹配 style 标签中的样式 | +| txv-video | 使用腾讯视频 | +| img-cache | 图片缓存 by [@PentaTea](https://github.com/PentaTea) | +| latex | 渲染 latex 公式 by [@Zeng-J](https://github.com/Zeng-J) | + +从插件市场导入的包中 **不含有** 扩展插件,使用插件需通过微信小程序 `富文本插件` 获取或参考以下方法进行打包: +1. 获取完整组件包 + ```bash + npm install mp-html + ``` +2. 编辑 `tools/config.js` 中的 `plugins` 项,选择需要的插件 +3. 生成新的组件包 + 在 `node_modules/mp-html` 目录下执行 + ```bash + npm install + npm run build:uni-app + ``` +4. 拷贝 `dist/uni-app` 中的内容到项目根目录 + +查看 [插件](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin) 了解更多 + +## 关于 nvue +`nvue` 使用原生渲染,不支持部分 `css` 样式,为实现和 `html` 相同的效果,组件内部通过 `web-view` 进行渲染,性能上差于原生,根据 `weex` 官方建议,`web` 标签仅应用在非常规的降级场景。因此,如果通过原生的方式(如 `richtext`)能够满足需要,则不建议使用本组件,如果有较多的富文本内容,则可以直接使用 `vue` 页面 +由于渲染方式与其他端不同,有以下限制: +1. 不支持 `lazy-load` 属性 +2. 视频不支持全屏播放 +3. 如果在 `flex-direction: row` 的容器中使用,需要给组件设置宽度或设置 `flex: 1` 占满剩余宽度 + +纯 `nvue` 模式下,[此问题](https://ask.dcloud.net.cn/question/119678) 修复前,不支持通过 `uni_modules` 引入,需要本地引入(将 [dist/uni-app](https://github.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 中的内容拷贝到项目根目录下) + +## 立即体验 +![富文本插件](https://mp-html.oss-cn-hangzhou.aliyuncs.com/qrcode.jpg) + +## 问题反馈 +遇到问题时,请先查阅 [常见问题](https://jin-yufeng.gitee.io/mp-html/#/question/faq) 和 [issue](https://github.com/jin-yufeng/mp-html/issues) 中是否已有相同的问题 +可通过 [issue](https://github.com/jin-yufeng/mp-html/issues/new/choose) 、插件问答或发送邮件到 [mp_html@126.com](mailto:mp_html@126.com) 提问,不建议在评论区提问(不方便回复) +提问请严格按照 [issue 模板](https://github.com/jin-yufeng/mp-html/issues/new/choose) ,描述清楚使用环境、`html` 内容或可复现的 `demo` 项目以及复现方式,对于 **描述不清**、**无法复现** 或重复的问题将不予回复 + +欢迎加入 `QQ` 交流群:`699734691` + +查看 [问题反馈](https://jin-yufeng.gitee.io/mp-html/#/question/feedback) 了解更多 diff --git a/uni_modules/mp-html/changelog.md b/uni_modules/mp-html/changelog.md new file mode 100644 index 0000000..51d049e --- /dev/null +++ b/uni_modules/mp-html/changelog.md @@ -0,0 +1,121 @@ +## v2.4.1(2022-12-25) +1. `F` 修复了没有图片时 `ready` 事件可能不触发的问题 +2. `F` 修复了加载过程中可能出现 `Root label not found` 错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/470) +3. `F` 修复了 `audio` 插件退出页面可能会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/457) +4. `F` 修复了 `vue3` 运行到 `app` 在 `HBuilder X 3.6.10` 以上报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/480) +5. `F` 修复了 `nvue` 端链接中包含 `%22` 时可能无法显示的问题 +6. `F` 修复了 `vue3` 使用 `highlight` 插件可能报错的问题 +## v2.4.0(2022-08-27) +1. `A` 增加了 [setPlaybackRate](https://jin-yufeng.gitee.io/mp-html/#/advanced/api#setPlaybackRate) 的 `api`,可以设置音视频的播放速率 [详细](https://github.com/jin-yufeng/mp-html/issues/452) +2. `A` 示例小程序代码开源 [详细](https://github.com/jin-yufeng/mp-html-demo) +3. `U` 优化 `ready` 事件触发时机,未设置懒加载的情况下基本可以准确触发 [详细](https://github.com/jin-yufeng/mp-html/issues/195) +4. `U` `highlight` 插件在编辑状态下不进行高亮处理,便于编辑 +5. `F` 修复了 `flex` 布局下图片大小可能不正确的问题 +6. `F` 修复了 `selectable` 属性没有设置 `force` 也可能出现渲染异常的问题 +7. `F` 修复了表格中的图片大小可能不正确的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/448) +8. `F` 修复了含有合并单元格的表格可能无法设置竖直对齐的问题 +9. `F` 修复了 `editable` 插件在 `scroll-view` 中使用时工具条位置可能不正确的问题 +10. `F` 修复了 `vue3` 使用 [search](advanced/plugin#search) 插件可能导致错误换行的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/449) +## v2.3.2(2022-08-13) +1. `A` 增加 [latex](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#latex) 插件,可以渲染数学公式 [详细](https://github.com/jin-yufeng/mp-html/pull/447) by [@Zeng-J](https://github.com/Zeng-J) +2. `U` 优化根节点下有很多标签的长内容渲染速度 +3. `U` `highlight` 插件适配 `lang-xxx` 格式 +4. `F` 修复了 `table` 标签设置 `border` 属性后可能无法修改边框样式的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/439) by [@zouxingjie](https://github.com/zouxingjie) +5. `F` 修复了 `editable` 插件输入连续空格无效的问题 +6. `F` 修复了 `vue3` 图片设置 `inline` 会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/438) +7. `F` 修复了 `vue3` 使用 `table` 可能报错的问题 +## v2.3.1(2022-05-20) +1. `U` `app` 端支持使用本地图片 +2. `U` 优化了微信小程序 `selectable` 属性在 `ios` 端的处理 [详细](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#selectable) +3. `F` 修复了 `editable` 插件不在顶部时 `tooltip` 位置可能错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/430) +4. `F` 修复了 `vue3` 运行到微信小程序可能报错丢失内容的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/414) +5. `F` 修复了 `vue3` 部分标签可能被错误换行的问题 +6. `F` 修复了 `editable` 插件 `app` 端插入视频无法预览的问题 +## v2.3.0(2022-04-01) +1. `A` 增加了 `play` 事件,音视频播放时触发,可用于与页面其他音视频进行互斥播放 [详细](basic/event#play) +2. `U` `show-img-menu` 属性支持控制预览时是否长按弹出菜单 +3. `U` 优化 `wxs` 处理,提高渲染性能 [详细](https://developers.weixin.qq.com/community/develop/article/doc/0006cc2b204740f601bd43fa25a413) +4. `U` `video` 标签支持 `object-fit` 属性 +5. `U` 增加支持一些常用实体编码 [详细](https://github.com/jin-yufeng/mp-html/issues/418) +6. `F` 修复了图片仅设置高度可能不显示的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/410) +7. `F` 修复了 `video` 标签高度设置为 `auto` 不显示的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/411) +8. `F` 修复了使用 `grid` 布局时可能样式错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/413) +9. `F` 修复了含有合并单元格的表格部分情况下显示异常的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/417) +10. `F` 修复了 `editable` 插件连续插入内容时顺序不正确的问题 +11. `F` 修复了 `uni-app` 包 `vue3` 使用 `audio` 插件报错的问题 +12. `F` 修复了 `uni-app` 包 `highlight` 插件使用自定义的 `prism.min.js` 报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/416) +## v2.2.2(2022-02-26) +1. `A` 增加了 [pauseMedia](https://jin-yufeng.gitee.io/mp-html/#/advanced/api#pauseMedia) 的 `api`,可用于暂停播放音视频 [详细](https://github.com/jin-yufeng/mp-html/issues/317) +2. `U` 优化了长内容的加载速度 +3. `U` 适配 `vue3` [#389](https://github.com/jin-yufeng/mp-html/issues/389)、[#398](https://github.com/jin-yufeng/mp-html/pull/398) by [@zhouhuafei](https://github.com/zhouhuafei)、[#400](https://github.com/jin-yufeng/mp-html/issues/400) +4. `F` 修复了小程序端图片高度设置为百分比时可能不显示的问题 +5. `F` 修复了 `highlight` 插件部分情况下可能显示不完整的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/403) +## v2.2.1(2021-12-24) +1. `A` `editable` 插件增加上下移动标签功能 +2. `U` `editable` 插件支持在文本中间光标处插入内容 +3. `F` 修复了 `nvue` 端设置 `margin` 后可能导致高度不正确的问题 +4. `F` 修复了 `highlight` 插件使用压缩版的 `prism.css` 可能导致背景失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/367) +5. `F` 修复了编辑状态下使用 `emoji` 插件内容为空时可能报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/371) +6. `F` 修复了使用 `editable` 插件后将 `selectable` 属性设置为 `force` 不生效的问题 +## v2.2.0(2021-10-12) +1. `A` 增加 `customElements` 配置项,便于添加自定义功能性标签 [详细](https://github.com/jin-yufeng/mp-html/issues/350) +2. `A` `editable` 插件增加切换音视频自动播放状态的功能 [详细](https://github.com/jin-yufeng/mp-html/pull/341) by [@leeseett](https://github.com/leeseett) +3. `A` `editable` 插件删除媒体标签时触发 `remove` 事件,便于删除已上传的文件 +4. `U` `editable` 插件 `insertImg` 方法支持同时插入多张图片 [详细](https://github.com/jin-yufeng/mp-html/issues/342) +5. `U` `editable` 插入图片和音视频时支持拼接 `domian` 主域名 +6. `F` 修复了内部链接参数中包含 `://` 时被认为是外部链接的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/356) +7. `F` 修复了部分 `svg` 标签名或属性名大小写不正确时不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/351) +8. `F` 修复了 `nvue` 页面运行到非 `app` 平台时可能样式错误的问题 +## v2.1.5(2021-08-13) +1. `A` 增加支持标签的 `dir` 属性 +2. `F` 修复了 `ruby` 标签文字与拼音没有居中对齐的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/325) +3. `F` 修复了音视频标签内有 `a` 标签时可能无法播放的问题 +4. `F` 修复了 `externStyle` 中的 `class` 名包含下划线或数字时可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326) +5. `F` 修复了 `h5` 端引入 `externStyle` 可能不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326) +## v2.1.4(2021-07-14) +1. `F` 修复了 `rt` 标签无法设置样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/318) +2. `F` 修复了表格中有单元格同时合并行和列时可能显示不正确的问题 +3. `F` 修复了 `app` 端无法关闭图片长按菜单的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/322) +4. `F` 修复了 `editable` 插件只能添加图片链接不能修改的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/312) by [@leeseett](https://github.com/leeseett) +## v2.1.3(2021-06-12) +1. `A` `editable` 插件增加 `insertTable` 方法 +2. `U` `editable` 插件支持编辑表格中的空白单元格 [详细](https://github.com/jin-yufeng/mp-html/issues/310) +3. `F` 修复了 `externStyle` 中使用伪类可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/298) +4. `F` 修复了多个组件同时使用时 `tag-style` 属性时可能互相影响的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/305) by [@woodguoyu](https://github.com/woodguoyu) +5. `F` 修复了包含 `linearGradient` 的 `svg` 可能无法显示的问题 +6. `F` 修复了编译到头条小程序时可能报错的问题 +7. `F` 修复了 `nvue` 端不触发 `click` 事件的问题 +8. `F` 修复了 `editable` 插件尾部插入时无法撤销的问题 +9. `F` 修复了 `editable` 插件的 `insertHtml` 方法只能在末尾插入的问题 +10. `F` 修复了 `editable` 插件插入音频不显示的问题 +## v2.1.2(2021-04-24) +1. `A` 增加了 [img-cache](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#img-cache) 插件,可以在 `app` 端缓存图片 [详细](https://github.com/jin-yufeng/mp-html/issues/292) by [@PentaTea](https://github.com/PentaTea) +2. `U` 支持通过 `container-style` 属性设置 `white-space` 来保留连续空格和换行符 [详细](https://jin-yufeng.gitee.io/mp-html/#/question/faq#space) +3. `U` 代码风格符合 [standard](https://standardjs.com) 标准 +4. `U` `editable` 插件编辑状态下支持预览视频 [详细](https://github.com/jin-yufeng/mp-html/issues/286) +5. `F` 修复了 `svg` 标签内嵌 `svg` 时无法显示的问题 +6. `F` 修复了编译到支付宝和头条小程序时部分区域不可复制的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/291) +## v2.1.1(2021-04-09) +1. 修复了对 `p` 标签设置 `tag-style` 可能不生效的问题 +2. 修复了 `svg` 标签中的文本无法显示的问题 +3. 修复了使用 `editable` 插件编辑表格时可能报错的问题 +4. 修复了使用 `highlight` 插件运行到头条小程序时可能没有样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/280) +5. 修复了使用 `editable` 插件 `editable` 属性为 `false` 时会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/284) +6. 修复了 `style` 插件连续子选择器失效的问题 +7. 修复了 `editable` 插件无法修改图片和字体大小的问题 +## v2.1.0.2(2021-03-21) +修复了 `nvue` 端使用可能报错的问题 +## v2.1.0(2021-03-20) +1. `A` 增加了 [container-style](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#container-style) 属性 [详细](https://gitee.com/jin-yufeng/mp-html/pulls/1) +2. `A` 增加支持 `strike` 标签 +3. `A` `editable` 插件增加 `placeholder` 属性 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable) +4. `A` `editable` 插件增加 `insertHtml` 方法 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable) +5. `U` 外部样式支持标签名选择器 [详细](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart#setting) +6. `F` 修复了 `nvue` 端部分情况下可能不显示的问题 +## v2.0.5(2021-03-12) +1. `U` [linktap](https://jin-yufeng.gitee.io/mp-html/#/basic/event#linktap) 事件增加返回内部文本内容 `innerText` [详细](https://github.com/jin-yufeng/mp-html/issues/271) +2. `U` [selectable](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#selectable) 属性设置为 `force` 时能够在微信 `iOS` 端生效(文本块会变成 `inline-block`) [详细](https://github.com/jin-yufeng/mp-html/issues/267) +3. `F` 修复了部分情况下竖向无法滚动的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/182) +4. `F` 修复了多次修改富文本数据时部分内容可能不显示的问题 +5. `F` 修复了 [腾讯视频](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#txv-video) 插件可能无法播放的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/265) +6. `F` 修复了 [highlight](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#highlight) 插件没有设置高亮语言时没有应用默认样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/276) by [@fuzui](https://github.com/fuzui) diff --git a/uni_modules/mp-html/components/mp-html/mp-html.vue b/uni_modules/mp-html/components/mp-html/mp-html.vue new file mode 100644 index 0000000..a9b5dec --- /dev/null +++ b/uni_modules/mp-html/components/mp-html/mp-html.vue @@ -0,0 +1,498 @@ + + + + + diff --git a/uni_modules/mp-html/components/mp-html/node/node.vue b/uni_modules/mp-html/components/mp-html/node/node.vue new file mode 100644 index 0000000..372bcd1 --- /dev/null +++ b/uni_modules/mp-html/components/mp-html/node/node.vue @@ -0,0 +1,576 @@ +