riku
2022-09-06 bf580d5477d65f5eefb70a8fb9a6b37eaf0ae9bb
2022.9.6
已修改25个文件
已添加42个文件
2619 ■■■■■ 文件已修改
app.json 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app.wxss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/actionsheet/actionsheet.js 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/actionsheet/actionsheet.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/actionsheet/actionsheet.wxml 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/actionsheet/actionsheet.wxss 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/gallery/gallery.wxss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/mygallery/mygallery.js 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/mygallery/mygallery.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/mygallery/mygallery.wxml 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/mygallery/mygallery.wxss 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/sidebar/sidebar.js 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/sidebar/sidebar.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/sidebar/sidebar.wxml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/sidebar/sidebar.wxss 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
component/switchtab/switchtab.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/gradereport/gradereport.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/mine/mine.wxml 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/mine/mine.wxss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailcase/consultdetailcase.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailcase/consultdetailcase.json 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailcase/consultdetailcase.wxml 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailcase/consultdetailcase.wxss 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailitem/consultdetailitem.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailqa/consultdetailqa.js 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailqa/consultdetailqa.json 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailqa/consultdetailqa.wxml 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultdetailqa/consultdetailqa.wxss 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consulthome/consulthome.js 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consulthome/consulthome.wxml 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consulthome/consulthome.wxss 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultonline/consultonline.wxml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultproblem/consultproblem.js 301 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultproblem/consultproblem.json 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultproblem/consultproblem.wxml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultproblem/consultproblem.wxss 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultresult/consultresult.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_consult/consultresultmore/consultresultmore.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_ledger/ledgerhistory/ledgerhistory.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_ledger/ledgerhistory/ledgerhistory.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/module_ledger/ledgerhistory/ledgerhistory.wxml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/test2/test2.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/test2/test2.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/test2/test2.wxml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/test2/test2.wxss 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/bg_star.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/case_forfeit.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/cq_detained.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/cq_illegal.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/cq_minor.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/cq_punish.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/cq_shotspot.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/cq_supervise.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/favourite.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/favourite1.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/filter.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/like.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/like1.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/link_1.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/link_2.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/link_3.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/link_4.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/locate.png 补丁 | 查看 | 原始文档 | blame | 历史
res/icons/time.png 补丁 | 查看 | 原始文档 | blame | 历史
service/baserequest.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/consultservice.js 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/util.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app.json
@@ -16,6 +16,7 @@
    "pages/notice/notice",
    "pages/gradereport/gradereport",
    "pages/test/test",
    "pages/test2/test2",
    "pages/promisesign/promisesign",
    "pages/module_consult/consulthome/consulthome",
    "pages/module_consult/consultsearch/consultsearch",
@@ -35,16 +36,19 @@
    "pages/module_consult/consultresultmore/consultresultmore",
    "pages/module_consult/consultdetailitem/consultdetailitem",
    "pages/module_learn/learfile/learnfile",
    "pages/module_learn/learncase/learncase"
    "pages/module_learn/learncase/learncase",
    "pages/module_consult/consultdetailqa/consultdetailqa",
    "pages/module_consult/consultdetailcase/consultdetailcase"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "中小企业环境守法服务平台",
    "navigationBarTextStyle": "black"
    "navigationBarTextStyle": "black",
    "backgroundColor": "#57E4CB"
  },
  "tabBar": {
    "selectedColor": "#0963F5",
    "selectedColor": "#59D5B3",
    "list": [
      {
        "pagePath": "pages/home/home",
app.wxss
@@ -10,6 +10,10 @@
  --fyui-BG-COLOR-ACTIVE: #ececec5d;
}
view {
  /* font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; */
}
/********************************** é€šç”¨-start ***********************************/
.statusbar-title {
  text-align: center;
@@ -104,6 +108,11 @@
  font-size: 14px;
  color: var(--fyui-primary-color);
  padding: 2px 4px 2px 18px;
}
.image-16 {
  width: 16px;
  height: 16px;
}
/********************************** é€šç”¨-end ***********************************/
@@ -221,7 +230,7 @@
.fyui-box:before{
  content: " ";
  width: 100%;
  width: 90%;
  height: 1px;
  background-color: var(--fyui-BG_1);
  top: -2px;
component/actionsheet/actionsheet.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,193 @@
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 = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */,
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Component({
  options: {
    multipleSlots: true,
    // åœ¨ç»„件定义时的选项中启用多slot支持
    addGlobalClass: true
  },
  properties: {
    title: {
      // æ ‡é¢˜
      type: String,
      value: ''
    },
    showCancel: {
      // æ˜¯å¦æ˜¾ç¤ºå–消按钮
      type: Boolean,
      value: true
    },
    cancelText: {
      // å–消按钮文案
      type: String,
      value: '取消'
    },
    maskClass: {
      // é®ç½©å±‚class
      type: String,
      value: ''
    },
    extClass: {
      // å¼¹å‡ºçª— class
      type: String,
      value: ''
    },
    maskClosable: {
      // ç‚¹å‡»é®ç½© å…³é—­ actionsheet
      type: Boolean,
      value: true
    },
    mask: {
      // æ˜¯å¦éœ€è¦ é®ç½©å±‚
      type: Boolean,
      value: true
    },
    show: {
      // æ˜¯å¦å¼€å¯ actionsheet
      type: Boolean,
      value: false
    },
    actions: {
      // actions åˆ—表
      type: Array,
      value: [],
      // {text, extClass}
      observer: '_groupChange'
    }
  },
  methods: {
    _groupChange(e) {
      // æ”¯æŒ ä¸€ç»´æ•°ç»„ å†™æ³•
      if (e.length > 0 && typeof e[0] !== 'string' && !(e[0] instanceof Array)) {
        this.setData({
          actions: [this.data.actions]
        });
      }
    },
    buttonTap(e) {
      const {
        value,
        groupindex,
        index
      } = e.currentTarget.dataset;
      this.triggerEvent('actiontap', {
        value,
        groupindex,
        index
      });
    },
    closeActionSheet(e) {
      const {
        type
      } = e.currentTarget.dataset;
      if (this.data.maskClosable || type) {
        // ç‚¹å‡» action é‡Œé¢çš„ å–消
        this.setData({
          show: false
        }); // å…³é—­å›žè°ƒäº‹ä»¶
        this.triggerEvent('close');
      }
    }
  }
});
/***/ })
/******/ ]);
component/actionsheet/actionsheet.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
{
  "component": true,
  "usingComponents": {
    "mp-icon": "../icon/icon"
  }
}
component/actionsheet/actionsheet.wxml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
<wxs module="utils">
    var join = function(a,b) {
        return a+b
    };
    var isNotSlot = function(v) {
        return typeof v !== 'string'
    }
    module.exports = {
        join: join,
        isNotSlot: isNotSlot
    }
</wxs>
<view wx:if="{{mask}}" class="weui-mask {{show ? '' : 'weui-mask_hidden'}} {{maskClass}}" bindtap="closeActionSheet"></view>
<view class="weui-actionsheet {{show ? 'weui-actionsheet_toggle' : ''}} {{extClass}}">
    <!-- å…³é—­å›¾æ ‡ -->
    <view class="close">
      <mp-icon bindtap="closeActionSheet" icon="close" size="{{20}}"></mp-icon>
    </view>
    <!-- æ ‡é¢˜ -->
    <block  wx:if="{{title}}">
        <view class="weui-actionsheet__title">
            <view class="weui-actionsheet__title-text">{{title}}</view>
        </view>
    </block>
    <slot name="title" wx:else></slot>
    <view
        class="{{ !showCancel && index === actions.length-1 ? 'weui-actionsheet__action' : 'weui-actionsheet__menu' }}"
        wx:key="index"
        wx:for-item="actionItem"
        wx:for-index="index"
        wx:for="{{actions}}"
    >
        <block wx:if="{{utils.isNotSlot(actionItem)}}">
            <view
                class="weui-actionsheet__cell {{item.type === 'warn' ? 'weui-actionsheet__cell_warn' : '' }}"
                hover-class="weui-active"
                wx:key="actionIndex"
                wx:for="{{actionItem}}"
                wx:for-index="actionIndex"
                data-groupindex="{{index}}"
                data-index="{{actionIndex}}"
                data-value="{{item.value}}"
                bindtap="buttonTap"
            >
                {{item.text}}
            </view>
        </block>
        <slot name="{{actionItem}}" wx:else></slot>
    </view>
    <!-- å–消按钮 -->
    <view class="weui-actionsheet__action" wx:if="{{showCancel}}">
        <view class="weui-actionsheet__cell" hover-class="weui-active" data-type="close" id="iosActionsheetCancel" bindtap="closeActionSheet">{{cancelText}}</view>
    </view>
