WXL (wul)
6 天以前 a5cba9ab040f6f97558046885dce3017f9bab7e9
src/views/followvisit/tasklist/index.vue
@@ -2,7 +2,6 @@
  <div class="app-container">
    <el-row :gutter="20">
      <!--用户数据-->
      <el-form
        :model="topqueryParams"
        ref="queryForm"
@@ -23,7 +22,7 @@
            @keyup.enter.native="handleQuery"
          ></el-input>
        </el-form-item>
        <el-form-item label="创发送时间">
        <el-form-item label="发送时间">
          <el-date-picker
            v-model="dateRange"
            style="width: 240px"
@@ -34,7 +33,6 @@
            end-placeholder="结束日期"
          ></el-date-picker>
        </el-form-item>
        <el-form-item label="任务模板" prop="status">
          <el-input
            v-model="topqueryParams.templatename"
@@ -107,42 +105,11 @@
            >新建任务</el-button
          >
        </el-col>
        <!-- <el-col :span="19">
          <div class="documentf">
            <div class="document">
              <el-button
                type="warning"
                plain
                icon="el-icon-download"
                size="medium"
                @click="handleExport"
                v-hasPermi="['system:user:export']"
                >导出</el-button
              >
            </div>
          </div>
        </el-col> -->
        <!-- <el-col :span="1.5"> </el-col> -->
      </el-row>
      <!-- <right-toolbar
              :showSearch.sync="showSearch"
              @queryTable="getList"
              :columns="columns"
            ></right-toolbar> -->
      <el-table v-loading="loading" :data="userList">
        <!-- <el-table-column
          label="序号"
          fixed
          align="center"
          key="taskid"
          prop="taskid"
        /> -->
        <el-table-column
          label="任务名称"
          fixed
          width="120"
          align="center"
          key="taskName"
          prop="taskName"
@@ -150,7 +117,6 @@
        />
        <el-table-column
          label="任务描述"
          width="280"
          align="center"
          key="taskDesc"
          prop="taskDesc"
@@ -158,20 +124,26 @@
        />
        <el-table-column
          label="服务项目"
          width="120"
          align="center"
          key="templatename"
          prop="templatename"
          :show-overflow-tooltip="true"
        />
        <el-table-column
          label="待执行/总任务"
          label="总任务/已随访"
          align="center"
          key="nickName"
          width="120"
          prop="nickName"
        >
          <template slot-scope="scope">
            <span>{{ scope.row.wfs }}/{{ scope.row.yfs }}</span>
            <span
              >{{
                scope.row.wfs || scope.row.wfs == 0
                  ? scope.row.wfs + scope.row.yfs
                  : ""
              }}/{{ scope.row.yfs }}</span
            >
          </template>
        </el-table-column>
        <el-table-column
@@ -179,19 +151,30 @@
          align="center"
          key="longTask"
          prop="longTask"
          width="120"
        >
          <template slot-scope="scope">
            <span>{{ scope.row.longTask ? "长期任务" : "非长期" }}</span>
            <div v-if="scope.row.longTask == 0">
              <el-tag type="primary" :disable-transitions="false"
                >自定义周期任务</el-tag
              >
            </div>
            <div v-if="scope.row.longTask == 1">
              <el-tag type="success" :disable-transitions="false"
                >长期任务</el-tag
              >
            </div>
            <div v-if="scope.row.longTask == 2">
              <el-tag type="success" :disable-transitions="false"
                >固定任务</el-tag
              >
            </div>
          </template>
        </el-table-column>
        <el-table-column
          label="状态"
          align="center"
          key="sendState"
          prop="sendState"
          width="120"
        >
          <template slot-scope="scope">
            <dict-tag
@@ -200,13 +183,11 @@
            />
          </template>
        </el-table-column>
        <el-table-column
          label="创建人"
          align="center"
          key="createBy"
          prop="createBy"
          width="120"
          :show-overflow-tooltip="true"
        />
        <el-table-column
