123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- <template>
- <div class="title cl">
- <span class="y"><router-link to="/home">返回考试主页</router-link></span>
- <h2>图片下载</h2>
- </div>
- <div class="picture cl">
- <table cellpadding="0" cellspacing="0" width="100%">
- <tr>
- <th>下载内容:</th>
- <td>
- <div class="input-radio">
- <a-radio-group name="radioGroup" v-model:value="type">
- <a-radio value="1">考生原图</a-radio>
- <a-radio value="2">签到表图片</a-radio>
- </a-radio-group>
- </div>
- </td>
- </tr>
- <tr>
- <th>本地保存地址:</th>
- <td>
- <input
- type="text"
- style="width: 400px"
- class="filetext"
- :value="dir"
- />
- <a href="##" class="filebtn" @click="chooseDirectory">选择</a>
- </td>
- </tr>
- <tr>
- <th>图片转存规则:</th>
- <td>
- <a-input v-model:value="template" style="width: 600px" />
- </td>
- </tr>
- <tr id="message-tr">
- <th></th>
- <td>
- <p v-if="ruleExample" class="error-tetx" id="message-text">
- {{ ruleExample }}
- </p>
- </td>
- </tr>
- <tr id="append-select">
- <th>是否续传:</th>
- <td>
- <div class="input-radio">
- <a-radio-group name="radioGroup" v-model:value="append">
- <a-radio :value="true">是</a-radio>
- <a-radio :value="false">否</a-radio>
- </a-radio-group>
- </div>
- </td>
- </tr>
- <tr id="exception-select">
- <th>异常处理:</th>
- <td>
- <div class="input-radio">
- <a-radio-group name="radioGroup" v-model:value="failover">
- <a-radio :value="true">终止</a-radio>
- <a-radio :value="false">跳过</a-radio>
- </a-radio-group>
- </div>
- </td>
- </tr>
- <template v-if="type === '1'">
- <tr id="watermark-select">
- <th>添加分数水印:</th>
- <td>
- <div class="input-radio">
- <a-radio-group name="radioGroup" v-model:value="watermark">
- <a-radio :value="true">是</a-radio>
- <a-radio :value="false">否</a-radio>
- </a-radio-group>
- </div>
- </td>
- </tr>
- <tr id="track-mode-select">
- <th>水印模式:</th>
- <td>
- <div class="input-radio">
- <a-radio-group name="radioGroup" v-model:value="trackMode">
- <a-radio value="1">普通</a-radio>
- <a-radio value="2">研究生</a-radio>
- </a-radio-group>
- </div>
- </td>
- </tr>
- <tr>
- <th>水印显示区域:</th>
- <td>
- <a-button type="primary" @click="showPreview">预览</a-button>
- </td>
- </tr>
- <tr id="examNumber-select">
- <th>准考证号:</th>
- <td>
- <a-input
- v-model:value="examNumber"
- style="width: 600px"
- placeholder="多个准考证号用逗号分隔"
- />
- </td>
- </tr>
- <tr id="subjectCode-select">
- <th>科目代码:</th>
- <td>
- <a-input
- v-model:value="subjectCode"
- style="width: 600px"
- placeholder="多个科目代码用逗号分隔"
- />
- </td>
- </tr>
- </template>
- <tr>
- <td colspan="2" style="text-align: center">
- <a href="##" class="start-btn" @click="start">
- <span>开始图片下载</span>
- </a>
- </td>
- </tr>
- </table>
- </div>
- <a-modal
- v-model:visible="visible"
- title="请选择水印位置"
- width="100%"
- wrapClassName="full-modal"
- ok-text="确定"
- cancel-text="取消"
- :cancel-button-props="{ style: 'display: none' }"
- @ok="visible = false"
- >
- <div style="position: relative">
- <img
- id="preview-image"
- :src="cardUrl"
- draggable="false"
- style="width: 100%; height: 100%; user-select: none"
- />
- <div
- ref="dragContainerRef"
- style="
- color: red;
- border: 2px dotted red;
- cursor: grab;
- width: 80px;
- height: 80px;
- top: 0;
- left: 0;
- user-select: none;
- "
- :style="{ top: yAttr, left: xAttr }"
- @mousedown="mouseDownHandler"
- class="water-mark"
- >
- <div>成绩明细</div>
- </div>
- </div>
- </a-modal>
- </template>
- <script setup lang="ts">
- import { store } from "@/store";
- import { computed, ref, watch } from "vue";
- import { useRouter } from "vue-router";
- import { message } from "ant-design-vue";
- import { throttle } from "lodash";
- const router = useRouter();
- let type = ref("");
- let template = ref("");
- let dir = ref("");
- let append = ref(false);
- let failover = ref(true);
- let watermark = ref(true);
- let trackMode = ref("");
- let examNumber = ref("");
- let subjectCode = ref("");
- let x = ref(0.01);
- let y = ref(0.03);
- const config = store.pageInputs["/image-download"];
- if (config) {
- type.value = config.type;
- template.value = config.template;
- dir.value = config.dir;
- append.value = config.append;
- failover.value = config.failover;
- watermark.value = config.watermark;
- trackMode.value = config.trackMode;
- examNumber.value = config.examNumber || "";
- subjectCode.value = config.subjectCode || "";
- x.value = config.x || 0.01;
- y.value = config.y || 0.03;
- }
- let ruleExample = computed(() => {
- switch (type.value) {
- case "1":
- return "转存规则范例: " + store.config.imageUrl.sheet;
- case "2":
- return "转存规则范例: " + store.config.imageUrl.package;
- }
- return "";
- });
- const chooseDirectory = (e: MouseEvent) => {
- e.preventDefault();
- window.electron.dialog
- .showOpenDialog({
- title: "请选择保存目录",
- properties: ["openDirectory"],
- })
- .then((result) => {
- if (result && result.filePaths) {
- dir.value = result.filePaths[0];
- }
- });
- };
- const start = (e: MouseEvent) => {
- e.preventDefault();
- if (!type.value) {
- message.info("请选择图片类型");
- return false;
- }
- if (!dir.value.trim()) {
- message.info("请选择图片转存目录");
- return false;
- }
- if (!template.value.trim()) {
- message.info("请填写图片转存规则");
- return false;
- }
- if (type.value === "1") {
- if (!x.value) {
- message.info("请填写水印起始位置(横向)");
- return false;
- }
- if (!y.value) {
- message.info("请填写水印起始位置(纵向)");
- return false;
- }
- if (type.value == "1" && trackMode.value == "") {
- message.info("请选择水印模式");
- return false;
- }
- }
- store.pageInputs["/image-download"] = {
- type: type.value,
- template: template.value.trim(),
- dir: dir.value.trim(),
- append: append.value,
- failover: failover.value,
- watermark: watermark.value,
- trackMode: trackMode.value,
- examNumber: examNumber.value.trim(),
- subjectCode: subjectCode.value.trim(),
- x: x.value - 0,
- y: y.value - 0,
- };
- router.push("/image-download");
- };
- watch(type, () => {
- if (type.value === "2") {
- watermark.value = false;
- trackMode.value = "";
- x.value = 0;
- y.value = 0;
- examNumber.value = "";
- subjectCode.value = "";
- }
- });
- let visible = ref(false);
- let cardUrl = computed(() => {
- if (trackMode.value === "1") {
- return "/img/common_card.jpg";
- } else if (trackMode.value === "2") {
- return "/img/master-card.jpg";
- } else {
- return "";
- }
- });
- let dragContainerRef = ref();
- const showPreview = () => {
- if (cardUrl.value) {
- visible.value = true;
- } else {
- message.info("请选择水印模式");
- }
- };
- let xAttr = computed(() => x.value * 100 + "%");
- let yAttr = computed(() => y.value * 100 + "%");
- let clientX = 0,
- clientY = 0;
- const mouseDownHandler = (e: MouseEvent) => {
- // console.log(e);
- const con = dragContainerRef.value as HTMLDivElement;
- con.addEventListener("mousemove", mouseMoveThrottle);
- con.addEventListener("mouseup", mouseUpHandler);
- con.addEventListener("mouseout", mouseoutHandler);
- clientX = e.clientX;
- clientY = e.clientY;
- };
- const mouseMoveHandler = (e: MouseEvent) => {
- // console.log(e);
- const image = document.querySelector("#preview-image") as HTMLImageElement;
- x.value += (e.clientX - clientX) / image.width;
- clientX = e.clientX;
- y.value += (e.clientY - clientY) / image.height;
- clientY = e.clientY;
- // console.log(x.value, y.value);
- if (x.value < 0) {
- x.value = 0;
- }
- if (x.value > 1) {
- x.value = 1;
- }
- if (y.value < 0) {
- y.value = 0;
- }
- if (y.value > 1) {
- y.value = 1;
- }
- };
- const mouseMoveThrottle = throttle((e: MouseEvent) => mouseMoveHandler(e), 100);
- const mouseoutHandler = () => {
- mouseUpHandler();
- };
- const mouseUpHandler = () => {
- // console.log(e);
- const con = dragContainerRef.value as HTMLDivElement;
- con.removeEventListener("mousemove", mouseMoveThrottle);
- con.removeEventListener("mouseup", mouseUpHandler);
- con.removeEventListener("mouseout", mouseoutHandler);
- };
- </script>
- <style>
- .full-modal .ant-modal {
- max-width: 100%;
- top: 0;
- padding-bottom: 0;
- margin: 0;
- }
- .full-modal .ant-modal-content {
- display: flex;
- flex-direction: column;
- height: calc(100vh);
- }
- .full-modal .ant-modal-body {
- flex: 1;
- }
- </style>
- <style scoped>
- .water-mark {
- position: absolute;
- }
- </style>
|