</view>
component/actionsheet/actionsheet.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
.weui-actionsheet {
  background-color: white;
}
.weui-mask.weui-mask_hidden {
  opacity: 0;
  transform: scale3d(1, 1, 0)
}
.weui-mask {
  opacity: 1;
  transform: scale3d(1, 1, 1);
  transition: all .3s
}
.close {
  display: block;
  text-align: end;
  /* background-color: red; */
  padding: 8px;
}
.close>mp-icon {
  background-color: #F0F0F0;
  border-radius: 50%;
  padding: 4px;
}
component/gallery/gallery.wxss
@@ -1 +1,7 @@
.weui-gallery{display:none}.weui-gallery_show.weui-gallery{display:flex}
.weui-gallery {
  display: none
}
.weui-gallery_show.weui-gallery {
  display: flex
}
component/mygallery/mygallery.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,328 @@
// component/mygallery/mygallery.js
Component({
  options: {
    addGlobalClass: true
  },
  properties: {
    imgUrls: {
      type: Array,
      value: [],
      observer(newVal) {
        this.setData({
          currentImgs: newVal
        });
      }
    },
    title: {
      type: String,
      value: ''
    },
    remark: {
      type: String,
      value: ''
    },
    show: {
      type: Boolean,
      value: true,
      observer(newVal) {
        if (newVal) {
          let that = this;
          let query = this.createSelectorQuery(); //必须要先创建一个查询
          setTimeout(() => {
            query.select('.fyui-gallery__img').boundingClientRect(function (rect) {
              console.log('observer');
              console.log(rect);
              that.setData({
                imgHeight: rect.height,
                imgWidth: rect.width,
                xLimit: [0, 0],
                yLimit: [0, 0],
              });
            }).exec();
          }, 500);
        }
      }
    },
    current: {
      type: Number,
      value: 0
    },
    hideOnClick: {
      type: Boolean,
      value: true
    },
    extClass: {
      type: String,
      value: ''
    }
  },
  data: {
    currentImgs: [],
    tabList: [],
    pageList: [],
    showRemark: true,
    imgHeight: 0, //图片高度
    imgWidth: 0, //图片宽度
    xLimit: [], //缩放后x轴移动范围
    yLimit: [], //缩放后y轴移动范围
    translateX: 0, // ä½ç§»x坐标 å•位px
    translateY: 0, // ä½ç§»y坐标 å•位px
    distance: undefined, // åŒæŒ‡æŽ¥è§¦ç‚¹è·ç¦»
    scale: 1, // ç¼©æ”¾å€æ•°
    endScale: 1,
    rotate: 0, // æ—‹è½¬è§’度
    oldRotate: 0, // ä¸Šä¸€æ¬¡æ—‹è½¬åœæ­¢åŽçš„角度
    startMove: { // èµ·å§‹ä½ç§»è·ç¦»
      x: 0,
      y: 0,
    },
    startTouches: [] // èµ·å§‹ç‚¹touch数组
  },
  pageLifetimes: {
    // ç»„件所在页面的生命周期函数
    show: function () {
    },
  },
  ready() {
    const data = this.data;
    this.setData({
      currentImgs: data.imgUrls
    });
  },
  methods: {
    change(e) {
      this.setData({
        current: e.detail.current
      });
      this.triggerEvent('change', {
        current: e.detail.current
      }, {});
      //图片复位
      this.setData({
        scale: 1,
        translateX: 0,
        translateY: 0,
        rotate: 0
      })
    },
    deleteImg() {
      const data = this.data;
      const imgs = data.currentImgs;
      const url = imgs.splice(data.current, 1);
      this.triggerEvent('delete', {
        url: url[0],
        index: data.current
      }, {});
      if (imgs.length === 0) {
        // @ts-ignore
        this.hideGallery();
        return;
      }
      this.setData({
        current: 0,
        currentImgs: imgs
      });
    },
    hideGallery() {
      const data = this.data;
      if (data.hideOnClick) {
        this.setData({
          show: false,
          scale: 1,
          endScale: 1,
          showRemark: true,
          translateX: 0,
          translateY: 0,
          rotate: 0
        });
        this.triggerEvent('hide', {}, {});
      }
    },
    /**
     * åº•部图片导航栏选择事件
     */
    swichNav(e) {
      var that = this;
      if (this.data.currentTab === e.target.dataset.current) {
        return false;
      } else {
        that.setData({
          current: e.target.dataset.current,
        })
      }
    },
    /**
     * åº•部图片导航栏、文本显隐事件
     */
    toggle() {
      const showRemark = !this.data.showRemark
      this.setData({
        showRemark
      })
    },
    rotateImg(e) {
      const clockwise = e.currentTarget.dataset.clockwise
      let rotate = this.data.rotate
      if (clockwise) {
        rotate += 90
      } else {
        rotate -= 90
      }
      rotate = rotate > 360 ? rotate - 360 : rotate
      rotate = rotate < 0 ? rotate + 360 : rotate
      const imgWidth = this.data.imgHeight
      const imgHeight = this.data.imgWidth
      this.setData({rotate, imgWidth, imgHeight})
    },
    touchStart(e) {
      const touches = e.touches
      console.log('touchStart:');
      console.log(touches);
      const { translateX, translateY } = this.data
      const { clientX, clientY } = touches[0]
      this.setData({
        startMove:{
          x: clientX - translateX,
          y: clientY - translateY
        }
      })
      this.setData({
        startTouches:touches,
      })
    },
    touchMove(e) {
      console.log('touchMove:');
      const touches = e.touches
      const { clientX: onePageX, clientY: onePageY } = touches[0]
      const { startMove, scale, distance: oldDistance, startTouches, oldRotate  } = this.data
      if (touches.length === 2 && startTouches.length === 2) {
        // åŒæŒ‡ç¼©æ”¾
        const { pageX: twoPageX, pageY: twoPageY } = touches[1]
        // æ±‚出当前双指距离
        const distance = Math.sqrt((twoPageX - onePageX) ** 2 + (twoPageY - onePageY) ** 2)
        this.setData({distance})
        // åŒæŒ‡æ—‹è½¬
        let rotate = this.getAngle(touches[0], touches[1]) - this.getAngle(startTouches[0], startTouches[1]) + oldRotate
        // å¦‚果大于360度,就减去360
        rotate = rotate > 360 ? rotate - 360 : rotate
        this.setData({
          scale: scale * (distance / (oldDistance || distance)),
          // rotate
        })
      } else if (scale > 1 && startTouches.length !== 2) {
        // å•指拖拽
        // const xL = this.data.xLimit
        // const yL = this.data.yLimit
        let x = onePageX - startMove.x
        let y = onePageY - startMove.y
        // if (x < xL[0]) {
        //   x = xL[0]
        // } else if (x > xL[1]) {
        //   x = xL[1]
        // }
        // if (y < yL[0]) {
        //   y = yL[0]
        // } else if (y > yL[1]) {
        //   y = yL[1]
        // }
        this.setData({
          translateX: x,
          translateY: y
        })
      }
    },
    getAngle(p1, p2) {
      const x = p1.clientX - p2.clientX
      const y = p1.clientY- p2.clientY
      return Math.atan2(y, x) * 180 / Math.PI
    },
    touchEnd() {
      console.log('touchEnd:');
      // ä¿å­˜å½“前旋转角度,清空双指距离
      const oldRotate = this.data.rotate
      this.setData({
        oldRotate,
        distance: undefined,
       })
      // æœ€å°ç¼©æ”¾ä¸º1倍,同时图片移动复位
      if (this.data.scale < 1) {
        this.setData({
          scale: 1,
          translateX: 0,
          translateY: 0
        })
      }
      // ä¿å­˜æœ€åŽç¼©æ”¾çš„倍率
      const s = this.data.scale
      this.setData({
        endScale: s,
      })
      // è®¡ç®—当前缩放倍率下,图片可移动范围
      const h = this.data.imgHeight
      const w = this.data.imgWidth
      const sH = h * s
      const sW = w * s
      const rH = (sH - h) / 2
      const rW = (sW - w) / 2
      const xLimit = [-rW, rW]
      const yLimit = [-rH, rH]
      this.setData({
        xLimit,
        yLimit
      })
      console.log('yLimit');
      console.log(yLimit);
      let that = this;
      let query = this.createSelectorQuery(); //必须要先创建一个查询
      query.select('.fyui-gallery__img').boundingClientRect(function (rect) {
        console.log('imgHeight:' + that.data.imgHeight);
        console.log('imgWidth:' + that.data.imgWidth);
        console.log(rect);
        console.log('endScale:' + that.data.endScale);
      }).exec();
      // ç¼©æ”¾åŽå›žå½’至当前移动位置
      let translateX = this.data.translateX
      let translateY = this.data.translateY
      const xL = this.data.xLimit
      const yL = this.data.yLimit
      if (translateX < xL[0]) {
        translateX = xL[0]
      } else if (translateX > xL[1]) {
        translateX = xL[1]
      }
      if (translateY < yL[0]) {
        translateY = yL[0]
      } else if (translateY > yL[1]) {
        translateY = yL[1]
      }
      this.setData({ translateX, translateY})
    },
  }
})
component/mygallery/mygallery.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
{
  "component": true,
  "usingComponents": {
    "mp-icon": "../icon/icon"
  }
}
component/mygallery/mygallery.wxml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
<!--component/mygallery/mygallery.wxml-->
<page-container show="{{show}}">
  <view class="fyui-gallery {{show ? 'fyui-gallery_show' : ''}} {{extClass}}">
    <mp-icon wx:if="{{showRemark}}" class="fyui-gallery__close" icon="close" color="white" size="26" bindtap="hideGallery"></mp-icon>
    <view class="fyui-gallery__info" wx:if="{{true}}">{{current+1}} / {{currentImgs.length}}</view>
    <swiper class="fyui-gallery__img__wrp" bindtap="toggle" indicator-dots="{{false}}" bindanimationfinish="change" current="{{current}}" autoplay="{{false}}" duration="{{500}}">
      <block wx:for="{{currentImgs}}" wx:key="index">
        <swiper-item>
          <image mode="aspectFit" src="{{item}}" class="fyui-gallery__img"
            style="transform: translate({{translateX}}px, {{translateY}}px) scale({{scale}}) rotate({{rotate}}deg);"
            bindtouchstart="touchStart"
            bindtouchmove="{{endScale <= 1 ? 'touchMove' : ''}}"
            capture-catch:touchmove="{{endScale > 1 ? 'touchMove' : undefined}}"
            bindtouchend="touchEnd"
            ></image>
        </swiper-item>
      </block>
    </swiper>
    <view class="fyui-gallery__opr" wx:if="{{showRemark}}">
      <view class="fyui-gallery__title">{{title}}</view>
      <view class="fyui-gallery__des">{{remark}}</view>
    </view>
    <scroll-view wx:if="{{showRemark}}" class="swiper-tab" scroll-into-view="item{{current > 2 ? current - 2 : 0}}" scroll-x="true" show-scrollbar="true" scroll-with-animation="true">
      <block wx:for="{{currentImgs}}" wx:key="i">
        <image id="item{{index}}" src="{{item}}" class="swiper-tab-list {{current == index ? 'on' : ''}}" data-current="{{index}}" bindtap="swichNav" mode="aspectFit"></image>
      </block>
    </scroll-view>
    <view wx:if="{{showRemark}}" class="fyui-gallery__tool">
      <mp-icon mode="filled" class="fyui-gallery__tool__rotate" icon="refresh" color="white" size="26" data-clockwise="{{true}}" bindtap="rotateImg"></mp-icon>
      <mp-icon mode="filled" class="fyui-gallery__tool__rotate left" icon="refresh" color="white" size="26" data-clockwise="{{false}}" bindtap="rotateImg"></mp-icon>
    </view>
  </view>
