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"
@@ -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,38 +105,8 @@
            >新建任务</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
@@ -185,10 +153,23 @@
          prop="longTask"
        >
          <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"
@@ -202,7 +183,6 @@
            />
          </template>
        </el-table-column>
        <el-table-column
          label="创建人"
          align="center"
@@ -220,12 +200,11 @@
            <span>{{ formatTime(scope.row.createTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          fixed="right"
          align="center"
          width="240"
          width="320"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
@@ -241,11 +220,6 @@
                ><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"
@@ -268,13 +242,23 @@
              @click="stop(scope.row)"
              ><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>
        </el-table-column>
        <el-table-column
          label="任务详情"
          fixed="right"
          align="center"
          width="240"
          width="180"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
@@ -286,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
@@ -295,7 +278,6 @@
          </template>
        </el-table-column>
      </el-table>
      <pagination
        v-show="total > 0"
        :total="total"
@@ -304,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="任务发起确认"
@@ -401,13 +408,16 @@
  getTasklist,
  delTaskInfo,
  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"],
@@ -436,6 +446,10 @@
      deptName: undefined,
      // 默认密码
      initPassword: undefined,
      // 二维码相关
      qrDialogVisible: false,
      qrCodeUrl: "", // 中间页链接
      qrCodeCanvas: null, // 存储canvas引用
      // 日期范围
      dateRange: [],
      // 岗位选项
@@ -1003,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(() => {});
      }
    },
@@ -1072,6 +1094,107 @@
      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>
@@ -1104,7 +1227,10 @@
    font-size: 23px;
  }
}
.button-qr {
  font-weight: 500;
  color: #e6a23c;
}
.uploading {
  margin-top: 20px;
  margin: 20px;
@@ -1165,42 +1291,50 @@
    }
  }
}
.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;
@@ -1217,6 +1351,7 @@
::v-deep.el-button + .el-button {
  margin-left: 0;
}
::v-deep.el-checkbox-group {
  span {
    font-size: 24px;