Browse Source

引入uview组件 图片上传 事件上传 需求上传表单实现 语音上传 语音回显还未做

master
mk 10 months ago
parent
commit
8cbafbf996
  1. 4
      App.vue
  2. 5
      main.js
  3. 3
      manifest.json
  4. 548
      package-lock.json
  5. 2
      package.json
  6. 3
      pages.json
  7. 1
      pages/statistics/modules/StayList/StayList.vue
  8. 7308
      subpages/demandCheck/pages/dissatisfied/demandCheck/demandCheck.vue
  9. 2
      uni.scss
  10. 6
      uni_modules/jia-cascader/changelog.md
  11. 15635
      uni_modules/jia-cascader/components/jia-cascader/area.json
  12. 409
      uni_modules/jia-cascader/components/jia-cascader/jia-cascader.vue
  13. 723
      uni_modules/jia-cascader/components/jia-cascader/select.vue
  14. 82
      uni_modules/jia-cascader/package.json
  15. 465
      uni_modules/jia-cascader/readme.md
  16. 4
      uni_modules/mumu-recorder/changelog.md
  17. 113
      uni_modules/mumu-recorder/components/mumu-recorder/mumu-recorder.vue
  18. 87
      uni_modules/mumu-recorder/package.json
  19. 117
      uni_modules/mumu-recorder/readme.md
  20. 11
      utils/config.js
  21. 5
      utils/util.js
  22. 264
      wxcomponents/vant/cascader/index.vue
  23. 42
      wxcomponents/vant/wxs/style.wxs
  24. 12
      wxcomponents/vant/wxs/wxs/add-unit.wxs
  25. 5
      wxcomponents/vant/wxs/wxs/array.wxs
  26. 39
      wxcomponents/vant/wxs/wxs/bem.wxs
  27. 55
      wxcomponents/vant/wxs/wxs/memoize.wxs
  28. 13
      wxcomponents/vant/wxs/wxs/object.wxs
  29. 10
      wxcomponents/vant/wxs/wxs/utils.wxs

4
App.vue

@ -55,6 +55,10 @@ export default {
}
};
</script>
<style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
@import "uview-ui/index.scss";
</style>
<style>
/**app.wxss**/
.container {

5
main.js

@ -8,8 +8,9 @@ import Vue from 'vue';
Vue.use(zpMixins);
Vue.config.productionTip = false;
App.mpType = 'app';
// import Vant from 'vant';
// Vue.use(Vant);
// main.js
import uView from "uview-ui";
Vue.use(uView);
const app = new Vue({
...App
});

3
manifest.json

@ -102,6 +102,9 @@
"uniStatistics" : {
"enable" : false
},
"devServer":{
"https":true
},
"sdkConfigs" : {
"maps" : {
"qqmap" : {

548
package-lock.json

@ -1,13 +1,559 @@
{
"name": "epmet-work-mp",
"version": "1.0.0",
"lockfileVersion": 1,
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "epmet-work-mp",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@vant/weapp": "^1.11.4",
"uview-ui": "^2.0.36",
"vant": "^4.9.8"
},
"devDependencies": {}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.25.9.tgz",
"integrity": "sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==",
"peer": true,
"dependencies": {
"@babel/types": "^7.25.9"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/types": {
"version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.25.9.tgz",
"integrity": "sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==",
"peer": true,
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"peer": true
},
"node_modules/@vant/popperjs": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
"integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
},
"node_modules/@vant/use": {
"version": "1.6.0",
"resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
"integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/@vant/weapp": {
"version": "1.11.4",
"resolved": "https://registry.npmmirror.com/@vant/weapp/-/weapp-1.11.4.tgz",
"integrity": "sha512-egOsWO4hVMP1SQSqQ46jy8UD3WysvlnUecRzPM21Y3ovkOFZ6wlaO7oHQmTXRpwr+V41Qri1qEbtNjhVxFqdyw=="
},
"node_modules/@vue/compiler-core": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.12.tgz",
"integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.25.3",
"@vue/shared": "3.5.12",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz",
"integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==",
"peer": true,
"dependencies": {
"@vue/compiler-core": "3.5.12",
"@vue/shared": "3.5.12"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz",
"integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.25.3",
"@vue/compiler-core": "3.5.12",
"@vue/compiler-dom": "3.5.12",
"@vue/compiler-ssr": "3.5.12",
"@vue/shared": "3.5.12",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.11",
"postcss": "^8.4.47",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz",
"integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.12",
"@vue/shared": "3.5.12"
}
},
"node_modules/@vue/reactivity": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.12.tgz",
"integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==",
"peer": true,
"dependencies": {
"@vue/shared": "3.5.12"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.12.tgz",
"integrity": "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.5.12",
"@vue/shared": "3.5.12"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.12.tgz",
"integrity": "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.5.12",
"@vue/runtime-core": "3.5.12",
"@vue/shared": "3.5.12",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.12.tgz",
"integrity": "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==",
"peer": true,
"dependencies": {
"@vue/compiler-ssr": "3.5.12",
"@vue/shared": "3.5.12"
},
"peerDependencies": {
"vue": "3.5.12"
}
},
"node_modules/@vue/shared": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.12.tgz",
"integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"peer": true
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"peer": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"peer": true
},
"node_modules/magic-string": {
"version": "0.30.12",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.12.tgz",
"integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==",
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"peer": true
},
"node_modules/postcss": {
"version": "8.4.47",
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.47.tgz",
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"peer": true,
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.1.0",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/uview-ui": {
"version": "2.0.36",
"resolved": "https://registry.npmmirror.com/uview-ui/-/uview-ui-2.0.36.tgz",
"integrity": "sha512-ASSZT6M8w3GTO1eFPbsgEFV0U5UujK+8pTNr+MSUbRNcRMC1u63DDTLJVeArV91kWM0bfAexK3SK9pnTqF9TtA==",
"engines": {
"HBuilderX": "^3.1.0"
}
},
"node_modules/vant": {
"version": "4.9.8",
"resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.8.tgz",
"integrity": "sha512-iP+jNzwxkCeEdTrlUjro3WoXgY32+1CldOtLSc2K8acY7hR7t1zCkjzXSR9zWjtWT7zgNL1LEXofL8O7mtkYdQ==",
"dependencies": {
"@vant/popperjs": "^1.3.0",
"@vant/use": "^1.6.0",
"@vue/shared": "^3.5.11"
},
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/vue": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.12.tgz",
"integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.12",
"@vue/compiler-sfc": "3.5.12",
"@vue/runtime-dom": "3.5.12",
"@vue/server-renderer": "3.5.12",
"@vue/shared": "3.5.12"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
}
},
"dependencies": {
"@babel/helper-string-parser": {
"version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"peer": true
},
"@babel/helper-validator-identifier": {
"version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
"peer": true
},
"@babel/parser": {
"version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.25.9.tgz",
"integrity": "sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==",
"peer": true,
"requires": {
"@babel/types": "^7.25.9"
}
},
"@babel/types": {
"version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.25.9.tgz",
"integrity": "sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==",
"peer": true,
"requires": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
}
},
"@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"peer": true
},
"@vant/popperjs": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
"integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
},
"@vant/use": {
"version": "1.6.0",
"resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
"integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
"requires": {}
},
"@vant/weapp": {
"version": "1.11.4",
"resolved": "https://registry.npmmirror.com/@vant/weapp/-/weapp-1.11.4.tgz",
"integrity": "sha512-egOsWO4hVMP1SQSqQ46jy8UD3WysvlnUecRzPM21Y3ovkOFZ6wlaO7oHQmTXRpwr+V41Qri1qEbtNjhVxFqdyw=="
},
"@vue/compiler-core": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.12.tgz",
"integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==",
"peer": true,
"requires": {
"@babel/parser": "^7.25.3",
"@vue/shared": "3.5.12",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"@vue/compiler-dom": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz",
"integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==",
"peer": true,
"requires": {
"@vue/compiler-core": "3.5.12",
"@vue/shared": "3.5.12"
}
},
"@vue/compiler-sfc": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz",
"integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==",
"peer": true,
"requires": {
"@babel/parser": "^7.25.3",
"@vue/compiler-core": "3.5.12",
"@vue/compiler-dom": "3.5.12",
"@vue/compiler-ssr": "3.5.12",
"@vue/shared": "3.5.12",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.11",
"postcss": "^8.4.47",
"source-map-js": "^1.2.0"
}
},
"@vue/compiler-ssr": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz",
"integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==",
"peer": true,
"requires": {
"@vue/compiler-dom": "3.5.12",
"@vue/shared": "3.5.12"
}
},
"@vue/reactivity": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.12.tgz",
"integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==",
"peer": true,
"requires": {
"@vue/shared": "3.5.12"
}
},
"@vue/runtime-core": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.12.tgz",
"integrity": "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==",
"peer": true,
"requires": {
"@vue/reactivity": "3.5.12",
"@vue/shared": "3.5.12"
}
},
"@vue/runtime-dom": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.12.tgz",
"integrity": "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==",
"peer": true,
"requires": {
"@vue/reactivity": "3.5.12",
"@vue/runtime-core": "3.5.12",
"@vue/shared": "3.5.12",
"csstype": "^3.1.3"
}
},
"@vue/server-renderer": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.12.tgz",
"integrity": "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==",
"peer": true,
"requires": {
"@vue/compiler-ssr": "3.5.12",
"@vue/shared": "3.5.12"
}
},
"@vue/shared": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.12.tgz",
"integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="
},
"csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"peer": true
},
"entities": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"peer": true
},
"estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"peer": true
},
"magic-string": {
"version": "0.30.12",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.12.tgz",
"integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==",
"peer": true,
"requires": {
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"peer": true
},
"picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"peer": true
},
"postcss": {
"version": "8.4.47",
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.47.tgz",
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"peer": true,
"requires": {
"nanoid": "^3.3.7",
"picocolors": "^1.1.0",
"source-map-js": "^1.2.1"
}
},
"source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"peer": true
},
"uview-ui": {
"version": "2.0.36",
"resolved": "https://registry.npmmirror.com/uview-ui/-/uview-ui-2.0.36.tgz",
"integrity": "sha512-ASSZT6M8w3GTO1eFPbsgEFV0U5UujK+8pTNr+MSUbRNcRMC1u63DDTLJVeArV91kWM0bfAexK3SK9pnTqF9TtA=="
},
"vant": {
"version": "4.9.8",
"resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.8.tgz",
"integrity": "sha512-iP+jNzwxkCeEdTrlUjro3WoXgY32+1CldOtLSc2K8acY7hR7t1zCkjzXSR9zWjtWT7zgNL1LEXofL8O7mtkYdQ==",
"requires": {
"@vant/popperjs": "^1.3.0",
"@vant/use": "^1.6.0",
"@vue/shared": "^3.5.11"
}
},
"vue": {
"version": "3.5.12",
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.12.tgz",
"integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==",
"peer": true,
"requires": {
"@vue/compiler-dom": "3.5.12",
"@vue/compiler-sfc": "3.5.12",
"@vue/runtime-dom": "3.5.12",
"@vue/server-renderer": "3.5.12",
"@vue/shared": "3.5.12"
}
}
}
}