@@ -214,18 +195,16 @@
          sortable
          align="center"
          prop="createTime"
          width="160"
        >
          <template slot-scope="scope">
            <span>{{ formatTime(scope.row.createTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          fixed="right"
          align="center"
          width="180"
          width="320"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
@@ -241,17 +220,19 @@
                ><i class="el-icon-s-promotion"></i>发起</span
              ></el-button
            >
            <!-- <el-button size="medium" type="text" @click="newAdd(scope.row)"
              ><span class="button-xj"
                ><i class="el-icon-circle-plus-outline"></i>终止</span
              ></el-button
            > -->
            <el-button
              size="medium"
              type="text"
              @click="handleUpdate(scope.row, 1)"
              ><span class="button-xj"
                ><i class="el-icon-circle-plus-outline"></i>依照新增</span
              ><span class="button-xj">依照新增</span></el-button
            >
            <el-button
              v-if="scope.row.sendState != 5"
              size="medium"
              type="text"
              @click="handleAddpatient(scope.row.taskid, scope.row.type)"
              ><span class="button-hz"
                ><i class="el-icon-circle-plus-outline"></i>新增患者</span
              ></el-button
            >
            <el-button
@@ -259,8 +240,16 @@
              size="medium"
              type="text"
              @click="stop(scope.row)"
              ><span class="button-zt"
                ><i class="el-icon-circle-plus-outline"></i>暂停</span
              ><span class="button-zt">暂停</span></el-button
            >
            <!-- 新增二维码按钮 -->
            <el-button
              v-if="orgname == '省立同德翠苑院区'"
              size="medium"
              type="text"
              @click="handleQrCode(scope.row)"
              ><span class="button-qr"
                ><i class="el-icon-s-grid"></i>二维码</span
              ></el-button
            >
          </template>
@@ -269,7 +258,7 @@
          label="任务详情"
          fixed="right"
          align="center"
          width="200"
          width="180"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
@@ -281,7 +270,6 @@
                ><i class="el-icon-s-data"></i>详情</span
              ></el-button
            >
            <el-button size="medium" type="text" @click="deletefn(scope.row)"
              ><span class="button-sc"
                ><i class="el-icon-delete"></i>删除</span
@@ -290,7 +278,6 @@
          </template>
        </el-table-column>
      </el-table>
      <pagination
        v-show="total > 0"
        :total="total"
@@ -299,6 +286,31 @@
        @pagination="getList"
      />
    </el-row>
    <!-- 二维码弹窗 -->
    <el-dialog
      title="任务二维码"
      :visible.sync="qrDialogVisible"
      width="400px"
      center
      :before-close="handleQrClose"
    >
      <div style="text-align: center; padding: 20px 0">
        <div
          id="qrCodeContainer"
          ref="qrCodeContainer"
          style="display: inline-block"
        ></div>
        <div style="margin-top: 15px; color: #606266; font-size: 14px">
          请使用微信/浏览器扫码访问
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="downloadQrCode">下载二维码</el-button>
        <el-button type="primary" @click="printQrCode">打印</el-button>
        <el-button @click="qrDialogVisible = false">关闭</el-button>
      </span>
    </el-dialog>
    <!-- 确认发起对话框 -->
    <el-dialog
      title="任务发起确认"
@@ -373,6 +385,13 @@
        >
      </div>
    </el-dialog>
    <!-- 选择患者弹框 -->
    <Patient-Selection
      ref="Patient"
      :dialogVisiblepatient="dialogVisiblepatient"
      @addoption="addoption"
      @kkoption="dialogVisiblepatient = true"
    />
  </div>
</template>
@@ -387,23 +406,22 @@
} from "@/api/system/user";
import {
  getTasklist,
  getTaskInfo,
  Editsingletask,
  delTaskInfo,
  Questionnairetasklist,
  Questionnairetaskget,
  Questionnairetasksponsor,
  TaskTemplateSendExecution,
  scanGenerateSubtask,
  goSfRelay,
} from "@/api/AiCentre/index";
import store from "@/store";
import PatientSelection from "@/components/PatientSelection"; //正则组件
import SFtable from "@/components/SFtable"; //表格组件
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
// 引入二维码库
import QRCode from "qrcode";
export default {
  name: "Tasklist",
  dicts: ["sys_normal_disable", "sys_user_sex", "task_status"],
  components: { Treeselect },
  components: { Treeselect, PatientSelection },
  data() {
    return {
      // 遮罩层
@@ -428,6 +446,10 @@
      deptName: undefined,
      // 默认密码
      initPassword: undefined,
      // 二维码相关
      qrDialogVisible: false,
      qrCodeUrl: "", // 中间页链接
      qrCodeCanvas: null, // 存储canvas引用
      // 日期范围
      dateRange: [],
      // 岗位选项
@@ -441,6 +463,8 @@
        showTimeNight: [],
        showTimeNoon: [],
      },
      dialogVisiblepatient: false,
      Patientlist: [],
      taskformVisible: false,
      dynamicTags: ["选项一", "选项二", "选项三"], //选项
      inputVisible: false,
@@ -452,6 +476,7 @@
      previewtype: 2, //预览影像随访类型
      total: 0, // 总条数
      ImportQuantity: 999, //导影像随访数量
      orgname: null,
      //预览影像随访信息
      previewvalue: {
        username: "这个医生对你怎么样",
@@ -469,43 +494,13 @@
          value: 3,
          label: "宣教关怀",
        },
      ],
      taskoptions: [
        {
          value: "1",
          label: "心电随访",
        },
        {
          value: "2",
          label: "出院随访",
        },
        {
          value: "3",
          label: "影像随访",
        },
        {
          value: "4",
          label: "宣教关怀",
        },
        {
          value: "5",
          label: "体检随访",
        },
        {
          value: "6",
          label: "满意度调查",
        },
        {
          value: "7",
          label: "患者报告",
        },
        {
          value: "8",
          label: "其他通知",
          value: 4,
          label: "消息通知",
        },
      ],
      tasktopic: "2", //新增类型
      taskoptions: store.getters.tasktypes,
      tasktopic: 2, //新增类型
      activname: "",
      value: [],
      list: [],
@@ -605,6 +600,8 @@
        pageNum: 1,
        pageSize: 10,
        type: 2,
        leaveldeptcodes: [],
        leavehospitaldistrictcodes: [],
        userName: undefined,
        tagid: undefined,
        topic: undefined,
@@ -662,14 +659,18 @@
  },
  watch: {},
  created() {
    this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
      (obj) => obj.deptCode
    );
    this.topqueryParams.leavehospitaldistrictcodes =
      store.getters.belongWards.map((obj) => obj.districtCode);
    this.orgname = localStorage.getItem("orgname");
    if (this.orgname == "南华大学附属第一医院") {
      this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
        (obj) => obj.deptCode
      );
      this.topqueryParams.leavehospitaldistrictcodes =
        store.getters.belongWards.map((obj) => obj.districtCode);
    }
    this.tasktopic = this.$route.query.tasktopic
      ? this.$route.query.tasktopic
      : this.tasktopic;
    this.tasktopic = Number(this.tasktopic);
    this.getList();
    this.getConfigKey("sys.user.initPassword").then((response) => {
      this.initPassword = response.msg;
@@ -689,7 +690,6 @@
    /** 查询任务列表 */
    getList() {
      this.loading = true;
      console.log(this.topqueryParams.type);
      this.topqueryParams.serviceType = Number(this.tasktopic);
      if (
@@ -697,9 +697,12 @@
        this.tasktopic == 3 ||
        this.tasktopic == 1 ||
        this.tasktopic == 7 ||
        this.tasktopic == 5 ||
        this.tasktopic == 18 ||
        this.tasktopic == 19 ||
        this.tasktopic == 6
      ) {
        if (!this.topqueryParams.type) this.topqueryParams.type = '2';
        if (!this.topqueryParams.type) this.topqueryParams.type = "2";
        this.longtermlist = [
          {
            value: 1,
@@ -710,16 +713,22 @@
            label: "问卷随访",
          },
        ];
      } else if (this.tasktopic == 4 || this.tasktopic == 8) {
        if (!this.topqueryParams.type) this.topqueryParams.type = '3';
        // this.topqueryParams.type = 2;
      } else if (
        this.tasktopic == 4 ||
        this.tasktopic == 8 ||
        this.tasktopic == 17
      ) {
        if (!this.topqueryParams.type) this.topqueryParams.type = "3";
        this.longtermlist = [
          {
            value: 3,
            label: "宣教关怀",
          },
        ];
      } else if (this.tasktopic == 5) {
        if (!this.topqueryParams.type) this.topqueryParams.type = '1';
        this.topqueryParams.type = 3;
      } else if (this.tasktopic == 16) {
        if (!this.topqueryParams.type) this.topqueryParams.type = "2";
        this.longtermlist = [
          {
            value: 1,
@@ -729,14 +738,15 @@
            value: 2,
            label: "问卷随访",
          },
          {
            value: 3,
            label: "宣教关怀",
          },
        ];
        // this.topqueryParams.type = 2;
      }
      // this.topqueryParams.typename = this.findLabelByValue(
      //   this.taskoptions,
      //   this.tasktopic
      // );
      this.topqueryParams.startOutHospTime = this.dateRange[0];
      this.topqueryParams.endOutHospTime = this.dateRange[1];
      this.topqueryParams.beginTime = this.dateRange[0];
      this.topqueryParams.endTime = this.dateRange[1];
      getTasklist(this.topqueryParams).then((response) => {
        this.userList = response.rows;
        this.total = response.total;
@@ -795,8 +805,15 @@
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.topqueryParams.deptId = undefined;
      this.$refs.tree.setCurrentKey(null);
      this.topqueryParams = {
        pageNum: 1,
        pageSize: 10,
        type: 2,
        userName: undefined,
        tagid: undefined,
        topic: undefined,
      };
      // this.$refs.tree.setCurrentKey(null);
      this.handleQuery();
    },
    // 多选框选中数据
@@ -1000,16 +1017,24 @@
    // 暂停
    stop(row) {
      console.log(row);
      if (row.sendState == 2) {
        this.TaskOperation.taskId = row.taskid;
        console.log(11);
        this.TaskOperation.sendState = 3;
        this.TaskOperation.sendType = "";
        this.TaskOperation.taskType = row.type;
        TaskTemplateSendExecution(this.TaskOperation).then((res) => {
          this.$modal.msgSuccess("任务已暂停");
          this.getList();
        });
        this.$modal
          .confirm('是否确认暂停"' + row.taskName + '"?')
          .then(() => {
            TaskTemplateSendExecution(this.TaskOperation).then((res) => {
              this.$modal.msgSuccess("任务已暂停");
              this.getList();
            });
          })
          .catch(() => {});
      }
    },
@@ -1061,6 +1086,115 @@
      const item = data.find((item) => item.value === value);
      return item ? item.label : null;
    },
    handleAddpatient(taskid) {
      this.$refs.Patient.handleAddpatient(taskid);
      this.dialogVisiblepatient = true; // 手动控制弹窗显示
    },
    addoption() {
      this.dialogVisiblepatient = false; // 手动控制弹窗显示
      this.handleQuery();
    },
    // ============二维码相关
    /**
     * 生成二维码
     */
    handleQrCode(row) {
      // 1. 构造请求参数
      const params = {
        taskId: row.taskid,
        deptcode: row.deptcode || "", // 当前用户部门编码,请确保 store 中有该 getter
        leavehospitaldistrictcode: row.leavehospitaldistrictcode || "", // 转为逗号分隔字符串,视接口需求
        // 如果有其他参数如 hospitalDistrictCode 也可补充
      };
      // 2. 调用 goSfRelay 获取中间页链接
      goSfRelay(params)
        .then((res) => {
          if (res.code == 200) {
            this.qrCodeUrl = res.msg; // 假设返回 data 为完整 URL
            this.qrDialogVisible = true;
            this.$nextTick(() => {
              this.generateQrCode(this.qrCodeUrl);
            });
          } else {
            this.$modal.msgError("获取二维码链接失败");
          }
        })
        .catch(() => {
          this.$modal.msgError("获取二维码链接异常");
        });
    },
    /**
     * 生成二维码图片
     */
    generateQrCode(url) {
      const container = this.$refs.qrCodeContainer;
      if (!container) return;
      // 清空容器
      container.innerHTML = "";
      // 使用 QRCode 库绘制 canvas
      QRCode.toCanvas(url, { width: 200, margin: 2 }, (err, canvas) => {
        if (err) {
          console.error(err);
          this.$modal.msgError("生成二维码失败");
          return;
        }
        container.appendChild(canvas);
        this.qrCodeCanvas = canvas; // 保存引用便于下载
      });
    },
    /**
     * 下载二维码(保存为图片)
     */
    downloadQrCode() {
      if (!this.qrCodeCanvas) {
        this.$modal.msgWarning("请先生成二维码");
        return;
      }
      const link = document.createElement("a");
      link.download = `task_qrcode_${Date.now()}.png`;
      link.href = this.qrCodeCanvas.toDataURL("image/png");
      link.click();
    },
    /**
     * 打印二维码(调用浏览器打印,只打印二维码区域)
     */
    printQrCode() {
      if (!this.qrCodeCanvas) {
        this.$modal.msgWarning("请先生成二维码");
        return;
      }
      // 构造打印内容
      const printWindow = window.open("", "_blank", "width=400,height=400");
      const doc = printWindow.document;
      doc.write(`
        <html>
          <head><title>打印二维码</title></head>
          <body style="text-align:center;padding-top:50px;">
            <img src="${this.qrCodeCanvas.toDataURL(
              "image/png"
            )}" style="width:300px;height:300px;" />
            <p style="font-size:14px;color:#666;">请使用微信/浏览器扫码</p>
          </body>
        </html>
      `);
      doc.close();
      printWindow.focus();
      printWindow.print();
    },
    /**
     * 关闭二维码弹窗
     */
    handleQrClose() {
      this.qrDialogVisible = false;
      this.qrCodeUrl = "";
      this.qrCodeCanvas = null;
      const container = this.$refs.qrCodeContainer;
      if (container) container.innerHTML = "";
    },
  },
};
</script>
@@ -1093,7 +1227,10 @@
    font-size: 23px;
  }
}
.button-qr {
  font-weight: 500;
  color: #e6a23c;
}
.uploading {
  margin-top: 20px;
  margin: 20px;
@@ -1154,38 +1291,52 @@
    }
  }
}
.button-bb {
  font-weight: 500;
  color: #2ba05c;
}
.button-xq {
  font-weight: 500;
  color: #409eff;
}
.button-sc {
  font-weight: 500;
  color: #dd302a;
}
.button-zx {
  background: #4fabe9;
  padding: 5px;
  border-radius: 1px;
  color: #ffffff;
}
.button-lj {
  background: #e9614f;
  padding: 5px;
  border-radius: 1px;
  color: #ffffff;
}
.button-xj {
  background: #815c94;
  padding: 5px;
  border-radius: 1px;
  color: #ffffff;
}
.button-zt {
  background: #f9c116;
  padding: 5px;
  border-radius: 1px;
  color: #ffffff;
}
.button-hz {
  background: #63d37b;
  padding: 5px;
  border-radius: 1px;
  color: #ffffff;
@@ -1200,6 +1351,7 @@
::v-deep.el-button + .el-button {
  margin-left: 0;
}
::v-deep.el-checkbox-group {
  span {
    font-size: 24px;