</page-container>
component/mygallery/mygallery.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,154 @@
/* component/mygallery/mygallery.wxss */
.fyui-gallery {
  display: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: #000;
  z-index: 1000;
  /* display: -webkit-box;
  display: -webkit-flex; */
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
  flex-direction: column;
  -webkit-flex-wrap: nowrap;
  flex-wrap: nowrap
}
.fyui-gallery_show {
  display: flex
}
.fyui-gallery__info {
  position: absolute;
  width: 100%;
  color: #fff;
  font-size: 17px;
  line-height: 5vh;
  /* min-height: 60px; */
  text-align: center;
  padding-top: 8px;
  /* background-color: rgba(128, 128, 128, 0.233); */
  z-index: 2;
}
.fyui-gallery__close {
  position: absolute;
  top: 0;
  right: 0;
  padding: 8px 8px 16px 16px;
  /* background-color: blue; */
  z-index: 3;
}
.fyui-gallery__img,
.fyui-gallery__opr {
  /* position: absolute; */
  left: 0;
  left: constant(safe-area-inset-left);
  left: env(safe-area-inset-left);
  right: 0;
  right: constant(safe-area-inset-right);
  right: env(safe-area-inset-right)
}
.fyui-gallery__img {
  position: relative;
  width: 100%;
  height: 100%;
  top: 0;
  top: constant(safe-area-inset-top);
  top: env(safe-area-inset-top);
  bottom: 60px;
  bottom: calc(60px + constant(safe-area-inset-bottom));
  bottom: calc(60px + env(safe-area-inset-bottom));
  background: 50% no-repeat;
  background-size: contain;
  /* background-color: red; */
}
.fyui-gallery__opr {
  position: absolute;
  bottom: calc(12vh + env(safe-area-inset-bottom));
  bottom: calc(12vh + constant(safe-area-inset-bottom));
  /* background-color: #0d0d0d; */
  background-color: rgba(0, 0, 0, 0.219);
  color: white;
  padding: 8px;
}
.fyui-gallery__title {
  font-size: 16px;
  font-weight: 550;
}
.fyui-gallery__des {
  font-size: 14px;
}
.fyui-gallery__img__wrp {
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  flex: 1;
  position: relative;
  font-size: 0
}
.swiper-tab{
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  /* text-align: center; */
  height: 12vh;
  white-space: nowrap;
  z-index: 2;
  /* background-color: rgba(36, 36, 36, 0.473); */
  background-color: rgba(0, 0, 0, 0.219);
  /* background-color: rgba(148, 147, 147, 0.473); */
  padding-left: 8px;
  padding-right: 8px;
  padding-bottom: 0;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}
.swiper-tab-list{
  position: relative;
  height: 8vh;
  width: 8vh;
  border: 1px solid rgb(99, 99, 99);
  margin-right: 8px;
  border-radius: 4px;
}
.on{
  height: 10vh;
  width: 10vh;
  color: white;
  border: 1px solid white;
}
.fyui-gallery__tool {
  position: absolute;
  display: block;
  right: 0;
  top: 45%;
  display: flex;
  flex-direction: column;
  z-index: 10;
}
.fyui-gallery__tool__rotate {
  padding: 8px;
  background-color: rgba(0, 0, 0, 0.384);
  /* transform: rotate(90deg); */
  border-radius: 8px;
}
.left {
  transform: rotateY(180deg);
  /* background-color: red; */
  margin-top: 8px;
}
component/sidebar/sidebar.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,118 @@
// component/sidebar/sidebar.js
Component({
  options: {
    multipleSlots: true,
    // åœ¨ç»„件定义时的选项中启用多slot支持
    addGlobalClass: true
  },
  properties: {
    maskClass: {
      // é®ç½©å±‚class
      type: String,
      value: ''
    },
    extClass: {
      // å¼¹å‡ºçª— class
      type: String,
      value: ''
    },
    maskClosable: {
      // ç‚¹å‡»é®ç½© å…³é—­ actionsheet
      type: Boolean,
      value: true
    },
    mask: {
      // æ˜¯å¦éœ€è¦ é®ç½©å±‚
      type: Boolean,
      value: true
    },
    show: {
      // æ˜¯å¦å¼€å¯ actionsheet
      type: Boolean,
      value: false
    },
    menus: {
      // ä¸€çº§èœå• åˆ—表
      type: Array,
      value: [],
    },
    items: {
      // äºŒçº§èœå• åˆ—表
      type: Array,
      value: [],
    }
  },
  data: {
    selectedIndex: [0, 0],
    tempSelectedIndex: [0, 0]
  },
  methods: {
    _groupChange(e) {
      // æ”¯æŒ ä¸€ç»´æ•°ç»„ å†™æ³•
      if (e.length > 0 && typeof e[0] !== 'string' && !(e[0] instanceof Array)) {
        this.setData({
          actions: [this.data.actions]
        });
      }
    },
    buttonTap(e) {
      const {
        value,
        groupindex,
        index
      } = e.currentTarget.dataset;
      this.triggerEvent('actiontap', {
        value,
        groupindex,
        index
      });
    },
    closeActionSheet(e) {
      this.setData({
        tempSelectedIndex: this.data.selectedIndex
      })
      const {
        type
      } = e.currentTarget.dataset;
      if (this.data.maskClosable || type) {
        // ç‚¹å‡» action é‡Œé¢çš„ å–消
        this.setData({
          show: false
        }); // å…³é—­å›žè°ƒäº‹ä»¶
        this.triggerEvent('close');
      }
    },
    chooseMenu(e) {
      const {
        index
      } = e.currentTarget.dataset;
      this.setData({
        tempSelectedIndex: [index, 0]
      })
    },
    chooseItem(e) {
      const {
        index
      } = e.currentTarget.dataset;
      this.setData({
        'tempSelectedIndex[1]': index
      })
    },
    submit() {
      this.setData({
        selectedIndex: this.data.tempSelectedIndex
      })
      this.triggerEvent('submit', this.data.selectedIndex);
      this.setData({
        show: false
      });
    }
  }
})
component/sidebar/sidebar.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
{
  "component": true,
  "usingComponents": {
    "mp-icon": "../icon/icon"
  }
}
component/sidebar/sidebar.wxml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
<wxs module="utils">
  var join = function (a, b) {
    return a + b
  };
  var isNotSlot = function (v) {
    return typeof v !== 'string'
  }
  module.exports = {
    join: join,
    isNotSlot: isNotSlot
  }
</wxs>
<view wx:if="{{mask}}" class="fyui-mask {{show ? '' : 'fyui-mask_hidden'}} {{maskClass}}" bindtap="closeActionSheet"></view>
<view class="fyui-sidebar {{show ? 'fyui-sidebar_toggle' : ''}} {{extClass}}">
  <view class="fyui-sidebar__menu">
    <block wx:for="{{menus}}" wx:key="index">
      <view class="{{index == tempSelectedIndex[0] ? 'selected' : ''}}" bindtap="chooseMenu" data-index="{{index}}">{{item.name}}</view>
    </block>
  </view>
  <view class="fyui-sidebar__content">
    <block wx:for="{{items[tempSelectedIndex[0]]}}" wx:key="index">
      <view class="{{index == tempSelectedIndex[1] ? 'selected' : ''}}" bindtap="chooseItem" data-index="{{index}}">{{item.name}}</view>
    </block>
  </view>
  <view class="fyui-sidebar__check">
    <!-- <mp-icon bindtap="submit" icon="done" size="{{30}}" color="white" extClass="fyui-sidebar__check_btn"></mp-icon>
    <mp-icon bindtap="closeActionSheet" icon="close" size="{{30}}" color="white" extClass="fyui-sidebar__check_btn"></mp-icon> -->
    <view class="submit" bindtap="submit">确定</view>
    <view class="submit submit_cancel" bindtap="closeActionSheet">取消</view>
  </view>
