riku
6 小时以前 b09c7e7aefd41a62326ea56460092aa0db54c083
现场监管模块

1. 完成任务的开始结束(新增了后台接口)
2. 日历界面完成任务状态和完成情况的同步
已修改13个文件
已添加8个文件
1015 ■■■■■ 文件已修改
app.json 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app.wxss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
config/index.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/api/taskApi.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/inspection/index.js 300 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/inspection/index.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/inspection/index.wxml 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/inspection/index.wxss 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/menu_evidence/index.js 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/menu_evidence/index.json 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/menu_evidence/index.wxml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/menu_evidence/index.wxss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/subtask/index.js 101 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/subtask/index.json 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/subtask/index.wxml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/subtask/index.wxss 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/subtask/subtaskitem-proxy.js 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/subtask/subtaskitem.wxml 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package_supervision/pages/subtask/subtaskitem.wxss 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
style/common.wxss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
style/page.wxss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app.json
@@ -47,7 +47,8 @@
      "root": "package_supervision",
      "pages": [
        "pages/inspection/index",
        "pages/subtask/index"
        "pages/subtask/index",
        "pages/menu_evidence/index"
      ]
    }
  ],
@@ -82,6 +83,7 @@
    "t-avatar": "tdesign-miniprogram/avatar/avatar",
    "t-badge": "tdesign-miniprogram/badge/badge",
    "t-button": "tdesign-miniprogram/button/button",
    "t-back-top": "tdesign-miniprogram/back-top/back-top",
    "t-cell": "tdesign-miniprogram/cell/cell",
    "t-cell-group": "tdesign-miniprogram/cell-group/cell-group",
    "t-collapse": "tdesign-miniprogram/collapse/collapse",
