diff --git a/common/betone_components/betone-list.vue b/common/betone_components/betone-list.vue index d4e17e3..1ec68b2 100644 --- a/common/betone_components/betone-list.vue +++ b/common/betone_components/betone-list.vue @@ -33,10 +33,13 @@ + 查看 + 下载 - 查看 + 提报 @@ -53,8 +56,7 @@ - 查看 + 接单 - 查看 + 审批 @@ -77,11 +78,10 @@ - 查看 + 确认 + type="primary" @click="openModel(item, 'submitOrder')">确认 驳回 - + - + @@ -127,18 +127,27 @@ 请确认付款是否已经完成? - - + + 请确认是否进行接单? + + + + + diff --git a/main.js b/main.js index b32d052..aa23260 100644 --- a/main.js +++ b/main.js @@ -20,6 +20,7 @@ const app = new Vue({ import request from '@/utils/request.js'; Vue.use(request, app); + // http接口API集中管理引入部分 import httpApi from '@/api/api.js' Vue.use(httpApi, app) diff --git a/manifest.json b/manifest.json index d131740..8e3d474 100644 --- a/manifest.json +++ b/manifest.json @@ -1,20 +1,20 @@ { - "name" : "科研医疗建筑运维平台", - "appid" : "__UNI__BB25171", - "description" : "", - "versionName" : "1.0.2", - "versionCode" : 1, - "transformPx" : false, - "app-plus" : { - "nvueCompiler" : "uni-app", - "compilerVersion" : 3, - "modules" : { - "Geolocation" : {}, - "Maps" : {} + "name": "科研医疗建筑运维平台", + "appid": "__UNI__BB25171", + "description": "", + "versionName": "1.0.2", + "versionCode": 1, + "transformPx": false, + "app-plus": { + "nvueCompiler": "uni-app", + "compilerVersion": 3, + "modules": { + "Geolocation": {}, + "Maps": {} }, - "distribute" : { - "android" : { - "permissions" : [ + "distribute": { + "android": { + "permissions": [ "", "", "", @@ -34,102 +34,106 @@ "", "", "", - "" + "", + "" ], - "minSdkVersion" : 19, - "targetSdkVersion" : 28 + "minSdkVersion": 19, + "targetSdkVersion": 28 }, - "ios" : { - "privacyDescription" : { - "NSLocationWhenInUseUsageDescription" : "", - "NSLocationAlwaysUsageDescription" : "", - "NSLocationAlwaysAndWhenInUseUsageDescription" : "" + "ios": { + "privacyDescription": { + "NSLocationWhenInUseUsageDescription": "", + "NSLocationAlwaysUsageDescription": "", + "NSLocationAlwaysAndWhenInUseUsageDescription": "" }, - "idfa" : false, - "UIBackgroundModes" : "audio,location", - "dSYMs" : false + "idfa": false, + "UIBackgroundModes": "audio,location", + "dSYMs": false }, - "sdkConfigs" : { - "ad" : {}, - "push" : { - "unipush" : {} + "sdkConfigs": { + "ad": {}, + "push": { + "unipush": {} }, - "maps" : { - "amap" : { - "name" : "amapAjPJDZFvd", - "appkey_ios" : "a9632baa2c4ae13a34c1fb265dda41f5", - "appkey_android" : "a9632baa2c4ae13a34c1fb265dda41f5" + "maps": { + "amap": { + "name": "amapAjPJDZFvd", + "appkey_ios": "a9632baa2c4ae13a34c1fb265dda41f5", + "appkey_android": "a9632baa2c4ae13a34c1fb265dda41f5" } }, - "geolocation" : { - "system" : { - "__platform__" : [ "ios", "android" ] + "geolocation": { + "system": { + "__platform__": [ + "ios", + "android" + ] } } }, - "icons" : { - "android" : { - "hdpi" : "unpackage/res/icons/72x72.png", - "xhdpi" : "unpackage/res/icons/96x96.png", - "xxhdpi" : "unpackage/res/icons/144x144.png", - "xxxhdpi" : "unpackage/res/icons/192x192.png" + "icons": { + "android": { + "hdpi": "unpackage/res/icons/72x72.png", + "xhdpi": "unpackage/res/icons/96x96.png", + "xxhdpi": "unpackage/res/icons/144x144.png", + "xxxhdpi": "unpackage/res/icons/192x192.png" }, - "ios" : { - "appstore" : "unpackage/res/icons/1024x1024.png", - "ipad" : { - "app" : "unpackage/res/icons/76x76.png", - "app@2x" : "unpackage/res/icons/152x152.png", - "notification" : "unpackage/res/icons/20x20.png", - "notification@2x" : "unpackage/res/icons/40x40.png", - "proapp@2x" : "unpackage/res/icons/167x167.png", - "settings" : "unpackage/res/icons/29x29.png", - "settings@2x" : "unpackage/res/icons/58x58.png", - "spotlight" : "unpackage/res/icons/40x40.png", - "spotlight@2x" : "unpackage/res/icons/80x80.png" + "ios": { + "appstore": "unpackage/res/icons/1024x1024.png", + "ipad": { + "app": "unpackage/res/icons/76x76.png", + "app@2x": "unpackage/res/icons/152x152.png", + "notification": "unpackage/res/icons/20x20.png", + "notification@2x": "unpackage/res/icons/40x40.png", + "proapp@2x": "unpackage/res/icons/167x167.png", + "settings": "unpackage/res/icons/29x29.png", + "settings@2x": "unpackage/res/icons/58x58.png", + "spotlight": "unpackage/res/icons/40x40.png", + "spotlight@2x": "unpackage/res/icons/80x80.png" }, - "iphone" : { - "app@2x" : "unpackage/res/icons/120x120.png", - "app@3x" : "unpackage/res/icons/180x180.png", - "notification@2x" : "unpackage/res/icons/40x40.png", - "notification@3x" : "unpackage/res/icons/60x60.png", - "settings@2x" : "unpackage/res/icons/58x58.png", - "settings@3x" : "unpackage/res/icons/87x87.png", - "spotlight@2x" : "unpackage/res/icons/80x80.png", - "spotlight@3x" : "unpackage/res/icons/120x120.png" + "iphone": { + "app@2x": "unpackage/res/icons/120x120.png", + "app@3x": "unpackage/res/icons/180x180.png", + "notification@2x": "unpackage/res/icons/40x40.png", + "notification@3x": "unpackage/res/icons/60x60.png", + "settings@2x": "unpackage/res/icons/58x58.png", + "settings@3x": "unpackage/res/icons/87x87.png", + "spotlight@2x": "unpackage/res/icons/80x80.png", + "spotlight@3x": "unpackage/res/icons/120x120.png" } } } }, - "nativePlugins" : {} + "nativePlugins": {} }, - "compatible" : { - "runtimeVersion" : "2.9.2", - "compilerVersion" : "2.9.5", - "ignoreVersion" : true + "compatible": { + "runtimeVersion": "2.9.2", + "compilerVersion": "2.9.5", + "ignoreVersion": true }, //"ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持 - "quickapp" : {}, - "mp-weixin" : { - "appid" : "wx81368cd255de5182", - "setting" : { - "urlCheck" : true, - "minified" : true + "quickapp": {}, + "mp-weixin": { + "appid": "wx81368cd255de5182", + "setting": { + "urlCheck": true, + "minified": true }, - "lazyCodeLoading" : "requiredComponents", - "optimization" : { - "subPackages" : true + "lazyCodeLoading": "requiredComponents", + "optimization": { + "subPackages": true }, - "permission" : {} + "permission": {} }, - "h5" : { - "sdkConfigs" : { - "maps" : { - "amap" : { - "key" : "a35a37c732890b60c4ff0aadd318d0aa", - "securityJsCode" : "7b6d007df2a0d16719b34ec5b7fce504", - "serviceHost" : "" + "h5": { + "sdkConfigs": { + "maps": { + "amap": { + "key": "a35a37c732890b60c4ff0aadd318d0aa", + "securityJsCode": "7b6d007df2a0d16719b34ec5b7fce504", + "serviceHost": "" } } } } -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 92329c8..f43aca4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,79 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "@types/raf": { + "version": "3.4.3", + "resolved": "https://registry.npmmirror.com/@types/raf/-/raf-3.4.3.tgz", + "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==", + "optional": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==" + }, + "btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" + }, + "canvg": { + "version": "3.0.10", + "resolved": "https://registry.npmmirror.com/canvg/-/canvg-3.0.10.tgz", + "integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==", + "optional": true, + "requires": { + "@babel/runtime": "^7.12.5", + "@types/raf": "^3.4.0", + "core-js": "^3.8.3", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.7", + "rgbcolor": "^1.0.1", + "stackblur-canvas": "^2.0.0", + "svg-pathdata": "^6.0.3" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "optional": true + } + } + }, + "core-js": { + "version": "3.39.0", + "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "optional": true + }, + "css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "requires": { + "utrie": "^1.0.2" + } + }, + "dompurify": { + "version": "2.5.7", + "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-2.5.7.tgz", + "integrity": "sha512-2q4bEI+coQM8f5ez7kt2xclg1XsecaV9ASJk/54vwlfRRNQfDqJz2pzQ8t0Ix/ToBpXlVjrRIx7pFC/o8itG2Q==", + "optional": true + }, "echarts": { "version": "5.5.1", "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz", @@ -13,11 +86,40 @@ "zrender": "5.6.0" } }, + "fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" + }, + "html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "requires": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + } + }, "jsbn": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" }, + "jspdf": { + "version": "2.5.2", + "resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-2.5.2.tgz", + "integrity": "sha512-myeX9c+p7znDWPk0eTrujCzNjT+CXdXyk7YmJq5nD5V7uLLKmSXnlQ/Jn/kuo3X09Op70Apm0rQSnFWyGK8uEQ==", + "requires": { + "@babel/runtime": "^7.23.2", + "atob": "^2.1.2", + "btoa": "^1.2.1", + "canvg": "^3.0.6", + "core-js": "^3.6.0", + "dompurify": "^2.5.4", + "fflate": "^0.8.1", + "html2canvas": "^1.0.0-rc.5" + } + }, "miniprogram-sm-crypto": { "version": "0.3.13", "resolved": "https://registry.npmmirror.com/miniprogram-sm-crypto/-/miniprogram-sm-crypto-0.3.13.tgz", @@ -26,6 +128,32 @@ "jsbn": "^1.1.0" } }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "optional": true + }, + "raf": { + "version": "3.4.1", + "resolved": "https://registry.npmmirror.com/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "optional": true, + "requires": { + "performance-now": "^2.1.0" + } + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "rgbcolor": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/rgbcolor/-/rgbcolor-1.0.1.tgz", + "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==", + "optional": true + }, "sm-crypto": { "version": "0.3.13", "resolved": "https://registry.npmmirror.com/sm-crypto/-/sm-crypto-0.3.13.tgz", @@ -34,11 +162,39 @@ "jsbn": "^1.1.0" } }, + "stackblur-canvas": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz", + "integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==", + "optional": true + }, + "svg-pathdata": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/svg-pathdata/-/svg-pathdata-6.0.3.tgz", + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "optional": true + }, + "text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "requires": { + "utrie": "^1.0.2" + } + }, "tslib": { "version": "2.3.0", "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" }, + "utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "requires": { + "base64-arraybuffer": "^1.0.2" + } + }, "zrender": { "version": "5.6.0", "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz", diff --git a/package.json b/package.json index 55b1673..58455d7 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "license": "ISC", "dependencies": { "echarts": "^5.5.1", + "html2canvas": "^1.4.1", + "jspdf": "^2.5.2", "miniprogram-sm-crypto": "^0.3.13", "sm-crypto": "^0.3.13" } diff --git a/pages/inspection/components/details.vue b/pages/inspection/components/details.vue new file mode 100644 index 0000000..19b2638 --- /dev/null +++ b/pages/inspection/components/details.vue @@ -0,0 +1,299 @@ + + + \ No newline at end of file diff --git a/pages/inspection/quest.vue b/pages/inspection/quest.vue index d9f0613..ca2258a 100644 --- a/pages/inspection/quest.vue +++ b/pages/inspection/quest.vue @@ -37,6 +37,8 @@ 查看 + 下载 @@ -111,13 +113,22 @@ + + + + diff --git a/pages/submission/components/details.vue b/pages/submission/components/details.vue new file mode 100644 index 0000000..dc87bb6 --- /dev/null +++ b/pages/submission/components/details.vue @@ -0,0 +1,538 @@ + + + \ No newline at end of file diff --git a/pages/submission/recordsdetails.vue b/pages/submission/recordsdetails.vue index 4f68b43..06e3a9c 100644 --- a/pages/submission/recordsdetails.vue +++ b/pages/submission/recordsdetails.vue @@ -1,7 +1,8 @@ + + + + + diff --git a/uni_modules/sp-html2canvas-render/package.json b/uni_modules/sp-html2canvas-render/package.json new file mode 100644 index 0000000..1e91cbb --- /dev/null +++ b/uni_modules/sp-html2canvas-render/package.json @@ -0,0 +1,86 @@ +{ + "id": "sp-html2canvas-render", + "displayName": "基于html2canvas和renderjs 指定盒子截图 截屏 截长屏", + "version": "1.2.3", + "description": "基于html2canvas和renderjs的页面指定盒子截图,截屏,可截长屏,页面生成图片", + "keywords": [ + "截图", + "截屏", + "截长屏", + "生成图片", + "html2canvas" +], + "repository": "", + "engines": { + "HBuilderX": "^3.8.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y", + "alipay": "n" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/sp-html2canvas-render/readme.md b/uni_modules/sp-html2canvas-render/readme.md new file mode 100644 index 0000000..536aee2 --- /dev/null +++ b/uni_modules/sp-html2canvas-render/readme.md @@ -0,0 +1,11 @@ +# sp-html2canvas-render + +### 文档迁移 + +> 防止文档失效,提供下列五个地址,内容一致 + +- [地址一](https://sonvee.github.io/sv-app-docs/docs-github/src/plugins/sp-html2canvas-render/sp-html2canvas-render.html) +- [地址二](https://sv-app-docs.pages.dev/src/plugins/sp-html2canvas-render/sp-html2canvas-render.html) +- [地址三](https://sv-app-docs.4everland.app/src/plugins/sp-html2canvas-render/sp-html2canvas-render.html) +- [地址四](https://sv-app-docs.vercel.app/src/plugins/sp-html2canvas-render/sp-html2canvas-render.html) (需要梯子) +- [地址五](https://static-mp-74bfcbac-6ba6-4f39-8513-8831390ff75a.next.bspapp.com/docs-uni/src/plugins/sp-html2canvas-render/sp-html2canvas-render.html) (有IP限制) diff --git a/uni_modules/sp-html2canvas-render/utils/index.js b/uni_modules/sp-html2canvas-render/utils/index.js new file mode 100644 index 0000000..1ef6bc0 --- /dev/null +++ b/uni_modules/sp-html2canvas-render/utils/index.js @@ -0,0 +1,255 @@ +function getLocalFilePath(path) { + if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf( + '_downloads') === 0) { + return path + } + if (path.indexOf('file://') === 0) { + return path + } + if (path.indexOf('/storage/emulated/0/') === 0) { + return path + } + if (path.indexOf('/') === 0) { + let localFilePath = plus.io.convertAbsoluteFileSystem(path) + if (localFilePath !== path) { + return localFilePath + } else { + path = path.substr(1) + } + } + return '_www/' + path +} + +function dataUrlToBase64(str) { + let array = str.split(',') + return array[array.length - 1] +} + +let index = 0 + +function getNewFileId() { + return Date.now() + String(index++) +} + +function biggerThan(v1, v2) { + let v1Array = v1.split('.') + let v2Array = v2.split('.') + let update = false + for (let index = 0; index < v2Array.length; index++) { + let diff = v1Array[index] - v2Array[index] + if (diff !== 0) { + update = diff > 0 + break + } + } + return update +} + +export function pathToBase64(path) { + return new Promise(function(resolve, reject) { + if (typeof window === 'object' && 'document' in window) { + if (typeof FileReader === 'function') { + let xhr = new XMLHttpRequest() + xhr.open('GET', path, true) + xhr.responseType = 'blob' + xhr.onload = function() { + if (this.status === 200) { + let fileReader = new FileReader() + fileReader.onload = function(e) { + resolve(e.target.result) + } + fileReader.onerror = reject + fileReader.readAsDataURL(this.response) + } + } + xhr.onerror = reject + xhr.send() + return + } + let canvas = document.createElement('canvas') + let c2x = canvas.getContext('2d') + let img = new Image + img.onload = function() { + canvas.width = img.width + canvas.height = img.height + c2x.drawImage(img, 0, 0) + resolve(canvas.toDataURL()) + canvas.height = canvas.width = 0 + } + img.onerror = reject + img.src = path + return + } + if (typeof plus === 'object') { + plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) { + entry.file(function(file) { + let fileReader = new plus.io.FileReader() + fileReader.onload = function(data) { + resolve(data.target.result) + } + fileReader.onerror = function(error) { + reject(error) + } + fileReader.readAsDataURL(file) + }, function(error) { + reject(error) + }) + }, function(error) { + reject(error) + }) + return + } + if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { + wx.getFileSystemManager().readFile({ + filePath: path, + encoding: 'base64', + success: function(res) { + resolve('data:image/png;base64,' + res.data) + }, + fail: function(error) { + reject(error) + } + }) + return + } + reject(new Error('not support')) + }) +} + +export function base64ToPath(base64) { + return new Promise(function(resolve, reject) { + if (typeof window === 'object' && 'document' in window) { + base64 = base64.split(',') + let type = base64[0].match(/:(.*?);/)[1] + let str = atob(base64[1]) + let n = str.length + let array = new Uint8Array(n) + while (n--) { + array[n] = str.charCodeAt(n) + } + return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { + type: type + }))) + } + let extName = base64.split(',')[0].match(/data\:\S+\/(\S+);/) + if (extName) { + extName = extName[1] + } else { + reject(new Error('base64 error')) + } + let fileName = getNewFileId() + '.' + extName + if (typeof plus === 'object') { + let basePath = '_doc' + let dirPath = 'uniapp_temp' + let filePath = basePath + '/' + dirPath + '/' + fileName + if (!biggerThan(plus.os.name === 'Android' ? '1.9.9.80627' : '1.9.9.80472', plus.runtime.innerVersion)) { + plus.io.resolveLocalFileSystemURL(basePath, function(entry) { + entry.getDirectory(dirPath, { + create: true, + exclusive: false, + }, function(entry) { + entry.getFile(fileName, { + create: true, + exclusive: false, + }, function(entry) { + entry.createWriter(function(writer) { + writer.onwrite = function() { + resolve(filePath) + } + writer.onerror = reject + writer.seek(0) + writer.writeAsBinary(dataUrlToBase64(base64)) + }, reject) + }, reject) + }, reject) + }, reject) + return + } + let bitmap = new plus.nativeObj.Bitmap(fileName) + bitmap.loadBase64Data(base64, function() { + bitmap.save(filePath, {}, function() { + bitmap.clear() + resolve(filePath) + }, function(error) { + bitmap.clear() + reject(error) + }) + }, function(error) { + bitmap.clear() + reject(error) + }) + return + } + if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { + let filePath = wx.env.USER_DATA_PATH + '/' + fileName + wx.getFileSystemManager().writeFile({ + filePath: filePath, + data: dataUrlToBase64(base64), + encoding: 'base64', + success: function() { + resolve(filePath) + }, + fail: function(error) { + reject(error) + } + }) + return + } + reject(new Error('not support')) + }) +} + +/** + * 图片地址转换为base64格式图片 + * @param {string} url 图片地址 网络地址 本地相对路径 + * @param {string} type base64图片类型 默认png + */ +export function urlToBase64(url, type = 'png') { + let promises + + // 网络地址 或者h5端本地相对路径 可使用request方式 + promises = new Promise((resolve, reject) => { + uni.request({ + url: url, + method: 'GET', + responseType: 'arraybuffer', + success: (res) => { + const base64 = `data:image/${type};base64,${uni.arrayBufferToBase64(res.data)}` + resolve(base64); + }, + fail: (err) => { + reject(err); + }, + }) + }) + + // #ifdef APP + if (!url.startsWith('http')) { + // app真机本地相对路径 + promises = new Promise((resolve, reject) => { + // 使用compressImage获取到安卓本地路径file:///... + uni.compressImage({ + src: url, + quality: 100, + success: (res) => { + const tempUrl = res.tempFilePath + plus.io.resolveLocalFileSystemURL(tempUrl, (entry) => { + entry.file((e) => { + let fileReader = new plus.io.FileReader(); + fileReader.onload = (r) => { + resolve(r.target.result) + } + fileReader.readAsDataURL(e) + }) + }) + }, + fail: (err) => { + reject(err); + }, + }) + }) + } + // #endif + + return promises +} \ No newline at end of file diff --git a/uni_modules/sp-html2pdf-render/changelog.md b/uni_modules/sp-html2pdf-render/changelog.md new file mode 100644 index 0000000..4fed5eb --- /dev/null +++ b/uni_modules/sp-html2pdf-render/changelog.md @@ -0,0 +1,34 @@ +## 1.1.2(2024-06-06) +1. pdf添加页头页尾占位 +## 1.1.1(2024-06-05) +1. 修复ios无法导出的问题 +## 1.1.0(2024-05-13) +1. 新增openPDF实例事件,以便于关闭autoOpen的之后,方便在任何时机一键重新打开文档 +## 1.0.9(2024-05-13) +1. 处理加载loading有延时问题和部分场景下未正常关闭问题 +## 1.0.8(2024-05-08) +1. 修改原util.js路径为@/uni_modules/sp-html2pdf-render/utils/index.js +## 1.0.7(2024-05-08) +1. 更新示例工程 +2. 修改原renderCanvas事件名为renderOver +3. 移除原afterSavePDF事件 +4. 新增autoOpen属性 +5. 文档迁移 +## 1.0.6(2024-03-18) +1. 新增pdfFileName属性,以自定义导出pdf的文件名,为空则默认以当前时间戳命名 +2. 更新文档 +## 1.0.5(2024-02-06) +1. 更新文档 +## 1.0.4(2024-02-06) +1. 重大更新,详情见文档 +2. 示例工程更新 +## 1.0.3(2024-02-06) +1. 更新文档 +## 1.0.2(2024-02-06) +1. 更新示例工程 +2. 插件优化,建议时刻保持最新版插件 +## 1.0.1(2024-02-05) +1. 更新示例工程,包括但不限于内联使用示例 +## 1.0.0(2023-10-24) +1. 发布插件 +2. 使用方式详见下文或示例项目 diff --git a/uni_modules/sp-html2pdf-render/components/sp-html2pdf-render/sp-html2pdf-render.vue b/uni_modules/sp-html2pdf-render/components/sp-html2pdf-render/sp-html2pdf-render.vue new file mode 100644 index 0000000..a29b2bb --- /dev/null +++ b/uni_modules/sp-html2pdf-render/components/sp-html2pdf-render/sp-html2pdf-render.vue @@ -0,0 +1,277 @@ + + + + + + + + diff --git a/uni_modules/sp-html2pdf-render/package.json b/uni_modules/sp-html2pdf-render/package.json new file mode 100644 index 0000000..f40af89 --- /dev/null +++ b/uni_modules/sp-html2pdf-render/package.json @@ -0,0 +1,85 @@ +{ + "id": "sp-html2pdf-render", + "displayName": "基于html2canvas+jspdf的截图导出成pdf", + "version": "1.1.2", + "description": "html转pdf,html转canvas,pdf文件保存导出分享,指定渲染的盒子导出图片截图或者pdf文件。", + "keywords": [ + "html2pdf", + "html2canvas", + "pdf", + "canvas" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y", + "alipay": "n" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "u", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/sp-html2pdf-render/readme.md b/uni_modules/sp-html2pdf-render/readme.md new file mode 100644 index 0000000..ac58731 --- /dev/null +++ b/uni_modules/sp-html2pdf-render/readme.md @@ -0,0 +1,11 @@ +# sp-html2pdf-render + +### 文档迁移 + +> 防止文档失效,提供下列五个地址,内容一致 + +- [地址一](https://sonvee.github.io/sv-app-docs/docs-github/src/plugins/sp-html2pdf-render/sp-html2pdf-render.html) +- [地址二](https://sv-app-docs.pages.dev/src/plugins/sp-html2pdf-render/sp-html2pdf-render.html) +- [地址三](https://sv-app-docs.4everland.app/src/plugins/sp-html2pdf-render/sp-html2pdf-render.html) +- [地址四](https://sv-app-docs.vercel.app/src/plugins/sp-html2pdf-render/sp-html2pdf-render.html) (需要梯子) +- [地址五](https://static-mp-74bfcbac-6ba6-4f39-8513-8831390ff75a.next.bspapp.com/docs-uni/src/plugins/sp-html2pdf-render/sp-html2pdf-render.html) (有IP限制) diff --git a/uni_modules/sp-html2pdf-render/utils/index.js b/uni_modules/sp-html2pdf-render/utils/index.js new file mode 100644 index 0000000..2fc40c9 --- /dev/null +++ b/uni_modules/sp-html2pdf-render/utils/index.js @@ -0,0 +1,261 @@ +function getLocalFilePath(path) { + if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf( + '_downloads') === 0) { + return path + } + if (path.indexOf('file://') === 0) { + return path + } + if (path.indexOf('/storage/emulated/0/') === 0) { + return path + } + if (path.indexOf('/') === 0) { + let localFilePath = plus.io.convertAbsoluteFileSystem(path) + if (localFilePath !== path) { + return localFilePath + } else { + path = path.substr(1) + } + } + return '_www/' + path +} + +function dataUrlToBase64(str) { + let array = str.split(',') + return array[array.length - 1] +} + +let index = 0 + +function getNewFileId() { + return Date.now() + String(index++) +} + +function biggerThan(v1, v2) { + let v1Array = v1.split('.') + let v2Array = v2.split('.') + let update = false + for (let index = 0; index < v2Array.length; index++) { + let diff = v1Array[index] - v2Array[index] + if (diff !== 0) { + update = diff > 0 + break + } + } + return update +} + +export function pathToBase64(path) { + return new Promise(function(resolve, reject) { + if (typeof window === 'object' && 'document' in window) { + if (typeof FileReader === 'function') { + let xhr = new XMLHttpRequest() + xhr.open('GET', path, true) + xhr.responseType = 'blob' + xhr.onload = function() { + if (this.status === 200) { + let fileReader = new FileReader() + fileReader.onload = function(e) { + resolve(e.target.result) + } + fileReader.onerror = reject + fileReader.readAsDataURL(this.response) + } + } + xhr.onerror = reject + xhr.send() + return + } + let canvas = document.createElement('canvas') + let c2x = canvas.getContext('2d') + let img = new Image + img.onload = function() { + canvas.width = img.width + canvas.height = img.height + c2x.drawImage(img, 0, 0) + resolve(canvas.toDataURL()) + canvas.height = canvas.width = 0 + } + img.onerror = reject + img.src = path + return + } + if (typeof plus === 'object') { + plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) { + entry.file(function(file) { + let fileReader = new plus.io.FileReader() + fileReader.onload = function(data) { + resolve(data.target.result) + } + fileReader.onerror = function(error) { + reject(error) + } + fileReader.readAsDataURL(file) + }, function(error) { + reject(error) + }) + }, function(error) { + reject(error) + }) + return + } + if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { + wx.getFileSystemManager().readFile({ + filePath: path, + encoding: 'base64', + success: function(res) { + resolve('data:image/png;base64,' + res.data) + }, + fail: function(error) { + reject(error) + } + }) + return + } + reject(new Error('not support')) + }) +} + +export function base64ToPath(base64, filename) { + return new Promise(function(resolve, reject) { + // web端 + if (typeof window === 'object' && 'document' in window) { + base64 = base64.split(',') + let type = base64[0].match(/:(.*?);/)[1] + let str = atob(base64[1]) + let n = str.length + let array = new Uint8Array(n) + while (n--) { + array[n] = str.charCodeAt(n) + } + return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { + type: type + }))) + } + + // 移动端 + let extName = base64.split(',')[0].match(/data\:\S+\/(\S+);/) + // extName 示例为 ["data:application/pdf;filename=generated.pdf;", "pdf;filename=generated.pdf"] + if (extName) { + extName = extName[1].split(';')[0] + } else { + reject(new Error('base64 error')) + } + + let fileName = (filename || Date.now()) + '.' + extName + + if (typeof plus === 'object') { + let basePath = '_doc' + let dirPath = 'uniapp_temp' + let filePath = basePath + '/' + dirPath + '/' + fileName + if (!biggerThan(plus.os.name === 'Android' ? '1.9.9.80627' : '1.9.9.80472', plus.runtime.innerVersion)) { + plus.io.resolveLocalFileSystemURL(basePath, function(entry) { + entry.getDirectory(dirPath, { + create: true, + exclusive: false, + }, function(entry) { + entry.getFile(fileName, { + create: true, + exclusive: false, + }, function(entry) { + entry.createWriter(function(writer) { + writer.onwrite = function() { + resolve(filePath) + } + writer.onerror = reject + writer.seek(0) + writer.writeAsBinary(dataUrlToBase64(base64)) + }, reject) + }, reject) + }, reject) + }, reject) + return + } + let bitmap = new plus.nativeObj.Bitmap(fileName) + bitmap.loadBase64Data(base64, function() { + bitmap.save(filePath, {}, function() { + bitmap.clear() + resolve(filePath) + }, function(error) { + bitmap.clear() + reject(error) + }) + }, function(error) { + bitmap.clear() + reject(error) + }) + return + } + if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { + let filePath = wx.env.USER_DATA_PATH + '/' + fileName + wx.getFileSystemManager().writeFile({ + filePath: filePath, + data: dataUrlToBase64(base64), + encoding: 'base64', + success: function() { + resolve(filePath) + }, + fail: function(error) { + reject(error) + } + }) + return + } + reject(new Error('not support')) + }) +} + +/** + * 图片地址转换为base64格式图片 + * @param {string} url 图片地址 网络地址 本地相对路径 + * @param {string} type base64图片类型 默认png + */ +export function urlToBase64(url, type = 'png') { + let promises + + // 网络地址 或者h5端本地相对路径 可使用request方式 + promises = new Promise((resolve, reject) => { + uni.request({ + url: url, + method: 'GET', + responseType: 'arraybuffer', + success: (res) => { + const base64 = `data:image/${type};base64,${uni.arrayBufferToBase64(res.data)}` + resolve(base64); + }, + fail: (err) => { + reject(err); + }, + }) + }) + + // #ifdef APP + if (!url.startsWith('http')) { + // app真机本地相对路径 + promises = new Promise((resolve, reject) => { + // 使用compressImage获取到安卓本地路径file:///... + uni.compressImage({ + src: url, + quality: 100, + success: (res) => { + const tempUrl = res.tempFilePath + plus.io.resolveLocalFileSystemURL(tempUrl, (entry) => { + entry.file((e) => { + let fileReader = new plus.io.FileReader(); + fileReader.onload = (r) => { + resolve(r.target.result) + } + fileReader.readAsDataURL(e) + }) + }) + }, + fail: (err) => { + reject(err); + }, + }) + }) + } + // #endif + + return promises +} \ No newline at end of file diff --git a/utils/website.js b/utils/website.js index e3714f8..7b0c62c 100644 --- a/utils/website.js +++ b/utils/website.js @@ -5,7 +5,7 @@ export default { // baseUrl: 'http://124.221.142.15:8088/lab', // baseUrl:'http://192.168.0.111:80', //李庆坤 // baseUrl:'http://192.168.0.109:80', //李涛 - baseUrl:'http://192.168.1.12:80', //李涛 + baseUrl:'http://192.168.0.113:80', //李涛 indexTitle: "科研医疗建筑运维平台", clientId: "saber", // 客户端id clientSecret: "saber_secret", // 客户端密钥