</view>
component/sidebar/sidebar.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
.fyui-mask.fyui-mask_hidden {
  opacity: 0;
  transform: scale3d(1, 1, 0)
}
.fyui-mask {
  opacity: 1;
  transform: scale3d(1, 1, 1);
  transition: all .3s
}
.fyui-sidebar {
  position: fixed;
  left: 0;
  top: 0;
  -webkit-transform: translateX(-100%);
  transform: translateX(-100%);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  z-index: 5000;
  /* min-width: 60%; */
  height: 100%;
  background-color: var(--fyui-BG_1);
  -webkit-transition: -webkit-transform .3s;
  transition: -webkit-transform .3s;
  transition: transform .3s;
  transition: transform .3s, -webkit-transform .3s;
  border-bottom-right-radius: 12px;
  border-top-right-radius: 12px;
  overflow: hidden;
  /* background-color: rgb(136, 136, 136); */
  display: flex;
}
.fyui-sidebar_toggle {
  -webkit-transform: translate(0);
  transform: translate(0)
}
.fyui-sidebar__menu {
  font-size: 14px;
  border-right: 1px solid var(--fyui-text-color_3);
}
.fyui-sidebar__menu>view{
  /* width: 20%; */
  text-align: center;
  padding: 8px 16px;
  overflow: hidden;
  overflow-y: auto;
}
.fyui-sidebar__content {
  position: relative;
  display: block;
  font-size: 14px;
}
.fyui-sidebar__content>view{
  display: block;
  width: 100%;
  /* text-align: center; */
  padding: 8px 16px;
  margin-right: 40px;
  /* background-color: teal; */
}
.selected {
  background-color: #1cebc5;
  color: white;
}
.fyui-sidebar__check {
  background-color: var(--fyui-BG_1);
  display: flex;
  flex-direction: column;
  padding-bottom: 40px;
  padding-bottom: calc(40px + constant(safe-area-inset-bottom));
  padding-bottom: calc(40px + env(safe-area-inset-bottom));
  z-index: 6000;
}
.fyui-sidebar__check>mp-icon {
  background-color: #1cebc5;
  margin-bottom: 8px;
  border-radius: 50%;
  padding: 16px;
}
.submit_cancel {
  background: linear-gradient(to right, #b3b3b3, #b3b3b3);
}
component/switchtab/switchtab.js
@@ -42,19 +42,22 @@
      let that = this;
      let query = this.createSelectorQuery(); //必须要先创建一个查询
      query.select(element).boundingClientRect(function (rect) {
        if (that.data.pageheight) {
          let pageheight = that.data.pageheight.split('px')[0]
          pageheight = parseInt(pageheight)
          if (rect.height > pageheight) {
        // if (that.data.pageheight) {
        //   let pageheight = that.data.pageheight.split('px')[0]
        //   pageheight = parseInt(pageheight)
        //   if (rect.height > pageheight) {
        //     that.setData({
        //       pageheight: rect.height + 'px'
        //     });
        //   }
        // } else {
        //   that.setData({
        //     pageheight: rect.height + 'px'
        //   });
        // }
            that.setData({
              pageheight: rect.height + 'px'
            });
          }
        } else {
          that.setData({
            pageheight: rect.height + 'px'
          });
        }
      }).exec();
    },
    swichNav: function (e) {
pages/gradereport/gradereport.js
@@ -247,7 +247,7 @@
                if (app.globalData.userInfo.extension2  === '1') {
                  const i = r.third.indexOf(',')
                  r.third = r.third.slice(i+1)
                  r.third = r.third.replace('ä½ ', '您')
                  r.third = r.third.replaceAll('ä½ ', '您')
                }
                p.itemlist.push({
                  ruleName: r.first,
pages/mine/mine.wxml
@@ -10,28 +10,49 @@
    </view>
  </view>
  <view class="page__bd">
    <view class="fyui-panel" bindtap="goto" data-index="1">
      <view class="fyui-cell fyui-cell_select title">
    <view class="fyui-panel">
      <view class="fyui-cell fyui-cell_select title" bindtap="goto" data-index="0">
        <view class="fyui-cell__hd">
          <image src="/res/icons/icon3.png" class="icon" />
        </view>
        <view class="fyui-cell__bd">企业认证</view>
        <view class="fyui-cell__ft"></view>
      </view>
      <view class="fyui-cell fyui-cell_select title">
      <view class="fyui-cell fyui-cell_select title" bindtap="goto" data-index="1">
        <view class="fyui-cell__hd">
          <image src="/res/icons/icon4.png" class="icon" />
        </view>
        <view class="fyui-cell__bd">通知管理</view>
        <view class="fyui-cell__ft"></view>
      </view>
      <view class="fyui-cell fyui-cell_select title">
      <view class="fyui-cell fyui-cell_select title" bindtap="goto" data-index="2">
        <view class="fyui-cell__hd">
          <image src="/res/icons/icon5.png" class="icon" />
        </view>
        <view class="fyui-cell__bd">问题反馈</view>
        <view class="fyui-cell__ft"></view>
      </view>
      <view class="fyui-cell fyui-cell_select title" bindtap="goto" data-index="3">
        <view class="fyui-cell__hd">
          <image src="/res/icons/icon5.png" class="icon" />
        </view>
        <view class="fyui-cell__bd">我的收藏</view>
        <view class="fyui-cell__ft"></view>
      </view>
      <view class="fyui-cell fyui-cell_select title" bindtap="goto" data-index="4">
        <view class="fyui-cell__hd">
          <image src="/res/icons/icon5.png" class="icon" />
        </view>
        <view class="fyui-cell__bd">我要咨询</view>
        <view class="fyui-cell__ft"></view>
      </view>
      <view class="fyui-cell fyui-cell_select title" bindtap="goto" data-index="5">
        <view class="fyui-cell__hd">
          <image src="/res/icons/icon5.png" class="icon" />
        </view>
        <view class="fyui-cell__bd">环保日程</view>
        <view class="fyui-cell__ft"></view>
      </view>
    </view>
  </view>
pages/mine/mine.wxss
@@ -39,3 +39,7 @@
  font-size: 12px;
  color: var(--fyui-text-color_2);
}
.title:active {
  background-color: var(--fyui-BG-COLOR-ACTIVE);
}
pages/module_consult/consultdetailcase/consultdetailcase.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
// pages/module_consult/consultdetailcase/consultdetailcase.js
const consultservice = require("../../../service/consultservice")
const util = require("../../../utils/util")
const app = getApp()
Page({
  /**
   * é¡µé¢çš„初始数据
   */
  data: {
    showloading: false,
    case: {},
    caseTag: [],
    showDialog: false,
    groups: [
      'actionSlot1',
    ]
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面加载
   */
  onLoad(options) {
    var that = this
    this.getOpenerEventChannel().on('acceptDataFromOpenerPage', function (data) {
      that.setData({
        caseId: data.caseId
      })
      that.getCase()
    })
  },
  getCase() {
    this.setData({
      showloading: true
    })
    var that = this
    consultservice.getCase(app.globalData.accessToken.userId, this.data.caseId, {
      success(res) {
        let caseTag = []
        if (res.ecIsPunish) caseTag.push({icon: '/res/icons/cq_punish.png', name: '涉及行政处罚'})
        if (res.ecIsIllegal) caseTag.push({icon: '/res/icons/cq_illegal.png', name: '涉及刑事责任'})
        if (res.ecIsSupervise) caseTag.push({icon: '/res/icons/cq_supervise.png', name: '涉及环保督察要点'})
        if (res.ecIsShotspot) caseTag.push({icon: '/res/icons/cq_shotspot.png', name: '涉及环保管理热点'})
        if (res.ecIsMinor) caseTag.push({icon: '/res/icons/cq_minor.png', name: '涉及轻微违法'})
        if (res.ecIsDetained) caseTag.push({icon: '/res/icons/cq_detained.png', name: '涉及行政拘留'})
        res.ecSummary = res.ecSummary.replaceAll('\\n', '<br/>')
        res.ecMeaning = res.ecMeaning.replaceAll('\\n', '<br/>')
        res.ecExamined = res.ecExamined.replaceAll('\\n', '<br/>')
        res.ecEnlightenment = res.ecEnlightenment.replaceAll('\\n', '<br/>')
        res.ecOccurDate = util.formatTime(res.ecOccurDate)
        that.setData({
          case: res,
          caseTag
        })
        console.log(res);
      },
      complete(res) {
        that.setData({
          showloading: false
        })
      }
    })
  },
  openDialog: function () {
    this.setData({
      showDialog: true
    })
  },
  closeDialog: function () {
    this.setData({
      showDialog: false
    })
  },
  btnClick(e) {
    console.log(e)
    this.closeDialog()
  },
  previewImage(e) {
    const i = e.currentTarget.dataset.index
    // const img = this.data.case.ecAppendixUrl[i]
    const remark = this.data.case.ecAppendixText[i]
    const previewImageUrls = this.data.case.ecAppendixUrl;
    this.setData({
      previewImageUrls,
      remark,
      previewCurrent: 0,
      showPreview: true
    });
  },
})
pages/module_consult/consultdetailcase/consultdetailcase.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
{
  "navigationBarTitleText": "案例详情",
  "navigationBarBackgroundColor": "#57E4CB",
  "navigationBarTextStyle": "white",
  "usingComponents": {
    "mp-loading": "/component/loading/loading",
    "mp-actionSheet": "/component/actionsheet/actionsheet",
    "mp-icon": "/component/icon/icon",
    "my-gallery": "/component/mygallery/mygallery"
  }
}
pages/module_consult/consultdetailcase/consultdetailcase.wxml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
<!--pages/module_consult/consultdetailcase/consultdetailcase.wxml-->
<view class="page">
  <view class="page__hd">
    <view class="fyui-box  fyui-box__text">
      <view class="fyui-box__hd">
        <view>{{case.ecTitle}}</view>
      </view>
      <view class="fyui-box__bd">
        <view class="q-tag" bindtap="openDialog">
          <block wx:for="{{caseTag}}" wx:key="index">
            <image src="{{item.icon}}"></image>
          </block>
        </view>
      </view>
      <view class="fyui-box__ft" style="flex-direction: column;">
        <view class="flex-h" style="justify-content: flex-start;"><image class="image-16" src="/res/icons/locate.png"></image>案发地址:{{case.ecProvinceName + case.ecCityName}}</view>
        <view class="flex-h" style="justify-content: flex-start;"><image class="image-16" src="/res/icons/time.png"></image>案发时间:{{case.ecOccurDate}}</view>
      </view>
    </view>
  </view>
  <view class="page__bd">
    <view class="fyui-panel flex-h">
      <view class="flex-h" style="justify-content: flex-start;">
        <image class="image-16" src="/res/icons/case_forfeit.png"></image>
        ç½šæ¬¾æ•°é¢
      </view>
      <view style="color: red;">{{case.ecForfeit}}万元</view>
    </view>
    <view class="fyui-panel">
      <view>案例类别:{{case.ecType}}</view>
      <view>要素类别:{{case.ecEpItemType}}</view>
      <view>要素子类:{{case.ecEpItemSubtype}}</view>
    </view>
    <view class="fyui-panel">
      <view class="case-type">案情简介</view>
      <view class="case-image-group" wx:for="{{case.ecAppendixUrl}}" wx:key="index">
        <image src="{{item}}" mode="widthFix" bindtap="previewImage" data-index="{{index}}"></image>
        <view>{{case.ecAppendixText[index]}}</view>
      </view>
      <rich-text nodes="{{case.ecSummary}}"></rich-text>
    </view>
    <view class="fyui-panel" style="background-color: #FFF8DE;">
      <view class="case-type" style="background-color: #FFEBA6;">查处情况</view>
      <rich-text nodes="{{case.ecExamined}}"></rich-text>
    </view>
    <view class="fyui-panel" style="background-color: #E6F6FC;">
      <view class="case-type" style="background-color: #AFEAFD;">案例意义</view>
      <rich-text nodes="{{case.ecMeaning}}"></rich-text>
    </view>
    <view class="fyui-panel" style="background-color: #E6FCF4;">
      <view class="case-type" style="background-color: #AAFFE0;">案件启示</view>
      <rich-text nodes="{{case.ecEnlightenment}}"></rich-text>
    </view>
    <view class="fyui-panel q-link-group">
      <view wx:if="{{case.ecIsAssociated}}" class="q-link">
        <image src="/res/icons/link_1.png"></image>
        ç›¸å…³æ¡ç›®
      </view>
    </view>
  </view>
  <view class="page__ft">
    <mp-loading duration="{{900}}" type="dot-gray" show="{{showloading}}" animated="{{true}}"></mp-loading>
  </view>
  <mp-actionSheet bindactiontap="btnClick" show="{{showDialog}}" actions="{{groups}}" showCancel="{{false}}">
    <view slot="{{'actionSlot' + '1'}}" class="custom-action">
      <image class="custom-action__bg" src="/res/icons/bg_star.png"></image>
      <block wx:for="{{caseTag}}" wx:key="index">
        <view class="custom-action__tag" style="{{questionTag.length == 1 ? 'flex: 1;' : ''}}">
          <image src="{{item.icon}}"></image>
          <view>{{item.name}}</view>
        </view>
      </block>
    </view>
  </mp-actionSheet>
  <my-gallery hide-on-click="{{true}}" show-delete="{{false}}" show="{{showPreview}}" img-urls="{{previewImageUrls}}" current="{{previewCurrent}}" remark="{{remark}}"></my-gallery>
</view>
pages/module_consult/consultdetailcase/consultdetailcase.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
/* pages/module_consult/consultdetailcase/consultdetailcase.wxss */
.page__hd {
  padding: 0;
}
.fyui-box .fyui-box__hd {
  display: flex;
}
.q-tag {
  display: flex;
  justify-content: flex-end;
}
.q-tag>image {
  width: 16px;
  height: 16px;
  /* background-color: red; */
  padding: 4px;
}
.q-link-group {
  display: flex;
}
.q-link{
  display: flex;
  align-items: center;
  background-color: #CFFFF7;
  color: #25D4B6;
  padding: 6px 8px;
  border-radius: 6px;
}
.q-link>image{
  width: 16px;
  height: 16px;
}
.fyui-box__bd {
  margin-top: 8px;
  font-size: 14px;
}
.custom-action {
  position: relative;
  min-height: 40vh;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
}
.custom-action__bg{
  position: absolute;
  top: 0;
  left: 0;
}
.custom-action__tag{
  font-size: 14px;
  color: var(--fyui-text-color_1);
  font-weight: 600;
  width: 50%;
  text-align: center;
  z-index: 2;
}
.custom-action__tag>image{
  width: 64px;
  height: 64px;
}
.fyui-panel {
  margin: 10px 0 0 0 ;
  padding: 10px 16px;
  font-size: 14px;
  border-radius: 0;
}
.case-type {
  display: inline-block;
  border-radius: 8px;
  background-color: #F6F6F6;
  padding: 4px 12px;
  font-size: 14px;
  margin-bottom: 4px;
}
.case-image-group {
  /* display: flex;
  flex-direction: column;
  justify-content: flex-start; */
}
.case-image-group>image {
  width: 100%;
}
.case-image-group>view {
  font-size: 12px;
  text-align: center;
  color: var(--fyui-text-color_3);
  margin-bottom: 8px;
}
pages/module_consult/consultdetailitem/consultdetailitem.js
@@ -56,7 +56,7 @@
      success (res) {
        let result = that.data.result
        res.forEach(r => {
          r.des = r.des.replace('\\n', '<br/>')
          r.des = r.des.replaceAll('\\n', '<br/>')
          if (result.length === 0) {
            result.push({
              typeId: r.typeId,
@@ -92,7 +92,7 @@
    }, 20000);
    consultservice.getMgtItem(app.globalData.accessToken.userId, this.data.itemId, {
      success (res) {
        res.miItemContent = res.miItemContent.replace('\\n', '<br/>')
        res.miItemContent = res.miItemContent.replaceAll('\\n', '<br/>')
        that.setData({
          content: res
        })
pages/module_consult/consultdetailqa/consultdetailqa.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
// pages/module_consult/consultdetailqa/consultdetailqa.js
const consultservice = require("../../../service/consultservice")
const app = getApp()
Page({
  /**
   * é¡µé¢çš„初始数据
   */
  data: {
    showloading: false,
    question: {},
    //问题涉及的项目
    questionTag: [{
      icon: '',
      name: ''
    }],
    answers: [],
    showDialog: false,
    groups: [
      'actionSlot1',
      // { text: '示例菜单', value: 1 },
      // { text: '示例菜单', value: 2 },
      // { text: '负向菜单', type: 'warn', value: 3 }
    ]
},
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面加载
   */
  onLoad(options) {
    var that = this
    this.getOpenerEventChannel().on('acceptDataFromOpenerPage', function (data) {
      that.setData({
        qId: data.qId
      })
      that.getQuestion()
      that.getAnswers()
    })
  },
  getQuestion() {
    this.setData({
      showloading: true
    })
    var that = this
    consultservice.getQuestion(app.globalData.accessToken.userId, this.data.qId, {
      success(res) {
        let questionTag = []
        if (res.cqIsPunish) questionTag.push({icon: '/res/icons/cq_punish.png', name: '涉及行政处罚'})
        if (res.cqIsIllegal) questionTag.push({icon: '/res/icons/cq_illegal.png', name: '涉及刑事责任'})
        if (res.cqIsSupervise) questionTag.push({icon: '/res/icons/cq_supervise.png', name: '涉及环保督察要点'})
        if (res.cqIsShotspot) questionTag.push({icon: '/res/icons/cq_shotspot.png', name: '涉及环保管理热点'})
        that.setData({
          question: res,
          questionTag
        })
        console.log(res);
      },
      complete(res) {
        that.setData({
          showloading: false
        })
      }
    })
  },
  getAnswers() {
    this.setData({
      showloading: true
    })
    var that = this
    consultservice.getAnswers(app.globalData.accessToken.userId, this.data.qId, {
      success(res) {
        res.forEach(r => {
          r.saContent = r.saContent.replaceAll('\\n', '<br/>')
        });
        that.setData({
          answers: res
        })
        console.log(res);
      },
      complete(res) {
        that.setData({
          showloading: false
        })
      }
    })
  },
  openDialog: function () {
    this.setData({
      showDialog: true
    })
  },
  closeDialog: function () {
    this.setData({
      showDialog: false
    })
  },
  btnClick(e) {
    console.log(e)
    this.closeDialog()
  }
})
pages/module_consult/consultdetailqa/consultdetailqa.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
{
  "navigationBarTitleText": "环保问答",
  "navigationBarBackgroundColor": "#57E4CB",
  "navigationBarTextStyle": "white",
  "usingComponents": {
    "mp-loading": "/component/loading/loading",
    "mp-actionSheet": "/component/actionsheet/actionsheet",
    "mp-icon": "/component/icon/icon"
  }
}
pages/module_consult/consultdetailqa/consultdetailqa.wxml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
<!--pages/module_consult/consultdetailqa/consultdetailqa.wxml-->
<view class="page">
  <view class="page__hd">
    <view class="fyui-box  fyui-box__text">
      <view class="fyui-box__hd">
        <view>{{question.cqContent}}</view>
      </view>
      <view class="fyui-box__bd">
        <view class="q-tag" bindtap="openDialog">
          <block wx:for="{{questionTag}}" wx:key="index">
            <image src="{{item.icon}}"></image>
          </block>
          <!-- <image wx:if="{{question.cqIsPunish}}" src="/res/icons/cq_punish.png"></image>
          <image wx:if="{{question.cqIsIllegal}}" src="/res/icons/cq_illegal.png"></image>
          <image wx:if="{{question.cqIsSupervise}}" src="/res/icons/cq_supervise.png"></image>
          <image wx:if="{{question.cqIsShotspot}}" src="/res/icons/cq_shotspot.png"></image> -->
        </view>
      </view>
      <view class="fyui-box__ft" style="flex-direction: column;">
        <view>共{{answers.length}}条回答</view>
        <view class="q-link-group">
          <view wx:if="{{question.cqIsAssociated}}" class="q-link">
            <image src="/res/icons/link_1.png"></image>
            ç›¸å…³æ¡ç›®
          </view>
        </view>
      </view>
    </view>
  </view>
  <view class="page__bd">
    <block wx:for="{{answers}}" wx:for-index="index" wx:key="index">
      <view class="fyui-box  fyui-box__text">
        <view class="fyui-box__hd">
          <image class="user-avator" src="/res/icons/con_qa.png"></image>
          <view>
            <view class="user-name">环保智能助手</view>
            <view class="user-tag">环保智能助手</view>
          </view>
        </view>
        <view class="fyui-box__bd">
          <!-- <view class="fyui-box__content tag">相关行业 -> {{item.fileIndustry}}</view> -->
          <rich-text nodes="{{item.saContent}}" class=""></rich-text>
        </view>
        <view class="a-tag-group">
          <view class="a-tag">
            <image class="image-16" src="/res/icons/favourite.png"></image>156
          </view>
          <view class="a-tag">
            <image class="image-16" src="/res/icons/like.png"></image>156
          </view>
        </view>
      </view>
      <view wx:if="{{index < answers.length - 1}}" class="next-answer"></view>
      <view wx:else class="next-answer">——到底了——</view>
    </block>
  </view>
  <view class="page__ft">
    <mp-loading duration="{{900}}" type="dot-gray" show="{{showloading}}" animated="{{true}}"></mp-loading>
  </view>
  <mp-actionSheet bindactiontap="btnClick" show="{{showDialog}}" actions="{{groups}}" showCancel="{{false}}">
    <view slot="{{'actionSlot' + '1'}}" class="custom-action">
      <image class="custom-action__bg" src="/res/icons/bg_star.png"></image>
      <block wx:for="{{questionTag}}" wx:key="index">
        <view class="custom-action__tag" style="{{questionTag.length == 1 ? 'flex: 1;' : ''}}">
          <image src="{{item.icon}}"></image>
          <view>{{item.name}}</view>
        </view>
      </block>
    </view>
  </mp-actionSheet>
</view>
pages/module_consult/consultdetailqa/consultdetailqa.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,114 @@
/* pages/module_consult/consultdetailqa/consultdetailqa.wxss */
.page__hd {
  padding: 0;
}
.fyui-box .fyui-box__hd {
  display: flex;
}
.q-tag {
  display: flex;
  justify-content: flex-end;
}
.q-tag>image {
  width: 16px;
  height: 16px;
  /* background-color: red; */
  padding: 4px;
}
.q-link-group {
  display: flex;
  justify-content: flex-end;
}
.q-link{
  display: flex;
  align-items: center;
  background-color: #CFFFF7;
  color: #25D4B6;
  padding: 6px 8px;
  border-radius: 6px;
}
.q-link>image{
  width: 16px;
  height: 16px;
}
.fyui-box .fyui-box__hd .user-avator{
  width: 36px;
  height: 36px;
  border-radius: 50%;
}
.fyui-box .fyui-box__hd .user-name{
  margin-left: 8px;
  font-size: 14px;
  font-weight: 500;
  color: var(--fyui-text-color_1);
}
.user-tag {
  margin-left: 8px;
  font-size: 10px;
  font-weight: 100;
  color: var(--fyui-text-color_2);
}
.fyui-box__bd {
  margin-top: 8px;
  font-size: 14px;
}
.next-answer {
  text-align: center;
  font-size: 12px;
  color: var(--fyui-text-color_3);
  padding: 8px;
}
.a-tag-group {
  display: flex;
  justify-content: flex-end;
  color: var(--fyui-text-color_3);
  font-size: 12px;
}
.a-tag {
  display: flex;
  align-items: center;
  line-height: 20px;
  margin-left: 8px;
}
.custom-action {
  position: relative;
  min-height: 40vh;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
}
.custom-action__bg{
  position: absolute;
  top: 0;
  left: 0;
}
.custom-action__tag{
  font-size: 14px;
  color: var(--fyui-text-color_1);
  font-weight: 600;
  width: 50%;
  text-align: center;
  z-index: 2;
}
.custom-action__tag>image{
  width: 64px;
  height: 64px;
}
pages/module_consult/consulthome/consulthome.js
@@ -22,6 +22,9 @@
      name: '条目',
      tag: 0
    }, {
      name: '问答',
      tag: 0
    }, {
      name: '案例',
      tag: 0
    }],
@@ -31,7 +34,11 @@
      [],
      [],
      [],
    ]
      [],
    ],
    //案例所涉及的要点
    caseTag: []
  },
  /**
@@ -39,7 +46,6 @@
   */
  onLoad: function (options) {
    this.getHotTopic()
    this.getTopicItem()
  },
  /**
@@ -56,12 +62,14 @@
  },
  // æœç´¢
  gotoSearch() {
    wx.navigateTo({
      url: "/pages/module_consult/consultsearch/consultsearch"
    })
  },
  // åŠŸèƒ½æŒ‰é’®
  goto(e) {
    var url = ""
    var index = e.currentTarget.dataset.index
@@ -95,13 +103,14 @@
   */
  getHotTopic() {
    var that = this
    // 1. çƒ­é—¨æ³•律法规
    consultservice.getTopicLaw(app.globalData.accessToken.userId, {
      success(res) {
        res.forEach(r => {
          r.mfKeywordLv1 = r.mfKeywordLv1.split('、').slice(0, 5)
          r.mfReleaseDate = that.formateTime(r.mfReleaseDate)
          r.mfEffectiveDate = that.formateTime(r.mfEffectiveDate)
          r.mfClosingDate = that.formateTime(r.mfClosingDate)
          r.mfReleaseDate = that.formatTime(r.mfReleaseDate)
          r.mfEffectiveDate = that.formatTime(r.mfEffectiveDate)
          r.mfClosingDate = that.formatTime(r.mfClosingDate)
        });
        that.setData({
          'pageList[0]': res,
@@ -109,27 +118,48 @@
        })
      }
    })
  },
  getTopicItem() {
    var that = this
    // 2. çƒ­é—¨æ³•律法规条目
    consultservice.getTopicItem(app.globalData.accessToken.userId, {
      success(res) {
        res.forEach(r => {
          r.miItemContent = r.miItemContent.replace('\\n', '<br/>')
          // r.mfKeywordLv1 = r.mfKeywordLv1.split('、').slice(0, 5)
          // r.mfReleaseDate = that.formateTime(r.mfReleaseDate)
          // r.mfEffectiveDate = that.formateTime(r.mfEffectiveDate)
          // r.mfClosingDate = that.formateTime(r.mfClosingDate)
          r.miItemContent = r.miItemContent.replaceAll('\\n', '<br/>')
        });
        that.setData({
          'pageList[2]': res
        })
      }
    })
    // 3. çƒ­é—¨é—®ç­”
    consultservice.getTopicQA(app.globalData.accessToken.userId, {
      success(res) {
        res.forEach(r => {
          r.cqCreateTime = that.formatTime(r.cqCreateTime)
        });
        that.setData({
          'pageList[3]': res
        })
      }
    })
    // 4. çƒ­é—¨æ¡ˆä¾‹
    consultservice.getTopicCase(app.globalData.accessToken.userId, {
      success(res) {
        res.forEach(r => {
          r.ecSummary = r.ecSummary.replaceAll('\\n', '<br/>')
          r.ecMeaning = r.ecMeaning.replaceAll('\\n', '<br/>')
          r.ecExamined = r.ecExamined.replaceAll('\\n', '<br/>')
          r.ecEnlightenment = r.ecEnlightenment.replaceAll('\\n', '<br/>')
          r.ecOccurDate = that.formatTime(r.ecOccurDate)
        });
        that.setData({
          'pageList[4]': res
        })
        console.log(that.data.pageList);
      }
    })
  },
  // åŽ»å¾€æ–‡ä»¶è¯¦æƒ…
  gotoFile(e) {
    const iList = e.currentTarget.dataset.index.split(',')
    const i1 = iList[0]
@@ -146,6 +176,7 @@
    })
  },
  // åŽ»å¾€æ¡ç›®è¯¦æƒ…
  gotoItem(e) {
    const iList = e.currentTarget.dataset.index.split(',')
    const i1 = iList[0]
@@ -162,9 +193,43 @@
    })
  },
  formateTime(t) {
  // åŽ»å¾€é—®ç­”è¯¦æƒ…
  gotoQA(e) {
    const iList = e.currentTarget.dataset.index.split(',')
    const i1 = iList[0]
    const i2 = iList[1]
    var qId = this.data.pageList[i1][i2].cqGuid
    wx.navigateTo({
      url: '/pages/module_consult/consultdetailqa/consultdetailqa',
      success: (res) => {
        // é€šè¿‡ eventChannel å‘被打开页面传送数据
        res.eventChannel.emit('acceptDataFromOpenerPage', {
          qId: qId
        })
      },
    })
  },
  // åŽ»å¾€æ¡ˆä¾‹è¯¦æƒ…
  gotoCase(e) {
    const iList = e.currentTarget.dataset.index.split(',')
    const i1 = iList[0]
    const i2 = iList[1]
    var caseId = this.data.pageList[i1][i2].ecGuid
    wx.navigateTo({
      url: '/pages/module_consult/consultdetailcase/consultdetailcase',
      success: (res) => {
        // é€šè¿‡ eventChannel å‘被打开页面传送数据
        res.eventChannel.emit('acceptDataFromOpenerPage', {
          caseId: caseId
        })
      },
    })
  },
  formatTime(t) {
    if (t) {
      return moment(t).format("YYYYå¹´MM月DD日")
      return moment(t).format("YYYY.MM.DD")
    } else {
      return undefined
    }
pages/module_consult/consulthome/consulthome.wxml
@@ -60,7 +60,7 @@
            </view>
          </block>
          <block wx:else="{{i1 == 2}}">
          <block wx:elif="{{i1 == 2}}">
            <view wx:for="{{page}}" wx:key="i2" wx:for-index="i2" data-index="{{i1}},{{i2}}" bindtap="gotoItem">
              <view class="fyui-box  fyui-box__text">
                <view class="fyui-box__hd">
@@ -82,6 +82,76 @@
              </view>
            </view>
          </block>
          <block wx:elif="{{i1 == 3}}">
            <view wx:for="{{page}}" wx:key="i2" wx:for-index="i2" data-index="{{i1}},{{i2}}" bindtap="gotoQA">
              <view class="fyui-box  fyui-box__text">
                <view class="fyui-box__hd">
                  <text class="fyui-box__content des subtitle">{{item.cqContent}}</text>
                </view>
                <view class="fyui-box__bd answer">
                  <!-- <view class="fyui-box__content tag">相关行业 -> {{item.fileIndustry}}</view> -->
                  <view class="tag2">答:</view>
                  <rich-text class="tag2 des" nodes="{{item.answer}}"></rich-text>
                </view>
                <view class="fyui-box__ft">
                  <text class="tag3">提问时间:{{item.cqCreateTime}}</text>
                  <text class="tag3">回复时间:{{item.cqCreateTime}}</text>
                  <!-- <text class="keyword">关键词:</text>
                <view class="keyword-item"><text wx:for="{{item.keywords}}" wx:for-index="i" wx:for-item="word" wx:key="i">{{word}}</text></view> -->
                </view>
              </view>
            </view>
          </block>
          <block wx:elif="{{i1 == 4}}">
            <view wx:for="{{page}}" wx:key="i2" wx:for-index="i2" data-index="{{i1}},{{i2}}" bindtap="gotoCase">
              <view class="fyui-box fyui-box__text">
                <view class="fyui-box__hd">
                  <text class="fyui-box__content des subtitle">{{item.ecTitle}}</text>
                </view>
                <view class="fyui-box__bd">
                  <view class="case-bd">
                    <rich-text class="tag2 des" nodes="{{item.ecSummary}}"></rich-text>
                    <image wx:if="{{item.ecAppendixUrl.length > 0}}" src="{{item.ecAppendixUrl[0]}}" mode="aspectFill"></image>
                  </view>
                </view>
                <view class="fyui-box__ft">
                  <text class="tag3">案发地址:{{item.ecProvinceName + item.ecCityName}}</text>
                  <text class="tag3">案发时间:{{item.ecOccurDate}}</text>
                </view>
                <view class="fyui-box__ft_2">
                  <view style="white-space: nowrap;">涉及:</view>
                  <view class="case-tag-group">
                    <view class="case-tag" wx:if="{{item.ecIsPunish}}">
                      <image src="/res/icons/cq_punish.png"></image>
                      <text>行政处罚</text>
                    </view>
                    <view class="case-tag" wx:if="{{item.ecIsDetained}}">
                      <image src="/res/icons/cq_detained.png"></image>
                      <text>行政拘留</text>
                    </view>
                    <view class="case-tag" wx:if="{{item.ecIsIllegal}}">
                      <image src="/res/icons/cq_illegal.png"></image>
                      <text>刑事责任</text>
                    </view>
                    <view class="case-tag" wx:if="{{item.ecIsShotspot}}">
                      <image src="/res/icons/cq_shotspot.png"></image>
                      <text>环保热点</text>
                    </view>
                    <view class="case-tag" wx:if="{{item.ecIsSupervise}}">
                      <image src="/res/icons/cq_supervise.png"></image>
                      <text>督察要点</text>
                    </view>
                    <view class="case-tag" wx:if="{{item.ecIsMinor}}">
                      <image src="/res/icons/cq_minor.png"></image>
                      <text>轻微违法</text>
                    </view>
                  </view>
                </view>
              </view>
            </view>
          </block>
        </block>
        <view wx:else class="page__ft">
pages/module_consult/consulthome/consulthome.wxss
@@ -77,7 +77,7 @@
.des {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  -webkit-line-clamp: 3;
  width: 100%;
  overflow: hidden;
  /* text-overflow: ellipsis; */
@@ -88,11 +88,61 @@
  font-size: 14px;
}
.fyui-box .answer {
  display: flex;
  flex-direction: row;
  /* justify-content: space-between; */
  /* background-color: red; */
}
.subtitle{
  font-size: 15px;
}
.tag2{
  line-height: 18px;
  font-size: 12px;
  color: var(--fyui-text-color_3);
}
.fyui-box__text .fyui-box__ft {
  font-size: 12px;
}
.case-bd{
  display: flex;
}
.case-bd>image{
  width: 60%;
  height: 54px;
  border-radius: 4px;
  margin-left: 4px;
}
.fyui-box__ft_2 {
  display: flex;
  font-size: 12px;
  color: var(--fyui-text-color_3);
  margin-top: 16px;
}
.case-tag-group {
  display: flex;
  flex-wrap: wrap;
}
.case-tag {
  display: flex;
  align-items: center;
}
.case-tag>image {
  width: 14px;
  height: 14px;
}
.case-tag>text {
  white-space: nowrap;
  margin-left: 4px;
  margin-right: 4px;
}
pages/module_consult/consultonline/consultonline.wxml
@@ -1,7 +1,7 @@
<!--pages/module_consult/consultonline/consultonline.wxml-->
<view class="consult-record">
  <block wx:for="{{record}}">
    <view wx:if="{{userId == item.userId}}" class="consult-record_item_user">
    <view wx:if="{{userId == item.userId}}" wx:key="index" class="consult-record_item_user">
      <view class="consult-text_user">{{item.text}}</view>
    </view>
    <view wx:else class="consult-record_item">
pages/module_consult/consultproblem/consultproblem.js
@@ -1,111 +1,228 @@
// pages/module_consult/consultproblem/consultproblem.js
const consultservice = require("../../../service/consultservice")
const util = require("../../../utils/util")
const app = getApp()
Page({
  /**
   * é¡µé¢çš„初始数据
   */
  data: {
    problemTypes: ['危废转移','企业排污','排污纳管','设备维护','设备安装','废气治理','固废转移','更多 >'],
    selectedIndex: 0,
    loading: false,
    menus: [
      { name: '大气', value: 1 },
      { name: 'æ°´', value: 2 },
      { name: '海洋', value: 3 },
      { name: '土壤', value: 4 },
      { name: '噪声', value: 5 },
      { name: '光', value: 6 },
      { name: '辐射', value: 7 },
      { name: 'æ ¸', value: 8 },
      { name: '固体废物', value: 9 },
      { name: '化学品', value: 10 },
      { name: '台账', value: 21 },
      { name: '执法', value: 31 },
      { name: '督察', value: 41 },
      { name: '监测', value: 51 },
      { name: '服务', value: 61 },
      { name: '其他', value: 99 }
    ],
    items: [
      [
        { name: 'PM', value: 1  },
        { name: 'NOX', value: 2  },
        { name: 'O3', value: 3  },
        { name: 'VOCs', value: 4  },
        { name: '工业废气', value: 5  },
        { name: '机动车尾气', value: 6  },
        { name: '扬尘', value: 7  },
        { name: '餐饮油烟', value: 8  },
        { name: '恶臭', value: 9  },
        { name: '其他', value: 99 },
      ],
      [
        { name: '地表水', value: 1  },
        { name: '地下水', value: 2  },
        { name: '饮用水', value: 3  },
        { name: '工业废水', value: 4  },
        { name: '生活污水', value: 5  },
        { name: '商业污水', value: 6  },
        { name: '其他', value: 99  },
      ],
      [
        { name: '石油及其产品', value: 1  },
        { name: '重金属和酸碱', value: 2  },
        { name: '农药', value: 3  },
        { name: '有机物质和营养盐类', value: 4  },
        { name: '放射性核素', value: 5  },
        { name: '固体废物', value: 6  },
        { name: '废热', value: 7  },
        { name: '其他', value: 99  },
      ],
      [
        { name: '农田耕地', value: 1  },
        { name: '工业企业用地', value: 2  },
        { name: '石油开采用地', value: 3  },
        { name: '矿山开采用地', value: 4  },
        { name: '其他', value: 99  },
      ],
      [
        { name: '工业生产噪声', value: 1  },
        { name: '交通运输噪声', value: 2  },
        { name: '建筑施工噪声', value: 3  },
        { name: '社会生活噪声', value: 4  },
        { name: '其他', value: 99  },
      ],
      [
        { name: '白亮污染', value: 1  },
        { name: '人工白昼污染', value: 2  },
        { name: '彩光污染', value: 3  },
        { name: '其他', value: 99  },
      ],
      [
        { name: '电磁辐射', value: 1  },
        { name: '放射性辐射', value: 2  },
        { name: '其他', value: 99  },
      ],
      [],
      [],
      [],
      [],
      [],
      [],
      [],
      [],
    ],
    selected: [{
      name: '全部',
      value: null
    },{
      name: '全部',
      value: null
    }],
    problems: [
      [
        {
          q: '企业危废转移联单过期的补办流程?',
          a: [{
            text: '企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下',
            author: 'NickName',
            time: '2022-05-03'
          },{
            text: '企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下',
            author: 'NickName',
            time: '2022-05-03'
          }],
          viewed: 120,
          like: 123,
          favorite: 50
        },
        {
          q: '企业危废转移联单过期的补办流程?',
          a: [{
            text: '企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下',
            author: 'NickName',
            time: '2022-05-03'
          }],
          viewed: 120,
          like: 123,
          favorite: 50
        },
        {
          q: '企业危废转移联单过期的补办流程?',
          a: [{
            text: '企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下',
            author: 'NickName',
            time: '2022-05-03'
          }],
          viewed: 120,
          like: 123,
          favorite: 50
        },
        {
          q: '企业危废转移联单过期的补办流程?',
          a: [{
            text: '企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下',
            author: 'NickName',
            time: '2022-05-03'
          }],
          viewed: 120,
          like: 123,
          favorite: 50
        },
      ],
      [
        {
          q: '企业危废转移联单过期的补办流程?',
          a: [{
            text: '企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下',
            author: 'NickName',
            time: '2022-05-03'
          },{
            text: '企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下企业危废转移联单过期的补办流程如下',
            author: 'NickName',
            time: '2022-05-03'
          }],
          viewed: 120,
          like: 123,
          favorite: 50
        },
      ],
    ],
    problemIndex: 0,
    questions: []
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面加载
   */
  onLoad(options) {
    this.getQuestionsByType(1)
    this.getEnElementTypes()
    this.getEnElementSubTypes()
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面初次渲染完成
   */
  onReady() {
  getQuestionsByType(page = 1) {
    this.setData({loading: true})
    setTimeout(() => {
      this.setData({loading: false})
    }, 100000);
    var that = this
    consultservice.getQuestionsByType(
      app.globalData.accessToken.userId,
      this.data.selected[0].value, this.data.selected[1].value,
      page, 10, {
        onPage(head) {
          that.cPage = head.page
          that.tPage = head.totalPage
          that.setData({
            totalCount: head.totalCount
          })
  },
  selectProblemType(e) {
    const selectedIndex = e.currentTarget.dataset.index
    this.setData({selectedIndex})
    this.getProblems()
  },
  getProblems() {
    let index = this.data.selectedIndex
    let length = this.data.problems.length
    let problemIndex = index % length
    this.setData({problemIndex})
    console.log(problemIndex);
        success(res) {
          res.forEach(r => {
            r.cqCreateTime = util.formatTime(r.cqCreateTime)
            r.answer = r.answer.replaceAll('\\n', '<br/>')
          });
          let questions = that.data.questions
          if (page == 1) {
            questions = []
  }
          questions = questions.concat(res)
          that.setData({questions})
        },
        complete(e) {
          that.setData({loading: false})
        }
      })
  },
  getEnElementTypes() {
    var that = this
    consultservice.getEnElementTypes(app.globalData.accessToken.userId, {
      success(res) {
        const menus = [{
          name: '全部',
          value: null,
        }]
        res.forEach(r => {
          menus.push({
            name: r.first,
            value: r.second,
          })
        });
        that.setData({menus})
      }
    })
  },
  getEnElementSubTypes() {
    var that = this
    consultservice.getEnElementSubTypes(app.globalData.accessToken.userId, {
      success(res) {
        const items = [
          [{
            name: '全部',
            value: null,
          }]
        ]
        res.forEach(r => {
          const l = []
          r.forEach(s => {
            l.push({
              name: s.first,
              value: s.second,
            })
          });
          items.push(l)
        });
        that.setData({items})
      }
    })
  },
  openChooseType() {
    this.setData({
      showMenu: true
    })
  },
  chooseMenu(e) {
    console.log('chooseMenu');
    console.log(e);
    const i = e.detail
    const menu = this.data.menus[i[0]]
    const item = this.data.items[i[0]][i[1]]
    this.setData({
      selected: [menu, item]
    })
    this.getQuestionsByType()
  },
  // åŽ»å¾€é—®ç­”è¯¦æƒ…
  gotoQA(e) {
    const index = e.currentTarget.dataset.index
    var qId = this.data.questions[index].cqGuid
    wx.navigateTo({
      url: '/pages/module_consult/consultdetailqa/consultdetailqa',
      success: (res) => {
        // é€šè¿‡ eventChannel å‘被打开页面传送数据
        res.eventChannel.emit('acceptDataFromOpenerPage', {
          qId: qId
        })
      },
    })
  },
})
pages/module_consult/consultproblem/consultproblem.json
@@ -2,5 +2,8 @@
  "navigationBarTitleText": "常见问题",
  "navigationBarBackgroundColor": "#57E4CB",
  "navigationBarTextStyle": "white",
  "usingComponents": {}
  "usingComponents": {
    "mp-loading": "/component/loading/loading",
    "mp-sidebar": "/component/sidebar/sidebar"
  }
}
pages/module_consult/consultproblem/consultproblem.wxml
@@ -1,32 +1,38 @@
<!--pages/module_consult/consultproblem/consultproblem.wxml-->
<!--pages/module_consult/consulthome/consulthome.wxml-->
<import src="/template/nodata.wxml"></import>
<view class="page">
  <view class="page__hd">
    <view class="switch-tab {{selectedIndex == index ? 'switch-tab_selected' : ''}}" wx:for="{{problemTypes}}" wx:index="index" data-index="{{index}}" bindtap="selectProblemType">{{item}}</view>
    <text style="color: #57E4CB;">{{selected[0].name}} > {{selected[1].name}}</text>
    <view class="filter" bindtap="openChooseType">
      <image src="/res/icons/filter.png" class="image-16"></image>
      ç­›é€‰
    </view>
  </view>
  <view class="page__bd">
    <block wx:for="{{problems[problemIndex]}}" wx:key="index">
      <view class="fyui-box  fyui-box__text">
    <block wx:if="{{!loading}}">
      <block wx:if="{{questions.length > 0}}">
        <block wx:for="{{questions}}" wx:key="index">
          <view class="fyui-box  fyui-box__text" bindtap="gotoQA" data-index="{{index}}">
        <view class="fyui-box__hd">
          Q. {{item.q}}
              <text class="fyui-box__content des subtitle">{{item.cqContent}}</text>
        </view>
        <view class="fyui-box__bd">
          <view class="fyui-box__content">{{item.a.length > 0 ? item.a[0].text : ''}}</view>
            <view class="fyui-box__bd answer">
              <view>答:</view>
              <rich-text class="des" nodes="{{item.answer}}"></rich-text>
        </view>
        <view class="fyui-box__ft">
          <view class="fyui-box__tag">
              <view class="flex-h">
                <image src="/res/icons/view.png" class="icon"></image>{{item.viewed}}
              </view>
              <view class="flex-h">
                <image src="/res/icons/like.png" class="icon"></image><view>{{item.like}}</view>
              <text class="tag3">提问时间:{{item.cqCreateTime}}</text>
              <text class="tag3">回复时间:{{item.cqCreateTime}}</text>
              </view>
            </view>
        </view>
      </view>
          <view wx:if="{{index == questions.length - 1}}" class="next-answer">——到底了——</view>
    </block>
      </block>
      <template wx:else is="nodataPage"></template>
    </block>
    <mp-loading duration="{{900}}" type="dot-gray" show="{{loading}}" animated="{{true}}"></mp-loading>
  </view>
  </view>
  <view class="page__ft">
  </view>
  <mp-sidebar show="{{showMenu}}" menus="{{menus}}" items="{{items}}" bindsubmit="chooseMenu"></mp-sidebar>
</view>
pages/module_consult/consultproblem/consultproblem.wxss
@@ -3,7 +3,10 @@
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  background-color: white;
  padding: 16px;
}
.switch-tab {
  border-radius: 8px;
  color: var(--fyui-text-color_1);
@@ -34,3 +37,40 @@
.fyui-box__tag .flex-h{
  margin-right: 16px;
}
.fyui-box .answer {
  display: flex;
  flex-direction: row;
  line-height: 18px;
  font-size: 12px;
  color: var(--fyui-text-color_3);
}
.des {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  width: 100%;
  overflow: hidden;
  /* text-overflow: ellipsis; */
}
.subtitle{
  font-size: 15px;
}
.next-answer {
  text-align: center;
  font-size: 12px;
  color: var(--fyui-text-color_3);
  padding: 8px;
}
.filter {
  display: flex;
  align-items: center;
}
.filter:active {
  background-color: var(--fyui-BG-COLOR-ACTIVE);
}
pages/module_consult/consultresult/consultresult.js
@@ -46,7 +46,7 @@
        let thisTypeId = ''
        let thisIndex = -1
        res.forEach(r => {
          r.des = r.des.replace('\\n', '<br/>')
          r.des = r.des.replaceAll('\\n', '<br/>')
          if (thisTypeId === '' || thisTypeId != r.typeId) {
            thisTypeId = r.typeId
            thisIndex++
pages/module_consult/consultresultmore/consultresultmore.js
@@ -58,7 +58,7 @@
      success (res) {
        let result = that.data.result
        res.forEach(r => {
          r.des = r.des.replace('\\n', '<br/>')
          r.des = r.des.replaceAll('\\n', '<br/>')
          if (result.length === 0) {
            result.push({
              typeId: r.typeId,
pages/module_ledger/ledgerhistory/ledgerhistory.js
@@ -51,7 +51,11 @@
    }],
    selectedMonIndex: 0,
    recordList: []
    recordList: [],
    previewImageUrls:[],
    previewCurrent: 0,
    showPreview: false,
  },
  /**
@@ -200,4 +204,21 @@
      },
    })
  },
  previewImage(e) {
    var i = e.currentTarget.dataset.index.split(',')
    var indexGroup = [parseInt(i[0]), parseInt(i[1])]
    var ledger = this.data.recordList[indexGroup[0]].ledgers[indexGroup[1]]
    const ledgerTitle = ledger.ledgerName
    const ledgerRemark = ledger.remark1
    const previewImageUrls = ledger.path1;
    this.setData({
      previewImageUrls,
      ledgerRemark,
      ledgerTitle,
      previewCurrent: 0,
      showPreview: true
    });
  },
})
pages/module_ledger/ledgerhistory/ledgerhistory.json
@@ -2,6 +2,7 @@
  "navigationBarTitleText": "历史台账",
  "navigationBarBackgroundColor": "#57E4CB",
  "usingComponents": {
    "mp-icon": "/component/icon/icon"
    "mp-icon": "/component/icon/icon",
    "my-gallery": "/component/mygallery/mygallery"
  }
}
pages/module_ledger/ledgerhistory/ledgerhistory.wxml
@@ -23,7 +23,7 @@
          <view class="ledger-type_2">({{item.ledgers.length}} / {{item.total}})</view>
        </view>
        <view class="ledger-group">
          <view wx:for="{{item.ledgers}}" wx:for-item="ledger" wx:for-index="i2" wx:key="i2" class="ledger-group_item" bindtap="gotoLedgerDetail" data-index="{{i1}},{{i2}}">
          <view wx:for="{{item.ledgers}}" wx:for-item="ledger" wx:for-index="i2" wx:key="i2" class="ledger-group_item" bindtap="previewImage" data-index="{{i1}},{{i2}}">
            <image class="" src="{{ledger.path1[0]}}" mode="aspectFill"></image>
            <view>{{ledger.ledgerName}}</view>
          </view>
@@ -33,3 +33,4 @@
    <template wx:else is="nodataPage"></template>
  </view>
</view>
<my-gallery hide-on-click="{{true}}" show-delete="{{false}}" show="{{showPreview}}" img-urls="{{previewImageUrls}}" current="{{previewCurrent}}" title="{{ledgerTitle}}" remark="{{ledgerRemark}}"></my-gallery>
pages/test2/test2.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
// pages/test2/test2.js
Page({
  /**
   * é¡µé¢çš„初始数据
   */
  data: {
    imgFiles: [
      '/res/icons/ass_1.png',
      '/res/icons/ass_2.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
      '/res/icons/ass_3.png',
    ],
    ledgerRemark: '台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注台账备注',
    previewImageUrls:[],
    previewCurrent: 0,
    showPreview: false,
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面加载
   */
  onLoad(options) {
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面初次渲染完成
   */
  onReady() {
  },
  previewImage(e) {
    const {
      index
    } = e.currentTarget.dataset;
    const previewImageUrls = this.data.imgFiles;
    this.setData({
      previewImageUrls,
      previewCurrent: index,
      showPreview: true
    });
  },
})
pages/test2/test2.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
{
  "usingComponents": {
    "my-gallery": "/component/mygallery/mygallery"
  }
}
pages/test2/test2.wxml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<!--pages/test2/test2.wxml-->
<view class="img-group">
  <view wx:for="{{imgFiles}}" wx:key="index">
    <image class="img-group_img" src="{{item}}" mode="aspectFill" bindtap="previewImage" data-index="{{index}}"></image>
  </view>
</view>
<my-gallery class="gallery" hide-on-click="{{true}}" show-delete="{{false}}" show="{{showPreview}}" img-urls="{{previewImageUrls}}" current="{{previewCurrent}}" remark="{{ledgerRemark}}"></my-gallery>
pages/test2/test2.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
/* pages/test2/test2.wxss */
.img-group {
  display: flex;
  flex-wrap: wrap;
  background-color: black;
}
.img-group>view {
  width: 30vw;
  text-align: center;
}
.img-group .img-group_img {
  width: 29vw;
  height: 29vw;
}
res/icons/bg_star.png
res/icons/case_forfeit.png
res/icons/cq_detained.png
res/icons/cq_illegal.png
res/icons/cq_minor.png
res/icons/cq_punish.png
res/icons/cq_shotspot.png
res/icons/cq_supervise.png
res/icons/favourite.png
res/icons/favourite1.png
res/icons/filter.png
res/icons/like.png

res/icons/like1.png
res/icons/link_1.png
res/icons/link_2.png
res/icons/link_3.png
res/icons/link_4.png
res/icons/locate.png
res/icons/time.png
service/baserequest.js
@@ -11,7 +11,7 @@
const originProperties = ['url', 'data', 'header', 'method', 'success', 'fail', 'complete'];
// const baseUrl = "http://127.0.0.1:8080"
// const baseUrl = "http://192.168.0.106:8080"
// const baseUrl = "http://192.168.1.106:8080"
const baseUrl = "https://fyami.com.cn:447"
// const basePicUrl = baseUrl + "/images/"
const basePicUrl = "https://fyami.com.cn:447/images/"
service/consultservice.js
@@ -57,6 +57,43 @@
    $f.get(cb)
  },
  //获取热门问答
  getTopicQA: function (userId, fun) {
    let cb = {
      url: `/consultation/topic/qa`,
      params: {
        userId: userId,
      },
    }
    Object.assign(cb, fun)
    $f.get(cb)
  },
  //获取热门案例
  getTopicCase: function (userId, fun) {
    let cb = {
      url: `/consultation/topic/case`,
      params: {
        userId: userId,
      },
    }
    Object.assign(cb, fun)
    let fun1 = util.deepCopy(cb)
    fun1.success = function (res) {
      res.forEach(r => {
        if (r.ecAppendixUrl && r.ecAppendixUrl != '' && r.ecAppendixUrl != null) {
          r.ecAppendixUrl = r.ecAppendixUrl.split(';').map((value, index) => {
            return $f.basePicUrl + value
          })
        }
      });
      cb.success(res)
    }
    $f.get(fun1)
  },
  //获取法律法规文件
  getMgtFile: function (userId, fileId, fun) {
    let cb = {
@@ -96,4 +133,120 @@
    $f.get(cb)
  },
  //根据类型获取问题
  getQuestionsByType: function (userId, kind, subKind, page, perPage, fun) {
    let cb = {
      url: `/consultation/question/type`,
      params: {
        userId: userId,
        page: page,
        perPage: perPage
      },
    }
    if (kind != null) {
      cb.params.kind = kind
    }
    if (subKind != null) {
      cb.params.subKind = subKind
  }
    Object.assign(cb, fun)
    let fun1 = util.deepCopy(cb)
    fun1.success = function (res) {
      if (cb.onPage) {
        cb.onPage(res.head)
      }
      if (res.success) {
        cb.success(res.data)
      } else {
        if (cb.fail) {
          cb.fail(res.message)
        }
      }
    }
    $f.get(fun1)
  },
  //获取问题
  getQuestion: function (userId, qId, fun) {
    let cb = {
      url: `/consultation/law/question`,
      params: {
        userId: userId,
        qId: qId,
      },
    }
    Object.assign(cb, fun)
    $f.get(cb)
  },
  //获取答案
  getAnswers: function (userId, qId, fun) {
    let cb = {
      url: `/consultation/law/answer`,
      params: {
        userId: userId,
        qId: qId,
      },
    }
    Object.assign(cb, fun)
    $f.get(cb)
  },
  //获取案例
  getCase: function (userId, caseId, fun) {
    let cb = {
      url: `/consultation/law/case`,
      params: {
        userId: userId,
        caseId: caseId,
      },
    }
    Object.assign(cb, fun)
    let fun1 = util.deepCopy(cb)
    fun1.success = function (res) {
      if (res.ecAppendixUrl && res.ecAppendixUrl != '' && res.ecAppendixUrl != null) {
        let urls = []
        let texts = []
        res.ecAppendixUrl.split(';').forEach(r => {
          urls.push($f.basePicUrl + r)
          const i1 = r.lastIndexOf('/') + 1
          const i2 = r.lastIndexOf('.')
          texts.push(r.slice(i1, i2))
        });
        res.ecAppendixUrl = urls
        res.ecAppendixText = texts
      }
      cb.success(res)
    }
    $f.get(fun1)
  },
  //获取环保要素大类
  getEnElementTypes: function (userId, fun) {
    let cb = {
      url: `/consultation/elementtype`,
      params: {
        userId: userId,
      },
    }
    Object.assign(cb, fun)
    $f.get(cb)
  },
  //获取环保要素小类
  getEnElementSubTypes: function (userId, fun) {
    let cb = {
      url: `/consultation/elementsubtype`,
      params: {
        userId: userId,
      },
    }
    Object.assign(cb, fun)
    $f.get(cb)
  },
}
utils/util.js
@@ -15,14 +15,14 @@
  const thisDay = now.date()
  if (timeYear < thisYear) {
    return time.format('YYYYå¹´MM月')
    return time.format('YYYY-MM-DD')
  } else if (timeMonth < thisMonth) {
    return time.format('MM月DD日')
    return time.format('MM-DD')
  } else if (timeDay < thisDay) {
    if (timeDay + 1 == thisDay) {
      return '昨天'
    } else {
      return time.format('MM月DD日')
      return time.format('MM-DD')
    }
  } else {
    return time.fromNow()