app.wxss
@@ -6,3 +6,4 @@
@import 'style/component.wxss';
@import 'style/panel.wxss';
@import 'style/iconfont.wxss';
@import 'style/common.wxss';
config/index.js
@@ -9,10 +9,8 @@
const baseFileUrl = `${bu}/meeting/file/`;
// çº¿ä¸Šç›‘管
const inspectUrl = 'https://fyami.com.cn:447';
// const inspectUrl = 'http://192.168.0.138:9001';
// const inspectUrl = 'http://192.168.0.138:8080';
// const inspectUrl = 'http://192.168.1.8:8080';
// const inspectUrl = 'https://fyami.com.cn:447';
const inspectUrl = 'http://192.168.1.7:9001';
// çº¿ä¸Šç›‘管图片
const iu = 'https://fyami.com.cn:447';
package_supervision/api/taskApi.js
@@ -45,4 +45,62 @@
      return res.data;
    });
  },
  /**
   * èŽ·å–å…·ä½“å­ä»»åŠ¡ä¿¡æ¯
   * @param {String} dayTaskId æ—¥ä»»åС䏻键id
   * @param {String} userId ç”¨æˆ·id,当用户类型userType为1(监管用户)时,会根据用户id获取其权限内的统计信息
   * @param {String} userType ç”¨æˆ·ç±»åž‹ï¼Œ0:管理员;1:监管用户;2:政府部门;3:企业
   */
  fetchSubtaskByDayTask(dayTaskId, userId = '', userType = '0') {
    return get(
      {
        url: `/subtask/byDayTaskId`,
        params: {
          dayTaskId,
          userId,
          userType,
        },
      },
      inspectUrl,
    ).then(res => {
      return res.data;
    });
  },
  /**
   * èŽ·å–å­ä»»åŠ¡çš„å·¡æŸ¥ä¿¡æ¯ï¼Œè¿˜åŒ…æ‹¬é—®é¢˜åˆ—è¡¨ã€æŠ€é˜²è®¾æ–½åˆ—è¡¨
   * @param {String} subTaskId
   */
  fetchInspectionData(subTaskId) {
    return get(
      {
        url: `/inspection/find/${subTaskId}`,
      },
      inspectUrl,
    ).then(res => {
      res.data.problemList.forEach(p => {
        p.mediafileList.forEach(m => {
          m.url = `${inspectPicUrl}${m.extension1}${m.guid}.jpg`;
        });
      });
      return res.data;
    });
  },
  /**
   * ä¿®æ”¹ä»»åŠ¡çŠ¶æ€ï¼Œæœªæ‰§è¡Œ -> æ‰§è¡Œä¸­ -> ç»“束
   * @param {string} stGuid
   */
  changeSubTaskStatus(stGuid) {
    return post(
      {
        url: `/subtask/status`,
        params: {
          stGuid,
        },
      },
      inspectUrl,
    ).then(res => res.data);
  },
};
package_supervision/pages/inspection/index.js
@@ -1,66 +1,282 @@
// package_supervision/pages/inspection/index.js
Page({
import { inspectPicUrl } from '../../../config/index';
import taskApi from '../../api/taskApi';
import { fetchScene } from '../../../services/inspection/fetchScene';
import Message from 'tdesign-miniprogram/message/index';
/**
 * status:  æœªæ‰§è¡Œ | æ­£åœ¨æ‰§è¡Œ | å·²ç»“束
 * action: å¼€å§‹ä»»åŠ¡ | ç»“束任务 | å·²ç»“束
 * theme: primary | danger | default
 * icon: play-circle-stroke | pause-circle-stroke | stop-circle
 */
const TASK_STATUS = {
  æœªæ‰§è¡Œ: {
    status: '未执行',
    action: '开始任务',
    theme: 'primary',
    icon: 'play-circle-stroke',
  },
  æ­£åœ¨æ‰§è¡Œ: {
    status: '正在执行',
    action: '结束任务',
    theme: 'danger',
    icon: 'pause-circle-stroke',
  },
  å·²ç»“束: {
    status: '已结束',
    action: '已结束',
    theme: 'default',
    icon: 'stop-circle-stroke',
  },
};
Page({
  /**
   * é¡µé¢çš„初始数据
   */
  data: {
    title: '现场监管',
    // å·¡æŸ¥å­ä»»åŠ¡
    subtask: {},
    // åœºæ™¯ä¿¡æ¯
    scene: {},
    inspeciton: {},
    //
    mapMarkers: [],
    // åŠŸèƒ½èœå•
    menu1: [
      {
        name: '问题复核',
        icon: `${inspectPicUrl}icons/icon_patrol_check.png`,
        disabled: true,
      },
      {
        name: '问题取证',
        icon: `${inspectPicUrl}icons/icon_patrol_new_question.png`,
        disabled: true,
        url: '/package_supervision/pages/menu_evidence/index'
      },
      {
        name: '问题清单',
        icon: `${inspectPicUrl}icons/icon_patrol_question_list.png`,
        disabled: true,
      },
      {
        name: '现场整改',
        icon: `${inspectPicUrl}icons/icon_patrol_change.png`,
        disabled: true,
      },
      {
        name: '任意拍照',
        icon: `${inspectPicUrl}icons/icon_patrol_camera.png`,
        disabled: true,
      },
      {
        name: '导航',
        icon: `${inspectPicUrl}icons/icon_patrol_navi.png`,
        disabled: false,
      },
      {
        name: '重新定位',
        icon: `${inspectPicUrl}icons/icon_patrol_latlng.png`,
        disabled: false,
      },
      {
        name: '修改信息',
        icon: `${inspectPicUrl}icons/icon_patrol_edit.png`,
        disabled: false,
      },
      {
        name: '问题审核',
        icon: `${inspectPicUrl}icons/icon_patrol_online.png`,
        disabled: true,
      },
      {
        name: '整改审核',
        icon: `${inspectPicUrl}icons/icon_patrol_promiss.png`,
        disabled: true,
      },
    ],
    menu2: [
      {
        name: '图片取证',
        icon: `${inspectPicUrl}icons/icon_patrol_new_question.png`,
        disabled: true,
      },
      {
        name: '整改承诺',
        icon: `${inspectPicUrl}icons/icon_patrol_promiss.png`,
        disabled: true,
      },
      {
        name: '综合评分',
        icon: `${inspectPicUrl}icons/icon_patrol_rate.png`,
        disabled: true,
      },
      {
        name: '一键分享',
        icon: `${inspectPicUrl}icons/icon_patrol_submit.png`,
        disabled: true,
      },
      {
        name: '技防措施',
        icon: `${inspectPicUrl}icons/icon_patrol_newgit.png`,
        disabled: true,
      },
    ],
    // ä»»åŠ¡çŠ¶æ€
    taskStatus: {
      loading: false,
      ...TASK_STATUS.已结束,
    },
    // ä»»åŠ¡çŠ¶æ€æŒ‰é’®åŠ è½½æ ·å¼
    loadProps: {
      theme: 'spinner',
      tClass: 'ins-buttons__loading',
    },
    // ä»»åŠ¡çŠ¶æ€æ›´æ”¹ç¡®è®¤å¼¹å‡ºæ¡†
    taskStatusDialog: {
      show: false,
      title: '要开始任务吗?',
      content: '',
    },
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面加载
   */
  onLoad(options) {
    // èŽ·å–å·¡æŸ¥ä»»åŠ¡å‚æ•° subtask,并更新任务状态 taskStatus
    this.getOpenerEventChannel().on('acceptSubTaskData', data => {
      if (data) {
        this.setData({
          subtask: data.subtask,
          taskStatus: {
            loading: false,
            ...TASK_STATUS[data.subtask.status],
          },
        });
        this.fetchInspectionData();
      }
    });
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面初次渲染完成
   * æ ¹æ®ä»»åŠ¡çŠ¶æ€ï¼Œæ›´æ–°æŒ‰é’®æ˜¯å¦å¯ç‚¹å‡»
   * @param {string} status ä»»åŠ¡çŠ¶æ€ï¼š æœªæ‰§è¡Œ | æ­£åœ¨æ‰§è¡Œ | å·²ç»“束
   */
  onReady() {
  refreshMenuStatus(status) {
    const { menu1, menu2 } = this.data;
    if (status == '正在执行') {
      menu1.forEach(m => {
        m.disabled = false;
      });
      menu2.forEach(m => {
        m.disabled = false;
      });
    } else if (status == '已结束') {
      menu1[1].disabled = true;
      menu2[0].disabled = true;
    } else {
      menu1.forEach(m => {
        m.disabled = true;
      });
      menu2.forEach(m => {
        m.disabled = true;
      });
      [5, 6, 7].forEach(i => {
        menu1[i].disabled = false;
      });
    }
    this.setData({ menu1, menu2 });
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面显示
   * èŽ·å–å·¡æŸ¥ä¿¡æ¯å’Œåœºæ™¯ä¿¡æ¯
   */
  onShow() {
  fetchInspectionData() {
    const { subtask } = this.data;
    taskApi.fetchInspectionData(subtask.stguid).then(res => {
      this.setData({
        inspeciton: res,
      });
    });
    fetchScene(subtask.scenseid).then(res => {
      const { mapMarkers } = this.data;
      mapMarkers.push({
        id: 1,
        longitude: res.longitude,
        latitude: res.latitude,
        title: res.name,
        callout: res.name,
        width: 16,
        height: 24,
      });
      this.setData({
        scene: res,
        mapMarkers,
        title: res.name,
      });
    });
  },
  showTaskStatusChangeDialog() {
    let { taskStatusDialog, taskStatus } = this.data;
    if (taskStatus.status == '未执行') {
      taskStatusDialog = {
        show: true,
        title: '要开始任务吗?',
        content: '',
      };
    } else if (taskStatus.status == '正在执行') {
      taskStatusDialog = {
        show: true,
        title: '要结束任务吗?',
        content: '结束任务后不能再新增问题',
      };
    }
    this.setData({ taskStatusDialog });
  },
  closeDialog() {
    this.setData({ 'taskStatusDialog.show': false });
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面隐藏
   * ä»»åŠ¡çŠ¶æ€å˜æ›´äº‹ä»¶å¤„ç†å‡½æ•°
   */
  onHide() {
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面卸载
   */
  onUnload() {
  },
  /**
   * é¡µé¢ç›¸å…³äº‹ä»¶å¤„理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
  },
  /**
   * é¡µé¢ä¸Šæ‹‰è§¦åº•事件的处理函数
   */
  onReachBottom() {
  },
  /**
   * ç”¨æˆ·ç‚¹å‡»å³ä¸Šè§’分享
   */
  onShareAppMessage() {
  handleTaskStatusChange() {
    this.closeDialog();
    let { taskStatus, subtask } = this.data;
    this.setData({ 'taskStatus.loading': true });
    if (taskStatus.status == '已结束') {
      return;
    }
    if (taskStatus.status == '未执行') {
      taskStatus = {
        loading: true,
        ...TASK_STATUS.正在执行,
      };
    } else if (taskStatus.status == '正在执行') {
      taskStatus = {
        loading: true,
        ...TASK_STATUS.已结束,
      };
    }
    taskApi
      .changeSubTaskStatus(subtask.stguid)
      .then(res => {
        if (res.success) {
          this.setData({ taskStatus });
          this.getOpenerEventChannel().emit('changeStatusEvent', { subtask: res.data });
          this.refreshMenuStatus(taskStatus.status)
        } else {
          Message.error({
            context: this,
            offset: [90, 32],
            duration: 2000,
            content: res.message,
          });
  }
})
      .finally(() => this.setData({ 'taskStatus.loading': false }));
  },
});
package_supervision/pages/inspection/index.json
@@ -1,3 +1,9 @@
{
  "navigationBarTitleText": "现场监管",
  "onReachBottomDistance": 10,
  "backgroundTextStyle": "light",
  "navigationBarTextStyle": "white",
  "navigationBarBackgroundColor": "#fff",
  "navigationStyle":"custom",
  "usingComponents": {}
}
package_supervision/pages/inspection/index.wxml
@@ -1,2 +1,68 @@
<!--package_supervision/pages/inspection/index.wxml-->
<text>package_supervision/pages/inspection/index.wxml</text>
<t-message id="t-message" />
<t-navbar left-arrow class="custom-navbar">
  <view slot="left" class="custom-title"> {{title}} </view>
</t-navbar>
<view class="page">
  <map
    class="ins-map"
    longitude="{{scene.longitude}}"
    latitude="{{scene.latitude}}"
    markers="{{mapMarkers}}"
  />
  <view class="ins-buttons">
    <t-button
      loading="{{taskStatus.loading}}"
      loading-props="{{loadProps}}"
      class="ins-buttons__status"
      shape="square"
      theme="{{taskStatus.theme}}"
      content="{{taskStatus.action}}"
      size="large"
      variant="base"
      disabled="{{taskStatus.loading || taskStatus.status == '已结束'}}"
      icon="{{taskStatus.loading ? '' : taskStatus.icon}}"
      bind:tap="showTaskStatusChangeDialog"
    >
    </t-button>
  </view>
  <view class="ins-menu">
    <t-tabs animation="{{ { duration: 0.6 } }}" defaultValue="{{0}}" class="custom-tabs">
      <t-tab-panel label="选项一" value="0">
        <t-grid theme="card" class="custom-grid" column="{{5}}" hover>
          <t-grid-item
            wx:for="{{menu1}}"
            wx:key="index"
            class="{{item.disabled ? 'diabled-grid-item' : ''}}"
            text="{{item.name}}"
            image="{{item.icon}}"
            url="{{item.disabled ? '' : item.url}}"
          >
          </t-grid-item>
        </t-grid>
        <t-icon class="icon-right" size="16" name="caret-right"></t-icon>
      </t-tab-panel>
      <t-tab-panel label="选项二" value="1">
        <t-grid theme="card" class="custom-grid" column="{{5}}" hover>
          <t-grid-item
            class="{{item.disabled ? 'diabled-grid-item' : ''}}"
            wx:for="{{menu2}}"
            wx:key="index"
            text="{{item.name}}"
            image="{{item.icon}}"
          >
          </t-grid-item>
        </t-grid>
        <t-icon class="icon-left" size="16" name="caret-left"></t-icon>
      </t-tab-panel>
    </t-tabs>
  </view>
</view>
<t-dialog
  visible="{{taskStatusDialog.show}}"
  title="{{taskStatusDialog.title}}"
  content="{{taskStatusDialog.content}}"
  confirm-btn="{{ {content: '确定', theme:'danger'} }}"
  cancel-btn="取消"
  bind:confirm="handleTaskStatusChange"
  bind:cancel="closeDialog"
/>
package_supervision/pages/inspection/index.wxss
@@ -1 +1,103 @@
/* package_supervision/pages/inspection/index.wxss */
page {
  /* --header-bottom-padding: 600rpx; */
}
.page .page-header {
  /* background: linear-gradient(var(--td-primary-color-7), var(--td-bg-color)); */
  /* padding-bottom: var(--header-bottom-padding); */
}
.page .page-container {
  /* margin-top: calc(0rpx - var(--header-bottom-padding)); */
  padding: 0;
}
.custom-navbar {
  --td-navbar-color: #fff;
  --td-navbar-bg-color: var(--td-primary-color);
  --td-navbar-title-font-size: var(--td-font-size-base);
}
.custom-title {
  font-size: var(--td-font-size-base);
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.ins-map {
  width: 100%;
  height: 90vh;
}
.ins-buttons {
  position: absolute;
  right: 10px;
  top: 10px;
}
.ins-buttons .ins-buttons__status {
  --td-button-primary-bg-color: rgb(0, 177, 0);
  --td-button-primary-border-color: rgb(0, 177, 0);
  --td-button-primary-disabled-bg: rgb(125, 201, 125);
  --td-button-primary-disabled-border-color: rgba(0, 177, 0, 0.2);
  --td-button-primary-active-bg-color: rgba(0, 128, 0, 0.534);
  --td-button-primary-active-border-color: rgba(0, 128, 0, 0.534);
  --td-button-default-disabled-border-color: rgba(0, 0, 0, 0.2);
  flex-direction: column;
}
.ins-buttons .ins-buttons__status .t-button__content {
  /* position: absolute; */
  font-size: var(--td-font-size-xs);
  /* bottom: 0; */
  line-height: initial;
  margin: initial !important;
}
.ins-buttons .t-loading {
  --td-loading-color: white;
}
.ins-menu {
  position: absolute;
  bottom: calc(env(safe-area-inset-bottom) + 96rpx);
  left: 0;
  right: 0;
  padding-bottom: calc(env(safe-area-inset-bottom) + 96rpx);
}
.custom-grid {
  box-shadow: var(--td-shadow-2);
  margin-bottom: 16px !important;
}
.custom-grid .diabled-grid-item {
  position: relative;
  opacity: 0.5;
}
.custom-tabs .t-tabs__wrapper {
  display: none;
}
.t-tabs {
  background: transparent !important;
  margin-bottom: -16px;
}
.t-tab-panel {
  position: relative;
}
.icon-right {
  position: absolute;
  right: 32rpx;
  bottom: calc(50%);
}
.icon-left {
  position: absolute;
  left: 32rpx;
  bottom: calc(50%);
}
package_supervision/pages/menu_evidence/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
// package_supervision/pages/menu_evidence/index.js
Page({
  /**
   * é¡µé¢çš„初始数据
   */
  data: {
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面加载
   */
  onLoad(options) {
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面初次渲染完成
   */
  onReady() {
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面显示
   */
  onShow() {
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面隐藏
   */
  onHide() {
  },
  /**
   * ç”Ÿå‘½å‘¨æœŸå‡½æ•°--监听页面卸载
   */
  onUnload() {
  },
  /**
   * é¡µé¢ç›¸å…³äº‹ä»¶å¤„理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
  },
  /**
   * é¡µé¢ä¸Šæ‹‰è§¦åº•事件的处理函数
   */
  onReachBottom() {
  },
  /**
   * ç”¨æˆ·ç‚¹å‡»å³ä¸Šè§’分享
   */
  onShareAppMessage() {
  }
})
package_supervision/pages/menu_evidence/index.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
{
  "usingComponents": {}
}
package_supervision/pages/menu_evidence/index.wxml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
<!--package_supervision/pages/menu_evidence/index.wxml-->
<text>package_supervision/pages/menu_evidence/index.wxml</text>
package_supervision/pages/menu_evidence/index.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
/* package_supervision/pages/menu_evidence/index.wxss */
package_supervision/pages/subtask/index.js
@@ -1,19 +1,30 @@
import taskApi from '../../api/taskApi';
import dayjs from 'dayjs';
import { useSubTaskItem } from './subtaskitem-proxy.js';
const app = getApp();
Page({
  behaviors: [useSubTaskItem],
  /**
   * é¡µé¢çš„初始数据
   */
  data: {
    minDate: new Date(2026, 0, 1).getTime(),
    // æ—¥åŽ†æ˜¾ç¤ºæ—¥æœŸèŒƒå›´
    minDate: new Date(2026, 2, 1).getTime(),
    maxDate: new Date(2026, 3, 30).getTime(),
    thisDate: new Date().getTime(),
    // é€‰ä¸­çš„æ—¥æœŸ
    thisDate: new Date().getTime(),
    // ä¸Šæ¬¡é€‰ä¸­çš„æ—¥æœŸ
    lastDate: new Date().getTime(),
    // å½“月总任务选项及选中的任务
    toptask: {
      options: [],
      value: '',
    },
    // é€‰ä¸­æ€»ä»»åŠ¡ä¸‹å¯¹åº”çš„æ—¥ä»»åŠ¡
    daytasks: [],
  },
@@ -22,6 +33,26 @@
   */
  onLoad(options) {
    this.fetchToptask();
    // é¡µé¢åŠ è½½å®ŒæˆåŽï¼Œè®¾å®šæ—¥åŽ†çš„æ ¼å¼åŒ–æ—¥æœŸå‡½æ•°
    const _formatCalendarDay = this._formatCalendarDay;
    this.setData({
      formatCalendarDay: _formatCalendarDay,
    });
    // è®¾ç½®æ—¥åŽ†èµ·æ­¢æ—¶é—´
    this.setData({
      minDate: dayjs().startOf('month').add(-1, 'month').toDate().getTime(),
      maxDate: dayjs().endOf('month').toDate().getTime(),
    });
  },
  /**
   * ç›‘听页面滚动
   */
  onPageScroll(e) {
    this.setData({
      scrollTop: e.scrollTop,
    });
  },
  /**
@@ -44,12 +75,23 @@
   * åˆ‡æ¢æœˆä»½æˆ–年份事件处理函数
   */
  handelMonthChange(e) {
    console.log('handelMonthChange', e);
    // é€‰ä¸­æ—¥æœŸåŒæ­¥åˆ‡æ¢ä¸€ä¸ªæœˆ
    const { year, month } = e.detail;
    let thisDay = dayjs(this.data.thisDate);
    thisDay = thisDay.year(year);
    thisDay = thisDay.month(month - 1);
    this.setData({ thisDate: thisDay.toDate().getTime() });
    // å¦‚果切换后的月份为当前日历范围的起始月份,则修改起始月份减少一个月,确保用户可继续查看历史月份
    const _minDate = dayjs(this.data.minDate);
    if (thisDay.month() == _minDate.month()) {
      this.setData({
        minDate: _minDate.add(-1, 'month').toDate().getTime(),
      });
    }
    this.setData({
      thisDate: thisDay.toDate().getTime(),
    });
    this.fetchToptask();
  },
@@ -60,21 +102,18 @@
   * type TDateType = 'selected' | 'disabled' | 'start' | 'start-end' |'centre' | 'end' | ''
   */
  _formatCalendarDay(day) {
    console.log('_formatCalendarDay', day);
    if (!this) return;
    const { date } = day;
    const year = date.getFullYear();
    const month = date.getMonth() + 1;
    const curDate = date.getDate();
    const { daytasks } = this.data;
    // æŸ¥æ‰¾å½“天是否有日任务
    const fdt = daytasks.find(d => {
      return dayjs(d.date).isSame(dayjs(date), 'day');
      return dayjs(d.date).isSame(dayjs(date), 'day') && d.totalTaskNum > 0;
    });
    if (fdt) {
      day.suffix = `${fdt.completeTaskNum}/${fdt.totalTaskNum}`;
      day.className = 'has-task';
    }
    return day;
  },
@@ -83,8 +122,14 @@
   * ç‚¹å‡»æ—¥æœŸäº‹ä»¶å¤„理函数
   */
  handleSelectDay(e) {
    console.log('app', app);
    const date = new Date(e.detail.value);
    console.log('handleSelectDay', date);
    const { thisDate } = this.data;
    this.setData({
      lastDate: thisDate,
      thisDate: date.getTime(),
    });
    this.fetchSubtaskByDayTask();
  },
  /**
@@ -96,16 +141,24 @@
    const starttime = thisDay.startOf('month').format('YYYY-MM-DD HH:mm:ss');
    const endtime = thisDay.endOf('month').format('YYYY-MM-DD HH:mm:ss');
    taskApi.fetchTopTasks({ starttime, endtime }).then(res => {
      const options = res.data.map(r => {
      const options =
        res.data.length > 0
          ? res.data.map(r => {
        return {
          label: r.name,
          value: r.tguid,
        };
      });
            })
          : [
              {
                label: '本月无监管任务',
                value: null,
              },
            ];
      this.setData({
        toptask: {
          options,
          value: options.length > 0 ? options[0].value : '',
          options: options,
          value: options[0].value,
        },
      });
      this.fetchDayTasks();
@@ -120,12 +173,22 @@
    taskApi
      .fetchDayTasks(this.data.toptask.value)
      .then(res => {
        if (res) {
        this.setData({ daytasks: res });
        setTimeout(() => {
          const _formatCalendarDay = this._formatCalendarDay;
          this.setData({ formatCalendarDay: _formatCalendarDay });
        }, 1000);
          this.selectThisDay();
        }
      })
      .finally(() => this.setData({ pageLoading: false }));
  },
  // ç”¨äºŽè§¦å‘日历的日期格式化函数,显示每日任务完成情况
  selectThisDay() {
    setTimeout(() => {
      const { thisDate } = this.data;
      this.setData({
        thisDate,
      });
      this.fetchSubtaskByDayTask();
    }, 200);
  },
});
package_supervision/pages/subtask/index.json
@@ -1,9 +1,9 @@
{
  "navigationBarTitleText": "现场监管",
  "navigationBarTitleText": "巡查日程",
  "onReachBottomDistance": 10,
  "backgroundTextStyle": "light",
  "navigationBarTextStyle": "black",
  "navigationBarBackgroundColor": "#fff",
  "navigationBarTextStyle": "white",
  "navigationBarBackgroundColor": "#389AFF",
  "usingComponents": {
    "scene-picker": "/components/scene-picker/index"
  }
package_supervision/pages/subtask/index.wxml
@@ -1,6 +1,7 @@
<!--pages/enterprise/result/index.wxml-->
<t-back-top theme="round" text="顶部" scroll-top="{{scrollTop }}"> </t-back-top>
<view class="page">
  <view class="page-header">
    <t-sticky style="z-index: 10000">
    <!-- <view class="subtask-header"> -->
    <t-dropdown-menu t-class-item="custom-dropdown-menu">
      <t-dropdown-item
@@ -18,6 +19,7 @@
      >
      </scene-picker> -->
    <!-- </view> -->
    </t-sticky>
    <t-loading
      wx:if="{{pageLoading}}"
      theme="circular"
@@ -42,6 +44,7 @@
      bind:select="handleSelectDay"
      value="{{thisDate}}"
    />
    <include src="./subtaskitem.wxml" />
  </view>
  <view class="page-footer"></view>
</view>
package_supervision/pages/subtask/index.wxss
@@ -1,6 +1,12 @@
@import './subtaskitem.wxss';
.subtask-header {
  display: flex;
  justify-content: space-between;
}
.has-task:not(.t-calendar__dates-item--selected) {
  color: #e34d59;
}
/* ç»„ä»¶t-dropdown-menu */
.custom-dropdown-menu {
@@ -22,5 +28,6 @@
}
.custom-calendar .t-calendar__dates-item {
  /* height: 80rpx; */
  height: 80rpx;
  align-items: flex-start;
}
package_supervision/pages/subtask/subtaskitem-proxy.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,139 @@
import dayjs from 'dayjs';
import taskApi from '../../api/taskApi';
/**
 * å­ä»»åŠ¡åˆ—è¡¨æ¨¡å—
 */
export const useSubTaskItem = Behavior({
  data: {
    subTaskLoading: false,
    // å½“日的子任务
    subtaskList: [],
  },
  methods: {
    statusType(status) {
      switch (status) {
        case '未执行':
          return {
            type: 'danger',
            icon: 'assignment-error-filled',
          };
        case '正在执行':
          return {
            type: 'success',
            icon: 'time',
          };
        case '已结束':
          return {
            type: '',
            icon: 'assignment-checked-filled',
          };
        default:
          return {
            type: 'danger',
            icon: 'assignment-error-filled',
          };
      }
    },
    /**
     * èŽ·å–å­ä»»åŠ¡
     */
    fetchSubtaskByDayTask() {
      this.setData({ subTaskLoading: true });
      const { thisDate, daytasks } = this.data;
      const fdt = daytasks.find(d => {
        return dayjs(d.date).isSame(dayjs(thisDate), 'day');
      });
      if (fdt) {
        taskApi
          .fetchSubtaskByDayTask(fdt.guid)
          .then(res => {
            this.setData({
              subtaskList: res
                .sort((a, b) => {
                  if (a.sceneTypeId != b.sceneTypeId) {
                    return a.sceneTypeId - b.sceneTypeId;
                  } else {
                    return dayjs(b.executionstarttime).unix() - dayjs(a.executionstarttime).unix();
                  }
                })
                .map(stask => {
                  const changePerType = () => {
                    if (status.value.changeNum == 0) {
                      if (status.value.proNum == 0) {
                        return 'success';
                      } else {
                        return 'danger';
                      }
                    } else if (status.value.proNum == status.value.changeNum) {
                      return 'success';
                    } else {
                      return 'warning';
                    }
                  };
                  const timeformat = date => {
                    return date ? dayjs(date).format('YYYY-MM-DD HH:mm') : '----/--/-- --:--';
                  };
                  return {
                    ...stask,
                    startTime: timeformat(stask.executionstarttime),
                    endTime: timeformat(stask.executionendtime),
                    statusType: this.statusType(stask.status),
                  };
                }),
            });
          })
          .finally(() => this.setData({ subTaskLoading: false }));
      } else {
        this.setData({
          subtaskList: [],
          subTaskLoading: false,
        });
      }
    },
    /**
     * ç‚¹å‡»å­ä»»åŠ¡äº‹ä»¶å¤„ç†å‡½æ•°
     */
    handleItemClick(e) {
      const { index } = e.currentTarget.dataset;
      const { subtaskList } = this.data;
      const subtask = subtaskList[index];
      wx.navigateTo({
        url: '/package_supervision/pages/inspection/index',
        success: result => {
          result.eventChannel.emit('acceptSubTaskData', {
            subtask,
          });
        },
        events: {
          // ä»»åŠ¡çŠ¶æ€å˜æ›´äº‹ä»¶
          changeStatusEvent: data => {
            const { daytasks } = this.data;
            subtask.status = data?.subtask?.status;
            subtask.statusType = this.statusType(subtask.status);
            // è‹¥ä»»åŠ¡ç»“æŸï¼Œåˆ™æ›´æ–°æ—¥ä»»åŠ¡ä¸­çš„å®Œæˆä»»åŠ¡æ•°é‡ç»Ÿè®¡
            if (subtask.status == '已结束') {
              let _index;
              const daytask = daytasks.find((d, i) => {
                if (d.guid == subtask.tsguid) {
                  _index = i;
                  return true;
                }
              });
              daytask.completeTaskNum++;
              this.setData({
                [`daytasks[${_index}]`]: daytask,
              });
            }
            this.setData({
              [`subtaskList[${index}]`]: subtask,
            });
            this.selectThisDay();
          },
        },
      });
    },
  },
});
package_supervision/pages/subtask/subtaskitem.wxml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
<t-loading
  wx:if="{{subTaskLoading}}"
  theme="circular"
  size="40rpx"
  text="加载中..."
  loading
  t-class="sti-loading"
>
</t-loading>
<t-empty
  wx:if="{{!subTaskLoading && subtaskList.length == 0}}"
  t-class-image="t-empty__image"
  image="/res/nodata.png"
  description="无巡查任务"
/>
<block wx:else>
  <view
    class="wrapper m-t-4"
    wx:for="{{subtaskList}}"
    wx:for-index="index"
    wx:key="index"
    data-index="{{index}}"
    bind:tap="handleItemClick"
  >
    <view class="m-t-4" style="display: flex; justify-content: space-between">
      <view style="width: 100%">
        <view class="text-title">
          <t-tag
            size="small"
            theme="{{item.statusType.type}}"
            variant="light-outline"
            class="m-r-4 m-b-4"
          >
            <view style="display: flex; align-items: center; gap: 4px">
              <t-icon size="16" name="{{item.statusType.icon}}"></t-icon>
              <text>{{item.status}}</text>
            </view>
          </t-tag>
          {{item.name}}
        </view>
        <view class="text-info">
          <view class="text-label">
            <t-icon class="m-r-4" size="16" name="location"></t-icon>
            <text>地址:</text>
          </view>
          {{item.scenseaddress}}
        </view>
        <view class="text-info">
          <view class="text-label">
            <t-icon class="m-r-4" size="16" name="alarm"></t-icon>
            <text>时间:</text>
          </view>
          {{item.startTime}}至{{item.endTime}}
        </view>
        <view class="text-info">
          <view class="text-label">
            <t-icon class="m-r-4" size="16" name="user"></t-icon>
            <text>人员:</text>
          </view>
          {{item.executorrealtimes}}
        </view>
        <view
          style="display: flex; justify-content: space-between; align-items: center"
          class="m-t-4"
        >
          <view style="display: flex; gap: 8px; align-items: center">
            <t-tag size="small" variant="light-outline" theme="primary"
              >{{item.sceneTypeName}}</t-tag
            >
            <t-tag size="small" variant="light-outline" theme="primary"
              >{{item.type}}</t-tag
            >
          </view>
          <t-icon size="16" name="arrow-right"></t-icon>
        </view>
      </view>
    </view>
  </view>
</block>
package_supervision/pages/subtask/subtaskitem.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
.sti-loading {
  width: 100%;
  text-align: center;
  padding: 4px;
  /* background-color: aliceblue; */
}
.wrapper {
  /* width: 300px; */
  border: 1px solid var(--td-text-color-brand);
  border-radius: var(--td-border-radius);
  padding: 4px 8px;
  background-color: white;
}
.wrapper:active {
  background-color: var(--td-bg-color);
}
.text-title {
  font-weight: 600;
  color: var(--td-text-color-primary);
  font-size: var(--td-font-size-m);
}
.text-info {
  display: flex;
  align-items: flex-start;
  color: var(--td-text-color-secondary);
  font-size: var(--td-font-size-s);
}
.text-label {
  display: flex;
  align-items: center;
  white-space: nowrap;
}
.t-empty__image {
  width: 240rpx !important;
  height: 240rpx !important;
}
style/common.wxss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
.m-t-4 {
  margin-top: 4px;
}
.m-b-4 {
  margin-bottom: 4px;
}
.m-r-4 {
  margin-right: 4px;
}
.m-l-4 {
  margin-left: 4px;
}
style/page.wxss
@@ -4,6 +4,7 @@
}
.page {
  position: relative;
  min-height: 100vh;
  background-color: var(--td-bg-color);
  padding-top: 0px;