2
package.json

@ -9,10 +9,10 @@
"author": "",
"dependencies": {
"@vant/weapp": "^1.11.4",
"uview-ui": "^2.0.36",
"vant": "^4.9.8"
},
"license": "ISC",
"devDependencies": {},
"repository": {
"type": "git",
"url": "http://120.46.222.128:10021/elink-star/epmet-work-mp.git"

3
pages.json

@ -1,4 +1,7 @@
{
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
},
"pages": [
{
"path": "pages/index/index",

1
pages/statistics/modules/StayList/StayList.vue

@ -15,7 +15,6 @@
<script>
import noData from '../../../../components/noData/nodata';
import { icEventOldList, userdemandList } from '../../../../utils/statisticsApi';
import { formatTime } from '../../../../utils/util';
export default {
components: {
noData

7308
subpages/demandCheck/pages/dissatisfied/demandCheck/demandCheck.vue

File diff suppressed because it is too large

2
uni.scss

@ -13,7 +13,7 @@
*/
/* 颜色变量 */
@import 'uview-ui/theme.scss';
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;

6
uni_modules/jia-cascader/changelog.md

@ -0,0 +1,6 @@
## 1.0.2(2024-05-10)
修复attrs问题
## 1.0.1(2024-05-09)
修复异步 默认值回填 问题
## 1.0.0(2024-05-01)
1.0.0

15635
uni_modules/jia-cascader/components/jia-cascader/area.json

File diff suppressed because it is too large

409
uni_modules/jia-cascader/components/jia-cascader/jia-cascader.vue

@ -0,0 +1,409 @@
<template>
<view class="uni-data-tree">
<slot :data="gridText">
<!-- 输入框 -->
<view class="uni-data-tree-input" @click="handleInput">
<view class="input-value" :class="{ 'input-value-border': border }">
<!-- 展示选择的值 -->
<scroll-view v-if="gridText" class="selected-area" scroll-x="true">
<view class="selected-list">
<view class="selected-item">
<text>{{ gridText }}</text>
</view>
</view>
</scroll-view>
<!-- 提示信息 -->
<text v-else class="selected-area placeholder">{{ placeholder }}</text>
<!-- 展示删除按钮 -->
<view v-if="clearIcon && !readonly && gridText" class="icon-clear" @click.stop="clear">
<view class="dialog-close">
<view class="dialog-close-plus" data-id="close"></view>
<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
</view>
</view>
<!-- 展示下拉图标 -->
<view class="arrow-area" v-if="(!clearIcon || !gridText) && !readonly">
<view class="input-arrow"></view>
</view>
</view>
</view>
</slot>
<!-- 遮罩层 -->
<view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
<!-- 弹出层 -->
<view class="uni-data-tree-dialog" v-show="isOpened">
<view class="uni-popper__arrow"></view>
<view class="dialog-caption">
<view class="title-area">
<text class="dialog-title">{{ popupTitle }}</text>
</view>
<view class="dialog-close" @click="handleClose">
<view class="dialog-close-plus" data-id="close"></view>
<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
</view>
</view>
<tui-cascade-selection ref="gridSelet" v-bind="$attrs" @complete="complete" @change="onChange"></tui-cascade-selection>
</view>
</view>
</template>
<script>
import tuiCascadeSelection from './select.vue';
export default {
name: 'grid-cascade-selection',
data() {
return {
isOpened: false,
gridText: ''
};
},
components: {
tuiCascadeSelection
},
emits: ['popupopened', 'popupclosed', 'completeChange', 'inputChange'],
props: {
placeholder: {
type: String,
default: '请选择'
},
popupTitle: {
type: String,
default: '请选择'
},
readonly: {
type: Boolean,
default: false
},
clearIcon: {
type: Boolean,
default: true
},
border: {
type: Boolean,
default: true
}
},
created() {},
watch: {
'$attrs.defaultItemList': {
handler(newVal, oldVal) {
if (!(newVal === oldVal)) {
this.gridText = this.getInitValue();
}
}
}
},
methods: {
//
getInitValue() {
let { defaultItemList, request } = this.$attrs;
let list = JSON.parse(JSON.stringify(defaultItemList || []));
if ((typeof list[0] === 'string' || typeof list[0] === 'number') && !this.request) {
return list.join('/');
} else {
let selsctArr = [];
list.forEach((item) => {
selsctArr.push(item.text);
});
return selsctArr.join('/');
}
},
//
complete(e) {
console.log(e);
let list = JSON.parse(JSON.stringify(e.result || []));
let selsctArr = [];
list.forEach((item) => {
selsctArr.push(item.text);
});
this.gridText = selsctArr.join('/');
this.isOpened = false;
this.$emit('completeChange', e);
this.$emit('popupclosed');
},
//
show() {
this.isOpened = true;
this.$emit('popupopened');
},
//
onChange(e) {
this.$emit('inputChange', e);
},
//
hide() {
this.isOpened = false;
this.$emit('popupclosed');
},
//
handleInput() {
if (this.readonly) {
return;
}
this.show();
},
//
handleClose(e) {
this.hide();
},
//
clear() {
this.gridText = '';
this.$refs.gridSelet.clear();
}
}
};
</script>
<style>
.uni-data-tree {
position: relative;
font-size: 14px;
}
.error-text {
color: #dd524d;
}
.input-value {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
font-size: 14px;
line-height: 38px;
padding: 0 5px;
overflow: hidden;
/* #ifdef APP-NVUE */
height: 40px;
/* #endif */
}
.input-value-border {
border: 1px solid #e5e5e5;
border-radius: 5px;
}
.selected-area {
flex: 1;
overflow: hidden;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.load-more {
/* #ifndef APP-NVUE */
margin-right: auto;
/* #endif */
/* #ifdef APP-NVUE */
width: 40px;
/* #endif */
}
.selected-list {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: nowrap;
padding: 0 5px;
}
.selected-item {
flex-direction: row;
padding: 0 1px;
/* #ifndef APP-NVUE */
white-space: nowrap;
/* #endif */
}
.placeholder {
font-size: 24rpx;
color: #bbbbbb;
}
.input-split-line {
opacity: 0.5;
}
.arrow-area {
position: relative;
width: 20px;
/* #ifndef APP-NVUE */
margin-bottom: 5px;
margin-left: auto;
display: flex;
/* #endif */
justify-content: center;
transform: rotate(-45deg);
transform-origin: center;
}
.input-arrow {
width: 7px;
height: 7px;
border-left: 1px solid #999;
border-bottom: 1px solid #999;
}
.uni-data-tree-cover {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
z-index: 100;
}
.uni-data-tree-dialog {
position: fixed;
left: 0;
top: 20%;
right: 0;
bottom: 0;
background-color: #ffffff;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
z-index: 102;
overflow: hidden;
/* #ifdef APP-NVUE */
width: 750rpx;
/* #endif */
}
.dialog-caption {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
/* border-bottom: 1px solid #f0f0f0; */
}
.title-area {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
/* #ifndef APP-NVUE */
margin: auto;
/* #endif */
padding: 0 10px;
}
.dialog-title {
/* font-weight: bold; */
line-height: 44px;
}
.dialog-close {
position: absolute;
top: 0;
right: 0;
bottom: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 0 15px;
z-index: 999;
}
.dialog-close-plus {
width: 16px;
height: 2px;
background-color: #666;
border-radius: 2px;
transform: rotate(45deg);
}
.dialog-close-rotate {
position: absolute;
transform: rotate(-45deg);
}
.picker-view {
flex: 1;
overflow: hidden;
}
/* #ifdef H5 */
@media all and (min-width: 768px) {
.uni-data-tree-cover {
background-color: transparent;
}
.uni-data-tree-dialog {
position: absolute;
top: 55px;
/* height: auto; */
/* min-height: 400px; */
max-height: 50vh;
background-color: #fff;
border: 1px solid #ebeef5;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 4px;
overflow: unset;
}
.dialog-caption {
display: none;
}
.icon-clear {
margin-right: 5px;
}
}
/* #endif */
/* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
/* #ifndef APP-NVUE */
.uni-popper__arrow,
.uni-popper__arrow::after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 6px;
}
.uni-popper__arrow {
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
top: -6px;
left: 10%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #ebeef5;
}
.uni-popper__arrow::after {
content: ' ';
top: 1px;
margin-left: -6px;
border-top-width: 0;
border-bottom-color: #fff;
}
/* #endif */
</style>

723
uni_modules/jia-cascader/components/jia-cascader/select.vue

@ -0,0 +1,723 @@
<template>
<view class="tui-cascade-selection">
<!-- 头部导航栏 -->
<scroll-view
scroll-x
scroll-with-animation
:scroll-into-view="scrollViewId"
:style="{ backgroundColor: headerBgColor }"
class="tui-bottom-line"
:class="{ 'tui-btm-none': !headerLine }"
>
<view class="tui-selection-header" :style="{ height: tabsHeight, backgroundColor: backgroundColor }">
<view
class="tui-header-item"
:class="{ 'tui-font-bold': idx === currentTab && bold }"
:style="{ color: idx === currentTab ? getActiveColor : color, fontSize: size + 'rpx' }"
:id="`id_${idx}`"
@tap.stop="swichNav"
:data-current="idx"
v-for="(item, idx) in selectedArr"
:key="idx"
>
{{ item.text }}
<view class="tui-active-line" :style="{ backgroundColor: getLineColor }" v-if="idx === currentTab && showLine"></view>
</view>
</view>
</scroll-view>
<!-- 视图切换器 -->
<swiper class="tui-selection-list" :current="defTab" duration="300" @change="switchTab" :style="{ height: height, backgroundColor: backgroundColor }">
<swiper-item v-for="(item, index) in selectedArr" :key="index">
<scroll-view scroll-y :scroll-into-view="item.scrollViewId" class="tui-selection-item" :style="{ height: height }">
<view class="tui-first-item" :style="{ height: firstItemTop }"></view>
<view
class="tui-selection-cell"
:style="{ padding: padding, backgroundColor: backgroundColor }"
:id="`id_${subIndex}`"
v-for="(subItem, subIndex) in item.list"
:key="subIndex"
@tap.stop="change(index, subIndex, subItem)"
>
<icon type="success_no_circle" v-if="item.index === subIndex" :color="getCkMarkColor" :size="checkMarkSize" class="tui-icon-success"></icon>
<image :src="subItem.src" v-if="subItem.src" class="tui-cell-img" :style="{ width: imgWidth, height: imgHeight, borderRadius: radius }"></image>
<view
class="tui-cell-title"
:class="{ 'tui-font-bold': item.index === subIndex && textBold, 'tui-flex-shrink': nowrap }"
:style="{ color: item.index === subIndex ? textActiveColor : textColor, fontSize: textSize + 'rpx' }"
>
{{ subItem.text }}
</view>
<view class="tui-cell-sub_title" :style="{ color: subTextColor, fontSize: subTextSize + 'rpx' }" v-if="subItem.subText">{{ subItem.subText }}</view>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default {
props: {
/**
* 如果下一级是请求返回则为第一级数据否则所有数据
* 数据格式
[{
src: "",
text: "",
subText: "",
value: 0,
children:[{
text: "",
subText: "",
value: 0,
children:[]
}]
}]
* */
itemList: {
type: Array,
default: () => {
return [];
}
},
/*
初始化默认选中数据
[{
text: "",//text
subText: '',//subText
value: '',//value
src: '', //src
index: 0, //layer
list: [{src: "", text: "", subText: "", value: 101}] //layer
}];
*/
defaultItemList: {
type: Array,
default() {
return [];
}
},
defaultKey: {
type: String,
default: 'text'
},
//header线
headerLine: {
type: Boolean,
default: true
},
//header
headerBgColor: {
type: String,
default: '#FFFFFF'
},
//
tabsHeight: {
type: String,
default: '88rpx'
},
//
text: {
type: String,
default: '请选择'
},
//tabs
size: {
type: Number,
default: 28
},
//tabs
color: {
type: String,
default: '#555'
},
//
activeColor: {
type: String,
default: ''
},
//
bold: {
type: Boolean,
default: true
},
//线
showLine: {
type: Boolean,
default: true
},
//线
lineColor: {
type: String,
default: ''
},
//icon
checkMarkSize: {
type: Number,
default: 15
},
//icon
checkMarkColor: {
type: String,
default: ''
},
//item
imgWidth: {
type: String,
default: '40rpx'
},
//item
imgHeight: {
type: String,
default: '40rpx'
},
//
radius: {
type: String,
default: '50%'
},
//item text
textColor: {
type: String,
default: '#333'
},
textActiveColor: {
type: String,
default: '#333'
},
//
textBold: {
type: Boolean,
default: true
},
//item text
textSize: {
type: Number,
default: 28
},
//text
nowrap: {
type: Boolean,
default: false
},
//item subText
subTextColor: {
type: String,
default: '#999'
},
//item subText
subTextSize: {
type: Number,
default: 24
},
// item padding
padding: {
type: String,
default: '20rpx 30rpx'
},
//
firstItemTop: {
type: String,
default: '20rpx'
},
//swiper
height: {
type: String,
default: '410px'
},
//item swiper
backgroundColor: {
type: String,
default: '#FFFFFF'
},
//false
request: {
type: Boolean,
default: false
},
//request=true
receiveData: {
type: Array,
default: () => {
return [];
}
},
//
reset: {
type: [Number, String],
default: 0
}
},
computed: {
getActiveColor() {
return this.activeColor || (uni && uni.$tui && uni.$tui.color.primary) || '#5677fc';
},
getLineColor() {
return this.lineColor || (uni && uni.$tui && uni.$tui.color.primary) || '#5677fc';
},
getCkMarkColor() {
return this.checkMarkColor || (uni && uni.$tui && uni.$tui.color.primary) || '#5677fc';
}
},
watch: {
itemList(val) {
this.initData(val, -1);
},
receiveData(val) {
this.subLevelData(val, this.currentTab);
},
reset() {
this.initData(this.itemList, -1);
},
defaultItemList(val) {
this.setDefaultData(val);
}
},
data() {
return {
currentTab: 0, //
defTab: 0,
//tabscrollview
scrollViewId: 'id__1',
selectedArr: [] //
};
},
created() {
this.setDefaultData(this.defaultItemList);
},
methods: {
clear: function () {
this.initData(this.itemList, -1);
},
/**
* 切换当前激活的标签页
* @param {Object} e 事件对象携带切换后的当前标签页信息
* @returns 无返回值
*/
switchTab: function (e) {
//
this.currentTab = e.detail.current;
//
this.checkCor();
},
/**
* 检查并更新当前选项卡的滚动视图ID
* 该函数首先根据当前选中的选项卡索引更新一个指定对象的scrollViewId属性
* 然后根据选项卡的索引调整全局的scrollViewId
* 此函数不接受参数并且没有返回值
*/
checkCor: function () {
// scrollViewId
let item = this.selectedArr[this.currentTab];
item.scrollViewId = 'id__1';
// 使$nextTickDOMitemscrollViewId
this.$nextTick(() => {
setTimeout(() => {
// itemindexscrollViewIditemscrollViewId
let val = item.index < 2 ? 0 : Number(item.index - 2);
item.scrollViewId = `id_${val}`;
}, 20);
});
// TabscrollViewId
if (this.currentTab > 1) {
this.scrollViewId = `id_${this.currentTab - 1}`;
} else {
this.scrollViewId = `id_0`;
}
},
/**
* 初始化数据函数
* @param {Array} data 要初始化的数据数组
* @param {Number} layer 数据所在的层级
* @description 根据传入的数据和层级对数据进行初始化处理如果数据为空或不存在则不执行任何操作
* 如果已有请求则处理第一级数据否则根据选定的值或默认条件来处理数据
*/
initData(data, layer) {
//
if (!data || data.length === 0) return;
if (this.request) {
//
this.subLevelData(data, layer);
} else {
let selectedValue = this.selectedValue || {};
//
if (selectedValue.type) {
this.setDefaultData(selectedValue);
} else {
//
this.subLevelData(this.getItemList(layer, -1), layer);
}
}
},
/**
* 处理子级数据选择逻辑
* @param {Array} data - 提供选择的数据数组
* @param {number} layer - 当前选择的层级
* 完成选择时会通过$emit发送选择结果重置数据时更新selectedArr以备下次选择
*/
subLevelData(data, layer) {
//
if (!data || data.length === 0) {
if (layer == -1) return;
// selectedArr
let arr = this.selectedArr;
if (layer < arr.length - 1) {
let newArr = arr.slice(0, layer + 1);
this.selectedArr = newArr;
}
let result = JSON.parse(JSON.stringify(this.selectedArr));
let lastItem = result[result.length - 1] || {};
let text = '';
result.map((item) => {
text += item.text;
delete item['list'];
//
delete item['scrollViewId'];
return item;
});
//
this.$emit('complete', {
result: result,
value: lastItem.value,
text: text,
subText: lastItem.subText,
src: lastItem.src
});
} else {
// selectedArr
let item = [
{
text: this.text,
subText: '',
value: '',
src: '',
index: -1,
scrollViewId: 'id__1',
list: data
}
];
if (layer == -1) {
this.selectedArr = item;
} else {
let retainArr = this.selectedArr.slice(0, layer + 1) || [];
this.selectedArr = retainArr.concat(item);
}
// ID
let current = this.selectedArr.length - 1;
if (current >= this.currentTab) {
this.defTab = this.currentTab;
}
this.$nextTick(() => {
setTimeout(() => {
this.defTab = current;
this.currentTab = current;
// ID
this.scrollViewId = `id_${this.currentTab > 1 ? this.currentTab - 1 : 0}`;
}, 50);
});
}
},
/**
* 从数据中移除所有子项属性
* @param {Array} data - 包含具有子项属性的对象的数组
* @returns {Array} 返回一个移除了子项属性的新数组
*/
removeChildren(data) {
//
let list = data.map((item) => {
delete item['children'];
return item;
});
return list;
},
/**
* 根据指定层号和索引获取项目列表
* @param {number} layer - 层号用于指定要获取的项目列表所在的层级
* @param {number} index - 当前层的索引值用于指定要获取的具体项目
* @param {Array} selectedArr - 已选择的项目数组用于在多层选择时追踪已选择的项
* @returns {Array} 返回一个项目列表数组
*/
getItemList(layer, index, selectedArr) {
let list = [];
let arr = JSON.parse(JSON.stringify(this.itemList)); // itemList
selectedArr = selectedArr || this.selectedArr; // selectedArr使selectedArr
if (layer == -1) {
// layer-1
list = this.removeChildren(arr);
} else {
// layerindex
let value = selectedArr[0].index;
value = value === undefined || value == -1 ? index : value;
if (arr[value] && arr[value].children) {
list = arr[value].children;
}
// layer0
if (layer > 0) {
for (let i = 1; i < layer + 1; i++) {
let val = layer === i ? index : selectedArr[i].index;
list = val === -1 ? [] : list[val].children || [];
if (list.length === 0) break; //
}
}
// list
list = this.removeChildren(list);
}
return list;
},
/**
* 设置默认数据
* @param val 可以是数组用于设置默认选中的项目如果为空或未定义则不执行任何操作
*/
setDefaultData(val) {
//
let defaultItemList = JSON.parse(JSON.stringify(val || []));
//
if (defaultItemList.length > 0) {
//
if ((typeof defaultItemList[0] === 'string' || typeof defaultItemList[0] === 'number') && !this.request) {
//
let subi = -1;
let selectedArr = [];
//
for (let j = 0, len = defaultItemList.length; j < len; j++) {
let item = defaultItemList[j];
let list = [];
let obj = {};
//
if (j === 0) {
list = this.getItemList(-1);
} else {
list = this.getItemList(j - 1, subi, selectedArr);
}
//
subi = this.getDefaultIndex(list, item);
//
if (subi !== -1) {
obj = list[subi];
selectedArr.push({
text: obj.text || this.text,
value: obj.value || '',
src: obj.src || '',
subText: obj.subText || '',
index: subi,
scrollViewId: `id_${subi}`,
list: list
});
}
//
if (subi === -1) break;
}
//
this.selectedArr = selectedArr;
this.defTab = this.currentTab;
// 使$nextTickDOM
this.$nextTick(() => {
setTimeout(() => {
this.currentTab = selectedArr.length - 1;
this.defTab = this.currentTab;
this.checkCor();
}, 20);
});
} else {
// 使
defaultItemList.map((item) => {
item.scrollViewId = `id_${item.index}`;
});
this.selectedArr = defaultItemList;
this.defTab = this.currentTab;
// DOM
this.$nextTick(() => {
setTimeout(() => {
this.currentTab = defaultItemList.length - 1;
this.defTab = this.currentTab;
this.checkCor();
}, 20);
});
}
} else {
// 使
this.initData(this.itemList, -1);
}
},
/**
* 点击标题切换当前选项卡
* @param {Object} e 事件对象包含了触发事件的元素信息
* 无返回值
*/
swichNav: function (e) {
//
let cur = e.currentTarget.dataset.current;
//
if (this.currentTab != cur) {
//
this.defTab = this.currentTab;
// 使setTimeout20
setTimeout(() => {
this.currentTab = cur;
this.defTab = this.currentTab;
}, 20);
}
},
/**
* 处理选项更改事件
* @param {number} index 主选项索引
* @param {number} subIndex 子选项索引
* @param {Object} subItem 子选项对象包含文本子文本和图片源等属性
* 此函数更新当前选定项的索引和属性并根据条件触发数据更新或事件emit
*/
change(index, subIndex, subItem) {
let item = this.selectedArr[index]; //
//
if (item.index == subIndex) return;
//
item.index = subIndex;
item.text = subItem.text;
item.value = subItem.value;
item.subText = subItem.subText || ''; //
item.src = subItem.src || ''; //
//
this.$emit('change', {
layer: index,
subIndex: subIndex, //layer=> Array index
...subItem
});
//
if (!this.request) {
let data = this.getItemList(index, subIndex);
this.subLevelData(data, index);
}
},
/**
* 获取给定数组中与指定值匹配的默认索引
* @param {Array} arr - 待搜索的数组
* @param {any} val - 要在数组中查找的值
* @returns {number} 如果找到匹配项则返回匹配项的索引如果没有找到或输入数组为空undefined或指定值未定义则返回-1
*/
getDefaultIndex(arr, val) {
// -1
if (!arr || arr.length === 0 || val === undefined) return -1;
let index = -1; // -1
let key = this.defaultKey || 'text'; // 使defaultKey使'text'
//
for (let i = 0, len = arr.length; i < len; i++) {
if (arr[i][key] == val) {
index = i; //
break; //
}
}
return index; //
}
}
};
</script>
<style scoped>
.tui-cascade-selection {
width: 100%;
box-sizing: border-box;
}
.tui-selection-header {
width: 100%;
display: flex;
align-items: center;
position: relative;
box-sizing: border-box;
}
.tui-bottom-line {
position: relative;
}
.tui-bottom-line::after {
width: 100%;
content: '';
position: absolute;
border-bottom: 1rpx solid #eaeef1;
-webkit-transform: scaleY(0.5) translateZ(0);
transform: scaleY(0.5) translateZ(0);
transform-origin: 0 100%;
bottom: 0;
right: 0;
left: 0;
}
.tui-btm-none::after {
border-bottom: 0 !important;
}
.tui-header-item {
max-width: 240rpx;
padding: 15rpx 30rpx;
box-sizing: border-box;
flex-shrink: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
position: relative;
}
.tui-font-bold {
font-weight: bold;
}
.tui-active-line {
width: 60rpx;
height: 6rpx;
border-radius: 4rpx;
position: absolute;
bottom: 0;
right: 0;
left: 50%;
transform: translateX(-50%);
}
.tui-selection-cell {
width: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
}
.tui-icon-success {
margin-right: 12rpx;
}
.tui-cell-img {
margin-right: 12rpx;
flex-shrink: 0;
}
.tui-cell-title {
word-break: break-all;
}
.tui-flex-shrink {
flex-shrink: 0;
}
.tui-font-bold {
font-weight: bold;
}
.tui-cell-sub_title {
margin-left: 20rpx;
word-break: break-all;
}
.tui-first-item {
width: 100%;
}
</style>

82
uni_modules/jia-cascader/package.json

@ -0,0 +1,82 @@
{
"id": "jia-cascader",
"displayName": "级联数据选择 data-picker 自定义多级选择 多级联动选择、 ",
"version": "1.0.2",
"description": "弹窗联动选择器, 无限级联,单选,远程/ajax加载,子节点增量/异步渲染, ",
"keywords": [
"仿uniui",
"data-picker",
"异步级联"
],
"repository": "",
"engines": {
},
"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"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "u"
},
"App": {
"app-vue": "u",
"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"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "u",
"字节跳动": "y",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

465
uni_modules/jia-cascader/readme.md

@ -0,0 +1,465 @@
# jia-cascader (内部携带最新省市区编码 需要可自取)
# Props
| 属性名 | 类型 | 说明 | 默认值 |
| ---------------- | --------------- | ------------------------------------------------------------ | ----------------- |
| readonly | Boolean | 只读 |false
| border | Boolean | 边框 | true
| clearIcon | Boolean | 清除按钮 | true
| placeholder | String | 默认提示 |请选择
| popupTitle | String | 弹窗标题 |请选择
| itemList | Array | 级联数据, 如果下一级是请求返回,则为第一级数据,否则为所有数据 | [ ] |
| defaultItemList | Array | 初始化默认选中数据,当一次性传入所有数据时,默认值可为字符串数组,如:['安徽省','阜阳市','颍上县'] | [ ] |
| defaultKey | V1.7.2+ String | 默认值字段key,可传值:text,value,仅当一次性传入所有数据时有效 | text |
| headerLine | Boolean | 是否显示header底部细线 | true |
| headerBgColor | String | header背景颜色 | #FFFFFF |
| tabsHeight | String | 顶部标签栏高度 | 88rpx |
| text | String | 默认显示文字 | 请选择 |
| size | Number | tabs 文字大小 | 28 |
| color | String | tabs 文字颜色 | #555 |
| activeColor | String | 选中颜色 | #5677fc |
| bold | Boolean | 选中后文字加粗 | true |
| showLine | Boolean | 选中后是否显示底部线条 | true |
| lineColor | String | 线条颜色 | #5677fc |
| checkMarkSize | Number | icon 大小 | 15 |
| checkMarkColor | String | icon 颜色 | #5677fc |
| imgWidth | String | item 图片宽度 | 40rpx |
| imgHeight | String | item 图片高度 | 40rpx |
| radius | String | 图片圆角 | 50% |
| textColor | String | item text颜色 | #333 |
| textActiveColor | String | item text选中后颜色 | #333 |
| textBold | Boolean | 选中后字体是否加粗 | true |
| textSize | Number | item text字体大小 | 28 |
| nowrap | Boolean | text 是否不换行 | false |
| subTextColor | String | item subText颜色 | #999 |
| subTextSize | Number | item subText字体大小 | 24 |
| padding | String | item padding | 20rpx 30rpx |
| firstItemTop | String | 占位高度,第一条数据距离顶部距离 | 20rpx |
| height | String | swiper 高度 | 300px |
| backgroundColor | String | item swiper 内容部分背景颜色 | #FFFFFF |
| request | Boolean | 子级数据是否请求返回(默认false,一次性返回所有数据) | false |
| receiveData | Array | 子级数据(当有改变时,默认为当前选中项新增子级数据,request为true时生效) | [ ] |
| reset | [Number, String]| 改变reset值则重置所有数据
# 事件方法
| 属性 | 类型 | 说明 | 返回值 |
|----------|-----|------------------|----------------- |--------|
| popupopened | Events | 弹框打开时触发 | |
| popupclosed | Events | 弹框关闭时触发 | |
| completeChange | Events | 选择器中item项点击时触发| |
| inputChange | Events | 选择结果数据 | |
# inputChange事件回调参数说明:
- layer 当前所属层级
- subIndex 当前层级点击项索引值
- subItem项 当前层级点击项所有数据,由父组件传入的数据
# completeChange事件回调参数说明:
- result 当前选择的结果
- text 所有层级选择的text值拼接数据,如:安徽省合肥市庐阳区
- value 最后一级点击项的value值
- subText 最后一级点击项的text值
- src 最后一级点击项的src值
# temList 属性Object参数说明
属性 receiveData 数据格式与 itemList中子集数据一致,数据为约定格式,尽量保持一致。
``` js
[{
src: "", //图标地址
text: "",//主文本
subText: "",//副文本
value: 0, //value值
children:[{
text: "",//主文本
subText: "",//副文本
value: 0,//value值
children:[] //子级数据 如果数据长度为0则表示没有下一级数据了
}] //子级数据
}]
```
# defaultItemList 属性Object参数说明
数据为约定格式,尽量保持一致,当一次性传入所有数据时,默认值可为字符串数组。
``` js
[{
text: "", //选中的text
subText: '', //选中的subText
value: '', //选中的value
src: '', //选中的src,没有则传空或不传
index: 0, //选中数据在当前layer索引
list: [{
src: "",//图标地址
text: "", //主文本
subText: "",//副文本
value: 101 //value值
}] //当前layer下所有数据集合
}]
```
使用方法示例
在template中使用
``` vue
<template>
<template>
<view>
<jia-cascader request :itemList="itemList" :receiveData="receiveData" :defaultItemList="defaultItemList" @completeChange="complete" @inputChange="change"></jia-cascader>
</view>
</template>
<script>
// data 数据 及 方法
export default {
data() {
return {
itemList: [],
receiveData: [],
defaultItemList: [
{
src: '',
text: '高一(3)班',
subText: '30人',
value: 102,
index: 1, //选中数据在当前layer索引
list: [
{
src: '',
text: '高一(1)班',
subText: '30人',
value: 101
},
{
src: '',
text: '高一(2)班',
subText: '30人',
value: 102
},
{
src: '',
text: '高一(3)班',
subText: '30人',
value: 103
},
{
src: '',
text: '高一(1)班',
subText: '30人',
value: 101
},
{
src: '',
text: '高一(2)班',
subText: '30人',
value: 102
},
{
src: '',
text: '高一(1)班',
subText: '30人',
value: 101
},
{
src: '',
text: '高一(2)班',
subText: '30人',
value: 102
},
{
src: '',
text: '高一(1)班',
subText: '30人',
value: 101
},
{
src: '',
text: '高一(2)班',
subText: '30人',
value: 102
},
{
src: '',
text: '高一(1)班',
subText: '30人',
value: 101
},
{
src: '',
text: '高一(2)班',
subText: '30人',
value: 102
},
{
src: '',
text: '高一(1)班',
subText: '30人',
value: 101
},
{
src: '',
text: '高一(2)班',
subText: '30人',
value: 102
},
{
src: '',
text: '高一(1)班',
subText: '30人',
value: 101
},
{
src: '',
text: '高一(2)班',
subText: '30人',
value: 102
},
{
src: '',
text: '高一(1)班',
subText: '30人',
value: 101
}
] //当前layer下所有数据集合
},
{
text: '周小小', //选中的text
subText: '女', //选中的subText
value: 11103, //选中的value
src: '', //选中的src,没有则传空或不传
index: 2, //选中数据在当前layer索引
list: [
{
text: '张三',
subText: '男',
value: 11101
},
{
text: '王五',
subText: '男',
value: 11102
},
{
text: '周小小',
subText: '女',
value: 11103
},
{
text: '周小小',
subText: '女',
value: 11103
},
{
text: '周小小',
subText: '女',
value: 11103
}
] //当前layer下所有数据集合
}
]
};
},
onLoad() {
this.itemList = [
{
src: ' ',
text: '高一(1)班',
subText: '30人',
value: 101
},
{
src: ' ',
text: '高一(2)班',
subText: '30人',
value: 102
},
{
src: ' ',
text: '高一(3)班',
subText: '30人',
value: 103
},
{
src: ' ',
text: '高一(4)班',
subText: '28人',
value: 104
},
{
src: ' ',
text: '高一(5)班',
subText: '28人',
value: 105
},
{
src: ' ',
text: '高一(6)班',
subText: '28人',
value: 106
},
{
src: ' ',
text: '高一(7)班',
subText: '28人',
value: 107
},
{
src: ' ',
text: '高一(8)班',
subText: '38人',
value: 108
},
{
src: ' ',
text: '高一(9)班',
subText: '38人',
value: 109
},
{
src: ' ',
text: '高一(10)班',
subText: '38人',
value: 110
},
{
src: ' ',
text: '高一(11)班',
subText: '38人',
value: 111
},
{
src: ' ',
text: '高一(12)班',
subText: '38人',
value: 112
}
];
},
methods: {
change(e) {
console.log(e);
/**
* layer: 0 第几级 index
src: '/static/images/basic/color.png'
subIndex: 2 //当前层级下选中项index
subText: '30人' //选中项数据
text: '高一(3)班'
value: 103 //选中项value数据
* */
// 模拟请求
let value = e.value;
let layer = e.layer;
if (layer === 7) {
//实际中以请求数据为准,无下级数据则传空数组
this.receiveData = [];
} else {
uni.showLoading({
title: '请稍候...'
});
setTimeout(() => {
uni.hideLoading();
//请求完成后将数据处理成以下格式,传入,最后一级没有则传空数组
switch (layer) {
case 0:
this.receiveData = [
{
text: '张三',
subText: '男',
value: 11101
},
{
text: '王五',
subText: '男',
value: 11102
},
{
text: '周小小',
subText: '女',
value: 11103
},
{
text: '周小小',
subText: '女',
value: 11103
},
{
text: '周小小',
subText: '女',
value: 11103
}
];
break;
case 1:
this.receiveData = [
{
text: '他(她)说',
value: 11101
}
];
break;
case 2:
this.receiveData = [
{
text: '这是一个',
value: 11101
}
];
break;
case 3:
this.receiveData = [
{
text: '级联选择器',
value: 11101
}
];
break;
case 4:
this.receiveData = [
{
text: '测试例子',
value: 11101
}
];
break;
case 5:
this.receiveData = [
{
text: '总共',
value: 11101
}
];
break;
case 6:
this.receiveData = [
{
text: '8级数据',
value: 11101
}
];
break;
default:
break;
}
}, 800);
}
},
complete(e) {
console.log(e);
console.log('您选择的数据为:' + e.text);
}
}
};
</script>
```

4
uni_modules/mumu-recorder/changelog.md

@ -0,0 +1,4 @@
## 1.0.1(2022-06-11)
修复苹果手机在微信中无法获取音频长度问题
## 1.0.0(2022-06-10)
版本上线

113
uni_modules/mumu-recorder/components/mumu-recorder/mumu-recorder.vue

@ -0,0 +1,113 @@
<template>
<view class="recorder">
</view>
</template>
<script>
export default {
data() {
return {
isUserMedia: false,
stream: null,
audio: null,
recorder: null,
chunks: [],
startTime: 0
}
},
mounted() {
/**
* error 事件的返回状态
* 100: 请在HTTPS环境中使用
* 101: 浏览器不支持
* 201: 用户拒绝授权
* 500: 未知错误
* */
if (origin.indexOf('https') === -1) {
this.$emit('error', '100')
throw '请在 https 环境中使用本插件。'
}
if (!navigator.mediaDevices || !window.MediaRecorder) {
this.$emit('error', '101')
throw '当前浏览器不支持'
}
this.getRecorderManager()
},
methods: {
getRecorderManager() {
this.audio = document.createElement('audio')
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
this.isUserMedia = true
stream.getTracks().forEach((track) => {
track.stop()
})
}).catch(err => {
this.onErrorHandler(err)
})
},
start() {
if (!this.isUserMedia) return console.log('设备不支持')
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
this.startTime = new Date().getTime()
this.stream = stream
this.recorder = new MediaRecorder(stream)
this.recorder.ondataavailable = this.getRecordingData
this.recorder.onstop = this.saveRecordingData
this.recorder.start()
}).catch(err => {
this.onErrorHandler(err)
})
},
stop() {
this.recorder.stop()
this.stream.getTracks().forEach((track) => {
track.stop()
})
},
getRecordingData(e) {
this.chunks.push(e.data)
},
saveRecordingData() {
const blob = new Blob(this.chunks, { 'type': 'audio/mpeg' }),
localUrl = URL.createObjectURL(blob)
const endTime = new Date().getTime()
let duration = (endTime - this.startTime).toString().split('')
duration.splice(duration.length - 2)
duration.splice(duration.length - 1, 0, '.')
duration = parseFloat(duration.join(''))
const recorder = {
data: blob,
duration: duration,
localUrl: localUrl
}
this.$emit('success', recorder)
},
onErrorHandler(err) {
console.log(err)
if (err.name === 'NotAllowedError') {
this.$emit('error', '201')
throw '用户拒绝了当前的浏览器实例的访问请求'
}
if (err.name === 'NotReadableError') {
this.$emit('error', '101')
throw '当前浏览器不支持'
}
this.$emit('error', '500')
throw '调用失败,原因不详'
}
},
destroyed() {
this.stop()
}
}
</script>
<style>
</style>

87
uni_modules/mumu-recorder/package.json

@ -0,0 +1,87 @@
{
"id": "mumu-recorder",
"displayName": "h5录音组件,调用H5原生功能使用麦克风进行录音",
"version": "1.0.1",
"description": "演示案例中模仿了微信的长按发送语音,与普通录音demo。",
"keywords": [
"录音",
"麦克风",
"模仿微信"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"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"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "n",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "n",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u",
"小红书": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

117
uni_modules/mumu-recorder/readme.md

@ -0,0 +1,117 @@
## 插件简绍
### 实现原理
> 通过 navigator.mediaDevices.getUserMedia(需要https环境) 这个api调用麦克风,获取到到音频流数据。
>
> 通过 MediaRecorder 这个构造函数对音频流进行接收,完成录制后会返回一个存储`Blob`内容的录制数据。
### 使用环境
需要https环境才能使用,本地测试可以在 manifest.json 中点击源码展示,找到h5 ,添加:"devServer" : { "https" : true}
**请勿使用 UC浏览器 与 夸克等阿里旗下的浏览器,发现他们使用的内核都较低,无法正常获取音频流,并且都有对接音频流截取的插件,导致无法正常获取音频流的数据。在微信中可以正常使用,推荐在微信内打开演示案例 **
需要https环境才能使用!!!
需要https环境才能使用!!!
需要https环境才能使用!!!
### 插件使用
**插件已支持 uni_modules 支持组件easycom,以下代码演示的是普通使用**
``` html
<!-- HTML -->
<view>
<audio :src='recorder.localUrl' v-if='recorder' name='本地录音' controls="true"></audio>
<view @click='handlerOnCahnger'>
{{!status?'开始录音':'结束录音'}}
</view>
<mumu-recorder ref='recorder' @success='handlerSuccess' @error='handlerError'></mumu-recorder>
</view>
```
``` javascript
// js
import MumuRecorder from '@/uni_modules/mumu-recorder/components/mumu-recorder/mumu-recorder.vue'
export default {
components: { MumuRecorder },
data() {
return {
status: false,
recorder: null
}
},
onLoad() {
},
methods: {
handlerSave() {
let tag = document.createElement('a')
tag.href = this.recorder.localUrl
tag.download = '录音'
tag.click()
},
handlerOnCahnger() {
if (this.status) {
this.$refs.recorder.stop()
} else {
this.$refs.recorder.start()
}
this.status = !this.status
},
handlerSuccess(res) {
console.log(res)
this.recorder = res
},
handlerError(code) {
switch (code) {
case '101':
uni.showModal({
content: '当前浏览器版本较低,请更换浏览器使用,推荐在微信中打开。'
})
break;
case '201':
uni.showModal({
content: '麦克风权限被拒绝,请刷新页面后授权麦克风权限。'
})
break
default:
uni.showModal({
content: '未知错误,请刷新页面重试'
})
break
}
}
}
}
```
### 相关API
##### 组件内部方法($refs 调用)
| 方法名 | 说明 | 参数 |
| ------ | -------- | ---- |
| start | 开始录音 | 无 |
| stop | 结束录音 | 无 |
##### 事件(Events)
| 事件名 | 说明 | 回调参数 |
| ------- | -------------------- | ------------------------------------------------------------ |
| success | 停止录音后调用此事件 | 返回录音数据,是一个对象<br />{ data: 音频的 blob 数据,上传请使用这个 <br />duration: 当前音频长度<br/>localUrl: 当前音频的本地链接,可直接通过 audio 标签进行播放 } |
| error | 组件内部发生错误 | 错误码:<100 当前不是https环境> <101 浏览器不支持> <201 麦克风权限被拒绝> <500 未知错误> |
### 案例演示
![enter description here](https://h5plugin.mumudev.top/public/recorder/qrcode.png)
## 支持作者
![支持作者](https://student.mumudev.top/wxMP.jpg)

11
utils/config.js

@ -4,13 +4,10 @@ module.exports = {
userId: ''
};
function BASEURL() {
// return 'https://epmet-preview.elinkservice.cn/api/' // 演示环境
return 'http://192.168.1.144/api/'; //测试环境
// return 'http://219.146.91.110:30801/api/'
// return 'https://epmet-preview.elinkservice.cn/api/' // 演示环境
// return 'http://192.168.1.144/api/' //测试环境
// return 'http://219.146.91.110:30801/api/'
//return http://219.146.91.110:30801/api //外网
// return 'https://epmet-test.elinkservice.cn/api/' // 测试环境
return 'http://192.168.1.144/api/'; //开发环境
// return 'https://epmet-preview.elinkservice.cn/api/' // 生产环境
//return http://219.146.91.110:30801/api //开发外网
}
function getToken() {

5
utils/util.js

@ -1,11 +1,12 @@
const formatTime = (date) => {
const formatTime = (timestamp) => {
const date = new Date(timestamp)
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
const second = date.getSeconds();
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':');
return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':');
};
const formatNumber = (n) => {
n = n.toString();

264
wxcomponents/vant/cascader/index.vue

@ -0,0 +1,264 @@
<template>
<uni-shadow-root class="vant-cascader-index"><view v-if="showHeader" class="van-cascader__header">
<slot name="title" v-if="useTitleSlot"></slot>
<text class="van-cascader__title" v-else>{{ title }}</text>
<van-icon v-if="closeable" :name="closeIcon" class="van-cascader__close-icon" @click.native="onClose"></van-icon>
</view>
<van-tabs :active="activeTab" custom-class="van-cascader__tabs" wrap-class="van-cascader__tabs-wrap" tab-class="van-cascader__tab" :color="activeColor" :border="false" :swipeable="swipeable" :ellipsis="ellipsis" @click="onClickTab">
<van-tab v-for="(tab,tabIndex) in (tabs)" :key="tab.tabIndex" :title="tab.selected ? tab.selected[textKey] : placeholder" style="width: 100%;" :title-style="(!tab.selected ? 'color: #969799;font-weight:normal;' : '')">
<view class="van-cascader__options">
<view v-for="(option,index) in (tab.options)" :key="option.index" :class="(option.className)+' '+(utils.optionClass(tab, valueKey, option))" :style="utils.optionStyle({ tab, valueKey, option, activeColor })" :data-option="option" :data-tab-index="tabIndex" @click="onSelect">
<text>{{ option[textKey] }}</text>
<van-icon v-if="utils.isSelected(tab, valueKey, option)" name="success" size="18"></van-icon>
</view>
</view>
</van-tab>
</van-tabs></uni-shadow-root>
</template>
<wxs src="./index.wxs" module="utils"></wxs>
<script>
import VanIcon from '../icon/index.vue'
import VanTab from '../tab/index.vue'
import VanTabs from '../tabs/index.vue'
global['__wxVueOptions'] = {components:{'van-icon': VanIcon,'van-tab': VanTab,'van-tabs': VanTabs}}
global['__wxRoute'] = 'vant/cascader/index'
"use strict";
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
var component_1 = require("../common/component");
var FieldName;
(function (FieldName) {
FieldName["TEXT"] = "text";
FieldName["VALUE"] = "value";
FieldName["CHILDREN"] = "children";
})(FieldName || (FieldName = {}));
var defaultFieldNames = {
text: FieldName.TEXT,
value: FieldName.VALUE,
children: FieldName.CHILDREN,
};
(0, component_1.VantComponent)({
props: {
title: String,
value: {
type: String,
},
placeholder: {
type: String,
value: '请选择',
},
activeColor: {
type: String,
value: '#1989fa',
},
options: {
type: Array,
value: [],
},
swipeable: {
type: Boolean,
value: false,
},
closeable: {
type: Boolean,
value: true,
},
ellipsis: {
type: Boolean,
value: true,
},
showHeader: {
type: Boolean,
value: true,
},
closeIcon: {
type: String,
value: 'cross',
},
fieldNames: {
type: Object,
value: defaultFieldNames,
observer: 'updateFieldNames',
},
useTitleSlot: Boolean,
},
data: {
tabs: [],
activeTab: 0,
textKey: FieldName.TEXT,
valueKey: FieldName.VALUE,
childrenKey: FieldName.CHILDREN,
innerValue: '',
},
watch: {
options: function (newVal,oldVal) {
this.updateTabs();
},
value: function (newVal) {
this.updateValue(newVal);
},
},
created: function () {
this.updateTabs();
},
methods: {
updateValue: function (val) {
var _this = this;
if (val !== undefined) {
var values = this.data.tabs.map(function (tab) { return tab.selected && tab.selected[_this.data.valueKey]; });
if (values.indexOf(val) > -1) {
return;
}
}
this.innerValue = val;
this.updateTabs();
},
updateFieldNames: function () {
var _a = this.data.fieldNames || defaultFieldNames, _b = _a.text, text = _b === void 0 ? 'text' : _b, _c = _a.value, value = _c === void 0 ? 'value' : _c, _d = _a.children, children = _d === void 0 ? 'children' : _d;
this.setData({
textKey: text,
valueKey: value,
childrenKey: children,
});
},
getSelectedOptionsByValue: function (options, value) {
for (var i = 0; i < options.length; i++) {
var option = options[i];
if (option[this.data.valueKey] === value) {
return [option];
}
if (option[this.data.childrenKey]) {
var selectedOptions = this.getSelectedOptionsByValue(option[this.data.childrenKey], value);
if (selectedOptions) {
return __spreadArray([option], selectedOptions, true);
}
}
}
},
updateTabs: function () {
var _this = this;
var options = this.data.options;
var innerValue = this.innerValue;
if (!options.length) {
return;
}
if (innerValue !== undefined) {
var selectedOptions = this.getSelectedOptionsByValue(options, innerValue);
if (selectedOptions) {
var optionsCursor_1 = options;
var tabs_1 = selectedOptions.map(function (option) {
var tab = {
options: optionsCursor_1,
selected: option,
};
var next = optionsCursor_1.find(function (item) { return item[_this.data.valueKey] === option[_this.data.valueKey]; });
if (next) {
optionsCursor_1 = next[_this.data.childrenKey];
}
return tab;
});
if (optionsCursor_1) {
tabs_1.push({
options: optionsCursor_1,
selected: null,
});
}
this.setData({
tabs: tabs_1,
});
wx.nextTick(function () {
_this.setData({
activeTab: tabs_1.length - 1,
});
});
return;
}
}
this.setData({
tabs: [
{
options: options,
selected: null,
},
],
activeTab: 0,
});
console.log(this.tabs,'see');
},
onClose: function () {
this.$emit('close');
},
onClickTab: function (e) {
var _a = e.detail, tabIndex = _a.index, title = _a.title;
this.$emit('click-tab', { title: title, tabIndex: tabIndex });
this.setData({
activeTab: tabIndex,
});
},
//
onSelect: function (e) {
var _this = this;
var _a = e.currentTarget.dataset, option = _a.option, tabIndex = _a.tabIndex;
if (option && option.disabled) {
return;
}
var _b = this.data, valueKey = _b.valueKey, childrenKey = _b.childrenKey;
var tabs = this.data.tabs;
tabs[tabIndex].selected = option;
if (tabs.length > tabIndex + 1) {
tabs = tabs.slice(0, tabIndex + 1);
}
if (option[childrenKey]) {
var nextTab = {
options: option[childrenKey],
selected: null,
};
if (tabs[tabIndex + 1]) {
tabs[tabIndex + 1] = nextTab;
}
else {
tabs.push(nextTab);
}
wx.nextTick(function () {
_this.setData({
activeTab: tabIndex + 1,
});
});
}
this.setData({
tabs: tabs,
});
var selectedOptions = tabs.map(function (tab) { return tab.selected; }).filter(Boolean);
var value = option[valueKey];
var params = {
value: value,
tabIndex: tabIndex,
selectedOptions: selectedOptions,
};
this.innerValue = value;
this.$emit('change', params);
if (!option[childrenKey]) {
this.$emit('finish', params);
}
},
},
});
export default global['__wxComponents']['vant/cascader/index']
</script>
<style platform="mp-weixin">
@import '../common/index.css';.van-cascader__header{align-items:center;display:flex;height:48px;justify-content:space-between;padding:0 16px}.van-cascader__title{font-size:16px;font-weight:600;line-height:20px}.van-cascader__close-icon{color:#c8c9cc;font-size:22px;height:22px}.van-cascader__tabs-wrap{height:48px!important;padding:0 8px}.van-cascader__tab{color:#323233!important;flex:none!important;font-weight:600!important;padding:0 8px!important}.van-cascader__tab--unselected{color:#969799!important;font-weight:400!important}.van-cascader__option{align-items:center;cursor:pointer;display:flex;font-size:14px;justify-content:space-between;line-height:20px;padding:10px 16px}.van-cascader__option:active{background-color:#f2f3f5}.van-cascader__option--selected{color:#1989fa;font-weight:600}.van-cascader__option--disabled{color:#c8c9cc;cursor:not-allowed}.van-cascader__option--disabled:active{background-color:initial}.van-cascader__options{-webkit-overflow-scrolling:touch;box-sizing:border-box;height:384px;overflow-y:auto;padding-top:6px}
</style>

42
wxcomponents/vant/wxs/style.wxs

@ -0,0 +1,42 @@
/* eslint-disable */
var object = require('./object.wxs');
var array = require('./array.wxs');
function kebabCase(word) {
var newWord = word
.replace(getRegExp("[A-Z]", 'g'), function (i) {
return '-' + i;
})
.toLowerCase()
return newWord;
}
function style(styles) {
if (array.isArray(styles)) {
return styles
.filter(function (item) {
return item != null && item !== '';
})
.map(function (item) {
return style(item);
})
.join(';');
}
if ('Object' === styles.constructor) {
return object
.keys(styles)
.filter(function (key) {
return styles[key] != null && styles[key] !== '';
})
.map(function (key) {
return [kebabCase(key), [styles[key]]].join(':');
})
.join(';');
}
return styles;
}
module.exports = style;

12
wxcomponents/vant/wxs/wxs/add-unit.wxs

@ -0,0 +1,12 @@
/* eslint-disable */
var REGEXP = getRegExp('^-?\d+(\.\d+)?$');
function addUnit(value) {
if (value == null) {
return undefined;
}
return REGEXP.test('' + value) ? value + 'px' : value;
}
module.exports = addUnit;

5
wxcomponents/vant/wxs/wxs/array.wxs

@ -0,0 +1,5 @@
function isArray(array) {
return array && (array.constructor === 'Array' || (typeof Array !== 'undefined' && Array.isArray(array)));
}
module.exports.isArray = isArray;

39
wxcomponents/vant/wxs/wxs/bem.wxs

@ -0,0 +1,39 @@
/* eslint-disable */
var array = require('./array.wxs');
var object = require('./object.wxs');
var PREFIX = 'van-';
function join(name, mods) {
name = PREFIX + name;
mods = mods.map(function(mod) {
return name + '--' + mod;
});
mods.unshift(name);
return mods.join(' ');
}
function traversing(mods, conf) {
if (!conf) {
return;
}
if (typeof conf === 'string' || typeof conf === 'number') {
mods.push(conf);
} else if (array.isArray(conf)) {
conf.forEach(function(item) {
traversing(mods, item);
});
} else if (typeof conf === 'object') {
object.keys(conf).forEach(function(key) {
conf[key] && mods.push(key);
});
}
}
function bem(name, conf) {
var mods = [];
traversing(mods, conf);
return join(name, mods);
}
module.exports = bem;

55
wxcomponents/vant/wxs/wxs/memoize.wxs

@ -0,0 +1,55 @@
/**
* Simple memoize
* wxs doesn't support fn.apply, so this memoize only support up to 2 args
*/
/* eslint-disable */
function isPrimitive(value) {
var type = typeof value;
return (
type === 'boolean' ||
type === 'number' ||
type === 'string' ||
type === 'undefined' ||
value === null
);
}
// mock simple fn.call in wxs
function call(fn, args) {
if (args.length === 2) {
return fn(args[0], args[1]);
}
if (args.length === 1) {
return fn(args[0]);
}
return fn();
}
function serializer(args) {
if (args.length === 1 && isPrimitive(args[0])) {
return args[0];
}
var obj = {};
for (var i = 0; i < args.length; i++) {
obj['key' + i] = args[i];
}
return JSON.stringify(obj);
}
function memoize(fn) {
var cache = {};
return function() {
var key = serializer(arguments);
if (cache[key] === undefined) {
cache[key] = call(fn, arguments);
}
return cache[key];
};
}
module.exports = memoize;

13
wxcomponents/vant/wxs/wxs/object.wxs

@ -0,0 +1,13 @@
/* eslint-disable */
var REGEXP = getRegExp('{|}|"', 'g');
function keys(obj) {
return JSON.stringify(obj)
.replace(REGEXP, '')
.split(',')
.map(function(item) {
return item.split(':')[0];
});
}
module.exports.keys = keys;

10
wxcomponents/vant/wxs/wxs/utils.wxs

@ -0,0 +1,10 @@
/* eslint-disable */
var bem = require('./bem.wxs');
var memoize = require('./memoize.wxs');
var addUnit = require('./add-unit.wxs');
module.exports = {
bem: memoize(bem),
memoize: memoize,
addUnit: addUnit
};
Loading…
Cancel
Save