付宇航 пре 1 година
родитељ
комит
163d1569cb
100 измењених фајлова са 8257 додато и 1547 уклоњено
  1. 0 16
      .gitignore
  2. 16 0
      .hbuilderx/launch.json
  3. 11 34
      App.vue
  4. 87 0
      README.md
  5. 0 1
      api/common.js
  6. 0 56
      api/login.js
  7. 0 10
      api/system/dict/data.js
  8. 0 41
      api/system/user.js
  9. 141 0
      app.css
  10. 20 0
      common/utils/setDataOverride.js
  11. 8 0
      components/tab-page/tab-page.css
  12. 33 0
      components/tab-page/tab-page.vue
  13. 78 0
      components/tabs/tabs.css
  14. 114 0
      components/tabs/tabs.vue
  15. 4 0
      components/vtabs/vtabs-content/index.css
  16. 54 0
      components/vtabs/vtabs-content/index.vue
  17. 44 0
      components/vtabs/vtabs/index.css
  18. 214 0
      components/vtabs/vtabs/index.vue
  19. 0 31
      config.js
  20. 377 0
      data/json.js
  21. 20 0
      index.html
  22. 35 21
      main.js
  23. 69 79
      manifest.json
  24. 18 0
      node_modules/.package-lock.json
  25. 127 0
      node_modules/@miniprogram-component-plus/vtabs-content/miniprogram_dist/index.js
  26. 4 0
      node_modules/@miniprogram-component-plus/vtabs-content/miniprogram_dist/index.json
  27. 3 0
      node_modules/@miniprogram-component-plus/vtabs-content/miniprogram_dist/index.wxml
  28. 1 0
      node_modules/@miniprogram-component-plus/vtabs-content/miniprogram_dist/index.wxss
  29. 15 0
      node_modules/@miniprogram-component-plus/vtabs-content/package.json
  30. 202 0
      node_modules/@miniprogram-component-plus/vtabs/miniprogram_dist/index.js
  31. 4 0
      node_modules/@miniprogram-component-plus/vtabs/miniprogram_dist/index.json
  32. 38 0
      node_modules/@miniprogram-component-plus/vtabs/miniprogram_dist/index.wxml
  33. 1 0
      node_modules/@miniprogram-component-plus/vtabs/miniprogram_dist/index.wxss
  34. 15 0
      node_modules/@miniprogram-component-plus/vtabs/package.json
  35. 38 0
      package-lock.json
  36. 14 13
      package.json
  37. 112 34
      pages.json
  38. 0 375
      pages/demo/delis.vue
  39. 0 244
      pages/demo/fwblz.vue
  40. 0 86
      pages/demo/index.vue
  41. 0 122
      pages/demo/my.vue
  42. 36 0
      pages/fenlei/fenlei.css
  43. 142 0
      pages/fenlei/fenlei.vue
  44. 1 0
      pages/fuwu/fuwu.css
  45. 48 0
      pages/fuwu/fuwu.vue
  46. 222 0
      pages/iconfont/iconfont.css
  47. 492 0
      pages/index/index.css
  48. 329 0
      pages/index/index.vue
  49. 0 157
      pages/login.vue
  50. 1 0
      pages/me/me.css
  51. 48 0
      pages/me/me.vue
  52. 191 0
      pages/sannong/sannong.css
  53. 238 0
      pages/sannong/sannong.vue
  54. 190 0
      pages/shangcheng/shangcheng.css
  55. 178 0
      pages/shangcheng/shangcheng.vue
  56. 112 0
      pages/shangpinxiangqingye/shangpinxiangqingye.css
  57. 97 0
      pages/shangpinxiangqingye/shangpinxiangqingye.vue
  58. 103 0
      pages/wenba/wenba.css
  59. 139 0
      pages/wenba/wenba.vue
  60. 160 0
      pages/wenbaxiangqing/wenbaxiangqing.css
  61. 114 0
      pages/wenbaxiangqing/wenbaxiangqing.vue
  62. 0 39
      permission.js
  63. 0 60
      plugins/auth.js
  64. 0 20
      plugins/index.js
  65. 0 74
      plugins/modal.js
  66. 0 30
      plugins/tab.js
  67. 52 0
      project.config.json
  68. 8 0
      project.private.config.json
  69. 0 0
      service
  70. 7 0
      sitemap.json
  71. BIN
      static/pages/images/chanpintu.png
  72. BIN
      static/pages/images/fuwu1.png
  73. BIN
      static/pages/images/fuwu2.png
  74. BIN
      static/pages/images/index1.png
  75. BIN
      static/pages/images/index2.png
  76. BIN
      static/pages/images/me1.png
  77. BIN
      static/pages/images/me2.png
  78. BIN
      static/pages/images/sc.png
  79. BIN
      static/pages/images/shangpinxaingqing01.jpg
  80. BIN
      static/pages/images/shangpinxaingqing02.jpg
  81. BIN
      static/pages/images/tongzhuan.png
  82. BIN
      static/pages/images/ty.png
  83. BIN
      static/pages/images/waitao.png
  84. BIN
      static/pages/images/yumi.png
  85. 46 0
      transform.log
  86. 17 4
      uni.scss
  87. 193 0
      uni_modules/mp-html/README.md
  88. 129 0
      uni_modules/mp-html/changelog.md
  89. 498 0
      uni_modules/mp-html/components/mp-html/mp-html.vue
  90. 576 0
      uni_modules/mp-html/components/mp-html/node/node.vue
  91. 1335 0
      uni_modules/mp-html/components/mp-html/parser.js
  92. 76 0
      uni_modules/mp-html/package.json
  93. 1 0
      uni_modules/mp-html/static/app-plus/mp-html/js/handler.js
  94. 1 0
      uni_modules/mp-html/static/app-plus/mp-html/js/uni.webview.min.js
  95. 1 0
      uni_modules/mp-html/static/app-plus/mp-html/local.html
  96. BIN
      uni_modules/p-f-unicom/1.jpg
  97. 188 0
      uni_modules/p-f-unicom/README.md
  98. 2 0
      uni_modules/p-f-unicom/changelog.md
  99. 369 0
      uni_modules/p-f-unicom/index.js
  100. 0 0
      uni_modules/p-f-unicom/package.json

+ 0 - 16
.gitignore

@@ -1,16 +0,0 @@
-######################################################################
-# Build Tools
-
-/unpackage/*
-/node_modules/*
-
-######################################################################
-# Development Tools
-
-/.idea/*
-/.vscode/*
-/.hbuilderx/*
-
-package-lock.json
-yarn.lock
-

+ 16 - 0
.hbuilderx/launch.json

@@ -0,0 +1,16 @@
+{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+  // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
+    "version": "0.0",
+    "configurations": [{
+     	"default" : 
+     	{
+     		"launchtype" : "local"
+     	},
+     	"mp-weixin" : 
+     	{
+     		"launchtype" : "local"
+     	},
+     	"type" : "uniCloud"
+     }
+    ]
+}

+ 11 - 34
App.vue

@@ -1,39 +1,16 @@
 <script>
-  import config from './config'
-  import store from '@/store'
-  import { getToken } from '@/utils/auth'
-
-  export default {
-    onLaunch: function() {
-      this.initApp()
+// app.js
+export default {
+    data() {
+        return {};
     },
-    methods: {
-      // 初始化应用
-      initApp() {
-        // 初始化应用配置
-        this.initConfig()
-        // 检查用户登录状态
-        //#ifdef H5
-        this.checkLogin()
-        //#endif
-      },
-      initConfig() {
-        this.globalData.config = config
-      },
-      checkLogin() {
-        if (!getToken()) {
-          this.$tab.reLaunch('/pages/login') 
-        }
-      }
+    globalData: {
+        host: 'http://119.3.201.155:9000',
+        globalToken: null,
+        isLoginSuccess: false
     }
-  }
+};
 </script>
-
-<style lang="scss">
-  @import '@/static/scss/index.scss';
-  @import './static/font/iconfont.css';
-  .uni-list-cell-db{
-	  max-width: 75% !important;
-  }
-
+<style>
+@import './app.css';
 </style>

+ 87 - 0
README.md

@@ -0,0 +1,87 @@
+# miniprogram-to-uniapp 转换说明
+
+## 0x00 转换模式
+根据转换模式,转换后的项目使用相应的工具打开,目前有两种模式:
+
+### HBuilder X 模式
+转换后的目录(以_uni结尾的目录), 需使用HBuilder X导入,进行运行和调试。
+如果项目使用了npm模块,需先使用npm install等命令进行安装,然后再运行
+
+### Vue-cli 模式
+转换后的目录(以_vue-cli结尾的目录), 需使用命令行安装依赖、运行和打包。
+详见文档:https://uniapp.dcloud.io/quickstart-cli.html#%E8%BF%90%E8%A1%8C%E3%80%81%E5%8F%91%E5%B8%83uni-app
+
+注:
+上述两种项目类型,可以相互转换。
+[uni-app HBuilderX 工程与 vue-cli 工程相互转换](https://ask.dcloud.net.cn/article/35750)
+
+
+## 0x01 调试建议
+如果您想转换小程序为uni-app项目,并发布为App,
+建议运行到H5平台,因为H5平台速度快,而且与App平台贴合度更高。
+只有当强依赖硬件时,才使用真机调试,这样可以节约时间!
+
+
+## 0x02 常见问题
+### 1.命令行提示:“'wtu'不是内部或外部命令, 也不是可运行的程序”
+一般是node未安装在默认目录导致的,参照文章 [解决“npm不是内部或外部命令“](https://www.cnblogs.com/ldq678/p/10291824.html) 解决。
+
+
+### 2.PowerShell里提示:无法加载文件 XXXXXXXXX.ps1,因为在此系统上禁止运行脚本。
+以管理员身份运行`powershell`,执行
+```
+set-executionpolicy remotesigned
+```
+输入 y 即可
+或者,在PowerShell输入 `cmd` 后回车也行
+
+
+### 3.setData为什么没有转换?需要我手动改吗?那我有100多个页面怎么改呀?
+`setData`函数已内置,在main.js通过mixin全局混入,所以不用转换,可直接使用`setData`函数!!!
+
+
+### 4.命令行报错:"cannot read property ‘某某某’ of undefined"
+报错解释:有代码“`xx.某某某`”,但xx的值是undefined,因此,需要进报错的页面,调试调试,为啥xx为undefined,相应的调试代码即可。
+常见原因:可能接口跨域,可能真的没值,也可能没声明变量,也可能是工具转换问题等。
+
+
+### 5.为什么我运行到H5或app时,拿不到小程序用户的信息?为什么登录失败?
+转换后的uni-app项目,如需运行到其他小程序、H5和App时,登录和支付功能均需“重新对接”,需要增加 “新” 接口!
+
+
+### 6.跨域问题:为什么我的接口都没有返回数据呀?
+控制台有“CORS”、“Access-Control-Allow-Origin”等关键字时,不要犹豫,果断判断是因为跨域,导致访问接口失败。
+跨域,前端老生常谈,有N种解决办法,最简单的办法是运行到“内置浏览器”。
+PS: 仅仅 H5 平台存在跨域问题!发布后上传到服务器无此问题!
+
+
+### 7.Vant项目怎么转换呀?
+
+Vant项目比较常见的报错是:代码`<button class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} {{ item.className || '' }}"></button>`转到后,运行会报错,因为uni-app不支持在class里面写函数)
+
+由于Vant的一些语法uni-app并不支持,因此需要特殊处理一下,这里分享三种方案,可以根据自己的情况进行选择。
+
+#### 方案一:【替换Vant组件】
+转换前,将vant组件全部用别的组件库替换掉再转换。
+
+#### 方案二:【替换Vant组件】
+转换后,将vant组件使用uview1.x替换掉同功能组件。
+
+#### 方案三:【不替换Vant组件】
+转换后,按uniapp引入小程序组件文档重新引入vant组件(小程序自定义组件支持:
+https://uniapp.dcloud.io/tutorial/miniprogram-subject.html#%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E6%94%AF%E6%8C%81)
+
+
+### 8.小程序转换为uni-app项目后,还能转换成其他小程序项目吗?
+当然可以,必须可以!
+小程序转换为uni-app项目后,就是uni-app项目了,uni-app项目能做啥就能做啥,
+能再次生成为各种小程序、发布H5和App。
+
+
+### 9.uni-app生成的小程序项目,还能再转换回uni-app项目吗?
+不能。不支持这种项目的转换!
+
+
+### 其他
+- 因各种原因,本工具并非100%完美转换!有问题实属正常!
+- 如遇运行报错,请在https://github.com/zhangdaren/miniprogram-to-uniapp,将详细情况提交Issue!

+ 0 - 1
api/common.js

@@ -1 +0,0 @@
-import request from '@/utils/request'

+ 0 - 56
api/login.js

@@ -1,56 +0,0 @@
-import request from '@/utils/request'
-
-// 登录方法
-export function wxLogin(code) {
-  const data = {
-    code
-  }
-  return request({
-    'url': '/wxLogin',
-    headers: {
-      isToken: false
-    },
-    'method': 'post',
-    'params': data
-  })
-}
-
-// 注册方法
-export function register(data) {
-  return request({
-    url: '/register',
-    headers: {
-      isToken: false
-    },
-    method: 'post',
-    data: data
-  })
-}
-
-// 获取用户详细信息
-export function getInfo() {
-  return request({
-    'url': '/getInfo',
-    'method': 'get'
-  })
-}
-
-// 退出方法
-export function logout() {
-  return request({
-    'url': '/logout',
-    'method': 'post'
-  })
-}
-
-// 获取验证码
-export function getCodeImg() {
-  return request({
-    'url': '/captchaImage',
-    headers: {
-      isToken: false
-    },
-    method: 'get',
-    timeout: 20000
-  })
-}

+ 0 - 10
api/system/dict/data.js

@@ -1,10 +0,0 @@
-import upload from '@/utils/upload'
-import request from '@/utils/request'
-
-// 根据字典类型查询字典数据信息
-export function getDicts(dictType) {
-  return request({
-    url: '/system/dict/data/type/' + dictType,
-    method: 'get'
-  })
-}

+ 0 - 41
api/system/user.js

@@ -1,41 +0,0 @@
-import upload from '@/utils/upload'
-import request from '@/utils/request'
-
-// 用户密码重置
-export function updateUserPwd(oldPassword, newPassword) {
-  const data = {
-    oldPassword,
-    newPassword
-  }
-  return request({
-    url: '/system/user/profile/updatePwd',
-    method: 'put',
-    params: data
-  })
-}
-
-// 查询用户个人信息
-export function getUserProfile() {
-  return request({
-    url: '/system/user/profile',
-    method: 'get'
-  })
-}
-
-// 修改用户个人信息
-export function updateUserProfile(data) {
-  return request({
-    url: '/system/user/profile',
-    method: 'put',
-    data: data
-  })
-}
-
-// 用户头像上传
-export function uploadAvatar(data) {
-  return upload({
-    url: '/system/user/profile/avatar',
-    name: data.name,
-    filePath: data.filePath
-  })
-}

+ 141 - 0
app.css

@@ -0,0 +1,141 @@
+@import './pages/iconfont/iconfont.css'; /**app.wxss**/
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+    margin: 0;
+    padding: 0;
+    border: 0;
+    font-size: 100%;
+    font: inherit;
+    vertical-align: baseline;
+}
+ 
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+    display: block;
+}
+ 
+body {
+    line-height: 1;
+}
+ 
+ol, ul {
+    list-style: none;
+}
+ 
+blockquote, q {
+    quotes: none;
+}
+ 
+blockquote:before, blockquote:after,
+q:before, q:after {
+    content: '';
+    content: none;
+}
+ 
+table {
+    border-collapse: collapse;
+    border-spacing: 0;
+}
+html {
+    font-size: 62.5%;
+    color: #222;
+}
+ 
+::selection {
+    background-color: #b3d4fc;
+    text-shadow: none;
+}
+ 
+ul {
+    margin: 0;
+    padding: 0;
+}
+ 
+li {
+    list-style: none;
+}
+.clearfix:before,
+.clearfix:after {
+    content: " ";
+    display: table;
+}
+ 
+.clearfix:after {
+    clear: both;
+}
+/* ===============
+   自定义页面样式
+   =============== */
+body {
+    font:1.2rem "simhei",Arial,Helvetica,sans-serif;
+    line-height: 1.5;
+    background-color: #f7f7f7;
+}
+ 
+a {
+    color: #666;
+    text-decoration: none;
+}
+ 
+a:hover, a:active {
+    color: #0ae;
+    text-decoration: underline;
+}
+/*公共类*/
+.fl {
+    float: left
+}
+.fr {
+    float: right
+}
+.al {
+    text-align: left
+}
+.ac {
+    text-align: center
+}
+.ar {
+    text-align: right
+}
+.hide {
+    display: none
+}
+.container {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0rpx 20rpx;
+    box-sizing: border-box;
+}
+.fengexian {
+    width: 100%;
+    height: 20rpx;
+    background: #f6f6f6;
+    border-radius: 6rpx;
+}
+image {
+    display: block;
+    overflow: auto;
+}
+.titleLeft {
+    font-size: 40rpx;
+    font-weight: 600;
+    color: #07c160;
+    text-align: left;
+    line-height: 90rpx;
+    width: 100%;
+}

+ 20 - 0
common/utils/setDataOverride.js

@@ -0,0 +1,20 @@
+export const setData = (obj) => {
+	let that = this;  
+	let keys = [];  
+	let val,data;  
+	Object.keys(obj).forEach(function(key){  
+		 keys = key.split('.');  
+		 val = obj[key];  
+		 data = that.$data;  
+		 keys.forEach(function(key2,index){  
+			 if(index+1 == keys.length){  
+				 that.$set(data,key2,val);  
+			 }else{  
+				 if(!data[key2]){  
+					that.$set(data,key2,{});  
+				 }  
+			 }  
+			 data = data[key2];  
+		 })  
+	});
+}

+ 8 - 0
components/tab-page/tab-page.css

@@ -0,0 +1,8 @@
+/* components/tab-page/tab-page.wxss */
+
+.page-content {
+    max-width: 100vw;
+    height: 100%;
+    background: #fff;
+    overflow-y: auto;
+}

+ 33 - 0
components/tab-page/tab-page.vue

@@ -0,0 +1,33 @@
+<template>
+    <!-- components/tab-page/tab-page.wxml -->
+    <view class="page-content">
+        <slot></slot>
+    </view>
+</template>
+
+<script>
+// components/tab-page/tab-page.js
+export default {
+    unicomGroup: ['tabs'],
+    data() {
+        return {};
+    },
+    /**
+     * 组件的属性列表
+     */
+    props: {},
+    relations: {
+        '../tabs/tabs': {
+            type: 'parent'
+        }
+    },
+    /**
+     * 组件的方法列表
+     */
+    methods: {},
+    created: function () {}
+};
+</script>
+<style>
+@import './tab-page.css';
+</style>

+ 78 - 0
components/tabs/tabs.css

@@ -0,0 +1,78 @@
+/* components/tabs/tabs.wxss */
+
+.tabs {
+    max-width: 100vw;
+    display: flex;
+    flex-direction: column;
+}
+
+.tabs-header {
+    max-width: 100vw;
+    height: 80rpx;
+    /* display: flex; */
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    overflow-x: scroll;
+}
+
+.tabs-header::-webkit-scrollbar {
+    display: none;
+    width: 0;
+    height: 0;
+    color: transparent;
+}
+
+.tabs-header-content {
+    display: flex;
+    overflow: visible;
+}
+
+.tabs-item {
+    width: 33%;
+    position: relative;
+    /* display: flex; */
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+}
+.lineBox {
+    /* 选中底线样式 */
+    background: #07c160;
+    margin-top: 16rpx;
+    border-radius: 4rpx;
+}
+
+.tabs-item:last-child {
+    margin-right: 0rpx;
+}
+
+.tabs-item-name {
+    font-size: 34rpx;
+    height: 76rpx;
+    line-height: 76rpx;
+    white-space: nowrap;
+    justify-content: center;
+    align-items: center;
+    text-align: center;
+}
+
+.tabs-item-badge {
+    position: absolute;
+    right: -24rpx;
+    top: 0rpx;
+    width: 36rpx;
+    height: 36rpx;
+    border-radius: 50%;
+    background-color: #d31c1c;
+    color: #ffffff;
+    font-size: 24rpx;
+    line-height: 40rpx;
+    text-align: center;
+}
+
+.tabs-page {
+    width: 100%;
+    flex: 1;
+    background-color: #eeeeee;
+}

+ 114 - 0
components/tabs/tabs.vue

@@ -0,0 +1,114 @@
+<template>
+    <!-- components/tabs/tabs.wxml -->
+    <view class="tabs tab-class">
+        <view class="tabs-header tab-header-class">
+            <view class="tabs-header-content">
+                <view class="tabs-item tab-item-class" @tap="selectIndexFun" :data-index="index" v-for="(item, index) in list" :key="index">
+                    <view class="tabs-item-name tab-item-name-class" :style="'color: ' + (currentClone == index ? activeColor : normalColor) + ';'">{{ item.name }}</view>
+
+                    <view :style="'width: 100%;height:10rpx;display: block; background: ' + (currentClone == index ? activeColor : '#FFFFFF00') + ';border-radius: 4rpx;'"></view>
+
+                    <view class="tabs-item-badge tab-item-badge-class" v-if="showBadge && item.count > 0">{{ item.count }}</view>
+                </view>
+            </view>
+        </view>
+        <swiper class="tabs-page tab-page-class" :current="currentClone" :circular="circular" @change="swiperChangeFun">
+            <swiper-item @touchmove.stop.prevent="parseEventDynamicCode($event, swiper ? '' : '_onTouchMove')" v-for="(item, index) in list" :key="index">
+                <slot :name="item.name"></slot>
+            </swiper-item>
+        </swiper>
+    </view>
+</template>
+
+<script>
+// components/tabs/tabs.js
+export default {
+    unicomGroup: ['tab-page'],
+    data() {
+        return {
+            currentClone: ''
+        };
+    },
+    /**
+     * 组件的属性列表
+     */
+    props: {
+        list: {
+            type: Array,
+            default: () => []
+        },
+        current: {
+            type: Number,
+            default: 0
+        },
+        normalColor: {
+            type: String,
+            default: '#101010'
+        },
+        activeColor: {
+            type: String,
+            default: '#55b428'
+        },
+        showBadge: {
+            type: Boolean,
+            default: true
+        },
+        circular: {
+            type: Boolean,
+            default: true
+        },
+        swiper: {
+            type: Boolean,
+            default: false
+        }
+    },
+    relations: {
+        '../tab-page/tab-page': {
+            type: 'child'
+        }
+    },
+    options: {
+        multipleSlots: true
+    },
+    externalClasses: ['tab-class', 'tab-header-class', 'tab-item-class', 'tab-item-name-class', 'tab-item-badge-class', 'tab-page-class'],
+    /**
+     * 组件的方法列表
+     */
+    methods: {
+        selectIndexFun: function (e) {
+            this.setData({
+                currentClone: e.currentTarget.dataset.index
+            });
+            this.$emit('change', {
+                detail: {
+                    current: e.currentTarget.dataset.index
+                }
+            });
+        },
+        swiperChangeFun: function (e) {
+            this.setData({
+                currentClone: e.detail.current
+            });
+            this.$emit('change', {
+                detail: {
+                    current: e.detail.current
+                }
+            });
+        },
+        onTouchMoveFun: function (e) {}
+    },
+    created: function () {},
+    watch: {
+        current: {
+            handler: function (newVal, oldVal) {
+                this.currentClone = newVal;
+            },
+
+            immediate: true
+        }
+    }
+};
+</script>
+<style>
+@import './tabs.css';
+</style>

+ 4 - 0
components/vtabs/vtabs-content/index.css

@@ -0,0 +1,4 @@
+.weui-tabs-content__item {
+    width: 100%;
+    height: 100%;
+}

+ 54 - 0
components/vtabs/vtabs-content/index.vue

@@ -0,0 +1,54 @@
+<template>
+    <view class="weui-vtabs-content__item" :id="'weui-vtabs-content__' + tabIndex">
+        <slot></slot>
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {};
+    },
+    unicomGroup: ['vtabs'],
+    options: {
+        addGlobalClass: true,
+        multipleSlots: true
+    },
+    props: {
+        tabIndex: {
+            type: Number,
+            default: 0
+        }
+    },
+    relations: {
+        '../vtabs/index': {
+            type: 'parent'
+        }
+    },
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+    methods: {
+        attached: function attached() {},
+
+        calcHeight: function calcHeight(callback) {
+            var query = uni.createSelectorQuery().in(this);
+            query
+                .select('.weui-vtabs-content__item')
+                .boundingClientRect(function (rect) {
+                    if (callback) {
+                        callback(rect);
+                    }
+                })
+                .exec();
+        }
+    },
+    created: function () {}
+};
+
+/***/
+</script>
+<style>
+@import './index.css';
+</style>

+ 44 - 0
components/vtabs/vtabs/index.css

@@ -0,0 +1,44 @@
+.weui-vtabs {
+    width: 100%;
+    height: 100%;
+    display: flex;
+}
+.weui-vtabs-bar__wrp {
+    width: 110px;
+    height: 100%;
+}
+.weui-vtabs-bar__scrollview {
+    height: 100%;
+}
+.weui-vtabs-bar__content {
+    width: 110px;
+    height: 100%;
+}
+.weui-vtabs-bar__item {
+    display: inline-block;
+    width: 110px;
+    height: 55px;
+    border-left: 4px solid transparent;
+}
+.weui-vtabs-bar__title {
+    box-sizing: border-box;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 14px;
+    white-space: nowrap;
+    overflow: hidden;
+}
+.weui-vtabs-content__wrp {
+    overflow: hidden;
+    flex: 1;
+    height: 100%;
+}
+.weui-vtabs-content__scrollview {
+    height: 100%;
+}
+.weui-vtabs-content {
+    height: 100%;
+}

+ 214 - 0
components/vtabs/vtabs/index.vue

@@ -0,0 +1,214 @@
+<template>
+    <view class="weui-vtabs">
+        <view :class="'weui-vtabs-bar__wrp ' + tabBarClass">
+            <scroll-view scroll-y class="weui-vtabs-bar__scrollview" :scroll-into-view="'weui-vtabs-item__' + currentView">
+                <view class="weui-vtabs-bar__content">
+                    <block v-for="(item, index) in vtabs" :key="index">
+                        <view
+                            :id="'weui-vtabs-item__' + index"
+                            class="weui-vtabs-bar__item"
+                            :data-index="index"
+                            :style="
+                                'background-color: ' +
+                                (activeTabClone === index ? tabActiveBgColor : tabInactiveBgColor) +
+                                '; color: ' +
+                                (activeTabClone === index ? tabActiveTextColor : tabInactiveTextColor) +
+                                '; border-left-color: ' +
+                                (activeTabClone === index ? tabLineColor : tabInactiveBgColor)
+                            "
+                            @tap="handleTabClick"
+                        >
+                            <view :class="'weui-vtabs-bar__title ' + (activeTabClone === index ? activeClass : '')">
+                                <text class="">{{ item.title }}</text>
+                            </view>
+                        </view>
+                    </block>
+                </view>
+            </scroll-view>
+        </view>
+        <view class="weui-vtabs-content__wrp">
+            <scroll-view scroll-y class="weui-vtabs-content__scrollview" :scroll-top="contentScrollTop" :scroll-with-animation="animation" @scroll="handleContentScroll">
+                <view class="weui-vtabs-content">
+                    <slot></slot>
+                </view>
+            </scroll-view>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    unicomGroup: ['vtabs-content'],
+    data() {
+        return {
+            currentView: 0,
+            contentScrollTop: 0,
+            heightRecords_var: [],
+            contentHeight_var: {},
+            activeTabClone: 0
+        };
+    },
+    options: {
+        addGlobalClass: true,
+        pureDataPattern: /^_/,
+        multipleSlots: true
+    },
+    props: {
+        vtabs: {
+            type: Array,
+            default: () => []
+        },
+        tabBarClass: {
+            type: String,
+            default: ''
+        },
+        activeClass: {
+            type: String,
+            default: ''
+        },
+        tabLineColor: {
+            type: String,
+            default: '#07c160'
+        },
+        tabInactiveTextColor: {
+            type: String,
+            default: '#000000'
+        },
+        tabActiveTextColor: {
+            type: String,
+            default: '#07c160'
+        },
+        tabInactiveBgColor: {
+            type: String,
+            default: '#eeeeee'
+        },
+        tabActiveBgColor: {
+            type: String,
+            default: '#ffffff'
+        },
+        activeTab: {
+            type: Number,
+            default: 0
+        },
+        animation: {
+            type: Boolean,
+            default: true
+        }
+    },
+    watch: {
+        activeTab: function activeTab(_activeTab) {
+            this.scrollTabBar(_activeTab);
+        },
+
+        activeTab: {
+            handler: function (newVal, oldVal) {
+                this.activeTabClone = newVal;
+            },
+
+            immediate: true
+        }
+    },
+    relations: {
+        '../vtabs-content/index': {
+            type: 'child',
+            linked: function linked(target) {
+                var that = this;
+                target.calcHeight(function (rect) {
+                    that._contentHeight[target.data.tabIndex] = rect.height;
+                    if (that._calcHeightTimer) {
+                        clearTimeout(that._calcHeightTimer);
+                    }
+                    that._calcHeightTimer = setTimeout(function () {
+                        that.calcHeight();
+                    }, 100);
+                });
+            },
+            unlinked: function unlinked(target) {
+                delete this._contentHeight[target.data.tabIndex];
+            }
+        }
+    },
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+    methods: {
+        attached: function attached() {},
+
+        calcHeight: function calcHeight() {
+            var length = this.vtabs.length;
+            var _contentHeight = this._contentHeight;
+            var _heightRecords = [];
+            var temp = 0;
+            for (var i = 0; i < length; i++) {
+                _heightRecords[i] = temp + (_contentHeight[i] || 0);
+                temp = _heightRecords[i];
+            }
+            this._heightRecords = _heightRecords;
+        },
+
+        scrollTabBar: function scrollTabBar(index) {
+            var len = this.vtabs.length;
+            if (len === 0) {
+                return;
+            }
+            var currentView = index < 6 ? 0 : index - 5;
+            if (currentView >= len) {
+                currentView = len - 1;
+            }
+            this.setData({
+                currentView: currentView
+            });
+        },
+
+        handleTabClick: function handleTabClick(e) {
+            var _heightRecords = this._heightRecords;
+            var index = e.currentTarget.dataset.index;
+            var contentScrollTop = _heightRecords[index - 1] || 0;
+            this.$emit('tabclick', {
+                detail: {
+                    index: index
+                }
+            });
+            this.setData({
+                activeTabClone: index,
+                contentScrollTop: contentScrollTop
+            });
+        },
+
+        handleContentScroll: function handleContentScroll(e) {
+            var _heightRecords = this._heightRecords;
+            if (_heightRecords.length === 0) {
+                return;
+            }
+            var length = this.vtabs.length;
+            var scrollTop = e.detail.scrollTop + (length - 1) * 0.19;
+            var index = 0;
+            if (scrollTop >= _heightRecords[0]) {
+                for (var i = 1; i < length; i++) {
+                    if (scrollTop >= _heightRecords[i - 1] && scrollTop < _heightRecords[i]) {
+                        index = i;
+                        break;
+                    }
+                }
+            }
+            if (index !== this.activeTab) {
+                this.$emit('change', {
+                    detail: {
+                        index: index
+                    }
+                });
+                this.setData({
+                    activeTabClone: index
+                });
+            }
+        }
+    },
+    created: function () {}
+};
+
+/***/
+</script>
+<style>
+@import './index.css';
+</style>

+ 0 - 31
config.js

@@ -1,31 +0,0 @@
-// 应用全局配置
-module.exports = {
-
-	// baseUrl: 'https://www.xcx.cczdsz.cn/prod-api',
-	// baseUrl: 'http://192.168.4.6:8080',
-	baseUrl: 'http://127.0.0.1:8080',
-	// baseUrl: 'http://192.168.4.11:8080',
-	// baseUrl: 'http://192.168.4.14:8089',
-	// baseIconUrl: 'https://www.xcx.cczdsz.cn/app/images/',
-	// 应用信息
-	appInfo: {
-		// 应用名称
-		name: "ruoyi-app",
-		// 应用版本
-		version: "1.1.0",
-		// 应用logo
-		logo: "/static/logo.png",
-		// 官方网站
-		site_url: "http://ruoyi.vip",
-		// 政策协议
-		agreements: [{
-				title: "隐私政策",
-				url: "https://ruoyi.vip/protocol.html"
-			},
-			{
-				title: "用户服务协议",
-				url: "https://ruoyi.vip/protocol.html"
-			}
-		]
-	}
-}

+ 377 - 0
data/json.js

@@ -0,0 +1,377 @@
+var qbwd = [
+    {
+        ck: '10',
+        dz: '10',
+        id: 1,
+        imgList: [],
+        jf: '100',
+        pl: '10',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '20',
+        dz: '200',
+        id: 2,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '220',
+        pl: '20',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '30',
+        dz: '320',
+        id: 3,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            }
+        ],
+        jf: '300',
+        ly: '30',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '40',
+        dz: '420',
+        id: 4,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            },
+            {
+                url: '/xczx03.png'
+            }
+        ],
+        jf: '400',
+        pl: '40',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '50',
+        dz: '520',
+        id: 5,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            },
+            {
+                url: '/xczx03.png'
+            }
+        ],
+        jf: '500',
+        pl: '50',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '60',
+        dz: '620',
+        id: 6,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            }
+        ],
+        jf: '600',
+        pl: '60',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    }
+];
+var jcwd = [
+    {
+        ck: '30',
+        dz: '320',
+        id: 3,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '300',
+        ly: '30',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '10',
+        dz: '10',
+        id: 1,
+        imgList: [],
+        jf: '100',
+        pl: '10',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '20',
+        dz: '200',
+        id: 2,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '220',
+        pl: '20',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '40',
+        dz: '420',
+        id: 4,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            }
+        ],
+        jf: '400',
+        pl: '40',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '50',
+        dz: '520',
+        id: 5,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            },
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '500',
+        pl: '50',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '60',
+        dz: '620',
+        id: 6,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            }
+        ],
+        jf: '600',
+        pl: '60',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    }
+];
+var zdxs = [
+    {
+        ck: '50',
+        dz: '520',
+        id: 5,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            },
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '500',
+        pl: '50',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '30',
+        dz: '320',
+        id: 3,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '300',
+        ly: '30',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '10',
+        dz: '10',
+        id: 1,
+        imgList: [],
+        jf: '100',
+        pl: '10',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '20',
+        dz: '200',
+        id: 2,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '220',
+        pl: '20',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '40',
+        dz: '420',
+        id: 4,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            }
+        ],
+        jf: '400',
+        pl: '40',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '60',
+        dz: '620',
+        id: 6,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx02.png'
+            }
+        ],
+        jf: '600',
+        pl: '60',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    }
+];
+var wb = [
+    {
+        ck: '10',
+        dz: '120',
+        id: 1,
+        jf: '100',
+        pl: '10',
+        title: '探索乡村能源供给新模式',
+        type: '三农'
+    },
+    {
+        ck: '20',
+        dz: '220',
+        id: 2,
+        jf: '200',
+        ly: '20',
+        title: '探索乡村能源供给新模式 美丽新画卷',
+        type: '三农'
+    },
+    {
+        ck: '30',
+        dz: '30',
+        id: 3,
+        jf: '300',
+        pl: '30',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷',
+        type: '三农'
+    }
+];
+var index = [
+    {
+        ck: '10',
+        dz: '10',
+        id: 1,
+        imgList: [],
+        jf: '100',
+        pl: '10',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '20',
+        dz: '200',
+        id: 2,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '220',
+        pl: '20',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '30',
+        dz: '320',
+        id: 3,
+        imgList: [
+            {
+                url: '/xczx01.png'
+            },
+            {
+                url: '/xczx01.png'
+            }
+        ],
+        jf: '300',
+        ly: '30',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    },
+    {
+        ck: '40',
+        dz: '420',
+        id: 4,
+        imgList: [
+            {
+                url: '/img1.png'
+            },
+            {
+                url: '/img1.png'
+            },
+            {
+                url: '/img1.png'
+            }
+        ],
+        jf: '400',
+        pl: '40',
+        title: '探索乡村能源供给新模式 绘就乡村振兴美丽新画卷'
+    }
+];
+module.exports = {
+    qnwdList: qbwd,
+    jcwdList: jcwd,
+    zdxsList: zdxs,
+    wbList: wb,
+    indexList: index
+};

+ 20 - 0
index.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <script>
+      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
+        CSS.supports('top: constant(a)'))
+      document.write(
+        '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
+        (coverSupport ? ', viewport-fit=cover' : '') + '" />')
+    </script>
+    <title></title>
+    <!--preload-links-->
+    <!--app-context-->
+  </head>
+  <body>
+    <div id="app"><!--app-html--></div>
+    <script type="module" src="/main.js"></script>
+  </body>
+</html>

+ 35 - 21
main.js

@@ -1,26 +1,40 @@
-import Vue from 'vue'
-import App from './App'
-import store from './store' // store
-import plugins from './plugins' // plugins
-import './permission' // permission
-import config from '@/config'
-Vue.use(plugins)
+import App from './App';
 
-Vue.config.productionTip = false
-Vue.prototype.$store = store
+// 全局mixins,用于实现setData等功能,请勿删除!';
+import zpMixins from '@/uni_modules/zp-mixins/index.js';
 
+// #ifndef VUE3
+import Vue from 'vue';
 
-App.mpType = 'app'
-// 挂载全局图片地址
-Vue.prototype.$HTTP = config.baseUrl
-// 图片使用网络地址
-Vue.prototype.loadImgSrc = function(img) {
-	//项目的地址域名,例如百度
-	return config.baseIconUrl+img;
-}
+Vue.use(zpMixins);
+
+// 导入p-f-unicom
+import unicom from '@/uni_modules/p-f-unicom/index.js';
+import * as setData from '@/common/utils/setDataOverride.js'
+// setData重写
+// 用于解决组件间关系(目前受制于平台及写法,仍可能存在小部分场景不生效,需手动调试修复或『替换对应组件』)
+Vue.use(unicom, {
+    name: 'unicom',
+    idName: 'unicomId',
+    groupName: 'unicomGroup'
+});
 
-const app = new Vue({  
-	...App
-})
+Vue.config.productionTip = false;
+Vue.prototype.setData = setData
+App.mpType = 'app';
+const app = new Vue({
+    ...App
+});
+app.$mount();
+// #endif
 
-app.$mount()
+// #ifdef VUE3
+import { createSSRApp } from 'vue';
+export function createApp() {
+    const app = createSSRApp(App);
+    app.mixin(zpMixins);
+    return {
+        app
+    };
+}
+// #endif

+ 69 - 79
manifest.json

@@ -1,80 +1,70 @@
 {
-    "name" : "长春市贞达市政施工管理平台",
-    "appid" : "__UNI__25A9D80",
-    "description" : "",
-    "versionName" : "1.1.0",
-    "versionCode" : "100",
-    "transformPx" : false,
-    "app-plus" : {
-        "usingComponents" : true,
-        "nvueCompiler" : "uni-app",
-        "splashscreen" : {
-            "alwaysShowBeforeRender" : true,
-            "waiting" : true,
-            "autoclose" : true,
-            "delay" : 0
-        },
-        "modules" : {
-            "OAuth" : {}
-        },
-        "distribute" : {
-            "android" : {
-                "permissions" : [
-                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
-                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
-                ]
-            },
-            "ios" : {},
-            "sdkConfigs" : {
-                "oauth" : {
-                    "weixin" : {
-                        "appid" : "wxf75b34dd1f737174",
-                        "UniversalLinks" : ""
-                    }
-                }
-            }
-        }
-    },
-    "quickapp" : {},
-    "mp-weixin" : {
-        "appid" : "wxf75b34dd1f737174",
-        "setting" : {
-            "urlCheck" : false,
-            "es6" : false,
-            "minified" : true,
-            "postcss" : true
-        },
-        "optimization" : {
-            "subPackages" : true
-        },
-        "usingComponents" : true,
-        "permission" : {},
-        "lazyCodeLoading" : "requiredComponents"
-    },
-    "vueVersion" : "2",
-    "h5" : {
-        "template" : "static/index.html",
-        "devServer" : {
-            "port" : 9090,
-            "https" : false
-        },
-        "title" : "RuoYi-App",
-        "router" : {
-            "mode" : "hash",
-            "base" : "./"
-        }
-    }
-}
+	"name": "",
+	"appid": "",
+	"description": "",
+	"versionName": "1.0.0",
+	"versionCode": "100",
+	"transformPx": false,
+	"app-plus": {
+		"usingComponents": true,
+		"nvueStyleCompiler": "uni-app",
+		"compilerVersion": 3,
+		"splashscreen": {
+			"alwaysShowBeforeRender": true,
+			"waiting": true,
+			"autoclose": true,
+			"delay": 0
+		},
+		"modules": {},
+		"distribute": {
+			"android": {
+				"permissions": [
+					"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
+					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+					"<uses-feature android:name=\"android.hardware.camera\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+				]
+			},
+			"ios": {},
+			"sdkConfigs": {}
+		}
+	},
+	"quickapp": {},
+	"mp-weixin": {
+		"appid": "wxea9d81159fec0287",
+		"setting": {
+			"urlCheck": false
+		},
+		"usingComponents": true,
+		"permission": {
+			"scope.userLocation": {
+				"desc": "你的位置信息将用于小程序位置接口的效果展示"
+			}
+		},
+		"plugins": {}
+	},
+	"mp-alipay": {
+		"usingComponents": true
+	},
+	"mp-baidu": {
+		"usingComponents": true
+	},
+	"mp-toutiao": {
+		"usingComponents": true
+	},
+	"uniStatistics": {
+		"enable": false
+	},
+	"vueVersion": "2"
+}

+ 18 - 0
node_modules/.package-lock.json

@@ -0,0 +1,18 @@
+{
+	"name": "sookauniapp_demo_uni",
+	"version": "1.0.0",
+	"lockfileVersion": 2,
+	"requires": true,
+	"packages": {
+		"node_modules/@miniprogram-component-plus/vtabs": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/@miniprogram-component-plus/vtabs/-/vtabs-1.0.0.tgz",
+			"integrity": "sha512-xDGrJwRbcpxd92rpQ0bbesBd2TKR6RGX1kJjuC6jlN4nRr28MTBhSPQEWfof2COms0xrLTa4WzU1QL+C2KH59w=="
+		},
+		"node_modules/@miniprogram-component-plus/vtabs-content": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/@miniprogram-component-plus/vtabs-content/-/vtabs-content-1.0.0.tgz",
+			"integrity": "sha512-/DGQjL1W1X7IMfOlB1ILfMZqyvhHHlrUsQ2liuVMZCwn46z5fTTQHcFWZKYZONaxKjTO3AecjRypKF0/k2s9aQ=="
+		}
+	}
+}

+ 127 - 0
node_modules/@miniprogram-component-plus/vtabs-content/miniprogram_dist/index.js

@@ -0,0 +1,127 @@
+module.exports =
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// define __esModule on exports
+/******/ 	__webpack_require__.r = function(exports) {
+/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 		}
+/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 	};
+/******/
+/******/ 	// create a fake namespace object
+/******/ 	// mode & 1: value is a module id, require it
+/******/ 	// mode & 2: merge all properties of value into the ns
+/******/ 	// mode & 4: return value when already ns object
+/******/ 	// mode & 8|1: behave like require
+/******/ 	__webpack_require__.t = function(value, mode) {
+/******/ 		if(mode & 1) value = __webpack_require__(value);
+/******/ 		if(mode & 8) return value;
+/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ 		var ns = Object.create(null);
+/******/ 		__webpack_require__.r(ns);
+/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ 		return ns;
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 7);
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ 7:
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Component({
+    options: {
+        addGlobalClass: true,
+        multipleSlots: true
+    },
+    properties: {
+        tabIndex: {
+            type: Number,
+            value: 0
+        }
+    },
+    relations: {
+        '../vtabs/index': {
+            type: 'parent'
+        }
+    },
+    lifetimes: {
+        attached: function attached() {}
+    },
+    methods: {
+        calcHeight: function calcHeight(callback) {
+            var query = this.createSelectorQuery();
+            query.select('.weui-vtabs-content__item').boundingClientRect(function (rect) {
+                callback && callback(rect);
+            }).exec();
+        }
+    }
+});
+
+/***/ })
+
+/******/ });

+ 4 - 0
node_modules/@miniprogram-component-plus/vtabs-content/miniprogram_dist/index.json

@@ -0,0 +1,4 @@
+{
+    "component": true,
+    "usingComponents": {}
+}

+ 3 - 0
node_modules/@miniprogram-component-plus/vtabs-content/miniprogram_dist/index.wxml

@@ -0,0 +1,3 @@
+<view class="weui-vtabs-content__item" id="weui-vtabs-content__{{tabIndex}}">
+  <slot ></slot>
+</view>

+ 1 - 0
node_modules/@miniprogram-component-plus/vtabs-content/miniprogram_dist/index.wxss

@@ -0,0 +1 @@
+.weui-tabs-content__item{width:100%;height:100%}

+ 15 - 0
node_modules/@miniprogram-component-plus/vtabs-content/package.json

@@ -0,0 +1,15 @@
+{
+  "name": "@miniprogram-component-plus/vtabs-content",
+  "version": "1.0.0",
+  "description": "",
+  "main": "miniprogram_dist/index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [
+    "tabs",
+    "miniprogram"
+  ],
+  "author": "sanfordsun",
+  "license": "ISC"
+}

+ 202 - 0
node_modules/@miniprogram-component-plus/vtabs/miniprogram_dist/index.js

@@ -0,0 +1,202 @@
+module.exports =
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// define __esModule on exports
+/******/ 	__webpack_require__.r = function(exports) {
+/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 		}
+/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 	};
+/******/
+/******/ 	// create a fake namespace object
+/******/ 	// mode & 1: value is a module id, require it
+/******/ 	// mode & 2: merge all properties of value into the ns
+/******/ 	// mode & 4: return value when already ns object
+/******/ 	// mode & 8|1: behave like require
+/******/ 	__webpack_require__.t = function(value, mode) {
+/******/ 		if(mode & 1) value = __webpack_require__(value);
+/******/ 		if(mode & 8) return value;
+/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ 		var ns = Object.create(null);
+/******/ 		__webpack_require__.r(ns);
+/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ 		return ns;
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 6);
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ 6:
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Component({
+    options: {
+        addGlobalClass: true,
+        pureDataPattern: /^_/,
+        multipleSlots: true
+    },
+    properties: {
+        vtabs: { type: Array, value: [] },
+        tabBarClass: { type: String, value: '' },
+        activeClass: { type: String, value: '' },
+        tabLineColor: { type: String, value: '#ff0000' },
+        tabInactiveTextColor: { type: String, value: '#000000' },
+        tabActiveTextColor: { type: String, value: '#ff0000' },
+        tabInactiveBgColor: { type: String, value: '#eeeeee' },
+        tabActiveBgColor: { type: String, value: '#ffffff' },
+        activeTab: { type: Number, value: 0 },
+        animation: { type: Boolean, value: true }
+    },
+    data: {
+        currentView: 0,
+        contentScrollTop: 0,
+        _heightRecords: [],
+        _contentHeight: {}
+    },
+    observers: {
+        activeTab: function activeTab(_activeTab) {
+            this.scrollTabBar(_activeTab);
+        }
+    },
+    relations: {
+        '../vtabs-content/index': {
+            type: 'child',
+            linked: function linked(target) {
+                var _this = this;
+
+                target.calcHeight(function (rect) {
+                    _this.data._contentHeight[target.data.tabIndex] = rect.height;
+                    if (_this._calcHeightTimer) {
+                        clearTimeout(_this._calcHeightTimer);
+                    }
+                    _this._calcHeightTimer = setTimeout(function () {
+                        _this.calcHeight();
+                    }, 100);
+                });
+            },
+            unlinked: function unlinked(target) {
+                delete this.data._contentHeight[target.data.tabIndex];
+            }
+        }
+    },
+    lifetimes: {
+        attached: function attached() {}
+    },
+    methods: {
+        calcHeight: function calcHeight() {
+            var length = this.data.vtabs.length;
+            var _contentHeight = this.data._contentHeight;
+            var _heightRecords = [];
+            var temp = 0;
+            for (var i = 0; i < length; i++) {
+                _heightRecords[i] = temp + (_contentHeight[i] || 0);
+                temp = _heightRecords[i];
+            }
+            this.data._heightRecords = _heightRecords;
+        },
+        scrollTabBar: function scrollTabBar(index) {
+            var len = this.data.vtabs.length;
+            if (len === 0) return;
+            var currentView = index < 6 ? 0 : index - 5;
+            if (currentView >= len) currentView = len - 1;
+            this.setData({ currentView: currentView });
+        },
+        handleTabClick: function handleTabClick(e) {
+            var _heightRecords = this.data._heightRecords;
+            var index = e.currentTarget.dataset.index;
+            var contentScrollTop = _heightRecords[index - 1] || 0;
+            this.triggerEvent('tabclick', { index: index });
+            this.setData({
+                activeTab: index,
+                contentScrollTop: contentScrollTop
+            });
+        },
+        handleContentScroll: function handleContentScroll(e) {
+            var _heightRecords = this.data._heightRecords;
+            if (_heightRecords.length === 0) return;
+            var length = this.data.vtabs.length;
+            var scrollTop = e.detail.scrollTop;
+            var index = 0;
+            if (scrollTop >= _heightRecords[0]) {
+                for (var i = 1; i < length; i++) {
+                    if (scrollTop >= _heightRecords[i - 1] && scrollTop < _heightRecords[i]) {
+                        index = i;
+                        break;
+                    }
+                }
+            }
+            if (index !== this.data.activeTab) {
+                this.triggerEvent('change', { index: index });
+                this.setData({ activeTab: index });
+            }
+        }
+    }
+});
+
+/***/ })
+
+/******/ });

+ 4 - 0
node_modules/@miniprogram-component-plus/vtabs/miniprogram_dist/index.json

@@ -0,0 +1,4 @@
+{
+    "component": true,
+    "usingComponents": {}
+}

+ 38 - 0
node_modules/@miniprogram-component-plus/vtabs/miniprogram_dist/index.wxml

@@ -0,0 +1,38 @@
+<view class="weui-vtabs">
+  <view class="weui-vtabs-bar__wrp {{tabBarClass}}">
+    <scroll-view 
+      scroll-y
+      class="weui-vtabs-bar__scrollview"
+      scroll-into-view="weui-vtabs-item__{{currentView}}"
+    >
+      <view class="weui-vtabs-bar__content">
+        <block wx:for="{{vtabs}}" wx:key="title">
+          <view 
+            id="weui-vtabs-item__{{index}}"
+            class="weui-vtabs-bar__item"
+            data-index="{{index}}"
+            style="background-color: {{activeTab === index ? tabActiveBgColor : tabInactiveBgColor}}; color: {{activeTab === index ? tabActiveTextColor : tabInactiveTextColor}}; border-left-color: {{activeTab === index ? tabLineColor : tabInactiveBgColor}}"
+            bindtap="handleTabClick"
+          >
+            <view class="weui-vtabs-bar__title {{activeTab === index ? activeClass : ''}}">
+              <text class="">{{item.title}}</text>
+            </view>
+          </view>
+        </block>
+      </view>
+    </scroll-view>
+  </view>
+  <view class="weui-vtabs-content__wrp">
+    <scroll-view 
+      scroll-y
+      class="weui-vtabs-content__scrollview" 
+      scroll-top="{{contentScrollTop}}"
+      scroll-with-animation="{{animation}}"
+      bindscroll="handleContentScroll"
+    >
+      <view class="weui-vtabs-content">
+        <slot ></slot>
+      </view>
+    </scroll-view>
+  </view>
+</view>

Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
node_modules/@miniprogram-component-plus/vtabs/miniprogram_dist/index.wxss


+ 15 - 0
node_modules/@miniprogram-component-plus/vtabs/package.json

@@ -0,0 +1,15 @@
+{
+  "name": "@miniprogram-component-plus/vtabs",
+  "version": "1.0.0",
+  "description": "",
+  "main": "miniprogram_dist/index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [
+    "tabs",
+    "miniprogram"
+  ],
+  "author": "sanfordsun",
+  "license": "ISC"
+}

+ 38 - 0
package-lock.json

@@ -0,0 +1,38 @@
+{
+	"name": "sookauniapp_demo_uni",
+	"version": "1.0.0",
+	"lockfileVersion": 2,
+	"requires": true,
+	"packages": {
+		"": {
+			"version": "1.0.0",
+			"license": "[object Object]",
+			"dependencies": {
+				"@miniprogram-component-plus/vtabs": "^1.0.0",
+				"@miniprogram-component-plus/vtabs-content": "^1.0.0"
+			}
+		},
+		"node_modules/@miniprogram-component-plus/vtabs": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/@miniprogram-component-plus/vtabs/-/vtabs-1.0.0.tgz",
+			"integrity": "sha512-xDGrJwRbcpxd92rpQ0bbesBd2TKR6RGX1kJjuC6jlN4nRr28MTBhSPQEWfof2COms0xrLTa4WzU1QL+C2KH59w=="
+		},
+		"node_modules/@miniprogram-component-plus/vtabs-content": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/@miniprogram-component-plus/vtabs-content/-/vtabs-content-1.0.0.tgz",
+			"integrity": "sha512-/DGQjL1W1X7IMfOlB1ILfMZqyvhHHlrUsQ2liuVMZCwn46z5fTTQHcFWZKYZONaxKjTO3AecjRypKF0/k2s9aQ=="
+		}
+	},
+	"dependencies": {
+		"@miniprogram-component-plus/vtabs": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/@miniprogram-component-plus/vtabs/-/vtabs-1.0.0.tgz",
+			"integrity": "sha512-xDGrJwRbcpxd92rpQ0bbesBd2TKR6RGX1kJjuC6jlN4nRr28MTBhSPQEWfof2COms0xrLTa4WzU1QL+C2KH59w=="
+		},
+		"@miniprogram-component-plus/vtabs-content": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/@miniprogram-component-plus/vtabs-content/-/vtabs-content-1.0.0.tgz",
+			"integrity": "sha512-/DGQjL1W1X7IMfOlB1ILfMZqyvhHHlrUsQ2liuVMZCwn46z5fTTQHcFWZKYZONaxKjTO3AecjRypKF0/k2s9aQ=="
+		}
+	}
+}

+ 14 - 13
package.json

@@ -1,14 +1,15 @@
 {
-  "name": "jnb_wechatapp",
-  "version": "1.0.0",
-  "main": "main.js",
-  "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "author": "",
-  "license": "ISC",
-  "description": "",
-  "dependencies": {
-    "quill": "^1.3.7"
-  }
-}
+	"name": "",
+	"version": "1.0.0",
+	"description": "",
+	"main": "main.js",
+	"scripts": {
+		"test": "echo \"Error: no test specified\" && exit 1"
+	},
+	"author": "",
+	"dependencies": {
+		"@miniprogram-component-plus/vtabs": "^1.0.0",
+		"@miniprogram-component-plus/vtabs-content": "^1.0.0"
+	},
+	"license": "[object Object]"
+}

+ 112 - 34
pages.json

@@ -1,61 +1,139 @@
 {
 	"pages": [
 		{
-			"path": "pages/login",
+			"path": "pages/index/index",
 			"style": {
-				"navigationBarTitleText": "登录",
-				"navigationStyle": "custom"
+				"component": true,
+				"usingComponents": {},
+				"navigationStyle": "custom",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "吉村宝"
 			}
 		},
 		{
-			"path": "pages/demo/index",
+			"path": "pages/me/me",
 			"style": {
-				"navigationBarTitleText": "通知公告",
-				"navigationStyle": "custom"
+				"usingComponents": {},
+				"navigationBarBackgroundColor": "#07c160",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "我的"
 			}
 		},
-		
 		{
-			"path": "pages/demo/my",
+			"path": "pages/fuwu/fuwu",
 			"style": {
-				"navigationBarTitleText": "我的",
-				"navigationStyle": "custom"
+				"usingComponents": {},
+				"navigationBarBackgroundColor": "#07c160",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "资讯"
 			}
 		},
 		{
-			"path": "pages/demo/delis",
+			"path": "pages/wenba/wenba",
 			"style": {
-				"navigationBarTitleText": "详情",
-				"navigationStyle": "custom"
+				"usingComponents": {},
+				"navigationBarBackgroundColor": "#07c160",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "问吧"
 			}
 		},
 		{
-			"path": "pages/demo/fwblz",
+			"path": "pages/sannong/sannong",
 			"style": {
-				"navigationBarTitleText": "详情",
-				"navigationStyle": "custom"
+				"usingComponents": {
+					"tabs": "../../components/tabs/tabs",
+					"tab-page": "../../components/tab-page/tab-page"
+				},
+				"navigationBarBackgroundColor": "#07c160",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "三农"
+			}
+		},
+		{
+			"path": "pages/wenbaxiangqing/wenbaxiangqing",
+			"style": {
+				"usingComponents": {},
+				"navigationBarBackgroundColor": "#07c160",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "问吧详情"
+			}
+		},
+		{
+			"path": "pages/shangcheng/shangcheng",
+			"style": {
+				"usingComponents": {},
+				"navigationBarBackgroundColor": "#07c160",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "商城首页"
+			}
+		},
+		{
+			"path": "pages/fenlei/fenlei",
+			"style": {
+				"usingComponents": {
+					"mp-vtabs": "../../components/vtabs/vtabs/index",
+					"mp-vtabs-content": "../../components/vtabs/vtabs-content/index"
+				},
+				"navigationBarBackgroundColor": "#07c160",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "分类"
+			}
+		},
+		{
+			"path": "pages/shangpinxiangqingye/shangpinxiangqingye",
+			"style": {
+				"usingComponents": {},
+				"navigationBarBackgroundColor": "#07c160",
+				"navigationBarTextStyle": "white",
+				"navigationBarTitleText": "商品详情页"
 			}
 		}
 	],
 	"tabBar": {
-		"color": "#5a5a5a",
-		"selectedColor": "#2a95f1",
-		"borderStyle": "white",
-		"backgroundColor": "#ffffff",
-		"list": [{
-			"pagePath": "pages/demo/index",
-			"iconPath": "static/images/tabbar/gg.png",
-			"selectedIconPath": "static/images/tabbar/gg_.png",
-			"text": "公告"
-		},{
-			"pagePath": "pages/demo/my",
-			"iconPath": "static/images/tabbar/gg.png",
-			"selectedIconPath": "static/images/tabbar/gg_.png",
-			"text": "我的"
-		}]
+		"index": "-1",
+		"color": "#737373",
+		"selectedColor": "#2f2f2f",
+		"borderStyle": "black",
+		"backgroundColor": "#f9f9f9",
+		"list": [
+			{
+				"text": "服务",
+				"pagePath": "pages/index/index",
+				"iconPath": "static/pages/images/fuwu2.png",
+				"selectedIconPath": "static/pages/images/fuwu1.png"
+			},
+			{
+				"text": "资讯",
+				"pagePath": "pages/fuwu/fuwu",
+				"iconPath": "static/pages/images/index2.png",
+				"selectedIconPath": "static/pages/images/index1.png"
+			},
+			{
+				"text": "我的",
+				"pagePath": "pages/me/me",
+				"iconPath": "static/pages/images/me2.png",
+				"selectedIconPath": "static/pages/images/me1.png"
+			}
+		]
 	},
+	"style": "v2",
+	"sitemapLocation": "sitemap.json",
+	"lazyCodeLoading": "requiredComponents",
 	"globalStyle": {
-		"navigationBarTextStyle": "white",
-		"navigationBarBackgroundColor": "#77b0ff"
-	}
+		"backgroundTextStyle": "light",
+		"navigationBarBackgroundColor": "#fff",
+		"navigationBarTitleText": "Weixin",
+		"navigationBarTextStyle": "black"
+	},
+	"condition" : { //模式配置,仅开发期间生效
+		"current": 0, //当前激活的模式(list 的索引项)
+		"list": [
+			{
+				"name": "", //模式名称
+				"path": "", //启动页面,必选
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			}
+		]
+	},
+	"subPackages": []
 }

+ 0 - 375
pages/demo/delis.vue

@@ -1,375 +0,0 @@
-<template>
-	<view class="gg-container">
-		<view class="gg-tit">
-			<view class="gg-title">
-				我的吉农宝<text>上个页面传过来的参数{{id}}</text>
-			</view>
-			<view>
-			<uni-section title="基本用法" type="line">
-						<view class="example">
-							<!-- 基础用法,不包含校验规则 -->
-							<uni-forms ref="baseForm" :modelValue="baseFormData">
-								<uni-forms-item label="姓名" required>
-									<uni-easyinput v-model="baseFormData.name" placeholder="请输入姓名" />
-								</uni-forms-item>
-								<uni-forms-item label="年龄" required>
-									<uni-easyinput v-model="baseFormData.age" placeholder="请输入年龄" />
-								</uni-forms-item>
-								<uni-forms-item label="性别" required>
-									<uni-data-checkbox v-model="baseFormData.sex" :localdata="sexs" />
-								</uni-forms-item>
-								<uni-forms-item label="兴趣爱好" required>
-									<uni-data-checkbox v-model="baseFormData.hobby" multiple :localdata="hobbys" />
-								</uni-forms-item>
-								<uni-forms-item label="自我介绍">
-									<uni-easyinput type="textarea" v-model="baseFormData.introduction" placeholder="请输入自我介绍" />
-								</uni-forms-item>
-								<uni-forms-item label="日期时间">
-									<uni-datetime-picker type="datetime" return-type="timestamp" v-model="baseFormData.datetimesingle"/>
-								</uni-forms-item>
-							</uni-forms>
-						</view>
-					</uni-section>
-					<uni-section title="多行文本" subTitle="指定属性 type=textarea 使用多行文本框" type="line" padding>
-						<uni-easyinput type="textarea" v-model="value" placeholder="请输入内容"></uni-easyinput>
-					</uni-section>
-					<view class="content">
-						<editor
-							class="myEdit"
-							placeholder="写点什么吧~~"
-							show-img-resize
-							show-img-toolbar
-							show-img-size
-							@ready="onEditReady"
-							@focus="OnFocus"
-							@statuschange="statuschange"
-						></editor>
-					</view>
-					<view class="btnGroup">
-						<u-button type="primary" text="确认发表" @click="onSubmit" :disabled="!artData.title"></u-button>
-					</view>
-					<view class="tools" v-show="toolsShow">
-						<!-- 标题 -->
-						<view class="item" @click="headChange">
-							<text class="iconfont icon-zitibiaoti" :class="headShow ? 'active' : ''"></text>
-						</view>
-						<!-- 加粗 -->
-						<view class="item" @click="boldChange">
-							<text class="iconfont icon-zitijiacu" :class="boldShow ? 'active' : ''"></text>
-						</view>
-						<!-- 斜体 -->
-						<view class="item" @click="italicChange">
-							<text class="iconfont icon-zitixieti" :class="italicShow ? 'active' : ''"></text>
-						</view>
-						<!-- 分割线 -->
-						<view class="item" @click="insertDivider"><text class="iconfont icon-fengexian"></text></view>
-						<view class="item" @click="insertImage"><text class="iconfont icon-charutupian"></text></view>
-						<!-- 完成 -->
-						<view class="item" @click="editOk"><text class="iconfont icon-duigou_kuai"></text></view>
-					</view>
-							    <!-- 这张图片就是自定义的图片,地址填写自己本地的就行 -->
-					<image src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png" 
-					mode="widthFix" style="width: 112rpx;height: 110rpx;" @click="uploadImagePhoto()"></image>
-					
-				</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-				toolsShow: false,
-				editorContent: null,
-				headShow: false,
-				boldShow: false,
-				italicShow: false,
-				artData: {
-					title: '',
-					content: ''
-				},
-				
-				
-				baseFormData: {
-					name: '',
-					age: '',
-					introduction: '',
-					sex: 2,
-					hobby: [5],
-					datetimesingle: 1627529992399
-				},
-				// 单选数据源
-				sexs: [{
-					text: '男',
-					value: 0
-				}, {
-					text: '女',
-					value: 1
-				}, {
-					text: '保密',
-					value: 2
-				}],
-				// 多选数据源
-				hobbys: [{
-					text: '跑步',
-					value: 0
-				}, {
-					text: '游泳',
-					value: 1
-				}, {
-					text: '绘画',
-					value: 2
-				}, {
-					text: '足球',
-					value: 3
-				}, {
-					text: '篮球',
-					value: 4
-				}, {
-					text: '其他',
-					value: 5
-				}],
-				value: '',
-				password: '',
-				placeholderStyle: "color:#2979FF;font-size:14px",
-				styles: {
-					color: '#2979FF',
-					borderColor: '#2979FF'
-				},
-				id:'',
-				fileList1: []
-			}
-
-		},
-		onLoad(options) {
-			this.id = options.id;
-		},
-		onReady() {},
-		methods: {
-			input(e) {
-				console.log('输入内容:', e);
-			},
-			iconClick(type) {
-				uni.showToast({
-					title: `点击了${type==='prefix'?'左侧':'右侧'}的图标`,
-					icon: 'none'
-				})
-			},
-			//*****************************************富文本编辑器方法**********************************************//
-			// 初始化
-			onEditReady() {
-				// 查询节点信息的对象
-				// 将选择器的选取范围更改为自定义组件 component 内,返回一个 SelectorQuery 对象实例。(初始时,选择器仅选取页面范围的节点,不会选取任何自定义组件中的节点)。
-				// 在当前页面下选择第一个匹配选择器 selector 的节点,返回一个 NodesRef 对象实例,可以用于获取节点信息。
-				// 获取节点的相关信息。第一个参数是节点相关信息配置(必选);第二参数是方法的回调函数,参数是指定的相关节点信息。
-				// 执行所有的请求。请求结果按请求次序构成数组,在 callback 的第一个参数中返回。
-				uni.createSelectorQuery()
-					.in(this)
-					.select('.myEdit')
-					.fields(
-						{
-							size: true, //是否返回节点尺寸(width height)
-							context: true //是否返回节点尺寸(width height)
-						},
-						(res) => {
-							console.log(res);
-							this.editorContent = res.context;
-						}
-					)
-					.exec();
-			},
-			// 离开焦点
-			OnFocus() {
-				this.toolsShow = true;
-			},
-			// 添加分割线
-			insertDivider() {
-				this.editorContent.insertDivider();
-			},
-			// 添加大标题
-			headChange() {
-				this.headShow = !this.headShow;
-				this.editorContent.format('header', this.headShow ? 'H2' : false);
-			},
-			// 加粗
-			boldChange() {
-				this.boldShow = !this.boldShow;
-				this.editorContent.format('bold');
-			},
-			// 斜体
-			italicChange() {
-				this.italicShow = !this.italicShow;
-				this.editorContent.format('italic');
-			},
-			// 用于检查对象detail是否包含名为name的属性
-			checkStatus(name, detail, key) {
-				if (detail.hasOwnProperty(name)) {
-					this[key] = true;
-				} else {
-					this[key] = false;
-				}
-			},
-			// 通过 Context 方法改变编辑器内样式时触发,返回选区已设置的样式(解决标题标签回弹问题)
-			statuschange(e) {
-				let detail = e.detail;
-				console.log(detail);
-				this.checkStatus('header', detail, 'headShow');
-				this.checkStatus('bold', detail, 'boldShow');
-				this.checkStatus('italic', detail, 'italicShow');
-			},
-			// 添加图像
-			insertImage() {
-				// 打开相机
-				uni.chooseImage({
-					count: 3, //默认9
-					sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
-					success: async (res) => {
-						let tempFiles = res.tempFiles;
-						for (let item of tempFiles) {
-							uni.showLoading({
-								mask: true,
-								title: '上传中...'
-							});
-							try {
-								let res = await uniCloud.uploadFile({
-									filePath: item.path, //要上传的文件对象
-									cloudPath: item.name //cloudPath为云端文件名,
-								});
-								// 设置图片地址 图片地址,仅支持 http(s)、base64、本地图片
-								this.editorContent.insertImage({
-									src: res.fileID
-								});
-								uni.hideLoading();
-							} catch (e) {
-								uni.hideLoading();
-								uni.showModal({
-									content: '上传失败',
-									title: '提示'
-								});
-							}
-						}
-					}
-				});
-			},
-			// 确认
-			editOk() {
-				this.toolsShow = false;
-			},
-			onSubmit() {
-				console.log(11);
-				this.editorContent.getContents({
-					success: (res) => {
-						console.log(res);
-						this.artData.content = res.html;
-					}
-				});
-			},
-			//*****************************************富文本编辑器方法**********************************************//
-			uploadImagePhoto() {
-				uni.chooseImage({
-					count: 9, //默认9
-					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
-					sourceType: ['album'], //从相册选择
-					success: function (res) {
-					}
-				});
-			},
-			// 新增图片
-			async afterRead(event) {
-				console.log(event)
-				// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
-				let lists = [].concat(event.file)
-				let fileListLen = this[`fileList${event.name}`].length
-				lists.map((item) => {
-					this[`fileList${event.name}`].push({
-						...item,
-						status: 'uploading',
-						message: '上传中'
-					})
-				})
-				for (let i = 0; i < lists.length; i++) {
-					const result = await this.uploadFilePromise(lists[i].url)
-					let item = this[`fileList${event.name}`][fileListLen]
-					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
-						status: 'success',
-						message: '',
-						url: result
-					}))
-					fileListLen++
-				}
-			},
-			//上传图片
-			uploadFilePromise(url) {
-				return new Promise((resolve, reject) => {
-					let a = uni.uploadFile({
-						//url: this.$common.domain+'/api/common/upload', // 仅为示例,非真实的接口地址
-						// url:'http://192.168.2.21:7001/upload', // 仅为示例,非真实的接口地址
-						filePath: url,
-						name: 'file',
-						formData: {
-							user: 'test'
-						},
-						success: (res) => {
-							let data=JSON.parse(res.data) //最终传给的是字符串,这里需要转换格式
-							resolve(data.data.url)
-						}
-					});
-				})
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	.uni-mt-5 {
-		margin-top: 5px;
-	}
-	
-	/deep/ .ql-blank::before {
-		font-style: normal;
-		color: #e0e0e0;
-	}
-	 
-	.edit {
-		padding: 30rpx;
-		.title {
-			input {
-				height: 120rpx;
-				font-size: 46rpx;
-				border-bottom: 1px solid #e4e4e4;
-				margin-bottom: 30rpx;
-				color: #000;
-			}
-			.placeholderClass {
-				color: #e0e0e0;
-			}
-		}
-		.content {
-			.myEdit {
-				height: calc(100vh - 500rpx);
-				margin-bottom: 30rpx;
-			}
-		}
-		.tools {
-			width: 100%;
-			height: 80rpx;
-			background: #fff;
-			border-top: 1rpx solid #f4f4f4;
-			position: fixed;
-			left: 0;
-			bottom: 0;
-			display: flex;
-			justify-content: space-around;
-			align-items: center;
-			.iconfont {
-				font-size: 36rpx;
-				color: #333;
-				// 选择按钮的高亮
-				&.active {
-					color: #0199fe;
-				}
-			}
-		}
-	}
-</style>

+ 0 - 244
pages/demo/fwblz.vue

@@ -1,244 +0,0 @@
-<template>
-	<view class="container">
-		<view class="page-body">
-			<view class='wrapper'>
-				<view class='toolbar' @tap="format" style="height: 150px;overflow-y: auto;">
-					<view :class="formats.bold ? 'ql-active' : ''" class="iconfont icon-zitijiacu" data-name="bold">
-					</view>
-					<view :class="formats.italic ? 'ql-active' : ''" class="iconfont icon-zitixieti" data-name="italic">
-					</view>
-					<view :class="formats.underline ? 'ql-active' : ''" class="iconfont icon-zitixiahuaxian"
-						data-name="underline"></view>
-					<view :class="formats.strike ? 'ql-active' : ''" class="iconfont icon-zitishanchuxian"
-						data-name="strike"></view>
-					<!-- #ifndef MP-BAIDU -->
-					<view :class="formats.align === 'left' ? 'ql-active' : ''" class="iconfont icon-zuoduiqi"
-						data-name="align" data-value="left"></view>
-					<!-- #endif -->
-					<view :class="formats.align === 'center' ? 'ql-active' : ''" class="iconfont icon-juzhongduiqi"
-						data-name="align" data-value="center"></view>
-					<view :class="formats.align === 'right' ? 'ql-active' : ''" class="iconfont icon-youduiqi"
-						data-name="align" data-value="right"></view>
-					<view :class="formats.align === 'justify' ? 'ql-active' : ''" class="iconfont icon-zuoyouduiqi"
-						data-name="align" data-value="justify"></view>
-					<!-- #ifndef MP-BAIDU -->
-					<view :class="formats.lineHeight ? 'ql-active' : ''" class="iconfont icon-line-height"
-						data-name="lineHeight" data-value="2"></view>
-					<view :class="formats.letterSpacing ? 'ql-active' : ''" class="iconfont icon-Character-Spacing"
-						data-name="letterSpacing" data-value="2em"></view>
-					<view :class="formats.marginTop ? 'ql-active' : ''" class="iconfont icon-722bianjiqi_duanqianju"
-						data-name="marginTop" data-value="20px"></view>
-					<view :class="formats.marginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju"
-						data-name="marginBottom" data-value="20px"></view>
-					<!-- #endif -->
- 
-					<view class="iconfont icon-clearedformat" @tap="removeFormat"></view>
- 
-					<!-- #ifndef MP-BAIDU -->
-					<view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize"
-						data-name="fontSize" data-value="24px"></view>
-					<!-- #endif -->
-					<view :class="formats.color === '#0000ff' ? 'ql-active' : ''" class="iconfont icon-text_color"
-						data-name="color" data-value="#0000ff"></view>
-					<view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
-						class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ff00"></view>
-					<view class="iconfont icon-date" @tap="insertDate"></view>
-					<view class="iconfont icon--checklist" data-name="list" data-value="check"></view>
-					<view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie"
-						data-name="list" data-value="ordered"></view>
-					<view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie"
-						data-name="list" data-value="bullet"></view>
- 
-					<view class="iconfont icon-undo" @tap="undo"></view>
-					<view class="iconfont icon-redo" @tap="redo"></view>
- 
-					<view class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
-					<view class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
-					<view class="iconfont icon-fengexian" @tap="insertDivider"></view>
-					<view class="iconfont icon-charutupian" @tap="insertImage"></view>
-					<view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1"
-						data-name="header" :data-value="1"></view>
-					<view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao"
-						data-name="script" data-value="sub"></view>
-					<view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao"
-						data-name="script" data-value="super"></view>
- 
-					<view class="iconfont icon-shanchu" @tap="clear"></view>
- 
-					<view :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl"
-						data-name="direction" data-value="rtl"></view>
-				</view>
- 
-				<view class="editor-wrapper">
-					<editor id="editor" class="ql-container" placeholder="开始输入..." show-img-size show-img-toolbar
-						show-img-resize @statuschange="onStatusChange" :read-only="readOnly" @ready="onEditorReady" @blur="blur">
-					</editor>
-					<view class="" style="text-align: center;margin-bottom: 30rpx;">
-						<button style="" type="primary" size="medium" @click="submitInfo()">发布</button>
-				</view>
-				</view>
-				
-				
-			</view>
-		</view>
-	</view>
-</template>
- 
- 
-<script>
-	// import quill from "quill";
-	export default {
-		data() {
-			return {
-				title: 'Hello',
-				readOnly: false,
-				formats: {},
-				info:''
-			}
-		},
-		onLoad() {
-		},
-		methods: {
-			blur(e){
-				this.info=e.detail.html
-				console.log(this.info,e,'失去焦点')
-			},
-			readOnlyChange() {
-				this.readOnly = !this.readOnly
-			},
-			onEditorReady() {
-				// #ifdef MP-BAIDU
-				this.editorCtx = requireDynamicLib('editorLib').createEditorContext('editor');
-				// #endif
- 
-				// #ifdef APP-PLUS || MP-WEIXIN || H5
-				uni.createSelectorQuery().select('#editor').context((res) => {
-					this.editorCtx = res.context
-				}).exec()
-				// #endif
-			},
-			undo() {
-				this.editorCtx.undo()
-			},
-			redo() {
-				this.editorCtx.redo()
-			},
-			format(e) {
-				let {
-					name,
-					value
-				} = e.target.dataset
-				if (!name) return
-				// console.log('format', name, value)
-				this.editorCtx.format(name, value)
-			},
-			onStatusChange(e) {
-				const formats = e.detail
-				this.formats = formats
-			},
-			insertDivider() {
-				this.editorCtx.insertDivider({
-					success: function() {
-						console.log('insert divider success')
-					}
-				})
-			},
-			clear() {
-				uni.showModal({
-					title: '清空编辑器',
-					content: '确定清空编辑器全部内容?',
-					success: res => {
-						if (res.confirm) {
-							this.editorCtx.clear({
-								success: function(res) {
-									console.log("clear success")
-								}
-							})
-						}
-					}
-				})
-			},
-			removeFormat() {
-				this.editorCtx.removeFormat()
-			},
-			insertDate() {
-				const date = new Date()
-				const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
-				this.editorCtx.insertText({
-					text: formatDate
-				})
-			},
-			insertImage() {
-				uni.chooseImage({
-					count: 1,
-					success: (res) => {
-						this.editorCtx.insertImage({
-							src: res.tempFilePaths[0],
-							alt: '图像',
-							success: function() {
-								console.log('insert image success')
-							}
-						})
-					}
-				})
-			},
-			submitInfo(){
-				this.info = "我已获取到内容,内容如下:"+this.info
-			}
-		}
-	}
-</script>
- 
-<style>
-	@import "../../static/editor/editor-icon.css";
-	.page-body {
-		height: calc(100vh - var(--window-top) - var(--status-bar-height));
-	}
- 
-	.wrapper {
-		height: 100%;
-		display: flex;
-		flex-direction: column;
-		justify-content: space-between;
-	}
- 
-	.editor-wrapper {
-		height: calc(100vh - var(--window-top) - var(--status-bar-height) - 140px);
-		background: #fff;
-		display: flex;
-		flex-direction: column;
-		justify-content: space-between;
-	}
- 
-	.iconfont {
-		display: inline-block;
-		padding: 26rpx 26rpx;
-		width: 80rpx;
-		height:80rpx;
-		cursor: pointer;
-		font-size: 20px;
-	}
- 
-	.toolbar {
-		box-sizing: border-box;
-		border-bottom: 0;
-		font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
-	}
- 
-	.ql-container {
-		flex:1;
-		box-sizing: border-box;
-		padding: 12px 15px;
-		width: 100%;
-		min-height: 30vh;
-		/* height: auto; */
-		/* height: 80%; */
-		margin-top: 20px;
-		font-size: 16px;
-		line-height: 1.5;
-	}
- 
-	.ql-active {
-		color: #06c;
-	}
-</style>

+ 0 - 86
pages/demo/index.vue

@@ -1,86 +0,0 @@
-<template>
-	<view class="gg-container">
-		<view class="gg-tit">
-			<view class="gg-title">
-				吉农宝
-			</view>
-			<view>
-				<uni-list>
-					<uni-list :border="true">
-						<!-- 显示圆形头像 -->
-						<uni-list-chat :avatar-circle="true" title="uni-app" avatar="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png" note="您收到一条新的消息" time="2020-02-02 20:20" ></uni-list-chat>
-						<!-- 右侧带角标 -->
-						<uni-list-chat title="uni-app" avatar="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-text="12"></uni-list-chat>
-						<!-- 头像显示圆点 -->
-						<uni-list-chat title="uni-app" avatar="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
-						<!-- 头像显示角标 -->
-						<uni-list-chat title="uni-app" avatar="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="99" to="/pages/demo/fwblz?id=123"></uni-list-chat>
-						<!-- 显示多头像 -->
-						<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
-						<!-- 自定义右侧内容 -->
-						<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot">
-							<view class="chat-custom-right">
-								<text class="chat-custom-text">刚刚</text>
-								<!-- 需要使用 uni-icons 请自行引入 -->
-								<uni-icons type="star-filled" color="#999" size="18"></uni-icons>
-							</view>
-						</uni-list-chat>
-					</uni-list>
-				</uni-list>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-import { getToken } from '../../utils/auth';
-import {getUserProfile} from '@/api/system/user';
-	export default {
-		data() {
-			return {
-				avatarList: [{
-								url: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png'
-							}, {
-								url: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png'
-							}, {
-								url: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png'
-							}]
-			}
-		},
-		onLoad(options) {
-			console.log("token");
-			console.log(getToken())
-			this.userInfo = getApp().globalData.userInfo;
-			this.ss();
-		},
-		methods: {
-			tiaozhuan(){
-				uni.navigateTo({
-					url:"/pages/delis"
-				})
-			},
-			ss(){
-				getUserProfile().then(res => {
-					this.rows = res.data;
-				})
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	.chat-custom-right {
-		flex: 1;
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: column;
-		justify-content: space-between;
-		align-items: flex-end;
-	}
-	
-	.chat-custom-text {
-		font-size: 12px;
-		color: #999;
-	}
-</style>

+ 0 - 122
pages/demo/my.vue

@@ -1,122 +0,0 @@
-<template>
-	<view class="gg-container">
-		<view class="gg-tit">
-			<view class="gg-title">
-				我的吉农宝
-			</view>
-			<view>
-			  <image class="userinfo-avatar" :src="userInfo.avatarUrl" mode="cover"></image>
-			  <text class="userinfo-nickname">{{userInfo.nickName}}</text>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		components: {
-		},
-		data() {
-			return {
-				userInfo: {}
-			}
-		},
-		onLoad() {
-			this.userInfo = getApp().globalData.userInfo
-		},
-		methods: {
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	.gg-container {
-		background-color: #fff;
-		display: flex;
-		flex-direction: column;
-	}
-
-	.gg-tit {
-		width: 100%;
-		position: relative;
-		top: 0;
-		height: 40vh;
-		display: flex;
-		justify-content: center;
-		align-items: center;
-	}
-
-	.gg-body {
-		display: flex;
-		position: absolute;
-		bottom: 25rpx;
-		width: 728rpx;
-		height: 80rpx;
-		background: linear-gradient(0deg, #90BDFF, #3F93FD, #20B9D5);
-		border-radius: 40rpx;
-		justify-content: center;
-		align-items: center;
-
-		.gg-body-tt {
-			text-align: left;
-			margin-left: 5px;
-			width: 25%;
-			display: flex;
-			align-items: center;
-			color: #FFFFFF;
-			font-weight: bold;
-			font-size: 30rpx;
-		}
-	}
-
-	.content {
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		justify-content: center;
-	}
-
-	.background {
-		border: 15px solid hsla(0, 0%, 100%, .5);
-		background: white;
-		background-clip: padding-box;
-		/*从padding开始往外面裁剪背景*/
-
-	}
-
-	.container {
-		display: flex;
-		margin-left: 10px;
-		margin-top: 10px;
-		margin-right: 10px;
-		align-items: flex-start;
-		justify-content: space-between;
-	}
-
-	.gg-title {
-		width: 100%;
-		position: absolute;
-		z-index: 1;
-		display: flex;
-		justify-content: center;
-		align-items: center;
-		font-size: 40rpx;
-		font-weight: bold;
-		color: #FFFFFF;
-	}
-
-
-
-	.notice {
-		margin: 20rpx;
-		padding: 20rpx;
-		background: #FFFFFF;
-		box-shadow: 0rpx 8rpx 17rpx 0rpx rgba(0, 0, 0, 0.04);
-		border-radius: 10rpx;
-	}
-
-	.text {
-		border-left: 15rpx solid #3857F3;
-		padding-left: 20rpx;
-	}
-</style>

+ 36 - 0
pages/fenlei/fenlei.css

@@ -0,0 +1,36 @@
+page {
+    background-color: #ffffff;
+    height: 100%;
+}
+
+.vtabs-content-item {
+    width: 100%;
+    height: 610px;
+    box-sizing: border-box;
+    padding-bottom: 20px;
+    padding: 20rpx;
+}
+.vtabs-contentTitle {
+    font-size: 36rpx;
+    color: #07c160;
+}
+.spflList {
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    flex-wrap: wrap;
+}
+.spflList li {
+    width: 33.33%;
+    text-align: center;
+}
+.spflList li span {
+    font-size: 28rpx;
+    color: #333;
+}
+.spflList li image {
+    width: 100rpx;
+    height: 100rpx;
+    margin: 0 auto;
+}

+ 142 - 0
pages/fenlei/fenlei.vue

@@ -0,0 +1,142 @@
+<template>
+    <view>
+        <mp-vtabs :vtabs="vtabs" :activeTab="activeTab" @tabclick="onTabCLick" @change="onChange">
+            <block v-for="(item, index) in vtabs" :key="index">
+                <mp-vtabs-content :tabIndex="index">
+                    <view class="vtabs-content-item">
+                        <span class="vtabs-contentTitle">{{ item.title }}</span>
+                        <ul class="spflList">
+                            <li>
+                                <image src="/static/pages/images/ty.png"></image>
+                                <span>体育用品</span>
+                            </li>
+                            <li>
+                                <image src="/static/pages/images/tongzhuan.png"></image>
+                                <span>童装</span>
+                            </li>
+                            <li>
+                                <image src="/static/pages/images/waitao.png"></image>
+                                <span>外套</span>
+                            </li>
+                            <li>
+                                <image src="/static/pages/images/yumi.png"></image>
+                                <span>农产品</span>
+                            </li>
+                        </ul>
+                    </view>
+                </mp-vtabs-content>
+            </block>
+        </mp-vtabs> 
+    </view>
+</template>
+
+<script>
+import mpVtabs from '../../components/vtabs/vtabs/index';
+import mpVtabsContent from '../../components/vtabs/vtabs-content/index';
+// pages/fenlei.js
+export default {
+    components: {
+        mpVtabs,
+        mpVtabsContent
+    },
+    data() {
+        return {
+            vtabs: [],
+            activeTab: 0,
+            test: 111
+        };
+    },
+    onLoad() {
+        const vtabs = [
+            {
+                title: '热搜推荐'
+            },
+            {
+                title: '手机数码'
+            },
+            {
+                title: '家用电器'
+            },
+            {
+                title: '生鲜果蔬'
+            },
+            {
+                title: '酒水饮料'
+            },
+            {
+                title: '生活美食'
+            },
+            {
+                title: '美妆护肤'
+            },
+            {
+                title: '个护清洁'
+            },
+            {
+                title: '女装内衣'
+            },
+            {
+                title: '男装内衣'
+            },
+            {
+                title: '鞋靴箱包'
+            },
+            {
+                title: '运动户外'
+            },
+            {
+                title: '生活充值'
+            },
+            {
+                title: '母婴童装'
+            }
+        ];
+        // const vtabs = titles.map(item => ({title: item}))
+        this.setData({
+            vtabs: vtabs
+        });
+    },
+    /**
+     * 生命周期函数--监听页面初次渲染完成
+     */
+    onReady() {},
+    /**
+     * 生命周期函数--监听页面显示
+     */
+    onShow() {},
+    /**
+     * 生命周期函数--监听页面隐藏
+     */
+    onHide() {},
+    /**
+     * 生命周期函数--监听页面卸载
+     */
+    onUnload() {},
+    /**
+     * 页面相关事件处理函数--监听用户下拉动作
+     */
+    onPullDownRefresh() {},
+    /**
+     * 页面上拉触底事件的处理函数
+     */
+    onReachBottom() {},
+    /**
+     * 用户点击右上角分享
+     */
+    onShareAppMessage() {},
+    methods: {
+        onTabCLick(e) {
+            const index = e.detail.index;
+            console.log('tabClick', index);
+        },
+
+        onChange(e) {
+            const index = e.detail.index;
+            console.log('change', index);
+        }
+    }
+};
+</script>
+<style>
+@import './fenlei.css';
+</style>

+ 1 - 0
pages/fuwu/fuwu.css

@@ -0,0 +1 @@
+/* pages/fuwu.wxss */

+ 48 - 0
pages/fuwu/fuwu.vue

@@ -0,0 +1,48 @@
+<template>
+    <!-- pages/me.wxml -->
+</template>
+
+<script>
+// pages/me.js
+export default {
+    data() {
+        return {};
+    }
+    /**
+     * 生命周期函数--监听页面加载
+     */,
+    onLoad(options) {},
+    /**
+     * 生命周期函数--监听页面初次渲染完成
+     */
+    onReady() {},
+    /**
+     * 生命周期函数--监听页面显示
+     */
+    onShow() {},
+    /**
+     * 生命周期函数--监听页面隐藏
+     */
+    onHide() {},
+    /**
+     * 生命周期函数--监听页面卸载
+     */
+    onUnload() {},
+    /**
+     * 页面相关事件处理函数--监听用户下拉动作
+     */
+    onPullDownRefresh() {},
+    /**
+     * 页面上拉触底事件的处理函数
+     */
+    onReachBottom() {},
+    /**
+     * 用户点击右上角分享
+     */
+    onShareAppMessage() {},
+    methods: {}
+};
+</script>
+<style>
+@import './fuwu.css';
+</style>

+ 222 - 0
pages/iconfont/iconfont.css

@@ -0,0 +1,222 @@
+@font-face {
+    font-family: 'iconfont'; /* Project id 3934749 */
+    src: url('//at.alicdn.com/t/c/font_3934749_vw3yr60jge.woff2?t=1678514567333') format('woff2'),
+        url('//at.alicdn.com/t/c/font_3934749_vw3yr60jge.woff?t=1678514567333') format('woff'),
+        url('//at.alicdn.com/t/c/font_3934749_vw3yr60jge.ttf?t=1678514567333') format('truetype');
+}
+
+.iconfont {
+    font-family: 'iconfont' !important;
+    font-size: 16px;
+    font-style: normal;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-zaixiankefu:before {
+    content: '\e617';
+}
+
+.icon-dianpu:before {
+    content: '\e678';
+}
+
+.icon-fenlei:before {
+    content: '\e620';
+}
+
+.icon-tuijianma:before {
+    content: '\e6a7';
+}
+
+.icon-shangpin:before {
+    content: '\e648';
+}
+
+.icon-shangpin2:before {
+    content: '\e622';
+}
+
+.icon-mingxi:before {
+    content: '\e689';
+}
+
+.icon-xinshouyindao:before {
+    content: '\e72f';
+}
+
+.icon-gengduo1:before {
+    content: '\e68b';
+}
+
+.icon-gongxiaoshelogo:before {
+    content: '\e629';
+}
+
+.icon-xinlizixun:before {
+    content: '\e655';
+}
+
+.icon-zhishi:before {
+    content: '\e62f';
+}
+
+.icon-wenzhen:before {
+    content: '\e856';
+}
+
+.icon-jurassic_nav:before {
+    content: '\e69e';
+}
+
+.icon-jurassic_nav1:before {
+    content: '\e69f';
+}
+
+.icon-youdaijiuzhu:before {
+    content: '\e6a0';
+}
+
+.icon-zhibo:before {
+    content: '\e605';
+}
+
+.icon-S_dianhuaxinlizixun:before {
+    content: '\e656';
+}
+
+.icon-zhishi1:before {
+    content: '\e813';
+}
+
+.icon-linshijiuzhu:before {
+    content: '\e653';
+}
+
+.icon-wenzhenguanli:before {
+    content: '\e613';
+}
+
+.icon-bianji:before {
+    content: '\e600';
+}
+
+.icon-shoucang1:before {
+    content: '\e659';
+}
+
+.icon-icon-:before {
+    content: '\e612';
+}
+
+.icon-shoucang2:before {
+    content: '\e603';
+}
+
+.icon-fasong:before {
+    content: '\e604';
+}
+
+.icon-xiangyoujiantou:before {
+    content: '\e641';
+}
+
+.icon-zhishiku1:before {
+    content: '\e650';
+}
+
+.icon-yuandianxiao:before {
+    content: '\e82f';
+}
+
+.icon-iclike:before {
+    content: '\e628';
+}
+
+.icon-falv1:before {
+    content: '\e619';
+}
+
+.icon-pinglun:before {
+    content: '\e63a';
+}
+
+.icon-licaiwenda:before {
+    content: '\e652';
+}
+
+.icon-lvyou:before {
+    content: '\e601';
+}
+
+.icon-jifen:before {
+    content: '\e897';
+}
+
+.icon--fuwu:before {
+    content: '\e8aa';
+}
+
+.icon-zhiku:before {
+    content: '\e6d8';
+}
+
+.icon-chakan:before {
+    content: '\e642';
+}
+
+.icon-shoucang:before {
+    content: '\e633';
+}
+
+.icon-zhishiku:before {
+    content: '\e621';
+}
+
+.icon-gonggao:before {
+    content: '\e60f';
+}
+
+.icon-jiuzhen:before {
+    content: '\ea4b';
+}
+
+.icon-jiuzhen1:before {
+    content: '\e610';
+}
+
+.icon-jiuye:before {
+    content: '\100dd';
+}
+
+.icon-sannongzhengce:before {
+    content: '\100de';
+}
+
+.icon-sannongzhengce1:before {
+    content: '\100e8';
+}
+
+.icon-gengduo:before {
+    content: '\e73a';
+}
+
+.icon-shangcheng11:before {
+    content: '\e67b';
+}
+
+.icon-hangqing:before {
+    content: '\e66c';
+}
+
+.icon-banshidating:before {
+    content: '\e602';
+}
+
+.icon-banshidating1:before {
+    content: '\e606';
+}
+
+.icon-wenhaofill:before {
+    content: '\e72c';
+}

+ 492 - 0
pages/index/index.css

@@ -0,0 +1,492 @@
+/**index.wxss**/
+.topBj {
+    position: relative;
+    width: 100%;
+    z-index: -1;
+}
+
+.topBj image {
+    width: 100%;
+    height: 460rpx;
+}
+
+.userinfo {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    color: #aaa;
+}
+
+.userinfo-avatar {
+    overflow: hidden;
+    width: 128rpx;
+    height: 128rpx;
+    margin: 20rpx;
+    border-radius: 50%;
+}
+
+.usermotto {
+    margin-top: 200px;
+}
+
+/* 图片轮播 */
+.banner {
+    width: 100%;
+    height: 300rpx;
+    padding: 30rpx 0;
+}
+
+.banner swiper-item image {
+    width: 100%;
+    height: 100%;
+}
+
+/* 主导航 */
+.mainNav {
+    width: 100%;
+    background: #fff;
+}
+
+.mainNav li {
+    width: 25%;
+    float: left;
+    text-align: center;
+}
+
+.mainNav li span {
+    font-size: 30rpx;
+    color: #555;
+}
+
+.mainNav li view.wb .icon-wenhaofill {
+    background: linear-gradient(#f5cd49, #fcb136);
+    -webkit-background-clip: text;
+    background-clip: text;
+    color: transparent;
+    font-size: 70rpx;
+}
+
+.mainNav li view.hq .icon-hangqing {
+    background: linear-gradient(#89adfd, #6898f9);
+    -webkit-background-clip: text;
+    background-clip: text;
+    color: transparent;
+    font-size: 70rpx;
+}
+
+.mainNav li view.sc .icon-shangcheng11 {
+    background: linear-gradient(#fd7668, #f85649);
+    -webkit-background-clip: text;
+    background-clip: text;
+    color: transparent;
+    font-size: 70rpx;
+}
+
+.mainNav li view.bs .icon-banshidating1 {
+    background: linear-gradient(#12c98a, #12c98a);
+    -webkit-background-clip: text;
+    background-clip: text;
+    color: transparent;
+    font-size: 64rpx;
+}
+
+.mainNav li view .iconfont {
+    color: #fff;
+    line-height: 90rpx;
+}
+
+.gonggao {
+    padding: 32rpx 0;
+    line-height: 40rpx;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    width: 100%;
+}
+
+.gonggao span {
+    font-size: 30rpx;
+    color: #07c160;
+}
+
+.gonggao span .iconfont {
+    font-size: 40rpx;
+    color: #07c160;
+    line-height: 40rpx;
+    float: left;
+    margin: 4rpx 0 0 0;
+}
+
+.gonggao a {
+    font-size: 28rpx;
+    color: #666;
+    margin: 0 20rpx;
+    width: 70%;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.icon-xiangyoujiantou {
+    font-size: 40rpx;
+    color: #c4c4c4;
+    line-height: 40rpx;
+}
+
+/* 村民福利 */
+.cmfl_title {
+    display: flex;
+    justify-content: center;
+    margin: 40rpx 0 0 0;
+    align-items: center;
+}
+
+.cmfl_title image {
+    width: 24rpx;
+    height: 18rpx;
+}
+
+.cmfl_title h1 {
+    font-size: 40rpx;
+    font-weight: bold;
+    color: #07c160;
+    margin: 0 40rpx;
+}
+
+.cnfl {
+    width: 100%;
+    margin: 40rpx 0;
+    display: flex;
+    justify-content: space-between;
+}
+
+.fv,
+.hm {
+    width: 48%;
+    border-radius: 20rpx;
+    overflow: hidden;
+    position: relative;
+}
+
+.fv text,
+.hm text {
+    position: absolute;
+    left: 13%;
+    top: 30%;
+    font-size: 36rpx;
+    font-weight: bold;
+}
+
+.fv text {
+    color: #005cc4;
+}
+
+.hm text {
+    color: #d36900;
+}
+
+.fv image,
+.hm image {
+    width: 100%;
+    height: 134rpx;
+}
+
+/* 政策推荐 */
+.zcTuijian {
+    width: 100%;
+    padding: 30rpx 0;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+}
+
+.zcTuijian ul {
+    width: 65%;
+}
+
+.zcTuijian ul li {
+    width: 100%;
+    display: block;
+    font-size: 28rpx;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    line-height: 52rpx;
+    color: #666;
+}
+
+.zcTuijian image {
+    width: 22%;
+    height: 150rpx;
+    border-radius: 20rpx;
+}
+
+.zcTuijian em.icon-gengduo {
+    line-height: 150rpx;
+    font-size: 40rpx;
+    color: #c4c4c4;
+}
+
+.bannerA {
+    width: 100%;
+}
+
+.bannerA image {
+    width: 100%;
+    height: 200rpx;
+}
+.icon--fuwu {
+    font-size: 40rpx;
+    margin: 0 10rpx 0 0;
+}
+
+.icon-licaiwenda {
+    font-size: 36rpx;
+    margin: 0 10rpx 0 0;
+}
+
+.icon-zhishiku1 {
+    font-size: 34rpx;
+    margin: 0 10rpx 0 0;
+}
+
+.gpfwNav ul {
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+}
+
+.gpfwNav ul li {
+    margin: 20rpx 2.5% 30rpx 2.5%;
+    font-size: 30rpx;
+    color: #333;
+    width: 20%;
+    text-align: center;
+}
+
+.gpfwNav ul li view {
+    width: 80rpx;
+    height: 80rpx;
+    margin: 0 auto 20rpx auto;
+    border-radius: 20rpx;
+    text-align: center;
+    line-height: 80rpx;
+}
+
+.gpfwNav ul li view em {
+    font-size: 50rpx;
+    color: #fff;
+}
+
+.gpfwNav ul li view.lvxd {
+    background: -webkit-linear-gradient(#eca6a6, #fd8585);
+    background: -o-linear-gradient(#eca6a6, #fd8585);
+    background: -moz-linear-gradient(#eca6a6, #fd8585);
+    background: linear-gradient(#eca6a6, #fd8585);
+}
+
+.gpfwNav ul li view.xlzx {
+    background: -webkit-linear-gradient(#bab3ec, #8170ff);
+    background: -o-linear-gradient(#bab3ec, #8170ff);
+    background: -moz-linear-gradient(#bab3ec, #8170ff);
+    background: linear-gradient(#bab3ec, #8170ff);
+}
+
+.gpfwNav ul li view.xswz {
+    background: -webkit-linear-gradient(#afd0ec, #61c5ff);
+    background: -o-linear-gradient(#afd0ec, #61c5ff);
+    background: -moz-linear-gradient(#afd0ec, #61c5ff);
+    background: linear-gradient(#afd0ec, #61c5ff);
+}
+
+.gpfwNav ul li view.gxs {
+    background: -webkit-linear-gradient(#c1fdc9, #57f5a1);
+    background: -o-linear-gradient(#c1fdc9, #57f5a1);
+    background: -moz-linear-gradient(#c1fdc9, #57f5a1);
+    background: linear-gradient(#c1fdc9, #57f5a1);
+}
+
+.gpfwNav ul li view.more {
+    background: -webkit-linear-gradient(#46aef7, #1dd5e6);
+    background: -o-linear-gradient(#46aef7, #1dd5e6);
+    background: -moz-linear-gradient(#46aef7, #1dd5e6);
+    background: linear-gradient(#46aef7, #1dd5e6);
+}
+
+/* 热门问答 */
+.rnwdList {
+    width: 100%;
+}
+
+.list {
+    border-bottom: solid 2rpx #f6f6f6;
+    padding: 10rpx 0;
+    width: 100%;
+}
+
+.listTitle {
+    font-size: 32rpx;
+    color: #333;
+    line-height: 40rpx;
+}
+
+.jlSj {
+    height: 40rpx;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: 24rpx;
+    margin: 20rpx 0 0 0;
+}
+
+.jf {
+    color: #07c160;
+}
+
+.icon-jifen {
+    font-size: 26rpx;
+    color: #07c160;
+    margin: 0 0 0 6rpx;
+}
+
+.ck {
+    color: #c4c4c4;
+}
+
+.icon-pinglun,
+.icon-chakan,
+.icon-shoucang {
+    font-size: 28rpx;
+    margin: 0 6rpx 0 20rpx;
+    color: #c4c4c4;
+}
+
+.onePic {
+    width: 100%;
+    height: 360rpx;
+    border-radius: 20rpx;
+    overflow: hidden;
+    margin: 20rpx 0;
+}
+
+.onePic image {
+    width: 100%;
+    height: 100%;
+}
+
+.twoPic {
+    width: 100%;
+    height: 220rpx;
+    margin: 20rpx 0;
+    display: flex;
+    justify-content: space-between;
+}
+
+.twoPic image {
+    width: 49%;
+    height: auto;
+    border-radius: 20rpx;
+}
+
+.threePic {
+    width: 100%;
+    height: 160rpx;
+    margin: 20rpx 0;
+    display: flex;
+    justify-content: space-between;
+}
+
+.threePic image {
+    width: 32%;
+    height: auto;
+    border-radius: 20rpx;
+}
+
+/* 热门知识 */
+.rmzsList li {
+    width: 100%;
+    border-bottom: solid 2rpx #f6f6f6;
+    padding: 20rpx 0;
+    display: flex;
+    justify-content: space-between;
+}
+
+.rmzsList li image {
+    width: 40%;
+    height: 200rpx;
+}
+
+.listCont {
+    width: 58%;
+}
+
+.listCont p {
+    font-size: 32rpx;
+    color: #333;
+    overflow: hidden;
+    line-height: 40rpx;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+}
+
+.listCont text {
+    font-size: 24rpx;
+    color: #9c9c9c;
+}
+
+.biaoqian {
+    display: flex;
+    margin: 6rpx 0;
+}
+
+.biaoqian span {
+    padding: 2rpx 20rpx;
+    font-size: 20rpx;
+    background: #e0e0e0;
+    color: #9c9c9c;
+    margin: 0 20rpx 0 0;
+    border-radius: 30rpx;
+}
+
+.jiage {
+    display: flex;
+}
+
+.yhjg {
+    font-size: 30rpx;
+    color: #07c160;
+}
+
+.yhjg em {
+    font-size: 24rpx;
+    color: #07c160;
+}
+
+.yjjg {
+    font-size: 24rpx;
+    color: #9c9c9c;
+    margin: 6rpx 0 0 20rpx;
+    text-decoration: line-through;
+}
+
+/* 公告start */
+
+.swiper_container {
+    height: 55rpx;
+    width: 70%;
+    line-height: 60rpx;
+}
+
+.swiper_item {
+    height: 100;
+    color: #000;
+    font-size: 28rpx;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+/* 公告end */

+ 329 - 0
pages/index/index.vue

@@ -0,0 +1,329 @@
+<template>
+    <view>
+        <!-- index.wxml -->
+        <view class="topBj">
+            <image :src="host + '/jcb-top.png'"></image>
+        </view>
+        <view class="container">
+            <!-- 主导航 -->
+            <ul class="mainNav">
+                <li>
+                    <view class="wb" @tap="goWenBa"><em class="iconfont icon-wenhaofill"></em></view>
+                    <span>问吧</span>
+                </li>
+                <li>
+                    <view class="hq"><em class="iconfont icon-hangqing"></em></view>
+                    <span>行情</span>
+                </li>
+                <li>
+                    <view class="sc" @tap="goShangCheng"><em class="iconfont icon-shangcheng11"></em></view>
+                    <span>商城</span>
+                </li>
+                <li>
+                    <view class="bs"><em class="iconfont icon-banshidating1"></em></view>
+                    <span>办事</span>
+                </li>
+            </ul>
+            <!-- 村民福利 -->
+            <view class="cmfl_title">
+                <image :src="host + '/cnfl-fl.png'"></image>
+                <h1>村民福利</h1>
+                <image :src="host + '/cnfl-fr.png'"></image>
+            </view>
+            <view class="cnfl">
+                <view class="fv">
+                    <text>法律乡下</text>
+                    <image :src="host + '/fv.jpg'"></image>
+                </view>
+                <view class="hm">
+                    <text>惠民通</text>
+                    <image :src="host + '/hm.jpg'"></image>
+                </view>
+            </view>
+        </view>
+        <view class="fengexian"></view>
+        <!-- 分割线 -->
+        <!-- 公告 -->
+        <view class="container">
+            <view class="gonggao">
+                <span>
+                    <em class="iconfont icon-gonggao"></em>
+                    [公告]
+                </span>
+                <swiper class="swiper_container" :autoplay="true" :circular="true" :vertical="true" interval="2000">
+                    <block v-for="(item, index) in msgList" :key="index">
+                        <swiper-item>
+                            <view class="swiper_item">{{ item.title }}</view>
+                        </swiper-item>
+                    </block>
+                </swiper>
+                <em class="iconfont icon-xiangyoujiantou"></em>
+            </view>
+        </view>
+        <!-- 公告 end -->
+        <view class="fengexian"></view>
+        <!-- 分割线 -->
+        <view class="container">
+            <!-- 政策推荐 -->
+            <view class="zcTuijian">
+                <image :src="host + '/zctj.png'"></image>
+                <ul>
+                    <view v-for="(item, index) in msgList" :key="index">
+                        <li>
+                            <em class="iconfont icon-yuandianxiao"></em>
+                            {{ item.title }}
+                        </li>
+                    </view>
+                </ul>
+                <em class="iconfont icon-xiangyoujiantou"></em>
+            </view>
+        </view>
+        <view class="fengexian"></view>
+        <!-- 分割线 -->
+        <view class="container">
+            <!-- 图片轮播 -->
+            <swiper :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval" :duration="duration" :circular="circular" class="banner">
+                <block v-for="(item, index) in banners" :key="index">
+                    <swiper-item><image :src="item.src" mode="aspectFill"></image></swiper-item>
+                </block>
+            </swiper>
+        </view>
+        <view class="fengexian"></view>
+        <!-- 分割线 -->
+        <view class="container">
+            <view class="titleLeft">
+                <em class="iconfont icon--fuwu"></em>
+                高频服务
+            </view>
+            <view class="gpfwNav">
+                <ul>
+                    <li>
+                        <view class="lvxd"><em class="iconfont icon-jurassic_nav"></em></view>
+                        <span>旅游向导</span>
+                    </li>
+                    <li>
+                        <view class="xlzx"><em class="iconfont icon-xinlizixun"></em></view>
+                        <span>心里咨询</span>
+                    </li>
+                    <li>
+                        <view class="xswz"><em class="iconfont icon-wenzhen"></em></view>
+                        <span>线上问诊</span>
+                    </li>
+                    <li>
+                        <view class="gxs"><em class="iconfont icon-gongxiaoshelogo"></em></view>
+                        <span>供销社</span>
+                    </li>
+                    <li>
+                        <view class="xlzx"><em class="iconfont icon-linshijiuzhu"></em></view>
+                        <span>帮扶救助</span>
+                    </li>
+                    <li>
+                        <view class="xswz"><em class="iconfont icon-zhishi1"></em></view>
+                        <span>知识库</span>
+                    </li>
+                    <li>
+                        <view class="lvxd"><em class="iconfont icon-zhibo"></em></view>
+                        <span>直播带货</span>
+                    </li>
+                    <li>
+                        <view class="more"><em class="iconfont icon-gengduo1"></em></view>
+                        <span>更多</span>
+                    </li>
+                </ul>
+            </view>
+        </view>
+        <view class="fengexian"></view>
+        <!-- 分割线 -->
+        <view class="container">
+            <view class="titleLeft">
+                <em class="iconfont icon-licaiwenda"></em>
+                热门问答
+            </view>
+            <view class="rnwdList">
+                <view class="list" @tap="goDetails" v-for="(item, index) in indexList" :key="index">
+                    <span class="listTitle">{{ item.title }}</span>
+
+                    <view class="onePic" v-if="item.imgList.length == 1">
+                        <image :src="host + item.url" v-for="(item, index1) in item.imgList" :key="index1"></image>
+                    </view>
+
+                    <view class="twoPic" v-if="item.imgList.length == 2">
+                        <image :src="host + item.url" v-for="(item, index1) in item.imgList" :key="index1"></image>
+                    </view>
+
+                    <view class="threePic" v-if="item.imgList.length == 3">
+                        <image :src="host + item.url" v-for="(item, index1) in item.imgList" :key="index1"></image>
+                    </view>
+
+                    <view class="jlSj">
+                        <span class="jf">
+                            {{ item.jf }}
+                            <em class="iconfont icon-jifen"></em>
+                        </span>
+                        <view class="ck">
+                            <span>
+                                <em class="iconfont icon-pinglun"></em>
+                                {{ item.pl }}
+                            </span>
+                            <span>
+                                <em class="iconfont icon-chakan"></em>
+                                {{ item.ck }}
+                            </span>
+                            <span>
+                                <em class="iconfont icon-shoucang"></em>
+                                {{ item.dz }}
+                            </span>
+                        </view>
+                    </view>
+                </view>
+            </view>
+        </view>
+        <view class="fengexian"></view>
+        <!-- 分割线 -->
+        <view class="container">
+            <view class="titleLeft">
+                <em class="iconfont icon-zhishiku1"></em>
+                热门知识
+            </view>
+            <ul class="rmzsList">
+                <li>
+                    <image :src="host + '/10_16.png'"></image>
+                    <view class="listCont">
+                        <p>稳预期 促互通——专家学者建言献策国际农产品市场和贸易高质量发展</p>
+                        <text>唐旭 姚媛</text>
+                        <view class="biaoqian">
+                            <span>三农</span>
+                            <span>教育</span>
+                        </view>
+                        <view class="jiage">
+                            <span class="yhjg">
+                                <em>¥</em>
+                                200
+                            </span>
+                            <span class="yjjg">¥500</span>
+                        </view>
+                    </view>
+                </li>
+                <li>
+                    <image :src="host + '/10_16.png'"></image>
+                    <view class="listCont">
+                        <p>稳预期 促互通——专家学者建言献策国际农产品市场和贸易高质量发展</p>
+                        <text>唐旭 姚媛</text>
+                        <view class="biaoqian">
+                            <span>三农</span>
+                            <span>教育</span>
+                        </view>
+                        <view class="jiage">
+                            <span class="yhjg">
+                                <em>¥</em>
+                                200
+                            </span>
+                            <span class="yjjg">¥500</span>
+                        </view>
+                    </view>
+                </li>
+            </ul>
+        </view>
+    </view>
+</template>
+
+<script>
+// pages/index/index.js
+const app = getApp();
+var localData = require('../../data/json');
+export default {
+    data() {
+        return {
+            host: app.globalData.host,
+            // 图片轮播
+            banners: [
+                {
+                    src: app.globalData.host + '/img1.png'
+                },
+                {
+                    src: app.globalData.host + '/img2.png'
+                }
+            ],
+            msgList: [
+                {
+                    id: 0,
+                    title: '关于高质量推进土地整治工作赋能乡村振兴的通知'
+                },
+                {
+                    id: 1,
+                    title: '关于高质量推进土地整治工作的通知'
+                },
+                {
+                    id: 2,
+                    title: '关于乡村振兴的通知'
+                }
+            ],
+            indicatorDots: true,
+            vertical: false,
+            autoplay: true,
+            interval: 2000,
+            duration: 500,
+            circular: true,
+            indexList: ''
+        };
+    }
+    /**
+     * 生命周期函数--监听页面加载
+     */,
+    onLoad(options) {
+        this.setData({
+            indexList: localData.indexList
+        });
+    },
+    /**
+     * 生命周期函数--监听页面初次渲染完成
+     */
+    onReady() {},
+    /**
+     * 生命周期函数--监听页面显示
+     */
+    onShow() {},
+    /**
+     * 生命周期函数--监听页面隐藏
+     */
+    onHide() {},
+    /**
+     * 生命周期函数--监听页面卸载
+     */
+    onUnload() {},
+    /**
+     * 页面相关事件处理函数--监听用户下拉动作
+     */
+    onPullDownRefresh() {},
+    /**
+     * 页面上拉触底事件的处理函数
+     */
+    onReachBottom() {},
+    /**
+     * 用户点击右上角分享
+     */
+    onShareAppMessage() {},
+    methods: {
+        goWenBa() {
+            uni.navigateTo({
+                url: '../wenba/wenba'
+            });
+        },
+
+        goShangCheng() {
+            uni.navigateTo({
+                url: '../shangcheng/shangcheng'
+            });
+        },
+
+        goDetails() {
+            uni.navigateTo({
+                url: '../wenbaxiangqing/wenbaxiangqing'
+            });
+        }
+    }
+};
+</script>
+<style>
+@import './index.css';
+</style>

+ 0 - 157
pages/login.vue

@@ -1,157 +0,0 @@
-<template>
-	<view class="normal-login-container">
-		<view class="login-form-content">
-			<view class="flex">
-				<view class="login-title flex">
-					吉农宝
-				</view>
-				<button @click="getUserInfo"> 获取头像昵称 </button>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-			}
-		},
-		created() {
-			this.getUserInfo();
-		},
-		methods: {
-		   getUserInfo() {
-			   let _this = this;
-		       uni.login({
-		         success (res) {
-		           if (res.code) {
-		             //发起网络请求
-					 _this.$store.dispatch('Login', res.code).then(() => {
-					 	_this.$modal.closeLoading()
-					 	uni.switchTab({
-					 		url:'/pages/demo/index'
-					 	})
-					 })
-		           } else {
-		             console.log('登录失败!' + res.errMsg)
-		           }
-		         }
-		       })
-			}
-		},
-	}
-</script>
-
-<style lang="scss">
-	page {
-		background-color: #ffffff;
-	}
-
-	.normal-login-container {
-		width: 100%;
-
-		.login-bg-img {
-			width: 100%;
-			height: 100vh;
-			position: absolute;
-			top: 0;
-			left: 0;
-			z-index: -1;
-		}
-
-		.logo-content {
-			width: 100%;
-			font-size: 21px;
-			text-align: center;
-			padding-top: 15%;
-
-			image {
-				border-radius: 4px;
-			}
-
-			.title {
-				margin-left: 10px;
-			}
-		}
-
-		.login-form-content {
-			text-align: center;
-			width: 90%;
-			min-height: 45vh;
-			background-color: #ffffff;
-			border-radius: 40rpx;
-			padding: 5%;
-			box-shadow: 0 0 10px #a7a7a7;
-			position: absolute;
-			bottom: 10vh;
-			left: 50%;
-			transform: translateX(-50%);
-
-
-			.login-title {
-				margin-top: 20px;
-				font-size: 40rpx;
-				color: #898989;
-
-				image {
-					width: 70rpx;
-					height: 53rpx;
-					margin-right: 20rpx;
-				}
-			}
-
-			.input-item {
-				margin: 20px auto;
-				background-color: #f5f6f7;
-				height: 96rpx;
-				border-radius: 50px;
-
-				.icon {
-					font-size: 38rpx;
-					margin-left: 10px;
-					color: #999;
-				}
-
-				.input {
-					width: 100%;
-					font-size: 14px;
-					line-height: 20px;
-					text-align: left;
-					padding-left: 15px;
-				}
-
-			}
-
-			.login-btn {
-				margin-top: 40px;
-				height: 96rpx;
-				background: linear-gradient(105deg, #72C6FF, #79A4F0);
-				box-shadow: 0rpx 18rpx 24rpx 0rpx rgba(63, 143, 255, 0.23);
-				border-radius: 48rpx;
-				color: #f5f6f7;
-			}
-
-			.reg {
-				margin-top: 15px;
-			}
-
-			.xieyi {
-				color: #333;
-				margin-top: 20px;
-			}
-
-			.login-code {
-				height: 38px;
-				float: right;
-
-				.login-code-img {
-					height: 38px;
-					position: absolute;
-					margin-left: 10px;
-					width: 200rpx;
-				}
-			}
-		}
-	}
-</style>

+ 1 - 0
pages/me/me.css

@@ -0,0 +1 @@
+/* pages/me.wxss */

+ 48 - 0
pages/me/me.vue

@@ -0,0 +1,48 @@
+<template>
+    <!-- pages/me.wxml -->
+</template>
+
+<script>
+// pages/me.js
+export default {
+    data() {
+        return {};
+    }
+    /**
+     * 生命周期函数--监听页面加载
+     */,
+    onLoad(options) {},
+    /**
+     * 生命周期函数--监听页面初次渲染完成
+     */
+    onReady() {},
+    /**
+     * 生命周期函数--监听页面显示
+     */
+    onShow() {},
+    /**
+     * 生命周期函数--监听页面隐藏
+     */
+    onHide() {},
+    /**
+     * 生命周期函数--监听页面卸载
+     */
+    onUnload() {},
+    /**
+     * 页面相关事件处理函数--监听用户下拉动作
+     */
+    onPullDownRefresh() {},
+    /**
+     * 页面上拉触底事件的处理函数
+     */
+    onReachBottom() {},
+    /**
+     * 用户点击右上角分享
+     */
+    onShareAppMessage() {},
+    methods: {}
+};
+</script>
+<style>
+@import './me.css';
+</style>

+ 191 - 0
pages/sannong/sannong.css

@@ -0,0 +1,191 @@
+/* pages/sannong.wxss */
+.snTab {
+    width: 100%;
+}
+
+.fontColorBox,
+.fontColorBox1 {
+    color: #07c160;
+}
+
+.navBox {
+    /* 顶部tab盒子样式 */
+    width: 100%;
+    height: 108rpx;
+    background: white;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    justify-content: center;
+}
+/* 最后一个tab标题的样式 */
+
+.titleBox {
+    /* 未选中文字的样式 */
+    color: rgb(168, 170, 175);
+    font-size: 30rpx;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    width: 32%;
+}
+.lineBox,
+.notLineBox {
+    /* 选中及未选中底线共同样式 */
+    width: 32rpx;
+    height: 8rpx;
+}
+
+.lineBox {
+    /* 选中底线样式 */
+    background: #07c160;
+    margin-top: 16rpx;
+    border-radius: 4rpx;
+}
+
+.notLineBox {
+    /* 未选中底线样式 */
+    background: transparent;
+}
+
+.swiperTtemBox {
+    /* 底部内容样式 */
+    height: 100vh;
+    overflow: scroll;
+    margin: 12rpx 0rpx;
+    background: white;
+    font-size: 28rpx;
+}
+
+/* 热门问答 */
+.rnwdList {
+    width: 100%;
+    height: 100%;
+}
+.list {
+    border-bottom: solid 2rpx #f6f6f6;
+    padding: 10rpx 0;
+    width: 100%;
+}
+.listTitle {
+    font-size: 32rpx;
+    color: #333;
+    line-height: 40rpx;
+}
+.jlSj {
+    height: 40rpx;
+    display: flex;
+    justify-content: space-between;
+    font-size: 24rpx;
+    margin: 20rpx 0 0 0;
+}
+.jf {
+    color: #07c160;
+}
+.icon-jifen {
+    font-size: 28rpx;
+    color: #07c160;
+    margin: 0 0 0 6rpx;
+}
+.ck {
+    color: #c4c4c4;
+}
+.icon-pinglun,
+.icon-chakan,
+.icon-shoucang {
+    font-size: 28rpx;
+    margin: 0 6rpx 0 20rpx;
+    color: #c4c4c4;
+}
+.onePic {
+    width: 100%;
+    height: 360rpx;
+    border-radius: 20rpx;
+    overflow: hidden;
+    margin: 20rpx 0;
+}
+.onePic image {
+    width: 100%;
+    height: 100%;
+}
+.twoPic {
+    width: 100%;
+    height: 220rpx;
+    margin: 20rpx 0;
+    display: flex;
+    justify-content: space-between;
+}
+.twoPic image {
+    width: 49%;
+    height: auto;
+    border-radius: 20rpx;
+}
+.threePic {
+    width: 100%;
+    height: 160rpx;
+    margin: 20rpx 0;
+    display: flex;
+    justify-content: space-between;
+}
+.threePic image {
+    width: 32%;
+    height: auto;
+    border-radius: 20rpx;
+}
+
+.pane-con {
+    margin: 20rpx 0;
+}
+.tabs-pane {
+    padding: 10rpx 20rpx;
+    margin-right: 20rpx;
+    border: 1px solid lightgrey;
+}
+.tabs-pane:nth-last-child(1) {
+    margin-right: 0;
+}
+.tabs-pane.active {
+    background: #5495df;
+    border-color: #5495df;
+    color: #fff;
+}
+
+.tab-class {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100vw;
+    bottom: 0;
+}
+
+.guidebook .img_box {
+    margin-bottom: 12rpx;
+    padding-left: 4rpx;
+}
+.guidebook .img_box .many_img {
+    display: flex;
+    justify-self: start;
+    flex-wrap: wrap;
+}
+.guidebook .img_item.four {
+    width: 198rpx;
+    height: 198rpx;
+    margin-right: 16rpx;
+    margin-bottom: 16rpx;
+    border-radius: 16rpx;
+    overflow: hidden;
+}
+.guidebook .img_item.four:nth-child(2n) {
+    margin-right: 30rpx;
+}
+.guidebook .img_item.many {
+    width: 198rpx;
+    height: 198rpx;
+    margin-right: 16rpx;
+    margin-bottom: 16rpx;
+    border-radius: 16rpx;
+    overflow: hidden;
+}
+.guidebook .img_item.many:nth-child(3n) {
+    margin-right: 0;
+}

+ 238 - 0
pages/sannong/sannong.vue

@@ -0,0 +1,238 @@
+<template>
+    <!-- pages/me.wxml -->
+    <view class="container">
+        <tabs :list="tabs" tab-class="tab-class" :showBadge="true" :swiper="true" activeColor="#07c160" normalColor="#000000" @change="tabChange">
+            <tab-page :slot="item.name" v-for="(item, index) in tabs" :key="index">
+                <!-- <view style="height: 100%;background-color: {{colors[index]}};">{{index}}</view> -->
+
+                <view v-if="index == 0" class="container">
+                    <view class="rnwdList">
+                        <view class="list" @tap="goDetails" v-for="(item, index1) in qbwd" :key="index1">
+                            <span class="listTitle">{{ item.title }}</span>
+
+                            <view class="onePic" v-if="item.imgList.length == 1">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="twoPic" v-if="item.imgList.length == 2">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="threePic" v-if="item.imgList.length == 3">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="jlSj">
+                                <span class="jf">
+                                    {{ item.jf }}
+                                    <em class="iconfont icon-jifen"></em>
+                                </span>
+                                <view class="ck">
+                                    <span>
+                                        <em class="iconfont icon-pinglun"></em>
+                                        {{ item.pl }}
+                                    </span>
+                                    <span>
+                                        <em class="iconfont icon-chakan"></em>
+                                        {{ item.ck }}
+                                    </span>
+                                    <span>
+                                        <em class="iconfont icon-shoucang"></em>
+                                        {{ item.dz }}
+                                    </span>
+                                </view>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+
+                <view v-if="index == 1" class="container">
+                    <view class="rnwdList">
+                        <view class="list" @tap="goDetails" v-for="(item, index1) in jcwd" :key="index1">
+                            <span class="listTitle">{{ item.title }}</span>
+
+                            <view class="onePic" v-if="item.imgList.length == 1">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="twoPic" v-if="item.imgList.length == 2">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="threePic" v-if="item.imgList.length == 3">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="jlSj">
+                                <span class="jf">
+                                    {{ item.jf }}
+                                    <em class="iconfont icon-jifen"></em>
+                                </span>
+                                <view class="ck">
+                                    <span>
+                                        <em class="iconfont icon-pinglun"></em>
+                                        {{ item.pl }}
+                                    </span>
+                                    <span>
+                                        <em class="iconfont icon-chakan"></em>
+                                        {{ item.ck }}
+                                    </span>
+                                    <span>
+                                        <em class="iconfont icon-shoucang"></em>
+                                        {{ item.dz }}
+                                    </span>
+                                </view>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+
+                <view v-if="index == 2" class="container">
+                    <view class="rnwdList">
+                        <view class="list" @tap="goDetails" v-for="(item, index1) in zdxs" :key="index1">
+                            <span class="listTitle">{{ item.title }}</span>
+
+                            <view class="onePic" v-if="item.imgList.length == 1">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="twoPic" v-if="item.imgList.length == 2">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="threePic" v-if="item.imgList.length == 3">
+                                <image :src="host + item.url" v-for="(item, index2) in item.imgList" :key="index2"></image>
+                            </view>
+
+                            <view class="jlSj">
+                                <span class="jf">
+                                    {{ item.jf }}
+                                    <em class="iconfont icon-jifen"></em>
+                                </span>
+                                <view class="ck">
+                                    <span>
+                                        <em class="iconfont icon-pinglun"></em>
+                                        {{ item.pl }}
+                                    </span>
+                                    <span>
+                                        <em class="iconfont icon-chakan"></em>
+                                        {{ item.ck }}
+                                    </span>
+                                    <span>
+                                        <em class="iconfont icon-shoucang"></em>
+                                        {{ item.dz }}
+                                    </span>
+                                </view>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+            </tab-page>
+        </tabs>
+    </view>
+</template>
+
+<script>
+import tabs from '../../components/tabs/tabs';
+import tabPage from '../../components/tab-page/tab-page';
+// pages/me.js
+var localData = require('../../data/json');
+const app = getApp();
+export default {
+    components: {
+        tabs,
+        tabPage
+    },
+    data() {
+        return {
+            host: app.globalData.host,
+            currentIndex: 0,
+            //默认是活动项
+            qbwd: '',
+            jcwd: '',
+            zdxs: '',
+            tabs: [
+                {
+                    name: '全部问答'
+                },
+                {
+                    name: '精彩问答'
+                },
+                {
+                    name: '最多悬赏'
+                }
+            ]
+        };
+    },
+    /**
+     * 生命周期函数--监听页面加载
+     */
+    onLoad(options) {
+        this.setData({
+            qbwd: localData.qnwdList,
+            jcwd: localData.jcwdList,
+            zdxs: localData.zdxsList
+        });
+    },
+    /**
+     * 生命周期函数--监听页面初次渲染完成
+     */
+    onReady() {},
+    /**
+     * 生命周期函数--监听页面显示
+     */
+    onShow() {},
+    /**
+     * 生命周期函数--监听页面隐藏
+     */
+    onHide() {},
+    /**
+     * 生命周期函数--监听页面卸载
+     */
+    onUnload() {},
+    /**
+     * 页面相关事件处理函数--监听用户下拉动作
+     */
+    onPullDownRefresh() {},
+    /**
+     * 页面上拉触底事件的处理函数
+     */
+    onReachBottom() {},
+    /**
+     * 用户点击右上角分享
+     */
+    onShareAppMessage() {},
+    methods: {
+        // // 切换swiper-item触发bindchange事件
+        // pagechange: function (e) {
+        //   // 通过touch判断,改变tab的下标值
+        //   if ("touch" === e.detail.source) {
+        //     let currentPageIndex = this.data.currentIndex;
+        //     currentPageIndex = (currentPageIndex + 1) % 2;
+        //     // 拿到当前索引并动态改变
+        //     this.setData({
+        //       currentIndex: currentPageIndex,
+        //     })
+        //   }
+        // },
+
+        // //点击tab时触发
+        // titleClick: function (e) {
+        //   this.setData({
+        //     //拿到当前索引并动态改变
+        //     currentIndex: e.currentTarget.dataset.idx
+        //   })
+        // },
+        tabChange: function (e) {},
+
+        goDetails() {
+            uni.navigateTo({
+                url: '../wenbaxiangqing/wenbaxiangqing'
+            });
+        }
+    }
+};
+</script>
+<style>
+@import './sannong.css';
+</style>

+ 190 - 0
pages/shangcheng/shangcheng.css

@@ -0,0 +1,190 @@
+/* pages/shangcheng.wxss */
+.shangchengTop {
+    width: 100%;
+}
+.shangchengTop image {
+    width: 100%;
+    height: 420rpx;
+}
+
+.cnfl {
+    width: 100%;
+    margin: 40rpx 0;
+    display: flex;
+    justify-content: space-between;
+}
+.gxs,
+.hm {
+    width: 48%;
+    border-radius: 20rpx;
+    overflow: hidden;
+    position: relative;
+}
+.gxs text,
+.hm text {
+    position: absolute;
+    left: 13%;
+    top: 30%;
+    font-size: 36rpx;
+    font-weight: bold;
+}
+.gxs text {
+    color: #2c8246;
+}
+.hm text {
+    color: #d36900;
+}
+.gxs image,
+.hm image {
+    width: 100%;
+    height: 134rpx;
+}
+/* 积分 */
+.jfZongshu {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    margin: 30rpx 0;
+}
+.jfZongshu_in {
+    width: 50%;
+    background: #07c160;
+    display: flex;
+    flex-direction: column;
+    padding: 3%;
+}
+.jfZongshu_in text {
+    font-size: 24rpx;
+    color: #fff;
+}
+.jfZongshu_in h2 {
+    font-size: 44rpx;
+    color: #fff;
+    font-weight: bold;
+    line-height: 80rpx;
+}
+.jfZongshu_in span {
+    padding: 10rpx 0;
+    font-size: 30rpx;
+    background: -webkit-linear-gradient(#e9c79a, #e7bd88);
+    background: -o-linear-gradient(#e9c79a, #e7bd88);
+    background: -moz-linear-gradient(#e9c79a, #e7bd88);
+    background: linear-gradient(#e9c79a, #e7bd88);
+    color: #4f3413;
+    width: 50%;
+    text-align: center;
+    border-radius: 20rpx;
+    margin: 20rpx 0 0 160rpx;
+    font-size: 28rpx;
+}
+.jfZongshuFr {
+    width: 40%;
+}
+.xszn,
+.jfmx {
+    background: #ecfcf2;
+    padding: 30rpx;
+    font-size: 30rpx;
+}
+.xszn {
+    margin: 0 0 30rpx 0;
+}
+.icon-xinshouyindao,
+.icon-mingxi {
+    font-size: 40rpx;
+    color: #07c160;
+    margin: 0 20rpx 0 0;
+}
+.icon-shangpin {
+    font-size: 40rpx;
+    margin: 0 10rpx 0 0;
+}
+.jiage {
+    display: flex;
+    margin: 20rpx 0 0 0;
+}
+
+.yhjg {
+    font-size: 30rpx;
+    color: #07c160;
+}
+
+.yhjg em {
+    font-size: 24rpx;
+    color: #07c160;
+}
+
+.yjjg {
+    font-size: 24rpx;
+    color: #9c9c9c;
+    margin: 6rpx 0 0 20rpx;
+    text-decoration: line-through;
+}
+.tjcpList {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    flex-wrap: wrap;
+    padding: 0 0 120rpx 0;
+}
+.tjcpList li {
+    width: 48%;
+    background: #f5f5f5;
+    border-radius: 10rpx;
+    overflow: hidden;
+    margin: 14rpx 0;
+    padding: 0 0 16rpx 0;
+}
+.sp_pic {
+    width: 100%;
+    height: 270rpx;
+}
+.sp_wenben {
+    width: 87%;
+    padding: 20rpx;
+    text-align: justify;
+}
+.sp_title {
+    font-size: 30rpx;
+    color: #333;
+}
+.tuijianCp {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+}
+.fenlei {
+    font-size: 28rpx;
+    line-height: 90rpx;
+    color: #c3c3c3;
+}
+.tuijianCp .titleLeft {
+    width: 80%;
+}
+.icon-fenlei {
+    margin: 8rpx 10rpx 0 0;
+}
+.fabiaoPl {
+    display: flex;
+    justify-content: space-between;
+    position: fixed;
+    left: 0;
+    bottom: 0;
+    height: 112rpx;
+    background: #e8e8e8;
+    box-shadow: 0rpx 0rpx 16rpx #999;
+    padding: 0 56rpx;
+    width: 85%;
+}
+.fabiaoPl view {
+    width: 112rpx;
+    text-align: center;
+}
+.fabiaoPl view span {
+    font-size: 20rpx;
+}
+.fabiaoPl view image {
+    width: 54rpx;
+    height: 54rpx;
+    margin: 10rpx auto 0 auto;
+}

+ 178 - 0
pages/shangcheng/shangcheng.vue

@@ -0,0 +1,178 @@
+<template>
+    <view>
+        <!-- pages/shangcheng.wxml -->
+        <view class="shangchengTop">
+            <image :src="host + '/sc-banner.png'"></image>
+        </view>
+        <view class="container">
+            <view class="cnfl">
+                <view class="hm">
+                    <text>惠民通</text>
+                    <image :src="host + '/hm.jpg'"></image>
+                </view>
+                <view class="gxs">
+                    <text>供销社</text>
+                    <image :src="host + '/gxs.png'"></image>
+                </view>
+            </view>
+        </view>
+        <view class="fengexian"></view>
+        <!-- 分割线 -->
+        <!-- 积分商城 -->
+        <view class="container">
+            <view class="jfZongshu">
+                <view class="jfZongshu_in">
+                    <text>--吉村宝--</text>
+                    <h2>9876554</h2>
+                    <span>积分商城</span>
+                </view>
+                <view class="jfZongshuFr">
+                    <view class="xszn">
+                        <em class="iconfont icon-xinshouyindao"></em>
+                        新手指南
+                    </view>
+                    <view class="jfmx">
+                        <em class="iconfont icon-mingxi"></em>
+                        积分明细
+                    </view>
+                </view>
+            </view>
+            <view class="tuijianCp">
+                <view class="titleLeft">
+                    <em class="iconfont icon-shangpin"></em>
+                    推荐产品
+                </view>
+                <view class="fenlei" @tap="goFenLei">
+                    <em class="iconfont icon-fenlei"></em>
+                    分类
+                </view>
+            </view>
+            <ul class="tjcpList">
+                <li>
+                    <image class="sp_pic" :src="host + '/chanpintu.png'"></image>
+                    <view class="sp_wenben">
+                        <span class="sp_title">生日礼物送女朋友给男女生闺蜜实用创意小众夜灯</span>
+                        <view class="jiage">
+                            <span class="yhjg">
+                                <em>¥</em>
+                                200
+                            </span>
+                            <span class="yjjg">¥500</span>
+                        </view>
+                    </view>
+                </li>
+                <li>
+                    <image class="sp_pic" :src="host + '/chanpintu.png'"></image>
+                    <view class="sp_wenben">
+                        <span class="sp_title">生日礼物送女朋友给男女生闺蜜实用创意小众夜灯</span>
+                        <view class="jiage">
+                            <span class="yhjg">
+                                <em>¥</em>
+                                200
+                            </span>
+                            <span class="yjjg">¥500</span>
+                        </view>
+                    </view>
+                </li>
+                <li>
+                    <image class="sp_pic" :src="host + '/chanpintu.png'"></image>
+                    <view class="sp_wenben">
+                        <span class="sp_title">生日礼物送女朋友给男女生闺蜜实用创意小众夜灯</span>
+                        <view class="jiage">
+                            <span class="yhjg">
+                                <em>¥</em>
+                                200
+                            </span>
+                            <span class="yjjg">¥500</span>
+                        </view>
+                    </view>
+                </li>
+                <li>
+                    <image class="sp_pic" :src="host + '/chanpintu.png'"></image>
+                    <view class="sp_wenben">
+                        <span class="sp_title">生日礼物送女朋友给男女生闺蜜实用创意小众夜灯</span>
+                        <view class="jiage">
+                            <span class="yhjg">
+                                <em>¥</em>
+                                200
+                            </span>
+                            <span class="yjjg">¥500</span>
+                        </view>
+                    </view>
+                </li>
+            </ul>
+        </view>
+        <view class="fabiaoPl">
+            <view>
+                <image class="bottomNav-shangcheng" :src="host + '/botnav-shangcheng2.png'"></image>
+                <span>商城</span>
+            </view>
+            <view>
+                <image class="bottomNav-xiaoxi" :src="host + '/botnav-xiaoxi2.png'"></image>
+                <span>消息</span>
+            </view>
+            <view>
+                <image class="bottomNav-gouwuche" :src="host + '/botnav-gouwuche2.png'"></image>
+                <span>购物车</span>
+            </view>
+            <view>
+                <image class="bottomNav-dingdan" :src="host + '/botnav-dingdan2.png'"></image>
+                <span>订单</span>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+// pages/me.js
+const app = getApp();
+export default {
+    data() {
+        return {
+            host: app.globalData.host
+        };
+    }
+    /**
+     * 生命周期函数--监听页面加载
+     */,
+    onLoad(options) {},
+    /**
+     * 生命周期函数--监听页面初次渲染完成
+     */
+    onReady() {},
+    /**
+     * 生命周期函数--监听页面显示
+     */
+    onShow() {},
+    /**
+     * 生命周期函数--监听页面隐藏
+     */
+    onHide() {},
+    /**
+     * 生命周期函数--监听页面卸载
+     */
+    onUnload() {},
+    /**
+     * 页面相关事件处理函数--监听用户下拉动作
+     */
+    onPullDownRefresh() {},
+    /**
+     * 页面上拉触底事件的处理函数
+     */
+    onReachBottom() {},
+    /**
+     * 用户点击右上角分享
+     */
+    onShareAppMessage() {},
+    methods: {
+        goFenLei() {
+            uni.navigateTo({
+                url: '../fenlei/fenlei'
+            });
+        }
+    }
+};
+</script>
+<style>
+@import './shangcheng.css';
+</style>

+ 112 - 0
pages/shangpinxiangqingye/shangpinxiangqingye.css

@@ -0,0 +1,112 @@
+/* pages/shangpinxiangqingye.wxss */
+.spZhutu {
+    width: 100%;
+}
+.spZhutu image {
+    width: 100%;
+    height: 680rpx;
+}
+.spxqJiage {
+    width: 94%;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    background: #ecfcf2;
+    margin: 30rpx 0;
+    padding: 3%;
+    border-radius: 20rpx;
+}
+.yuanJia {
+    color: #07c160;
+    font-size: 36rpx;
+    margin: 0 20rpx 0 0;
+}
+.yuanJia em {
+    font-size: 24rpx;
+}
+.youhuiJia p em {
+    font-size: 28rpx;
+}
+.youhuiJia {
+    background: #07c160;
+    color: #fff;
+    border-radius: 20rpx;
+    padding: 10rpx 30rpx;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+}
+.youhuiJia span {
+    font-size: 24rpx;
+}
+.youhuiJia p {
+    font-size: 36rpx;
+}
+.sp_title {
+    font-size: 30rpx;
+    color: #333;
+    margin: 0 0 30rpx 0;
+}
+.shanpinContTitle {
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    margin: 30rpx 0;
+    font-size: 30rpx;
+    color: #999;
+}
+.shangpinXQtu {
+    width: 100%;
+    padding: 0 0 130rpx 0;
+}
+.shangpinXQtu image {
+    width: 100%;
+    height: 1000rpx;
+}
+/* 底部 */
+.fabiaoPl {
+    width: 94%;
+    display: flex;
+    justify-content: space-between;
+    position: fixed;
+    align-items: center;
+    left: 0;
+    bottom: 0;
+    height: 112rpx;
+    background: #e8e8e8;
+    box-shadow: 0rpx 0rpx 16rpx #999;
+    padding: 0 3%;
+}
+.fabiaoPl .dp_kf_cs {
+    text-align: center;
+    display: flex;
+    flex-direction: column;
+    font-size: 20rpx;
+}
+.icon-dianpu,
+.icon-zaixiankefu,
+.icon-shoucang1 {
+    font-size: 48rpx;
+    color: #999;
+}
+.gwc_ljgm {
+    width: 440rpx;
+    border-radius: 40rpx;
+    overflow: hidden;
+    font-size: 30rpx;
+    display: flex;
+    flex-direction: row;
+    color: #fff;
+}
+.gouwuche,
+.fukuan {
+    width: 50%;
+    text-align: center;
+    line-height: 80rpx;
+}
+.gouwuche {
+    background: #07c160;
+}
+.fukuan {
+    background: #048d2d;
+}

+ 97 - 0
pages/shangpinxiangqingye/shangpinxiangqingye.vue

@@ -0,0 +1,97 @@
+<template>
+    <view>
+        <!-- pages/shangpinxiangqingye.wxml -->
+        <view class="spZhutu">
+            <image class="sp_pic" src="/static/pages/images/chanpintu.png"></image>
+        </view>
+        <view class="container">
+            <view class="spxqJiage">
+                <span class="yuanJia">
+                    <em>¥</em>
+                    500
+                </span>
+                <view class="youhuiJia">
+                    <span>优惠促销劵后</span>
+                    <p>
+                        <em>¥</em>
+                        300
+                    </p>
+                </view>
+            </view>
+            <span class="sp_title">兔子硅胶小夜灯充电卧室床头睡眠拍拍伴睡网红台灯儿童可爱女礼物</span>
+        </view>
+        <view class="fengexian"></view>
+        <!-- 分割线 -->
+        <view class="container">
+            <!-- 商品详情 -->
+            <text class="shanpinContTitle">---商品详情---</text>
+            <view class="shangpinXQtu">
+                <image class="sp_pic" src="/static/pages/images/shangpinxiangqing01.jpg"></image>
+                <image class="sp_pic" src="/static/pages/images/shangpinxiangqing02.jpg"></image>
+            </view>
+        </view>
+        <view class="fabiaoPl">
+            <view class="dp_kf_cs">
+                <em class="iconfont icon-dianpu"></em>
+                店铺
+            </view>
+            <view class="dp_kf_cs">
+                <em class="iconfont icon-zaixiankefu"></em>
+                客服
+            </view>
+            <view class="dp_kf_cs">
+                <em class="iconfont icon-shoucang1"></em>
+                收藏
+            </view>
+            <view class="gwc_ljgm">
+                <view class="gouwuche">加入购物车</view>
+                <view class="fukuan">立即购买</view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+// pages/shangpinxiangqingye.js
+export default {
+    data() {
+        return {};
+    }
+    /**
+     * 生命周期函数--监听页面加载
+     */,
+    onLoad(options) {},
+    /**
+     * 生命周期函数--监听页面初次渲染完成
+     */
+    onReady() {},
+    /**
+     * 生命周期函数--监听页面显示
+     */
+    onShow() {},
+    /**
+     * 生命周期函数--监听页面隐藏
+     */
+    onHide() {},
+    /**
+     * 生命周期函数--监听页面卸载
+     */
+    onUnload() {},
+    /**
+     * 页面相关事件处理函数--监听用户下拉动作
+     */
+    onPullDownRefresh() {},
+    /**
+     * 页面上拉触底事件的处理函数
+     */
+    onReachBottom() {},
+    /**
+     * 用户点击右上角分享
+     */
+    onShareAppMessage() {},
+    methods: {}
+};
+</script>
+<style>
+@import './shangpinxiangqingye.css';
+</style>

+ 103 - 0
pages/wenba/wenba.css

@@ -0,0 +1,103 @@
+/* pages/wenda/wenda.wxss */
+.wendaFL {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    margin: 30rpx 0 0 0;
+}
+.wendaFL li {
+    width: 48%;
+    height: 168rpx;
+    position: relative;
+}
+.lbBj {
+    position: absolute;
+    left: 0;
+    top: 0;
+    z-index: 0;
+    width: 100%;
+    height: 100%;
+}
+.wendaFL li h2 {
+    font-size: 36rpx;
+    position: absolute;
+    left: 30rpx;
+    top: 40rpx;
+    z-index: 1;
+    font-weight: bold;
+}
+.wendaFL li span {
+    font-size: 30rpx;
+    position: absolute;
+    left: 30rpx;
+    top: 88rpx;
+    z-index: 1;
+}
+.wendaFL li.sanNong {
+    color: #0d9970;
+}
+.wendaFL li.jiuYe {
+    color: #1e8fb4;
+}
+.wendaFL li.faLv {
+    color: #1e5dab;
+}
+.wendaFL li.jiuZhen {
+    color: #4a700d;
+}
+/* 列表 */
+.rnwdList {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    margin: 20rpx 0;
+}
+.list {
+    width: 79%;
+}
+.lb {
+    background: #0d9970;
+    color: #fff;
+    font-size: 24rpx;
+    width: 12%;
+    text-align: center;
+    padding: 2rpx 0;
+    line-height: 40rpx;
+    height: 40rpx;
+    border-radius: 10rpx;
+}
+.listTitle {
+    font-size: 32rpx;
+    color: #333;
+    line-height: 40rpx;
+}
+.jlSj {
+    height: 40rpx;
+    display: flex;
+    justify-content: space-between;
+    font-size: 24rpx;
+    margin: 20rpx 0 0 0;
+}
+.jf {
+    color: #07c160;
+}
+.icon-jifen {
+    font-size: 28rpx;
+    color: #07c160;
+    margin: 0 0 0 6rpx;
+}
+.ck {
+    color: #c4c4c4;
+}
+.icon-pinglun,
+.icon-chakan,
+.icon-shoucang {
+    font-size: 28rpx;
+    margin: 0 6rpx 0 20rpx;
+    color: #c4c4c4;
+}
+.icon-xiangyoujiantou {
+    font-size: 30rpx;
+    color: #c4c4c4;
+    line-height: 60rpx;
+}

+ 139 - 0
pages/wenba/wenba.vue

@@ -0,0 +1,139 @@
+<template>
+    <!-- pages/fuwu/fuwu.wxml -->
+    <view class="container">
+        <!-- 问答类别 -->
+
+        <ul class="wendaFL">
+            <li class="sanNong">
+                <image :src="host + '/snbj.png'" class="lbBj" @tap="goSanNong"></image>
+                <h2>三农</h2>
+                <span>1566</span>
+            </li>
+            <li class="jiuYe">
+                <image :src="host + '/jybj.png'" class="lbBj"></image>
+                <h2>就业</h2>
+                <span>1589</span>
+            </li>
+        </ul>
+        <ul class="wendaFL">
+            <li class="faLv">
+                <image :src="host + '/flbj.png'" class="lbBj"></image>
+                <h2>法律</h2>
+                <span>6589</span>
+            </li>
+            <li class="jiuZhen">
+                <image :src="host + '/jzbj.png'" class="lbBj"></image>
+                <h2>就诊</h2>
+                <span>1566</span>
+            </li>
+        </ul>
+        <ul class="wendaFL">
+            <li class="jiuYe">
+                <image :src="host + '/zkbj.png'" class="lbBj"></image>
+                <h2>智库</h2>
+                <span>1589</span>
+            </li>
+            <li class="sanNong">
+                <image :src="host + '/lybj.png'" class="lbBj"></image>
+                <h2>旅游</h2>
+                <span>6589</span>
+            </li>
+        </ul>
+        <!-- 问答列表 -->
+        <view class="rnwdList" @tap="goDetails" v-for="(item, index) in wb" :key="index">
+            <span class="lb">{{ item.type }}</span>
+
+            <view class="list">
+                <span class="listTitle">{{ item.title }}</span>
+                <view class="jlSj">
+                    <span class="jf">
+                        {{ item.jf }}
+                        <em class="iconfont icon-jifen"></em>
+                    </span>
+                    <view class="ck">
+                        <span>
+                            <em class="iconfont icon-pinglun"></em>
+                            {{ item.pl }}
+                        </span>
+                        <span>
+                            <em class="iconfont icon-chakan"></em>
+                            {{ item.ck }}
+                        </span>
+                        <span>
+                            <em class="iconfont icon-shoucang"></em>
+                            {{ item.dz }}
+                        </span>
+                    </view>
+                </view>
+            </view>
+
+            <em class="iconfont icon-xiangyoujiantou"></em>
+        </view>
+    </view>
+</template>
+
+<script>
+// pages/fuwu/fuwu.js
+const app = getApp();
+var localData = require('../../data/json');
+export default {
+    data() {
+        return {
+            host: app.globalData.host,
+            wb: ''
+        };
+    }
+    /**
+     * 生命周期函数--监听页面加载
+     */,
+    onLoad(options) {
+        this.setData({
+            wb: localData.wbList
+        });
+    },
+    /**
+     * 生命周期函数--监听页面初次渲染完成
+     */
+    onReady() {},
+    /**
+     * 生命周期函数--监听页面显示
+     */
+    onShow() {},
+    /**
+     * 生命周期函数--监听页面隐藏
+     */
+    onHide() {},
+    /**
+     * 生命周期函数--监听页面卸载
+     */
+    onUnload() {},
+    /**
+     * 页面相关事件处理函数--监听用户下拉动作
+     */
+    onPullDownRefresh() {},
+    /**
+     * 页面上拉触底事件的处理函数
+     */
+    onReachBottom() {},
+    /**
+     * 用户点击右上角分享
+     */
+    onShareAppMessage() {},
+    methods: {
+        goSanNong() {
+            uni.navigateTo({
+                url: '../sannong/sannong'
+            });
+        },
+
+        goDetails() {
+            uni.navigateTo({
+                url: '../wenbaxiangqing/wenbaxiangqing'
+            });
+        }
+    }
+};
+</script>
+<style>
+@import './wenba.css';
+</style>

+ 160 - 0
pages/wenbaxiangqing/wenbaxiangqing.css

@@ -0,0 +1,160 @@
+/* pages/wenbaxiangqing.wxss */
+.title {
+    font-size: 44rpx;
+    text-align: center;
+    line-height: 70rpx;
+    color: #333;
+    margin: 30rpx 0;
+}
+.wenzhangLy {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    border-bottom: solid 2rpx #e8e8e8;
+    padding: 0 0 14rpx 0;
+}
+.txTime {
+    display: flex;
+    flex-direction: row;
+}
+.txTime image {
+    width: 80rpx;
+    height: 80rpx;
+}
+.time {
+    display: flex;
+    flex-direction: column;
+    padding: 10rpx 0 0 8px;
+}
+.time p {
+    font-size: 28rpx;
+    color: #9c9c9c;
+}
+.time span {
+    font-size: 24rpx;
+    color: #c4c4c4;
+}
+
+.jf {
+    color: #07c160;
+    line-height: 80rpx;
+    font-size: 24rpx;
+}
+.icon-jifen {
+    font-size: 28rpx;
+    color: #07c160;
+    margin: 0 0 0 6rpx;
+}
+.ck {
+    color: #c4c4c4;
+    font-size: 28rpx;
+}
+.icon-pinglun,
+.icon-chakan,
+.ck .icon-shoucang {
+    font-size: 28rpx;
+    margin: 0 6rpx 0 20rpx;
+    color: #c4c4c4;
+    line-height: 0;
+}
+.wenzhangCont {
+    font-size: 34rpx;
+    margin: 30rpx 0;
+}
+.wenzhangCont image {
+    width: 100%;
+    height: 320rpx;
+    margin: 20rpx auto;
+}
+.pinglunTj {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    margin: 30rpx 0;
+}
+.pinglunTitle {
+    font-size: 34rpx;
+    color: #2e2e2e;
+    font-weight: 600;
+}
+.pinglunTitle em {
+    font-size: 34rpx;
+    color: #9b9b9b;
+    font-weight: normal;
+    margin: 0 0 0 10rpx;
+}
+.pinglunList {
+    width: 100%;
+    padding: 0 0 120rpx 0;
+}
+.pinglunList li {
+    margin: 20rpx 0;
+    border-bottom: solid 2rpx #e8e8e8;
+    padding: 0 0 20rpx 0;
+    display: flex;
+    flex-direction: column;
+}
+.plListcont {
+    font-size: 30rpx;
+    color: #696868;
+    margin: 20rpx 0;
+}
+.pinglunList li button {
+    width: 80%;
+    border-radius: 10rpx;
+    background: #07c160;
+    color: #fff;
+    font-size: 28rpx;
+    font-weight: normal;
+    margin: 16rpx auto;
+}
+.fabiaoPl {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    position: fixed;
+    left: 0;
+    bottom: 0;
+    height: 112rpx;
+    background: #e8e8e8;
+    box-shadow: 0rpx 0rpx 16rpx #999;
+}
+.shuRu {
+    width: 72%;
+    display: flex;
+    flex-direction: row;
+    height: 76rpx;
+    background: #e0e0e0;
+    border-radius: 60rpx;
+    margin: 20rpx 0 0 20rpx;
+}
+.shuRu input {
+    line-height: 38px;
+    height: 76rpx;
+    font-size: 30rpx;
+    width: 83%;
+}
+.icon-bianji {
+    font-size: 38rpx;
+    line-height: 76rpx;
+    margin: 0 10rpx 0 20rpx;
+    color: #828181;
+}
+.icon-shoucang {
+    font-size: 50rpx;
+    line-height: 112rpx;
+    color: #828181;
+}
+.fasong {
+    width: 58rpx;
+    height: 58rpx;
+    border-radius: 50rpx;
+    background: #07c160;
+    margin: 26rpx 20rpx 0 10rpx;
+    text-align: center;
+    line-height: 58rpx;
+}
+.icon-fasong {
+    font-size: 40rpx;
+    color: #fff;
+}

Разлика између датотеке није приказан због своје велике величине
+ 114 - 0
pages/wenbaxiangqing/wenbaxiangqing.vue


+ 0 - 39
permission.js

@@ -1,39 +0,0 @@
-import { getToken } from '@/utils/auth'
-
-// 登录页面
-const loginPage = "/pages/login"
-  
-// 页面白名单
-const whiteList = [
-  '/pages/login', '/pages/demo/index', '/pages/demo/my','/pages/demo/fwblz'
-]
-
-// 检查地址白名单
-function checkWhite(url) {
-  const path = url.split('?')[0]
-  return whiteList.indexOf(path) !== -1
-}
-
-// 页面跳转验证拦截器
-let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]
-list.forEach(item => {
-  uni.addInterceptor(item, {
-    invoke(to) {
-      if (getToken()) {
-        if (to.url === loginPage) {
-          uni.reLaunch({ url: "/" })
-        }
-        return true
-      } else {
-        if (checkWhite(to.url)) {
-          return true
-        }
-        uni.reLaunch({ url: loginPage })
-        return false
-      }
-    },
-    fail(err) {
-      console.log(err)
-    }
-  })
-})

+ 0 - 60
plugins/auth.js

@@ -1,60 +0,0 @@
-import store from '@/store'
-
-function authPermission(permission) {
-  const all_permission = "*:*:*"
-  const permissions = store.getters && store.getters.permissions
-  if (permission && permission.length > 0) {
-    return permissions.some(v => {
-      return all_permission === v || v === permission
-    })
-  } else {
-    return false
-  }
-}
-
-function authRole(role) {
-  const super_admin = "admin"
-  const roles = store.getters && store.getters.roles
-  if (role && role.length > 0) {
-    return roles.some(v => {
-      return super_admin === v || v === role
-    })
-  } else {
-    return false
-  }
-}
-
-export default {
-  // 验证用户是否具备某权限
-  hasPermi(permission) {
-    return authPermission(permission)
-  },
-  // 验证用户是否含有指定权限,只需包含其中一个
-  hasPermiOr(permissions) {
-    return permissions.some(item => {
-      return authPermission(item)
-    })
-  },
-  // 验证用户是否含有指定权限,必须全部拥有
-  hasPermiAnd(permissions) {
-    return permissions.every(item => {
-      return authPermission(item)
-    })
-  },
-  // 验证用户是否具备某角色
-  hasRole(role) {
-    return authRole(role)
-  },
-  // 验证用户是否含有指定角色,只需包含其中一个
-  hasRoleOr(roles) {
-    return roles.some(item => {
-      return authRole(item)
-    })
-  },
-  // 验证用户是否含有指定角色,必须全部拥有
-  hasRoleAnd(roles) {
-    return roles.every(item => {
-      return authRole(item)
-    })
-  }
-}

+ 0 - 20
plugins/index.js

@@ -1,20 +0,0 @@
-import tab from './tab'
-import auth from './auth'
-import modal from './modal'
-import validation from '@/utils/test.js';
-import user from '../store/modules/user.js'
-
-export default {
-	install(Vue) {
-		// 页签操作
-		Vue.prototype.$tab = tab
-		// 认证对象
-		Vue.prototype.$auth = auth
-		// 模态框对象
-		Vue.prototype.$modal = modal
-		//校验
-		Vue.prototype.$validation = validation
-		//用户信息
-		Vue.prototype.$user = user
-	}
-}

+ 0 - 74
plugins/modal.js

@@ -1,74 +0,0 @@
-export default {
-  // 消息提示
-  msg(content) {
-    uni.showToast({
-      title: content,
-      icon: 'none'
-    })
-  },
-  // 错误消息
-  msgError(content) {
-    uni.showToast({
-      title: content,
-      icon: 'error'
-    })
-  },
-  // 成功消息
-  msgSuccess(content) {
-    uni.showToast({
-      title: content,
-      icon: 'success'
-    })
-  },
-  // 隐藏消息
-  hideMsg(content) {
-    uni.hideToast()
-  },
-  // 弹出提示
-  alert(content, title) {
-    uni.showModal({
-      title: title || '系统提示',
-      content: content,
-      showCancel: false
-    })
-  },
-  // 确认窗体
-  confirm(content, title) {
-    return new Promise((resolve, reject) => {
-      uni.showModal({
-        title: title || '系统提示',
-        content: content,
-        cancelText: '取消',
-        confirmText: '确定',
-        success: function(res) {
-          if (res.confirm) {
-            resolve(res.confirm)
-          }
-        }
-      })
-    })
-  },
-  // 提示信息
-  showToast(option) {
-    if (typeof option === "object") {
-      uni.showToast(option)
-    } else {
-      uni.showToast({
-        title: option,
-        icon: "none",
-        duration: 2500
-      })
-    }
-  },
-  // 打开遮罩层
-  loading(content) {
-    uni.showLoading({
-      title: content,
-      icon: 'none'
-    })
-  },
-  // 关闭遮罩层
-  closeLoading() {
-    uni.hideLoading()
-  }
-}

+ 0 - 30
plugins/tab.js

@@ -1,30 +0,0 @@
-export default {
-  // 关闭所有页面,打开到应用内的某个页面
-  reLaunch(url) {
-    return uni.reLaunch({
-      url: url
-    })
-  },
-  // 跳转到tabBar页面,并关闭其他所有非tabBar页面
-  switchTab(url) {
-    return uni.switchTab({
-      url: url
-    })
-  },
-  // 关闭当前页面,跳转到应用内的某个页面
-  redirectTo(url) {
-    return uni.redirectTo({
-      url: url
-    })
-  },
-  // 保留当前页面,跳转到应用内的某个页面
-  navigateTo(url) {
-    return uni.navigateTo({
-      url: url
-    })
-  },
-  // 关闭当前页面,返回上一页面或多级页面
-  navigateBack() {
-    return uni.navigateBack()
-  }
-}

+ 52 - 0
project.config.json

@@ -0,0 +1,52 @@
+{
+  "description": "项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "setting": {
+    "urlCheck": false,
+    "es6": false,
+    "enhance": false,
+    "postcss": true,
+    "preloadBackgroundData": false,
+    "minified": true,
+    "newFeature": false,
+    "coverView": true,
+    "nodeModules": false,
+    "autoAudits": false,
+    "showShadowRootInWxmlPanel": true,
+    "scopeDataCheck": false,
+    "uglifyFileName": false,
+    "checkInvalidKey": true,
+    "checkSiteMap": true,
+    "uploadWithSourceMap": true,
+    "compileHotReLoad": false,
+    "lazyloadPlaceholderEnable": false,
+    "useMultiFrameRuntime": true,
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
+    },
+    "useIsolateContext": true,
+    "userConfirmedBundleSwitch": false,
+    "packNpmManually": false,
+    "packNpmRelationList": [],
+    "minifyWXSS": true,
+    "disableUseStrict": false,
+    "minifyWXML": true,
+    "showES6CompileOption": false,
+    "useCompilerPlugins": false,
+    "ignoreUploadUnusedFiles": true,
+    "useStaticServer": true
+  },
+  "compileType": "miniprogram",
+  "condition": {},
+  "editorSetting": {
+    "tabIndent": "insertSpaces",
+    "tabSize": 2
+  },
+  "packOptions": {
+    "ignore": [],
+    "include": []
+  },
+  "appid": "touristappid",
+  "libVersion": "2.30.2"
+}

+ 8 - 0
project.private.config.json

@@ -0,0 +1,8 @@
+{
+  "projectname": "Sooka_demo",
+  "setting": {
+    "compileHotReLoad": true
+  },
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "libVersion": "2.25.3"
+}


+ 7 - 0
sitemap.json

@@ -0,0 +1,7 @@
+{
+  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+  "rules": [{
+  "action": "allow",
+  "page": "*"
+  }]
+}

BIN
static/pages/images/chanpintu.png


BIN
static/pages/images/fuwu1.png


BIN
static/pages/images/fuwu2.png


BIN
static/pages/images/index1.png


BIN
static/pages/images/index2.png


BIN
static/pages/images/me1.png


BIN
static/pages/images/me2.png


BIN
static/pages/images/sc.png


BIN
static/pages/images/shangpinxaingqing01.jpg


BIN
static/pages/images/shangpinxaingqing02.jpg


BIN
static/pages/images/tongzhuan.png


BIN
static/pages/images/ty.png


BIN
static/pages/images/waitao.png


BIN
static/pages/images/yumi.png


+ 46 - 0
transform.log

@@ -0,0 +1,46 @@
+开始转换……
+小程序路径:  C:\Users\Administrator\Desktop\sookauniapp_demo
+搜索到97个文件(含目录),耗时:10ms
+
+开始分析文件
+分析文件信息完成,共21组数据
+开始转换文件组为vue文件
+
+[Tip]这里引用的全是网络字体,可能在app上面有兼容问题(如字体图标显示不出来,运行后没问题就不用管)  fileKey: pages/iconfont/iconfont
+[WARN] 文件 pages/images/shangpinxiangqing01.jpg 不存在,但仍然对路径进行转换为相对于static目录,运行时需注意!   fileKey: pages/shangpinxiangqingye/shangpinxiangqingye
+[WARN] 文件 pages/images/shangpinxiangqing02.jpg 不存在,但仍然对路径进行转换为相对于static目录,运行时需注意!   fileKey: pages/shangpinxiangqingye/shangpinxiangqingye
+开始二次遍历及生成vue文件
+write pages.json success!
+write manifest.json success!
+write main.js success!
+write package.json success!
+
+
+统计信息:
+
+Component数量: 4
+Page数量: 9
+支付api数量: 0
+登录api数量: 0
+chooseMedia数量: 0
+getLocation数量: 0
+getRelationNodes数量: 0
+<ad/>数量: 0
+<map/>数量: 0
+<video/>数量: 0
+Vant组件: , 数量:0
+
+项目转换完成!
+用时: 2.772s
+工具版本:v2.2.6
+在该小程序项目的同级目录可以看到_uni结尾的项目,即是转换好的uniapp项目,相关日志在该目录里。
+
+!!! 当前项目引用了npm模块,请转换完后,在命令行里运行“npm install”命令安装npm模块 !!!
+
+使用说明:
+    1.因各种原因,本工具并非100%完美转换!部分语法仍需人工处理!
+    2.工具转换原理及说明文档参考:https://l4rz4zwpx7.k.topthink.com/@kmrvzg72lx/
+    3.如遇运行报错,请添加QQ群(五群:536178289)带图反馈或https://github.com/zhangdaren/miniprogram-to-uniapp提交Issue!
+    4.转换后请查阅_uni目录或_uni-cli目录里的 README.md 和 transform.log
+
+

+ 17 - 4
uni.scss

@@ -1,6 +1,19 @@
 /**
- * uni-app内置的常用样式变量
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
  */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
 /* 行为相关颜色 */
 $uni-color-primary: #007aff;
 $uni-color-success: #4cd964;
@@ -21,14 +34,14 @@ $uni-bg-color-hover:#f1f1f1;//点击状态颜色
 $uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
 
 /* 边框颜色 */
-$uni-border-color:#e5e5e5;
+$uni-border-color:#c8c7cc;
 
 /* 尺寸变量 */
 
 /* 文字尺寸 */
 $uni-font-size-sm:12px;
 $uni-font-size-base:14px;
-$uni-font-size-lg:16px;
+$uni-font-size-lg:16;
 
 /* 图片尺寸 */
 $uni-img-size-sm:20px;
@@ -60,4 +73,4 @@ $uni-font-size-title:20px;
 $uni-color-subtitle: #555555; // 二级标题颜色
 $uni-font-size-subtitle:26px;
 $uni-color-paragraph: #3F536E; // 文章段落颜色
-$uni-font-size-paragraph:15px;
+$uni-font-size-paragraph:15px;

+ 193 - 0
uni_modules/mp-html/README.md

@@ -0,0 +1,193 @@
+## 为减小组件包的大小,默认组件包中不包含编辑、latex 公式等扩展功能,需要使用扩展功能的请参考下方的 插件扩展 栏的说明
+
+## 功能介绍
+- 全端支持(含 `v3、NVUE`)
+- 支持丰富的标签(包括 `table`、`video`、`svg` 等)
+- 支持丰富的事件效果(自动预览图片、链接处理等)
+- 支持设置占位图(加载中、出错时、预览时)
+- 支持锚点跳转、长按复制等丰富功能
+- 支持大部分 *html* 实体
+- 丰富的插件(关键词搜索、内容编辑、`latex` 公式等)
+- 效率高、容错性强且轻量化
+
+查看 [功能介绍](https://jin-yufeng.gitee.io/mp-html/#/overview/feature) 了解更多
+
+## 使用方法
+- `uni_modules` 方式  
+  1. 点击右上角的 `使用 HBuilder X 导入插件` 按钮直接导入项目或点击 `下载插件 ZIP` 按钮下载插件包并解压到项目的 `uni_modules/mp-html` 目录下  
+  2. 在需要使用页面的 `(n)vue` 文件中添加  
+     ```html
+     <!-- 不需要引入,可直接使用 -->
+     <mp-html :content="html" />
+     ```
+     ```javascript
+     export default {
+       data() {
+         return {
+           html: '<div>Hello World!</div>'
+         }
+       }
+     }
+     ```
+  3. 需要更新版本时在 `HBuilder X` 中右键 `uni_modules/mp-html` 目录选择 `从插件市场更新` 即可  
+
+- 源码方式  
+  1. 从 [github](https://github.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 或 [gitee](https://gitee.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 下载源码  
+     插件市场的 **非 uni_modules 版本** 无法更新,不建议从插件市场获取  
+  2. 在需要使用页面的 `(n)vue` 文件中添加  
+     ```html
+     <mp-html :content="html" />
+     ```
+     ```javascript
+     import mpHtml from '@/components/mp-html/mp-html'
+     export default {
+       // HBuilderX 2.5.5+ 可以通过 easycom 自动引入
+       components: {
+         mpHtml
+       },
+       data() {
+         return {
+           html: '<div>Hello World!</div>'
+         }
+       }
+     }
+     ```
+
+- npm 方式  
+  1. 在项目根目录下执行  
+     ```bash
+     npm install mp-html
+     ```
+  2. 在需要使用页面的 `(n)vue` 文件中添加  
+     ```html
+     <mp-html :content="html" />
+     ```
+     ```javascript
+     import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html'
+     export default {
+       // 不可省略
+       components: {
+         mpHtml
+       },
+       data() {
+         return {
+           html: '<div>Hello World!</div>'
+         }
+       }
+     }
+     ```
+  3. 需要更新版本时执行以下命令即可  
+     ```bash
+     npm update mp-html
+     ```
+  
+  使用 *cli* 方式运行的项目,通过 *npm* 方式引入时,需要在 *vue.config.js* 中配置 *transpileDependencies*,详情可见 [#330](https://github.com/jin-yufeng/mp-html/issues/330#issuecomment-913617687)  
+  如果在 **nvue** 中使用还要将 `dist/uni-app/static` 目录下的内容拷贝到项目的 `static` 目录下,否则无法运行  
+
+查看 [快速开始](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart) 了解更多
+
+## 组件属性
+
+| 属性 | 类型 | 默认值 | 说明 |
+|:---:|:---:|:---:|---|
+| container-style | String |  | 容器的样式([2.1.0+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v210)) |
+| content | String |  | 用于渲染的 html 字符串 |
+| copy-link | Boolean | true | 是否允许外部链接被点击时自动复制 |
+| domain | String |  | 主域名(用于链接拼接) |
+| error-img | String |  | 图片出错时的占位图链接 |
+| lazy-load | Boolean | false | 是否开启图片懒加载 |
+| loading-img | String |  | 图片加载过程中的占位图链接 |
+| pause-video | Boolean | true | 是否在播放一个视频时自动暂停其他视频 |
+| preview-img | Boolean | true | 是否允许图片被点击时自动预览 |
+| scroll-table | Boolean | false | 是否给每个表格添加一个滚动层使其能单独横向滚动 |
+| selectable | Boolean | false | 是否开启文本长按复制 |
+| set-title | Boolean | true | 是否将 title 标签的内容设置到页面标题 |
+| show-img-menu | Boolean | true | 是否允许图片被长按时显示菜单 |
+| tag-style | Object |  | 设置标签的默认样式 |
+| use-anchor | Boolean | false | 是否使用锚点链接 |
+
+查看 [属性](https://jin-yufeng.gitee.io/mp-html/#/basic/prop) 了解更多
+
+## 组件事件
+
+| 名称 | 触发时机 |
+|:---:|---|
+| load | dom 树加载完毕时 |
+| ready | 图片加载完毕时 |
+| error | 发生渲染错误时 |
+| imgtap | 图片被点击时 |
+| linktap | 链接被点击时 |
+| play | 音视频播放时 |
+
+查看 [事件](https://jin-yufeng.gitee.io/mp-html/#/basic/event) 了解更多
+
+## api
+组件实例上提供了一些 `api` 方法可供调用
+
+| 名称 | 作用 |
+|:---:|---|
+| in | 将锚点跳转的范围限定在一个 scroll-view 内 |
+| navigateTo | 锚点跳转 |
+| getText | 获取文本内容 |
+| getRect | 获取富文本内容的位置和大小 |
+| setContent | 设置富文本内容 |
+| imgList | 获取所有图片的数组 |
+| pauseMedia | 暂停播放音视频([2.2.2+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v222)) |
+| setPlaybackRate | 设置音视频播放速率([2.4.0+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v240)) |
+
+查看 [api](https://jin-yufeng.gitee.io/mp-html/#/advanced/api) 了解更多
+
+## 插件扩展  
+除基本功能外,本组件还提供了丰富的扩展,可按照需要选用
+
+| 名称 | 作用 |
+|:---:|---|
+| audio | 音乐播放器 |
+| editable | 富文本 **编辑**([示例项目](https://mp-html.oss-cn-hangzhou.aliyuncs.com/editable.zip)) |
+| emoji | 解析 emoji |
+| highlight | 代码块高亮显示 |
+| markdown | 渲染 markdown |
+| search | 关键词搜索 |
+| style | 匹配 style 标签中的样式 |
+| txv-video | 使用腾讯视频 |
+| img-cache | 图片缓存 by [@PentaTea](https://github.com/PentaTea) |
+| latex | 渲染 latex 公式 by [@Zeng-J](https://github.com/Zeng-J) |
+
+从插件市场导入的包中 **不含有** 扩展插件,使用插件需通过微信小程序 `富文本插件` 获取或参考以下方法进行打包:  
+1. 获取完整组件包  
+   ```bash
+   npm install mp-html
+   ```
+2. 编辑 `tools/config.js` 中的 `plugins` 项,选择需要的插件  
+3. 生成新的组件包  
+   在 `node_modules/mp-html` 目录下执行  
+   ```bash
+   npm install
+   npm run build:uni-app
+   ```
+4. 拷贝 `dist/uni-app` 中的内容到项目根目录  
+
+查看 [插件](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin) 了解更多
+
+## 关于 nvue
+`nvue` 使用原生渲染,不支持部分 `css` 样式,为实现和 `html` 相同的效果,组件内部通过 `web-view` 进行渲染,性能上差于原生,根据 `weex` 官方建议,`web` 标签仅应用在非常规的降级场景。因此,如果通过原生的方式(如 `richtext`)能够满足需要,则不建议使用本组件,如果有较多的富文本内容,则可以直接使用 `vue` 页面  
+由于渲染方式与其他端不同,有以下限制:  
+1. 不支持 `lazy-load` 属性
+2. 视频不支持全屏播放
+3. 如果在 `flex-direction: row` 的容器中使用,需要给组件设置宽度或设置 `flex: 1` 占满剩余宽度
+
+纯 `nvue` 模式下,[此问题](https://ask.dcloud.net.cn/question/119678) 修复前,不支持通过 `uni_modules` 引入,需要本地引入(将 [dist/uni-app](https://github.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 中的内容拷贝到项目根目录下)  
+
+## 立即体验
+![富文本插件](https://mp-html.oss-cn-hangzhou.aliyuncs.com/qrcode.jpg)
+
+## 问题反馈
+遇到问题时,请先查阅 [常见问题](https://jin-yufeng.gitee.io/mp-html/#/question/faq) 和 [issue](https://github.com/jin-yufeng/mp-html/issues) 中是否已有相同的问题  
+可通过 [issue](https://github.com/jin-yufeng/mp-html/issues/new/choose) 、插件问答或发送邮件到 [mp_html@126.com](mailto:mp_html@126.com) 提问,不建议在评论区提问(不方便回复)  
+提问请严格按照 [issue 模板](https://github.com/jin-yufeng/mp-html/issues/new/choose) ,描述清楚使用环境、`html` 内容或可复现的 `demo` 项目以及复现方式,对于 **描述不清**、**无法复现** 或重复的问题将不予回复  
+
+欢迎加入 `QQ` 交流群:  
+群1(已满):`699734691`  
+群2:`778239129`  
+
+查看 [问题反馈](https://jin-yufeng.gitee.io/mp-html/#/question/feedback) 了解更多

+ 129 - 0
uni_modules/mp-html/changelog.md

@@ -0,0 +1,129 @@
+## v2.4.2(2023-05-14)
+1. `A` `editable` 插件支持修改文字颜色 [详细](https://github.com/jin-yufeng/mp-html/issues/254)
+2. `F` 修复了 `svg` 中有 `style` 不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/505)
+3. `F` 修复了使用旧版编译器可能报错 `Bad attr nodes` 的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/472)
+4. `F` 修复了 `app` 端可能出现无法读取 `lazyLoad` 的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/513)
+5. `F` 修复了 `editable` 插件在点击换图时未拼接 `domain` 的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/497) by [@TwoKe945](https://github.com/TwoKe945)
+6. `F` 修复了 `latex` 插件部分情况下不显示的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/515) 
+7. `F` 修复了 `editable` 插件点击音视频时其他标签框不消失的问题
+## v2.4.1(2022-12-25)
+1. `F` 修复了没有图片时 `ready` 事件可能不触发的问题
+2. `F` 修复了加载过程中可能出现 `Root label not found` 错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/470)
+3. `F` 修复了 `audio` 插件退出页面可能会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/457)
+4. `F` 修复了 `vue3` 运行到 `app` 在 `HBuilder X 3.6.10` 以上报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/480)
+5. `F` 修复了 `nvue` 端链接中包含 `%22` 时可能无法显示的问题
+6. `F` 修复了 `vue3` 使用 `highlight` 插件可能报错的问题
+## v2.4.0(2022-08-27)
+1. `A` 增加了 [setPlaybackRate](https://jin-yufeng.gitee.io/mp-html/#/advanced/api#setPlaybackRate) 的 `api`,可以设置音视频的播放速率 [详细](https://github.com/jin-yufeng/mp-html/issues/452)
+2. `A` 示例小程序代码开源 [详细](https://github.com/jin-yufeng/mp-html-demo)
+3. `U` 优化 `ready` 事件触发时机,未设置懒加载的情况下基本可以准确触发 [详细](https://github.com/jin-yufeng/mp-html/issues/195)
+4. `U` `highlight` 插件在编辑状态下不进行高亮处理,便于编辑
+5. `F` 修复了 `flex` 布局下图片大小可能不正确的问题
+6. `F` 修复了 `selectable` 属性没有设置 `force` 也可能出现渲染异常的问题
+7. `F` 修复了表格中的图片大小可能不正确的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/448)
+8. `F` 修复了含有合并单元格的表格可能无法设置竖直对齐的问题
+9. `F` 修复了 `editable` 插件在 `scroll-view` 中使用时工具条位置可能不正确的问题
+10. `F` 修复了 `vue3` 使用 [search](advanced/plugin#search) 插件可能导致错误换行的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/449)
+## v2.3.2(2022-08-13)
+1. `A` 增加 [latex](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#latex) 插件,可以渲染数学公式 [详细](https://github.com/jin-yufeng/mp-html/pull/447) by [@Zeng-J](https://github.com/Zeng-J)
+2. `U` 优化根节点下有很多标签的长内容渲染速度
+3. `U` `highlight` 插件适配 `lang-xxx` 格式
+4. `F` 修复了 `table` 标签设置 `border` 属性后可能无法修改边框样式的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/439) by [@zouxingjie](https://github.com/zouxingjie)
+5. `F` 修复了 `editable` 插件输入连续空格无效的问题
+6. `F` 修复了 `vue3` 图片设置 `inline` 会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/438)
+7. `F` 修复了 `vue3` 使用 `table` 可能报错的问题
+## v2.3.1(2022-05-20)
+1. `U` `app` 端支持使用本地图片
+2. `U` 优化了微信小程序 `selectable` 属性在 `ios` 端的处理 [详细](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#selectable)
+3. `F` 修复了 `editable` 插件不在顶部时 `tooltip` 位置可能错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/430)
+4. `F` 修复了 `vue3` 运行到微信小程序可能报错丢失内容的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/414)
+5. `F` 修复了 `vue3` 部分标签可能被错误换行的问题
+6. `F` 修复了 `editable` 插件 `app` 端插入视频无法预览的问题
+## v2.3.0(2022-04-01)
+1. `A` 增加了 `play` 事件,音视频播放时触发,可用于与页面其他音视频进行互斥播放 [详细](basic/event#play)
+2. `U` `show-img-menu` 属性支持控制预览时是否长按弹出菜单
+3. `U` 优化 `wxs` 处理,提高渲染性能 [详细](https://developers.weixin.qq.com/community/develop/article/doc/0006cc2b204740f601bd43fa25a413)  
+4. `U` `video` 标签支持 `object-fit` 属性
+5. `U` 增加支持一些常用实体编码 [详细](https://github.com/jin-yufeng/mp-html/issues/418)
+6. `F` 修复了图片仅设置高度可能不显示的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/410)
+7. `F` 修复了 `video` 标签高度设置为 `auto` 不显示的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/411)
+8. `F` 修复了使用 `grid` 布局时可能样式错误的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/413)
+9. `F` 修复了含有合并单元格的表格部分情况下显示异常的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/417)
+10. `F` 修复了 `editable` 插件连续插入内容时顺序不正确的问题
+11. `F` 修复了 `uni-app` 包 `vue3` 使用 `audio` 插件报错的问题
+12. `F` 修复了 `uni-app` 包 `highlight` 插件使用自定义的 `prism.min.js` 报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/416)
+## v2.2.2(2022-02-26)
+1. `A` 增加了 [pauseMedia](https://jin-yufeng.gitee.io/mp-html/#/advanced/api#pauseMedia) 的 `api`,可用于暂停播放音视频 [详细](https://github.com/jin-yufeng/mp-html/issues/317)
+2. `U` 优化了长内容的加载速度  
+3. `U` 适配 `vue3` [#389](https://github.com/jin-yufeng/mp-html/issues/389)、[#398](https://github.com/jin-yufeng/mp-html/pull/398) by [@zhouhuafei](https://github.com/zhouhuafei)、[#400](https://github.com/jin-yufeng/mp-html/issues/400)
+4. `F` 修复了小程序端图片高度设置为百分比时可能不显示的问题
+5. `F` 修复了 `highlight` 插件部分情况下可能显示不完整的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/403)
+## v2.2.1(2021-12-24)
+1. `A` `editable` 插件增加上下移动标签功能
+2. `U` `editable` 插件支持在文本中间光标处插入内容
+3. `F` 修复了 `nvue` 端设置 `margin` 后可能导致高度不正确的问题
+4. `F` 修复了 `highlight` 插件使用压缩版的 `prism.css` 可能导致背景失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/367)
+5. `F` 修复了编辑状态下使用 `emoji` 插件内容为空时可能报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/371)
+6. `F` 修复了使用 `editable` 插件后将 `selectable` 属性设置为 `force` 不生效的问题
+## v2.2.0(2021-10-12)
+1. `A` 增加 `customElements` 配置项,便于添加自定义功能性标签 [详细](https://github.com/jin-yufeng/mp-html/issues/350)
+2. `A` `editable` 插件增加切换音视频自动播放状态的功能 [详细](https://github.com/jin-yufeng/mp-html/pull/341) by [@leeseett](https://github.com/leeseett)
+3. `A` `editable` 插件删除媒体标签时触发 `remove` 事件,便于删除已上传的文件
+4. `U` `editable` 插件 `insertImg` 方法支持同时插入多张图片 [详细](https://github.com/jin-yufeng/mp-html/issues/342)
+5. `U` `editable` 插入图片和音视频时支持拼接 `domian` 主域名
+6. `F` 修复了内部链接参数中包含 `://` 时被认为是外部链接的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/356)
+7. `F` 修复了部分 `svg` 标签名或属性名大小写不正确时不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/351)
+8. `F` 修复了 `nvue` 页面运行到非 `app` 平台时可能样式错误的问题
+## v2.1.5(2021-08-13)
+1. `A` 增加支持标签的 `dir` 属性
+2. `F` 修复了 `ruby` 标签文字与拼音没有居中对齐的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/325)
+3. `F` 修复了音视频标签内有 `a` 标签时可能无法播放的问题
+4. `F` 修复了 `externStyle` 中的 `class` 名包含下划线或数字时可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326)
+5. `F` 修复了 `h5` 端引入 `externStyle` 可能不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326)
+## v2.1.4(2021-07-14)
+1. `F` 修复了 `rt` 标签无法设置样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/318)
+2. `F` 修复了表格中有单元格同时合并行和列时可能显示不正确的问题
+3. `F` 修复了 `app` 端无法关闭图片长按菜单的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/322)
+4. `F` 修复了 `editable` 插件只能添加图片链接不能修改的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/312) by [@leeseett](https://github.com/leeseett)
+## v2.1.3(2021-06-12)
+1. `A` `editable` 插件增加 `insertTable` 方法
+2. `U` `editable` 插件支持编辑表格中的空白单元格 [详细](https://github.com/jin-yufeng/mp-html/issues/310)
+3. `F` 修复了 `externStyle` 中使用伪类可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/298)
+4. `F` 修复了多个组件同时使用时 `tag-style` 属性时可能互相影响的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/305) by [@woodguoyu](https://github.com/woodguoyu)
+5. `F` 修复了包含 `linearGradient` 的 `svg` 可能无法显示的问题
+6. `F` 修复了编译到头条小程序时可能报错的问题
+7. `F` 修复了 `nvue` 端不触发 `click` 事件的问题
+8. `F` 修复了 `editable` 插件尾部插入时无法撤销的问题
+9. `F` 修复了 `editable` 插件的 `insertHtml` 方法只能在末尾插入的问题
+10. `F` 修复了 `editable` 插件插入音频不显示的问题
+## v2.1.2(2021-04-24)
+1. `A` 增加了 [img-cache](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#img-cache) 插件,可以在 `app` 端缓存图片 [详细](https://github.com/jin-yufeng/mp-html/issues/292) by [@PentaTea](https://github.com/PentaTea)
+2. `U` 支持通过 `container-style` 属性设置 `white-space` 来保留连续空格和换行符 [详细](https://jin-yufeng.gitee.io/mp-html/#/question/faq#space)
+3. `U` 代码风格符合 [standard](https://standardjs.com) 标准
+4. `U` `editable` 插件编辑状态下支持预览视频 [详细](https://github.com/jin-yufeng/mp-html/issues/286)
+5. `F` 修复了 `svg` 标签内嵌 `svg` 时无法显示的问题
+6. `F` 修复了编译到支付宝和头条小程序时部分区域不可复制的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/291)
+## v2.1.1(2021-04-09)
+1. 修复了对 `p` 标签设置 `tag-style` 可能不生效的问题
+2. 修复了 `svg` 标签中的文本无法显示的问题
+3. 修复了使用 `editable` 插件编辑表格时可能报错的问题
+4. 修复了使用 `highlight` 插件运行到头条小程序时可能没有样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/280)
+5. 修复了使用 `editable` 插件 `editable` 属性为 `false` 时会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/284)
+6. 修复了 `style` 插件连续子选择器失效的问题
+7. 修复了 `editable` 插件无法修改图片和字体大小的问题
+## v2.1.0.2(2021-03-21)
+修复了 `nvue` 端使用可能报错的问题
+## v2.1.0(2021-03-20)
+1. `A` 增加了 [container-style](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#container-style) 属性 [详细](https://gitee.com/jin-yufeng/mp-html/pulls/1)
+2. `A` 增加支持 `strike` 标签
+3. `A` `editable` 插件增加 `placeholder` 属性 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable)
+4. `A` `editable` 插件增加 `insertHtml` 方法 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable)
+5. `U` 外部样式支持标签名选择器 [详细](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart#setting)
+6. `F` 修复了 `nvue` 端部分情况下可能不显示的问题
+## v2.0.5(2021-03-12)
+1. `U` [linktap](https://jin-yufeng.gitee.io/mp-html/#/basic/event#linktap) 事件增加返回内部文本内容 `innerText` [详细](https://github.com/jin-yufeng/mp-html/issues/271)
+2. `U` [selectable](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#selectable) 属性设置为 `force` 时能够在微信 `iOS` 端生效(文本块会变成 `inline-block`) [详细](https://github.com/jin-yufeng/mp-html/issues/267)
+3. `F` 修复了部分情况下竖向无法滚动的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/182)
+4. `F` 修复了多次修改富文本数据时部分内容可能不显示的问题
+5. `F` 修复了 [腾讯视频](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#txv-video) 插件可能无法播放的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/265)
+6. `F` 修复了 [highlight](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#highlight) 插件没有设置高亮语言时没有应用默认样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/276) by [@fuzui](https://github.com/fuzui)

+ 498 - 0
uni_modules/mp-html/components/mp-html/mp-html.vue

@@ -0,0 +1,498 @@
+<template>
+  <view id="_root" :class="(selectable?'_select ':'')+'_root'" :style="containerStyle">
+    <slot v-if="!nodes[0]" />
+    <!-- #ifndef APP-PLUS-NVUE -->
+    <node v-else :childs="nodes" :opts="[lazyLoad,loadingImg,errorImg,showImgMenu,selectable]" name="span" />
+    <!-- #endif -->
+    <!-- #ifdef APP-PLUS-NVUE -->
+    <web-view ref="web" src="/uni_modules/mp-html/static/app-plus/mp-html/local.html" :style="'margin-top:-2px;height:' + height + 'px'" @onPostMessage="_onMessage" />
+    <!-- #endif -->
+  </view>
+</template>
+
+<script>
+/**
+ * mp-html v2.4.2
+ * @description 富文本组件
+ * @tutorial https://github.com/jin-yufeng/mp-html
+ * @property {String} container-style 容器的样式
+ * @property {String} content 用于渲染的 html 字符串
+ * @property {Boolean} copy-link 是否允许外部链接被点击时自动复制
+ * @property {String} domain 主域名,用于拼接链接
+ * @property {String} error-img 图片出错时的占位图链接
+ * @property {Boolean} lazy-load 是否开启图片懒加载
+ * @property {string} loading-img 图片加载过程中的占位图链接
+ * @property {Boolean} pause-video 是否在播放一个视频时自动暂停其他视频
+ * @property {Boolean} preview-img 是否允许图片被点击时自动预览
+ * @property {Boolean} scroll-table 是否给每个表格添加一个滚动层使其能单独横向滚动
+ * @property {Boolean | String} selectable 是否开启长按复制
+ * @property {Boolean} set-title 是否将 title 标签的内容设置到页面标题
+ * @property {Boolean} show-img-menu 是否允许图片被长按时显示菜单
+ * @property {Object} tag-style 标签的默认样式
+ * @property {Boolean | Number} use-anchor 是否使用锚点链接
+ * @event {Function} load dom 结构加载完毕时触发
+ * @event {Function} ready 所有图片加载完毕时触发
+ * @event {Function} imgtap 图片被点击时触发
+ * @event {Function} linktap 链接被点击时触发
+ * @event {Function} play 音视频播放时触发
+ * @event {Function} error 媒体加载出错时触发
+ */
+// #ifndef APP-PLUS-NVUE
+import node from './node/node'
+// #endif
+import Parser from './parser'
+const plugins=[]
+// #ifdef APP-PLUS-NVUE
+const dom = weex.requireModule('dom')
+// #endif
+export default {
+  name: 'mp-html',
+  data () {
+    return {
+      nodes: [],
+      // #ifdef APP-PLUS-NVUE
+      height: 3
+      // #endif
+    }
+  },
+  props: {
+    containerStyle: {
+      type: String,
+      default: ''
+    },
+    content: {
+      type: String,
+      default: ''
+    },
+    copyLink: {
+      type: [Boolean, String],
+      default: true
+    },
+    domain: String,
+    errorImg: {
+      type: String,
+      default: ''
+    },
+    lazyLoad: {
+      type: [Boolean, String],
+      default: false
+    },
+    loadingImg: {
+      type: String,
+      default: ''
+    },
+    pauseVideo: {
+      type: [Boolean, String],
+      default: true
+    },
+    previewImg: {
+      type: [Boolean, String],
+      default: true
+    },
+    scrollTable: [Boolean, String],
+    selectable: [Boolean, String],
+    setTitle: {
+      type: [Boolean, String],
+      default: true
+    },
+    showImgMenu: {
+      type: [Boolean, String],
+      default: true
+    },
+    tagStyle: Object,
+    useAnchor: [Boolean, Number]
+  },
+  // #ifdef VUE3
+  emits: ['load', 'ready', 'imgtap', 'linktap', 'play', 'error'],
+  // #endif
+  // #ifndef APP-PLUS-NVUE
+  components: {
+    node
+  },
+  // #endif
+  watch: {
+    content (content) {
+      this.setContent(content)
+    }
+  },
+  created () {
+    this.plugins = []
+    for (let i = plugins.length; i--;) {
+      this.plugins.push(new plugins[i](this))
+    }
+  },
+  mounted () {
+    if (this.content && !this.nodes.length) {
+      this.setContent(this.content)
+    }
+  },
+  beforeDestroy () {
+    this._hook('onDetached')
+  },
+  methods: {
+    /**
+     * @description 将锚点跳转的范围限定在一个 scroll-view 内
+     * @param {Object} page scroll-view 所在页面的示例
+     * @param {String} selector scroll-view 的选择器
+     * @param {String} scrollTop scroll-view scroll-top 属性绑定的变量名
+     */
+    in (page, selector, scrollTop) {
+      // #ifndef APP-PLUS-NVUE
+      if (page && selector && scrollTop) {
+        this._in = {
+          page,
+          selector,
+          scrollTop
+        }
+      }
+      // #endif
+    },
+
+    /**
+     * @description 锚点跳转
+     * @param {String} id 要跳转的锚点 id
+     * @param {Number} offset 跳转位置的偏移量
+     * @returns {Promise}
+     */
+    navigateTo (id, offset) {
+      return new Promise((resolve, reject) => {
+        if (!this.useAnchor) {
+          reject(Error('Anchor is disabled'))
+          return
+        }
+        offset = offset || parseInt(this.useAnchor) || 0
+        // #ifdef APP-PLUS-NVUE
+        if (!id) {
+          dom.scrollToElement(this.$refs.web, {
+            offset
+          })
+          resolve()
+        } else {
+          this._navigateTo = {
+            resolve,
+            reject,
+            offset
+          }
+          this.$refs.web.evalJs('uni.postMessage({data:{action:"getOffset",offset:(document.getElementById(' + id + ')||{}).offsetTop}})')
+        }
+        // #endif
+        // #ifndef APP-PLUS-NVUE
+        let deep = ' '
+        // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
+        deep = '>>>'
+        // #endif
+        const selector = uni.createSelectorQuery()
+          // #ifndef MP-ALIPAY
+          .in(this._in ? this._in.page : this)
+          // #endif
+          .select((this._in ? this._in.selector : '._root') + (id ? `${deep}#${id}` : '')).boundingClientRect()
+        if (this._in) {
+          selector.select(this._in.selector).scrollOffset()
+            .select(this._in.selector).boundingClientRect()
+        } else {
+          // 获取 scroll-view 的位置和滚动距离
+          selector.selectViewport().scrollOffset() // 获取窗口的滚动距离
+        }
+        selector.exec(res => {
+          if (!res[0]) {
+            reject(Error('Label not found'))
+            return
+          }
+          const scrollTop = res[1].scrollTop + res[0].top - (res[2] ? res[2].top : 0) + offset
+          if (this._in) {
+            // scroll-view 跳转
+            this._in.page[this._in.scrollTop] = scrollTop
+          } else {
+            // 页面跳转
+            uni.pageScrollTo({
+              scrollTop,
+              duration: 300
+            })
+          }
+          resolve()
+        })
+        // #endif
+      })
+    },
+
+    /**
+     * @description 获取文本内容
+     * @return {String}
+     */
+    getText (nodes) {
+      let text = '';
+      (function traversal (nodes) {
+        for (let i = 0; i < nodes.length; i++) {
+          const node = nodes[i]
+          if (node.type === 'text') {
+            text += node.text.replace(/&amp;/g, '&')
+          } else if (node.name === 'br') {
+            text += '\n'
+          } else {
+            // 块级标签前后加换行
+            const isBlock = node.name === 'p' || node.name === 'div' || node.name === 'tr' || node.name === 'li' || (node.name[0] === 'h' && node.name[1] > '0' && node.name[1] < '7')
+            if (isBlock && text && text[text.length - 1] !== '\n') {
+              text += '\n'
+            }
+            // 递归获取子节点的文本
+            if (node.children) {
+              traversal(node.children)
+            }
+            if (isBlock && text[text.length - 1] !== '\n') {
+              text += '\n'
+            } else if (node.name === 'td' || node.name === 'th') {
+              text += '\t'
+            }
+          }
+        }
+      })(nodes || this.nodes)
+      return text
+    },
+
+    /**
+     * @description 获取内容大小和位置
+     * @return {Promise}
+     */
+    getRect () {
+      return new Promise((resolve, reject) => {
+        uni.createSelectorQuery()
+          // #ifndef MP-ALIPAY
+          .in(this)
+          // #endif
+          .select('#_root').boundingClientRect().exec(res => res[0] ? resolve(res[0]) : reject(Error('Root label not found')))
+      })
+    },
+
+    /**
+     * @description 暂停播放媒体
+     */
+    pauseMedia () {
+      for (let i = (this._videos || []).length; i--;) {
+        this._videos[i].pause()
+      }
+      // #ifdef APP-PLUS
+      const command = 'for(var e=document.getElementsByTagName("video"),i=e.length;i--;)e[i].pause()'
+      // #ifndef APP-PLUS-NVUE
+      let page = this.$parent
+      while (!page.$scope) page = page.$parent
+      page.$scope.$getAppWebview().evalJS(command)
+      // #endif
+      // #ifdef APP-PLUS-NVUE
+      this.$refs.web.evalJs(command)
+      // #endif
+      // #endif
+    },
+
+    /**
+     * @description 设置媒体播放速率
+     * @param {Number} rate 播放速率
+     */
+    setPlaybackRate (rate) {
+      this.playbackRate = rate
+      for (let i = (this._videos || []).length; i--;) {
+        this._videos[i].playbackRate(rate)
+      }
+      // #ifdef APP-PLUS
+      const command = 'for(var e=document.getElementsByTagName("video"),i=e.length;i--;)e[i].playbackRate=' + rate
+      // #ifndef APP-PLUS-NVUE
+      let page = this.$parent
+      while (!page.$scope) page = page.$parent
+      page.$scope.$getAppWebview().evalJS(command)
+      // #endif
+      // #ifdef APP-PLUS-NVUE
+      this.$refs.web.evalJs(command)
+      // #endif
+      // #endif
+    },
+
+    /**
+     * @description 设置内容
+     * @param {String} content html 内容
+     * @param {Boolean} append 是否在尾部追加
+     */
+    setContent (content, append) {
+      if (!append || !this.imgList) {
+        this.imgList = []
+      }
+      const nodes = new Parser(this).parse(content)
+      // #ifdef APP-PLUS-NVUE
+      if (this._ready) {
+        this._set(nodes, append)
+      }
+      // #endif
+      this.$set(this, 'nodes', append ? (this.nodes || []).concat(nodes) : nodes)
+
+      // #ifndef APP-PLUS-NVUE
+      this._videos = []
+      this.$nextTick(() => {
+        this._hook('onLoad')
+        this.$emit('load')
+      })
+
+      if (this.lazyLoad || this.imgList._unloadimgs < this.imgList.length / 2) {
+        // 设置懒加载,每 350ms 获取高度,不变则认为加载完毕
+        let height = 0
+        const callback = rect => {
+          if (!rect || !rect.height) rect = {}
+          // 350ms 总高度无变化就触发 ready 事件
+          if (rect.height === height) {
+            this.$emit('ready', rect)
+          } else {
+            height = rect.height
+            setTimeout(() => {
+              this.getRect().then(callback).catch(callback)
+            }, 350)
+          }
+        }
+        this.getRect().then(callback).catch(callback)
+      } else {
+        // 未设置懒加载,等待所有图片加载完毕
+        if (!this.imgList._unloadimgs) {
+          this.getRect().then(rect => {
+            this.$emit('ready', rect)
+          }).catch(() => {
+            this.$emit('ready', {})
+          })
+        }
+      }
+      // #endif
+    },
+
+    /**
+     * @description 调用插件钩子函数
+     */
+    _hook (name) {
+      for (let i = plugins.length; i--;) {
+        if (this.plugins[i][name]) {
+          this.plugins[i][name]()
+        }
+      }
+    },
+
+    // #ifdef APP-PLUS-NVUE
+    /**
+     * @description 设置内容
+     */
+    _set (nodes, append) {
+      this.$refs.web.evalJs('setContent(' + JSON.stringify(nodes).replace(/%22/g, '') + ',' + JSON.stringify([this.containerStyle.replace(/(?:margin|padding)[^;]+/g, ''), this.errorImg, this.loadingImg, this.pauseVideo, this.scrollTable, this.selectable]) + ',' + append + ')')
+    },
+
+    /**
+     * @description 接收到 web-view 消息
+     */
+    _onMessage (e) {
+      const message = e.detail.data[0]
+      switch (message.action) {
+        // web-view 初始化完毕
+        case 'onJSBridgeReady':
+          this._ready = true
+          if (this.nodes) {
+            this._set(this.nodes)
+          }
+          break
+        // 内容 dom 加载完毕
+        case 'onLoad':
+          this.height = message.height
+          this._hook('onLoad')
+          this.$emit('load')
+          break
+        // 所有图片加载完毕
+        case 'onReady':
+          this.getRect().then(res => {
+            this.$emit('ready', res)
+          }).catch(() => {
+            this.$emit('ready', {})
+          })
+          break
+        // 总高度发生变化
+        case 'onHeightChange':
+          this.height = message.height
+          break
+        // 图片点击
+        case 'onImgTap':
+          this.$emit('imgtap', message.attrs)
+          if (this.previewImg) {
+            uni.previewImage({
+              current: parseInt(message.attrs.i),
+              urls: this.imgList
+            })
+          }
+          break
+        // 链接点击
+        case 'onLinkTap': {
+          const href = message.attrs.href
+          this.$emit('linktap', message.attrs)
+          if (href) {
+            // 锚点跳转
+            if (href[0] === '#') {
+              if (this.useAnchor) {
+                dom.scrollToElement(this.$refs.web, {
+                  offset: message.offset
+                })
+              }
+            } else if (href.includes('://')) {
+              // 打开外链
+              if (this.copyLink) {
+                plus.runtime.openWeb(href)
+              }
+            } else {
+              uni.navigateTo({
+                url: href,
+                fail () {
+                  uni.switchTab({
+                    url: href
+                  })
+                }
+              })
+            }
+          }
+          break
+        }
+        case 'onPlay':
+          this.$emit('play')
+          break
+        // 获取到锚点的偏移量
+        case 'getOffset':
+          if (typeof message.offset === 'number') {
+            dom.scrollToElement(this.$refs.web, {
+              offset: message.offset + this._navigateTo.offset
+            })
+            this._navigateTo.resolve()
+          } else {
+            this._navigateTo.reject(Error('Label not found'))
+          }
+          break
+        // 点击
+        case 'onClick':
+          this.$emit('tap')
+          this.$emit('click')
+          break
+        // 出错
+        case 'onError':
+          this.$emit('error', {
+            source: message.source,
+            attrs: message.attrs
+          })
+      }
+    }
+    // #endif
+  }
+}
+</script>
+
+<style>
+/* #ifndef APP-PLUS-NVUE */
+/* 根节点样式 */
+._root {
+  padding: 1px 0;
+  overflow-x: auto;
+  overflow-y: hidden;
+  -webkit-overflow-scrolling: touch;
+}
+
+/* 长按复制 */
+._select {
+  user-select: text;
+}
+/* #endif */
+</style>

+ 576 - 0
uni_modules/mp-html/components/mp-html/node/node.vue

@@ -0,0 +1,576 @@
+<template>
+  <view :id="attrs.id" :class="'_block _'+name+' '+attrs.class" :style="attrs.style">
+    <block v-for="(n, i) in childs" v-bind:key="i">
+      <!-- 图片 -->
+      <!-- 占位图 -->
+      <image v-if="n.name==='img'&&!n.t&&((opts[1]&&!ctrl[i])||ctrl[i]<0)" class="_img" :style="n.attrs.style" :src="ctrl[i]<0?opts[2]:opts[1]" mode="widthFix" />
+      <!-- 显示图片 -->
+      <!-- #ifdef H5 || (APP-PLUS && VUE2) -->
+      <img v-if="n.name==='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class" :style="(ctrl[i]===-1?'display:none;':'')+n.attrs.style" :src="n.attrs.src||(ctrl.load?n.attrs['data-src']:'')" :data-i="i" @load="imgLoad" @error="mediaError" @tap.stop="imgTap" @longpress="imgLongTap" />
+      <!-- #endif -->
+      <!-- #ifndef H5 || (APP-PLUS && VUE2) -->
+      <!-- 表格中的图片,使用 rich-text 防止大小不正确 -->
+      <rich-text v-if="n.name==='img'&&n.t" :style="'display:'+n.t" :nodes="[{attrs:{style:n.attrs.style,src:n.attrs.src},name:'img'}]" :data-i="i" @tap.stop="imgTap" />
+      <!-- #endif -->
+      <!-- #ifndef H5 || APP-PLUS -->
+      <image v-else-if="n.name==='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class" :style="(ctrl[i]===-1?'display:none;':'')+'width:'+(ctrl[i]||1)+'px;height:1px;'+n.attrs.style" :src="n.attrs.src" :mode="!n.h?'widthFix':(!n.w?'heightFix':'')" :lazy-load="opts[0]" :webp="n.webp" :show-menu-by-longpress="opts[3]&&!n.attrs.ignore" :image-menu-prevent="!opts[3]||n.attrs.ignore" :data-i="i" @load="imgLoad" @error="mediaError" @tap.stop="imgTap" @longpress="imgLongTap" />
+      <!-- #endif -->
+      <!-- #ifdef APP-PLUS && VUE3 -->
+      <image v-else-if="n.name==='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class" :style="(ctrl[i]===-1?'display:none;':'')+'width:'+(ctrl[i]||1)+'px;'+n.attrs.style" :src="n.attrs.src||(ctrl.load?n.attrs['data-src']:'')" :mode="!n.h?'widthFix':(!n.w?'heightFix':'')" :data-i="i" @load="imgLoad" @error="mediaError" @tap.stop="imgTap" @longpress="imgLongTap" />
+      <!-- #endif -->
+      <!-- 文本 -->
+      <!-- #ifdef MP-WEIXIN -->
+      <text v-else-if="n.text" :user-select="opts[4]=='force'&&isiOS" decode>{{n.text}}</text>
+      <!-- #endif -->
+      <!-- #ifndef MP-WEIXIN || MP-BAIDU || MP-ALIPAY || MP-TOUTIAO -->
+      <text v-else-if="n.text" decode>{{n.text}}</text>
+      <!-- #endif -->
+      <text v-else-if="n.name==='br'">\n</text>
+      <!-- 链接 -->
+      <view v-else-if="n.name==='a'" :id="n.attrs.id" :class="(n.attrs.href?'_a ':'')+n.attrs.class" hover-class="_hover" :style="'display:inline;'+n.attrs.style" :data-i="i" @tap.stop="linkTap">
+        <node name="span" :childs="n.children" :opts="opts" style="display:inherit" />
+      </view>
+      <!-- 视频 -->
+      <!-- #ifdef APP-PLUS -->
+      <view v-else-if="n.html" :id="n.attrs.id" :class="'_video '+n.attrs.class" :style="n.attrs.style" v-html="n.html" @vplay.stop="play" />
+      <!-- #endif -->
+      <!-- #ifndef APP-PLUS -->
+      <video v-else-if="n.name==='video'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :autoplay="n.attrs.autoplay" :controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted" :object-fit="n.attrs['object-fit']" :poster="n.attrs.poster" :src="n.src[ctrl[i]||0]" :data-i="i" @play="play" @error="mediaError" />
+      <!-- #endif -->
+      <!-- #ifdef H5 || APP-PLUS -->
+      <iframe v-else-if="n.name==='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder" :src="n.attrs.src" />
+      <embed v-else-if="n.name==='embed'" :style="n.attrs.style" :src="n.attrs.src" />
+      <!-- #endif -->
+      <!-- #ifndef MP-TOUTIAO || ((H5 || APP-PLUS) && VUE3) -->
+      <!-- 音频 -->
+      <audio v-else-if="n.name==='audio'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :author="n.attrs.author" :controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name" :poster="n.attrs.poster" :src="n.src[ctrl[i]||0]" :data-i="i" @play="play" @error="mediaError" />
+      <!-- #endif -->
+      <view v-else-if="(n.name==='table'&&n.c)||n.name==='li'" :id="n.attrs.id" :class="'_'+n.name+' '+n.attrs.class" :style="n.attrs.style">
+        <node v-if="n.name==='li'" :childs="n.children" :opts="opts" />
+        <view v-else v-for="(tbody, x) in n.children" v-bind:key="x" :class="'_'+tbody.name+' '+tbody.attrs.class" :style="tbody.attrs.style">
+          <node v-if="tbody.name==='td'||tbody.name==='th'" :childs="tbody.children" :opts="opts" />
+          <block v-else v-for="(tr, y) in tbody.children" v-bind:key="y">
+            <view v-if="tr.name==='td'||tr.name==='th'" :class="'_'+tr.name+' '+tr.attrs.class" :style="tr.attrs.style">
+              <node :childs="tr.children" :opts="opts" />
+            </view>
+            <view v-else :class="'_'+tr.name+' '+tr.attrs.class" :style="tr.attrs.style">
+              <view v-for="(td, z) in tr.children" v-bind:key="z" :class="'_'+td.name+' '+td.attrs.class" :style="td.attrs.style">
+                <node :childs="td.children" :opts="opts" />
+              </view>
+            </view>
+          </block>
+        </view>
+      </view>
+      
+      <!-- 富文本 -->
+      <!-- #ifdef H5 || ((MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE2) -->
+      <rich-text v-else-if="!n.c&&!handler.isInline(n.name, n.attrs.style)" :id="n.attrs.id" :style="n.f" :user-select="opts[4]" :nodes="[n]" />
+      <!-- #endif -->
+      <!-- #ifndef H5 || ((MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE2) -->
+      <rich-text v-else-if="!n.c" :id="n.attrs.id" :style="'display:inline;'+n.f" :preview="false" :selectable="opts[4]" :user-select="opts[4]" :nodes="[n]" />
+      <!-- #endif -->
+      <!-- 继续递归 -->
+      <view v-else-if="n.c===2" :id="n.attrs.id" :class="'_block _'+n.name+' '+n.attrs.class" :style="n.f+';'+n.attrs.style">
+        <node v-for="(n2, j) in n.children" v-bind:key="j" :style="n2.f" :name="n2.name" :attrs="n2.attrs" :childs="n2.children" :opts="opts" />
+      </view>
+      <node v-else :style="n.f" :name="n.name" :attrs="n.attrs" :childs="n.children" :opts="opts" />
+    </block>
+  </view>
+</template>
+<script module="handler" lang="wxs">
+// 行内标签列表
+var inlineTags = {
+  abbr: true,
+  b: true,
+  big: true,
+  code: true,
+  del: true,
+  em: true,
+  i: true,
+  ins: true,
+  label: true,
+  q: true,
+  small: true,
+  span: true,
+  strong: true,
+  sub: true,
+  sup: true
+}
+/**
+ * @description 判断是否为行内标签
+ */
+module.exports = {
+  isInline: function (tagName, style) {
+    return inlineTags[tagName] || (style || '').indexOf('display:inline') !== -1
+  }
+}
+</script>
+<script>
+
+import node from './node'
+export default {
+  name: 'node',
+  options: {
+    // #ifdef MP-WEIXIN
+    virtualHost: true,
+    // #endif
+    // #ifdef MP-TOUTIAO
+    addGlobalClass: false
+    // #endif
+  },
+  data () {
+    return {
+      ctrl: {},
+      // #ifdef MP-WEIXIN
+      isiOS: uni.getSystemInfoSync().system.includes('iOS')
+      // #endif
+    }
+  },
+  props: {
+    name: String,
+    attrs: {
+      type: Object,
+      default () {
+        return {}
+      }
+    },
+    childs: Array,
+    opts: Array
+  },
+  components: {
+
+    // #ifndef (H5 || APP-PLUS) && VUE3
+    node
+    // #endif
+  },
+  mounted () {
+    this.$nextTick(() => {
+      for (this.root = this.$parent; this.root.$options.name !== 'mp-html'; this.root = this.root.$parent);
+    })
+    // #ifdef H5 || APP-PLUS
+    if (this.opts[0]) {
+      let i
+      for (i = this.childs.length; i--;) {
+        if (this.childs[i].name === 'img') break
+      }
+      if (i !== -1) {
+        this.observer = uni.createIntersectionObserver(this).relativeToViewport({
+          top: 500,
+          bottom: 500
+        })
+        this.observer.observe('._img', res => {
+          if (res.intersectionRatio) {
+            this.$set(this.ctrl, 'load', 1)
+            this.observer.disconnect()
+          }
+        })
+      }
+    }
+    // #endif
+  },
+  beforeDestroy () {
+    // #ifdef H5 || APP-PLUS
+    if (this.observer) {
+      this.observer.disconnect()
+    }
+    // #endif
+  },
+  methods:{
+    // #ifdef MP-WEIXIN
+    toJSON () { return this },
+    // #endif
+    /**
+     * @description 播放视频事件
+     * @param {Event} e
+     */
+    play (e) {
+      this.root.$emit('play')
+      // #ifndef APP-PLUS
+      if (this.root.pauseVideo) {
+        let flag = false
+        const id = e.target.id
+        for (let i = this.root._videos.length; i--;) {
+          if (this.root._videos[i].id === id) {
+            flag = true
+          } else {
+            this.root._videos[i].pause() // 自动暂停其他视频
+          }
+        }
+        // 将自己加入列表
+        if (!flag) {
+          const ctx = uni.createVideoContext(id
+            // #ifndef MP-BAIDU
+            , this
+            // #endif
+          )
+          ctx.id = id
+          if (this.root.playbackRate) {
+            ctx.playbackRate(this.root.playbackRate)
+          }
+          this.root._videos.push(ctx)
+        }
+      }
+      // #endif
+    },
+
+    /**
+     * @description 图片点击事件
+     * @param {Event} e
+     */
+    imgTap (e) {
+      const node = this.childs[e.currentTarget.dataset.i]
+      if (node.a) {
+        this.linkTap(node.a)
+        return
+      }
+      if (node.attrs.ignore) return
+      // #ifdef H5 || APP-PLUS
+      node.attrs.src = node.attrs.src || node.attrs['data-src']
+      // #endif
+      this.root.$emit('imgtap', node.attrs)
+      // 自动预览图片
+      if (this.root.previewImg) {
+        uni.previewImage({
+          // #ifdef MP-WEIXIN
+          showmenu: this.root.showImgMenu,
+          // #endif
+          // #ifdef MP-ALIPAY
+          enablesavephoto: this.root.showImgMenu,
+          enableShowPhotoDownload: this.root.showImgMenu,
+          // #endif
+          current: parseInt(node.attrs.i),
+          urls: this.root.imgList
+        })
+      }
+    },
+
+    /**
+     * @description 图片长按
+     */
+    imgLongTap (e) {
+      // #ifdef APP-PLUS
+      const attrs = this.childs[e.currentTarget.dataset.i].attrs
+      if (this.opts[3] && !attrs.ignore) {
+        uni.showActionSheet({
+          itemList: ['保存图片'],
+          success: () => {
+            const save = path => {
+              uni.saveImageToPhotosAlbum({
+                filePath: path,
+                success () {
+                  uni.showToast({
+                    title: '保存成功'
+                  })
+                }
+              })
+            }
+            if (this.root.imgList[attrs.i].startsWith('http')) {
+              uni.downloadFile({
+                url: this.root.imgList[attrs.i],
+                success: res => save(res.tempFilePath)
+              })
+            } else {
+              save(this.root.imgList[attrs.i])
+            }
+          }
+        })
+      }
+      // #endif
+    },
+
+    /**
+     * @description 图片加载完成事件
+     * @param {Event} e
+     */
+    imgLoad (e) {
+      const i = e.currentTarget.dataset.i
+      /* #ifndef H5 || (APP-PLUS && VUE2) */
+      if (!this.childs[i].w) {
+        // 设置原宽度
+        this.$set(this.ctrl, i, e.detail.width)
+      } else /* #endif */ if ((this.opts[1] && !this.ctrl[i]) || this.ctrl[i] === -1) {
+        // 加载完毕,取消加载中占位图
+        this.$set(this.ctrl, i, 1)
+      }
+      this.checkReady()
+    },
+
+    /**
+     * @description 检查是否所有图片加载完毕
+     */
+    checkReady () {
+      if (this.root && !this.root.lazyLoad) {
+        this.root._unloadimgs -= 1
+        if (!this.root._unloadimgs) {
+          setTimeout(() => {
+            this.root.getRect().then(rect => {
+              this.root.$emit('ready', rect)
+            }).catch(() => {
+              this.root.$emit('ready', {})
+            })
+          }, 350)
+        }
+      }
+    },
+
+    /**
+     * @description 链接点击事件
+     * @param {Event} e
+     */
+    linkTap (e) {
+      const node = e.currentTarget ? this.childs[e.currentTarget.dataset.i] : {}
+      const attrs = node.attrs || e
+      const href = attrs.href
+      this.root.$emit('linktap', Object.assign({
+        innerText: this.root.getText(node.children || []) // 链接内的文本内容
+      }, attrs))
+      if (href) {
+        if (href[0] === '#') {
+          // 跳转锚点
+          this.root.navigateTo(href.substring(1)).catch(() => { })
+        } else if (href.split('?')[0].includes('://')) {
+          // 复制外部链接
+          if (this.root.copyLink) {
+            // #ifdef H5
+            window.open(href)
+            // #endif
+            // #ifdef MP
+            uni.setClipboardData({
+              data: href,
+              success: () =>
+                uni.showToast({
+                  title: '链接已复制'
+                })
+            })
+            // #endif
+            // #ifdef APP-PLUS
+            plus.runtime.openWeb(href)
+            // #endif
+          }
+        } else {
+          // 跳转页面
+          uni.navigateTo({
+            url: href,
+            fail () {
+              uni.switchTab({
+                url: href,
+                fail () { }
+              })
+            }
+          })
+        }
+      }
+    },
+
+    /**
+     * @description 错误事件
+     * @param {Event} e
+     */
+    mediaError (e) {
+      const i = e.currentTarget.dataset.i
+      const node = this.childs[i]
+      // 加载其他源
+      if (node.name === 'video' || node.name === 'audio') {
+        let index = (this.ctrl[i] || 0) + 1
+        if (index > node.src.length) {
+          index = 0
+        }
+        if (index < node.src.length) {
+          this.$set(this.ctrl, i, index)
+          return
+        }
+      } else if (node.name === 'img') {
+        // #ifdef H5 && VUE3
+        if (this.opts[0] && !this.ctrl.load) return
+        // #endif
+        // 显示错误占位图
+        if (this.opts[2]) {
+          this.$set(this.ctrl, i, -1)
+        }
+        this.checkReady()
+      }
+      if (this.root) {
+        this.root.$emit('error', {
+          source: node.name,
+          attrs: node.attrs,
+          // #ifndef H5 && VUE3
+          errMsg: e.detail.errMsg
+          // #endif
+        })
+      }
+    }
+  }
+}
+</script>
+<style>
+/* a 标签默认效果 */
+._a {
+  padding: 1.5px 0 1.5px 0;
+  color: #366092;
+  word-break: break-all;
+}
+
+/* a 标签点击态效果 */
+._hover {
+  text-decoration: underline;
+  opacity: 0.7;
+}
+
+/* 图片默认效果 */
+._img {
+  max-width: 100%;
+  -webkit-touch-callout: none;
+}
+
+/* 内部样式 */
+
+._block {
+  display: block;
+}
+
+._b,
+._strong {
+  font-weight: bold;
+}
+
+._code {
+  font-family: monospace;
+}
+
+._del {
+  text-decoration: line-through;
+}
+
+._em,
+._i {
+  font-style: italic;
+}
+
+._h1 {
+  font-size: 2em;
+}
+
+._h2 {
+  font-size: 1.5em;
+}
+
+._h3 {
+  font-size: 1.17em;
+}
+
+._h5 {
+  font-size: 0.83em;
+}
+
+._h6 {
+  font-size: 0.67em;
+}
+
+._h1,
+._h2,
+._h3,
+._h4,
+._h5,
+._h6 {
+  display: block;
+  font-weight: bold;
+}
+
+._image {
+  height: 1px;
+}
+
+._ins {
+  text-decoration: underline;
+}
+
+._li {
+  display: list-item;
+}
+
+._ol {
+  list-style-type: decimal;
+}
+
+._ol,
+._ul {
+  display: block;
+  padding-left: 40px;
+  margin: 1em 0;
+}
+
+._q::before {
+  content: '"';
+}
+
+._q::after {
+  content: '"';
+}
+
+._sub {
+  font-size: smaller;
+  vertical-align: sub;
+}
+
+._sup {
+  font-size: smaller;
+  vertical-align: super;
+}
+
+._thead,
+._tbody,
+._tfoot {
+  display: table-row-group;
+}
+
+._tr {
+  display: table-row;
+}
+
+._td,
+._th {
+  display: table-cell;
+  vertical-align: middle;
+}
+
+._th {
+  font-weight: bold;
+  text-align: center;
+}
+
+._ul {
+  list-style-type: disc;
+}
+
+._ul ._ul {
+  margin: 0;
+  list-style-type: circle;
+}
+
+._ul ._ul ._ul {
+  list-style-type: square;
+}
+
+._abbr,
+._b,
+._code,
+._del,
+._em,
+._i,
+._ins,
+._label,
+._q,
+._span,
+._strong,
+._sub,
+._sup {
+  display: inline;
+}
+
+/* #ifdef APP-PLUS */
+._video {
+  width: 300px;
+  height: 225px;
+}
+/* #endif */
+</style>

Разлика између датотеке није приказан због своје велике величине
+ 1335 - 0
uni_modules/mp-html/components/mp-html/parser.js


+ 76 - 0
uni_modules/mp-html/package.json

@@ -0,0 +1,76 @@
+{
+    "id": "mp-html",
+    "displayName": "mp-html 富文本组件【全端支持,支持编辑、latex等扩展】",
+    "version": "v2.4.2",
+    "description": "一个强大的富文本组件,高效轻量,功能丰富",
+    "keywords": [
+        "富文本",
+        "编辑器",
+        "html",
+        "rich-text",
+        "editor"
+    ],
+    "repository": "https://github.com/jin-yufeng/mp-html",
+    "dcloudext": {
+        "sale": {
+            "regular": {
+                "price": "0.00"
+            },
+            "sourcecode": {
+                "price": "0.00"
+            }
+        },
+        "contact": {
+            "qq": ""
+        },
+        "declaration": {
+            "ads": "无",
+            "data": "无",
+            "permissions": "无"
+        },
+        "npmurl": "https://www.npmjs.com/package/mp-html",
+        "type": "component-vue"
+    },
+    "uni_modules": {
+        "platforms": {
+            "cloud": {
+                "tcb": "y",
+                "aliyun": "y"
+            },
+            "client": {
+                "App": {
+                    "app-vue": "y",
+                    "app-nvue": "y"
+                },
+                "H5-mobile": {
+                    "Safari": "y",
+                    "Android Browser": "y",
+                    "微信浏览器(Android)": "y",
+                    "QQ浏览器(Android)": "y"
+                },
+                "H5-pc": {
+                    "Chrome": "y",
+                    "IE": "u",
+                    "Edge": "y",
+                    "Firefox": "y",
+                    "Safari": "y"
+                },
+                "小程序": {
+                    "微信": "y",
+                    "阿里": "y",
+                    "百度": "y",
+                    "字节跳动": "y",
+                    "QQ": "y"
+                },
+                "快应用": {
+                    "华为": "y",
+                    "联盟": "y"
+                },
+                "Vue": {
+                    "vue2": "y",
+                    "vue3": "y"
+                }
+            }
+        }
+    }
+}

Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
uni_modules/mp-html/static/app-plus/mp-html/js/handler.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
uni_modules/mp-html/static/app-plus/mp-html/js/uni.webview.min.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
uni_modules/mp-html/static/app-plus/mp-html/local.html


BIN
uni_modules/p-f-unicom/1.jpg


+ 188 - 0
uni_modules/p-f-unicom/README.md

@@ -0,0 +1,188 @@
+## p-f-unicom 跨层级通信插件,解决非父子通信的痛点
+
+> 前言:我们在使用`Vue`进行开发时如何能够解决非父子组件之间的一个通信问题,那如果碰到这样一个问题其实按照一般的开发步骤解决起来是非常繁琐的可能各种的`parent`、`children`或者有人可能会直接定义在全局环境上那这样的操作会使得你的项目在越来越复杂的业务开发中变得非常的脆弱。
+
+##### `p-f-unicom` 自定义插件:
+
+1. 它是`Vue.js`的一个自定义插件,解决了`Vue`中非父子组件通讯的痛点。
+2. 利用订阅者和发布者模式来管理消息。
+
+##### 功能:
+1. 任意一个`Vue`组件向其他所有组件发送指令。
+2. 任意一个`Vue`组件向某组`Vue`组件发送指令。
+3. 任意一个`Vue`组件向特定`unicom-id`组件发送消息。
+4. 在任意一个`Vue`组件内获取某组组件列表。
+5. 在任意一个`Vue`组件内获取特定`unciom-id`组件。
+6. 发送指令到还没初始化的`unicom-id`组件。
+7. 发送指令到还没初始化的`unicom-group`分组组件。
+8. 组件销毁时自动销毁绑定的订阅事件。
+
+##### 使用:
+`main.js` 注册`Unicom`插件
+
+`unicom`是插件内置的名称,如果需要修改可以在`Vue.use`时自定义。
+```javascript
+// 导入
+import unicom from './plugin/p-f-unicom.js'
+// 使用
+Vue.use(unicom, {
+  name: 'unicom',
+  idName: 'unicomId',
+  groupName: 'unicomGroup'
+})
+```
+
+##### Vue组件内部使用
+
+child.vue (订阅)
+```javascript
+<template>
+  <div>
+    // ......
+  </div>
+</template>
+<script>
+  export default {
+    // 将这个组件归到 group 分组,必须是数组
+    unicomGroup: ['group'],
+    unicom: {
+      // message 通讯指令名称和 this.$unicom 时对应
+      /**
+      * @desc 注册接收指令
+      * sender: 发送指令者(建议只能读区不能修改)
+      * args:指令发出者附带参数
+      */
+      message (sender, ...args){
+        // 订阅消息 (名称为 `message`)
+      }
+    }  
+  }
+</script>
+```
+index.vue (发布)
+
+```javascript
+<template>
+  <div>
+    // unicom-id 不能和其它组件所定的 unicom-id 相同
+    // unicom-group 定义组的名称数组,会和组件内的 `unicomGroup` 合并并去重 ,不定义默认使用 child 组件内的 `unicomGroup`
+    <child unicom-id="child-id" :unicom-group="aUnicomGroupList"></child>
+  </div>
+</template>
+<script>
+  import Child from './child.vue'
+  export default {
+    components: {
+      Child
+    },
+		data(){
+			return {
+        // 名字不能叫 unicomGroup,因为已经被 unicom 插件占用自动放到了组件的props对象中所以名字会重名冲突
+				aUnicomGroupList: ['group', 'group1']
+			}
+		},
+    methods: {
+      doExec () {
+        // 发布订阅消息,会自动调用 child 组件内订阅的 `message` 指令
+        this.$unicom("message", arg1, arg2, ...)
+        
+        // 获取被命名为 child-id 的组件引用
+        const child = this.$unicom("#child-id")
+        
+        // 获取分组为 group 的所有 vue 组件
+        const childs = this.$unicom("@group")
+      }
+    }
+  }
+</script>
+```
+
+
+#### 发布的使用模式:
+
+##### 组件已经存在
+
+instruct1 是指令也就是你在 vue 组件中定义的接收消息的事件名称:
+
+```javascript
+unicom: {
+  instruct1(sender, oQueryParams, aYearList) {
+    // 查询栏消息
+    console.log('订阅消息', JSON.stringify(oQueryParams), aYearList);
+  }
+}
+```
+
+1. instruct1@group (发送到指定分组)
+2. instruct1#id1 (发送到指定组件)
+3. @group (获取指定分组组件)
+4. #id1 (获取指定组件)
+
+##### 组件还未创建,延迟发送指令(一次性指令)
+
+指令使用 ~ 打头
+
+1. ~instruct1 (指令延迟发送,直到包含有 `instruct1` 指令的组件出现)
+2. ~instruct1@group (指令延迟发送,直到出现分组命名`group`的组件)
+3. ~instruct1#id1 (指令延迟发送,直到出现命名`id1`的组件)
+
+如果你的组件是通过点击按钮这样通过判断来渲染出来的,那么事件的执行可以按下面的示例:
+
+```javascript
+this.$unicom('~onQuery111@industrialAnalyseFilterGroup', 'hello'); // 这个是发送组件未创建时的指令,指令将被缓存等待组件创建后触发onQuery111指令方法
+this.$unicom('onQuery111@industrialAnalyseFilterGroup', 'hello111'); // 第二次向已经创建完成的组件发送指令onQuery111需要使用不带~号的形式
+```
+
+对应的组件
+```javascript
+<template>
+  <div>我不是初始化时就渲染</div>
+</template>
+<script>
+export default {
+  unicomGroup: ['industrialAnalyseFilterGroup'],
+  // unicomId: 'aaaa',
+  unicom: {
+    // onQuery(sender, args) {
+    //   console.log(sender, args, 11111111111);
+    // },
+    onQuery111(sender, p) {
+      console.log('hello: ', p);
+    }
+  },
+  data(){
+    return {
+
+    }
+  },
+  created(){}
+}
+</script>
+```
+
+
+##### 组件监听
+
+组件监听使用,指令使用 ~ 打头, 第二个参数为 `callback` 回调
+
+```
+methods: {
+    doExec () {
+        this.$unicom('~#child-id', function(child){
+            // `child`组件创建完成,从 `child` 组件的`created`函数触发出来,所以请不要操作 `child`组件的 dom 元素,组件挂载请监听 this.$nextTick
+        })
+    }
+}
+```
+
+1. ~@group (监听分组命名group的组件出现)
+2. ~#id1 (监听命名id1的组件出现)
+
+具体的使用 demo 请参考 v-demo 目录。
+
+
+*****
+注: 
+1.此插件原始地址:[vue-plugins](https://gitee.com/zhangh-design/vue-plugins)。
+2.版权归原作者所有,仅为了方便,挂上插件市场。
+3.对原作者表示感谢!

+ 2 - 0
uni_modules/p-f-unicom/changelog.md

@@ -0,0 +1,2 @@
+## 1.0.0(2023-02-02)
+init

+ 369 - 0
uni_modules/p-f-unicom/index.js

@@ -0,0 +1,369 @@
+import _get from 'lodash/get'
+import _set from 'lodash/set'
+import _isEmpty from 'lodash/isEmpty'
+import _isEqual from 'lodash/isEqual'
+import _forEach from 'lodash/forEach'
+import _isUndefined from 'lodash/isUndefined'
+import _flattenDeep from 'lodash/flattenDeep'
+import _toString from 'lodash/toString'
+import _has from 'lodash/has'
+import _includes from 'lodash/includes'
+import _keys from 'lodash/keys'
+import _isFunction from 'lodash/isFunction'
+import _uniq from 'lodash/uniq'
+import _flatMap from 'lodash/flatMap'
+import _union from 'lodash/union'
+/**
+ * @desc
+ * Vue 跨组件通信插件
+ */
+let unicomIdName = ''
+let unicomGroupName = ''
+// vm容器、分组、事件、命名 唯一、推迟触发的事件
+const [vmMap, groupForVm, events, idForVm, sendDefer] = [new Map(), {}, {}, {}, []]
+/**
+ * @desc 触发执行事件
+ * @param {string} method - 指令的名称
+ * @param {string} toKey - 目标组件的 unicomId 或者 unicomGroup
+ * @param {string} aim - 标识 (#)
+ * @param {Array} args - 参数
+ */
+const emitEvent = function (method, toKey, aim, args) {
+  const evs = _get(events, method, [])
+  let evLen = 0
+  const len = evs.length
+  // 循环已经注册的指令
+  for (evLen; evLen < len; evLen++) {
+    // 存储的数据
+    const { fn, scope } = evs[evLen]
+    if (_isEqual(aim, '#')) {
+      // id
+      if (scope[unicomIdName] !== toKey) {
+        // 目标不存在
+        continue
+      }
+    } else if (_isEqual(aim, '@')) {
+      // 分组
+      const group = _get(vmMap.get(scope), 'group', [])
+      if (_isEmpty(group) || _isEqual(_includes(group, toKey), false)) {
+        // 目标不存在
+        continue
+      }
+    }
+    _isEqual(_isUndefined(scope), false) && fn.apply(scope, args)
+  }
+  // 返回被触发的指令
+  return evLen
+}
+/**
+ * @desc 发送容器 或者 获得 目标容器
+ * @param {string} query - 指令名称 (~instruct1#id1)
+ * @param  {...any} args - 可变参数
+ */
+const unicomQuery = function (query, ...args) {
+  let [toKey, aim, defer, eventIndex] = ['', '', false, -1]
+  // query=instruct1#id1
+  const method = query
+    .replace(/^([`~])/, function (s0, s1) {
+      // query=~instruct1#id1
+      if (_isEqual(s1, '~')) {
+        defer = true
+      }
+      return ''
+    })
+    .replace(/([@#])([^@#]*)$/, function (s0, s1, s2) {
+      // query=instruct1@child-a
+      // s0=@child-a s1=@ s2=child-a
+      toKey = s2
+      aim = s1
+      return ''
+    })
+  // method=instruct1
+  if (defer) {
+    sendDefer.push([method, toKey, aim, args, this])
+    return this
+  }
+  if (_isEqual(_isEqual(method, ''), false)) {
+    args.unshift(this)
+    eventIndex = emitEvent(method, toKey, aim, args)
+  }
+  // 获取目标 vm
+  switch (aim) {
+    case '#':
+      return _get(idForVm, toKey, null)
+    case '@':
+      return _get(groupForVm, toKey, [])
+  }
+  return eventIndex
+}
+/**
+ * @desc 更新分组
+ * @param {Object} scope - 组件的实例
+ * @param {string[]} nv - 指令 unicom-group 传入的组数据 (新)
+ * @param {string[]} [ov] - 指令 unicom-group 传入的组数据 (旧)
+ */
+const updateName = function (scope, nv, ov) {
+  // 实例上设置分组
+  const vmData = vmMap.get(scope) || {}
+  const group = _get(vmData, 'group', [])
+  // 删除旧的 vm
+  if (_isEqual(_isUndefined(ov), false)) {
+    _uniq(_flattenDeep(_flatMap(ov))).forEach(function (key) {
+      if (_includes(group, key)) {
+        const vms = _get(groupForVm, key, [])
+        _isEqual(_isEmpty(vms), false) && vms.splice(vms.indexOf(scope), 1)
+        if (_isEmpty(vms)) {
+          group.splice(group.indexOf(key), 1)
+          Reflect.deleteProperty(groupForVm, key)
+        }
+      }
+    })
+  }
+  // 增加新的
+  if (_isEqual(_isUndefined(nv), false)) {
+    _uniq(_flattenDeep(_flatMap(nv))).forEach(function (key) {
+      const vms = _get(groupForVm, key, [])
+      if (_isEmpty(vms)) {
+        _set(groupForVm, key, vms)
+      }
+      // 新添加 组件 到组里面
+      if (_isEqual(_includes(vms, scope), false)) {
+        vms.push(scope)
+      }
+      if (_isEqual(_includes(group, key), false)) {
+        group.push(key)
+      }
+    })
+  }
+}
+/**
+ * @desc 更新 unicomId
+ * @param {Object} scope - 组件的实例
+ * @param {string} newValue - 指令 unicom-id 传入的id数据 (新)
+ * @param {string} [oldValue] - 指令 unicom-id 传入的id数据 (旧)
+ */
+const updateId = function (scope, newValue, oldValue) {
+  if (_isEqual(newValue, oldValue)) {
+    return
+  }
+  if (_isEqual(_isUndefined(oldValue), false) && _isEqual(_get(idForVm, oldValue), scope)) {
+    // watch 监测值修改需要删除,组件销毁时需要删除
+    Reflect.deleteProperty(idForVm, oldValue)
+  }
+  if (_isEqual(_isUndefined(newValue), false) && _isEqual(_has(idForVm, newValue), false)) {
+    _set(idForVm, newValue, scope)
+  } else if (_isEqual(_isUndefined(newValue), false) && _has(idForVm, newValue)) {
+    console.warn(`${unicomIdName}='${newValue}'的组件已经定义并存在。`)
+  }
+}
+/**
+ * @desc 添加事件
+ * @param {string} method - 指令的名称
+ * @param {function} fn - 指令名称对应的函数
+ * @param {Object} scope - 指令名称对应函数所运行的作用域
+ */
+const appendEvent = function (method, fn, scope) {
+  if (_isEqual(_has(events, method), false)) {
+    events[method] = []
+  }
+  if (_isFunction(fn)) {
+    events[method].push({ fn, scope, method })
+  }
+}
+/**
+ * @desc 移除事件
+ * @param {string} method - 指令的名称
+ * @param {Object} scope - 指令名称对应函数所运行的作用域
+ */
+const removeEvent = function (method, scope) {
+  const evs = _get(events, method, [])
+  if (_isEqual(_isEmpty(evs), false)) {
+    for (let i = 0; i < evs.length; i++) {
+      if (_isEqual(scope, evs[i].scope)) {
+        evs.splice(i, 1)
+      }
+    }
+  }
+}
+export default {
+  install (Vue, { name = 'unicom', idName = `${name}Id`, groupName = `${name}Group` } = {}) {
+    // 添加原型方法 (unicomQuery 函数放在 install 外部不然无法获取调用函数的 this 对象)
+    Vue.prototype['$' + name] = unicomQuery
+    // unicom-id
+    unicomIdName = idName
+    // 分组  unicom-group
+    unicomGroupName = groupName
+    // 全局混入
+    Vue.mixin({
+      props: {
+        // 命名 unicom-id="id1"
+        [idName]: {
+          type: String,
+          default: ''
+        },
+        // 分组(纯字符串类数组不能是真实的数组) unicom-group="['child-a', 'child-b']"
+        [groupName]: {
+          type: Array,
+          default: () => []
+        }
+      },
+      watch: {
+        [idName] (nv, ov) {
+          updateId(this, nv, ov)
+        },
+        [groupName]: {
+          deep: true,
+          handler (nv, ov) {
+            updateName(this, nv, ov);
+          }
+        }
+      },
+      // 创建的时候加入事件机制
+      beforeCreate () {
+        const opt = this.$options
+        const vmData = {}
+        const [us, uni, group] = [
+          _get(opt, name, {}),
+          (vmData.uni = {}),
+          (vmData.group = [])
+        ]
+        if (_isEqual(_isEmpty(us), false)) {
+          _forEach(us, opt => {
+            if (_isEmpty(opt)) {
+              return true
+            }
+            _forEach(opt, (handler, key) => {
+              if (_isEqual(_isUndefined(handler), false)) {
+                _isUndefined(_get(uni, key)) && _set(uni, key, [])
+                uni[key].push(handler)
+                // 添加事件
+                appendEvent(key, handler, this)
+              }
+            })
+          })
+        }
+        // 命名分组
+        const groupNameOpt = _get(opt, groupName, [])
+        if (_isEqual(_isEmpty(groupNameOpt), false)) {
+          _forEach(_uniq(_flattenDeep(_flatMap(groupNameOpt))), item => {
+            const key = _toString(item)
+            _isUndefined(_get(groupForVm, key)) && (groupForVm[key] = [])
+            group.push(key)
+            groupForVm[key].push(this)
+          })
+        }
+        if (_isEqual(_isEmpty(group), false) || _isEqual(_isEmpty(uni), false)) {
+          vmMap.set(this, vmData)
+        }
+      },
+      created () {
+        // 实例命名 唯一
+        const uId = this[idName]
+        const uGroupName = this[groupName]
+        _isEqual(_isEqual(uId, ''), false) && updateId(this, uId)
+        _isEqual(_isEmpty(uGroupName), false) && updateName(this, uGroupName)
+        // 实例上设置分组
+        const vmData = vmMap.get(this) || {}
+        for (let i = 0; i < sendDefer.length; i++) {
+          const [method, toKey, aim, args, scope] = sendDefer[i]
+          let flag = false
+          if (_isEqual(aim, '#')) {
+            if (_isEqual(toKey, uId)) {
+              flag = true
+            }
+          } else if (_isEqual(aim, '@')) {
+            if (
+              _isEqual(_isUndefined(_get(vmData, 'group')), false) &&
+              _includes(_get(vmData, 'group'), toKey)
+            ) {
+              flag = true
+            }
+          } else {
+            if (
+              _isEqual(method, '') ||
+              _includes(_keys(_get(vmData, 'uni', {})), method)
+            ) {
+              flag = true
+            }
+          }
+          if (flag) {
+            // 延后,并且方法为空
+            if (_isEqual(method, '')) {
+              /**
+               * @desc 监听组件事件
+               * @example
+               * this.$unicom('~#id1', function (childScope) {// unicomId=id1的组件创建完成})
+               */
+              if (_isFunction(args[0])) {
+                args[0](this)
+              }
+            } else {
+              sendDefer.splice(i--, 1)
+              args.unshift(scope)
+              emitEvent(method, toKey, aim, args)
+            }
+          }
+        }
+      },
+      // 全局混合,销毁实例的时候销毁事件
+      destroyed () {
+        // 移除唯一ID
+        const uId = this[idName]
+        if (_isEqual(_isEqual(uId, ''), false)) {
+          updateId(this, undefined, uId)
+        }
+        // 移除 命名分组、实例命名
+        const uGroupName = _get(this, groupName, [])
+        const optGroupName = _get(this.$options, groupName, [])
+        if (_isEqual(_isEmpty(uGroupName), false) || _isEqual(_isEmpty(optGroupName), false)) {
+          updateName(this, undefined, _union(uGroupName, optGroupName))
+        }
+
+        const vmData = vmMap.get(this)
+        if (_isUndefined(vmData)) {
+          return
+        }
+        vmMap.delete(this)
+
+        const uni = _get(vmData, 'uni', {})
+        // 移除事件
+        for (const key in uni) {
+          removeEvent(key, this)
+        }
+        // 分组,一对多, 单个vm可以多个分组名称 组件命名
+        const group = _get(vmData, 'group', [])
+        _forEach(group, function (name) {
+          const gs = groupForVm[name]
+          if (_isEqual(_isUndefined(gs), false)) {
+            const index = gs.indexOf(this)
+            if (index > -1) {
+              gs.splice(index, 1)
+            }
+            if (gs.length === 0) {
+              delete groupForVm[name]
+            }
+          }
+        })
+        // 监控销毁 method为空
+        for (let i = 0; i < sendDefer.length;) {
+          const pms = sendDefer[i]
+          if (_isEqual(pms[0], '') && _isEqual(pms[4], this)) {
+            sendDefer.splice(i, 1)
+          } else {
+            i += 1
+          }
+        }
+      }
+    })
+    // 自定义属性合并策略
+    // 混入(mixins)时不是简单的覆盖而是追加
+    const merge = _get(Vue, 'config.optionMergeStrategies', {})
+    merge[name] = merge[unicomGroupName] = function (parentVal, childVal) {
+      const p = parentVal || []
+      if (_isEqual(_isUndefined(childVal), false)) {
+        p.push(childVal)
+      }
+      return p
+    }
+  }
+}

+ 0 - 0
uni_modules/p-f-unicom/package.json


Неке датотеке нису приказане због велике количине промена