From 2140c5aae2032673cef7055df9738b9bacf37816 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期三, 23 九月 2026 16:46:20 +0800
Subject: [PATCH] 青岛维护
---
pagesSub/ethicalReview/ethicalInfo.vue | 1089 ++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 777 insertions(+), 312 deletions(-)
diff --git a/pagesSub/ethicalReview/ethicalInfo.vue b/pagesSub/ethicalReview/ethicalInfo.vue
index 6cb25c2..84e3fd9 100644
--- a/pagesSub/ethicalReview/ethicalInfo.vue
+++ b/pagesSub/ethicalReview/ethicalInfo.vue
@@ -28,7 +28,7 @@
<up-icon name="man" size="14" color="#909399" />
<text class="compact-label">鎬у埆/骞撮緞</text>
<text class="compact-value"
- >{{ caseInfo.sex || "--" }}/{{ caseInfo.age || "--"
+ >{{ caseInfo.sex == 1 ? '鐢�' : caseInfo.sex == 2 ? '濂�' : '鏈煡' }}/{{ caseInfo.age || "--"
}}{{ caseInfo.ageunit || "宀�" }}</text
>
</view>
@@ -213,69 +213,75 @@
<text>褰撳墠浠诲姟宸茶秴鏃讹紝浠呭彲鏌ョ湅锛屼笉鍙搷浣�</text>
</view>
- <!-- 浼樺寲鐨勭鍚嶅脊绐楃粍浠� -->
- <u-popup
- :show="showSignaturePanel"
- @close="closeSignaturePanel"
- mode="bottom"
- :round="20"
- :closeable="true"
- closeIcon="close"
- >
- <view class="signature-modal">
- <view class="modal-header">
- <text class="modal-title">鎵嬪啓绛惧悕</text>
- <text class="modal-subtitle">璇峰湪涓嬫柟鍖哄煙杩涜绛惧悕</text>
- </view>
+ <!-- 鍏ㄥ睆绛惧悕寮规锛圕anvas 2D 鍚屾缁樺埗锛岃В鍐虫柇鐐逛笌 iOS 鍏煎闂锛� -->
+ <view v-if="showSignaturePanel" class="fullscreen-signature">
+ <!-- 椤堕儴鏍� -->
+ <view class="fs-header">
+ <text class="fs-header-btn fs-cancel" @tap="closeSignaturePanel">鍙栨秷</text>
+ <text class="fs-title">鎵嬪啓绛惧悕</text>
+ <text class="fs-header-btn fs-clear" @tap="clearCanvas">娓呯┖</text>
+ </view>
- <view class="signature-canvas-container">
- <!-- 鎵嬪啓绛惧悕鐢诲竷 -->
- <canvas
- canvas-id="signatureCanvas"
- class="signature-canvas"
- :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
- @touchstart="onTouchStart"
- @touchmove="onTouchMove"
- @touchend="onTouchEnd"
- disable-scroll
- ></canvas>
+ <!-- 绛惧悕鐢诲竷鍖哄煙锛堝崰婊″墿浣欑┖闂达級 -->
+ <view class="fs-body">
+ <!-- H5 绔細canvas 鐢� JS 鍘熺敓鍒涘缓 + 鍘熺敓浜嬩欢缁戝畾锛堢粫寮�缁勪欢缂栬瘧灞傜殑鍧愭爣宸紓锛屾牴娌荤瑪杩归敊浣嶏級 -->
+ <!-- #ifdef H5 -->
+ <view id="h5CanvasWrap" ref="h5CanvasWrap" class="fs-canvas-wrap"></view>
+ <!-- #endif -->
- <!-- 鎿嶄綔鎸夐挳 -->
- <view class="canvas-actions">
- <button class="action-btn clear-btn" @tap="clearCanvas">
- <up-icon name="trash" size="20" />
- <text>娓呯┖</text>
- </button>
- <button
- class="action-btn redo-btn"
- @tap="undoLastStroke"
- :disabled="!canUndo"
- >
- <up-icon name="play-left" size="20" />
- <text>鎾ら攢</text>
- </button>
- <button
- class="action-btn confirm-btn"
- @tap="confirmSignature"
- :disabled="!hasSignature"
- >
- <up-icon name="checkmark" size="20" />
- <text>纭绛惧悕</text>
- </button>
- </view>
+ <!-- 灏忕▼搴�/App 绔細canvas 2d 缁勪欢 -->
+ <!-- #ifndef H5 -->
+ <canvas
+ id="signatureCanvas"
+ canvas-id="signatureCanvas"
+ type="2d"
+ class="fs-canvas"
+ @touchstart="onTouchStart"
+ @touchmove="onTouchMove"
+ @touchend="onTouchEnd"
+ @touchcancel="onTouchEnd"
+ disable-scroll
+ ></canvas>
+ <!-- #endif -->
- <!-- 绛惧悕棰勮 -->
- <view v-if="tempSignatureData" class="signature-preview">
- <text class="preview-title">绛惧悕棰勮</text>
- <image
- :src="tempSignatureData"
- mode="aspectFit"
- class="preview-image"
- />
- </view>
+ <view v-if="!hasSignature" class="fs-hint" @tap.stop>
+ <up-icon name="edit-pen" size="44" color="#c0c4cc" />
+ <text>璇峰湪姝ゅ尯鍩熺鍚�</text>
</view>
</view>
- </u-popup>
+
+ <!-- 绗旇Е绮楃粏閫夋嫨 -->
+ <view class="fs-toolbar">
+ <view
+ class="toolbar-item"
+ v-for="s in strokeSizes"
+ :key="s.value"
+ @tap="strokeWidth = s.value"
+ >
+ <view
+ class="size-dot"
+ :style="{
+ width: s.value * 2 + 'px',
+ height: s.value * 2 + 'px',
+ background: strokeWidth == s.value ? '#0f95b0' : '#c0c4cc',
+ }"
+ ></view>
+ <text class="size-label" :class="{ active: strokeWidth == s.value }">{{
+ s.label
+ }}</text>
+ </view>
+ </view>
+
+ <!-- 搴曢儴鎿嶄綔鏍� -->
+ <view class="fs-footer">
+ <button class="fs-btn fs-undo" :disabled="!canUndo" @tap="undoLastStroke">
+ 鎾ら攢
+ </button>
+ <button class="fs-btn fs-confirm" :disabled="!hasSignature" @tap="confirmSignature">
+ 纭绛惧悕
+ </button>
+ </view>
+ </view>
<view v-if="showHomeButton" class="home-fab" @click="goHome">
<uni-icons type="home" size="24" color="#fff" />
@@ -290,15 +296,28 @@
@confirm="confirmSubmit"
@cancel="showSubmitModal = false"
></u-modal>
+
+ <!-- H5 鍐呭祵 PDF 棰勮缁勪欢 -->
+ <!-- #ifdef H5 -->
+ <pdf-preview
+ :show="pdfPreview.show"
+ :url="pdfPreview.url"
+ :title="pdfPreview.title"
+ @close="pdfPreview.show = false"
+ />
+ <!-- #endif -->
</view>
</template>
<script setup>
-import { ref, computed, reactive, onMounted, nextTick } from "vue";
+import { ref, computed, reactive, onMounted, nextTick, getCurrentInstance } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import dayjs from "dayjs";
import { useUserStore } from "@/stores/user";
import { useHomeButton } from "@/stores/useHomeButton";
+// #ifdef H5
+import PdfPreview from "@/components/pdf-preview/index.vue";
+// #endif
const { showHomeButton, checkAutoLogin, goHome } = useHomeButton();
const userStore = useUserStore();
@@ -318,27 +337,22 @@
const fcid = ref(null);
const materials = ref([]);
-// ==================== 鏂板锛氭牴鎹幆澧冭幏鍙� baseUrlHt ====================
+// PDF 棰勮锛圚5 绔唴宓� pdf.js 缁勪欢棰勮锛�
+const pdfPreview = reactive({ show: false, url: "", title: "" });
+
+// ============== 鏂板锛氭牴鎹幆澧冭幏鍙� baseUrlHt ==============
const getBaseUrlHt = () => {
// #ifdef H5
- // H5 鐜锛氭牴鎹祻瑙堝櫒鍦板潃鍔ㄦ�佹嫾鎺�
+ // H5 鐜锛氭枃浠剁粺涓�璧般�屽悓婧愩�嶅湴鍧�锛坵indow.location.origin锛夛紝鐢遍儴缃茶椤甸潰鐨� nginx 鍙嶅悜浠g悊
+ // /profile/ 鍒板悗绔�傝繖鏍锋枃浠朵笌椤甸潰鍚屾簮锛屾祻瑙堝櫒涓嶄細瑙﹀彂 CORS锛堝交搴曡閬垮悗绔噸澶�
+ // Access-Control-Allow-Origin 澶村鑷寸殑璺ㄥ煙鎶ラ敊锛屼篃瑙勯伩浜嗛〉闈㈠湪 :8091銆佹枃浠跺湪 :443 鐨勮法鍩燂級銆�
try {
- const href = window.location.href;
-
- // 瑙勫垯 1锛�192.168.120.27:8091 鈫� 120.27 + :9095
- if (href.startsWith('http://192.168.120.27:8091')) {
- return 'http://192.168.120.27:9095';
- }
-
- // 瑙勫垯 2锛�192.168.76.25:8091 鈫� 76.25 + :9095
- if (href.startsWith('http://192.168.76.25:8091')) {
- return 'http://www.qdopo.com:9095';
- }
-
- // 瑙勫垯 3锛氬叾浣欏叏閮ㄨ蛋鐢熶骇
- return 'https://opo.qduh.cn';
+ return (
+ window.location.origin ||
+ `${window.location.protocol}//${window.location.host}`
+ );
} catch {
- return 'https://opo.qduh.cn';
+ return "https://opo.qduh.cn";
}
// #endif
@@ -376,8 +390,10 @@
});
const conclusionOptions = ref([
- { label: "鍚屾剰", value: "1" }, // 瀵瑰簲receiveStatus 5-瀹屾垚
- { label: "椹冲洖", value: "2" }, // 瀵瑰簲receiveStatus 6-椹冲洖
+ { label: "涓嶅悓鎰�", value: "0" },
+ { label: "鍚屾剰", value: "1" },
+ { label: "寮冩潈", value: "3" },
+ { label: "淇敼鍚庡悓鎰�", value: "4" },
]);
// 绛惧悕鐩稿叧鏁版嵁
@@ -389,17 +405,26 @@
serverData: null,
});
-// 鎵嬪啓绛惧悕鐩稿叧
-const canvasWidth = 650;
-const canvasHeight = 300;
-let ctx = null;
+// 鎵嬪啓绛惧悕鐩稿叧锛圕anvas 2D 鍏ㄥ睆鐗堬級
+let ctx = null; // Canvas 2D 娓叉煋涓婁笅鏂囷紙鍚屾缁樺埗锛�
+let canvasNode = null; // canvas 鑺傜偣锛堢敤浜庡鍑哄浘鐗囷級
+let canvasCssWidth = 0; // 鐢诲竷 CSS 瀹藉害
+let canvasCssHeight = 0; // 鐢诲竷 CSS 楂樺害
+let canvasRect = { left: 0, top: 0 }; // 鐢诲竷鐩稿瑙嗗彛鐨勪綅缃紙閫昏緫鍍忕礌锛夛紝鐢ㄤ簬瑙︽懜鍧愭爣鎹㈢畻
+let strokes = ref([]); // 鎵�鏈夌瑪鐢伙紙姣忕瑪涓� { points: [...], width: n }锛岀敤浜庢挙閿�锛�
+let currentStroke = []; // 褰撳墠姝e湪缁樺埗鐨勭偣鏁扮粍
+let currentStrokeWidth = 4; // 褰撳墠绗旇Е绮楃粏锛坧x锛�
let isDrawing = false;
-let lastX = 0;
-let lastY = 0;
-let strokeHistory = [];
-const tempSignatureData = ref("");
-const canUndo = computed(() => strokeHistory.length > 0);
-const hasSignature = computed(() => tempSignatureData.value !== "");
+
+// 绗旇Е绮楃粏閫夐」
+const strokeSizes = [
+ { label: "缁�", value: 2 },
+ { label: "涓�", value: 4 },
+ { label: "绮�", value: 6 },
+];
+const strokeWidth = ref(4); // 褰撳墠閫変腑鐨勭矖缁嗭紙瀵规柊绗旂敾鐢熸晥锛�
+const hasSignature = ref(false);
+const canUndo = computed(() => strokes.value.length > 0);
// 涓婁紶閰嶇疆
const uploadConfig = reactive({
@@ -455,12 +480,11 @@
return isTimeout.value;
});
-// 鏄惁鍙互鎻愪氦
+// 鏄惁鍙互鎻愪氦锛堝鏌ユ剰瑙佷负闈炲繀濉級
const canSubmit = computed(() => {
if (isReadonly.value) return false;
return (
form.value.expertconclusion !== "" &&
- form.value.expertopinion.trim().length > 0 &&
signatureData.signatureUrl !== "" &&
signatureData.signatureUrl.startsWith("http") // 纭繚鏄畬鏁寸殑URL璺緞
);
@@ -525,7 +549,11 @@
console.log(caseInfo.value.receiveStatus, "caseInfo.value");
// 璁剧疆琛ㄥ崟鏁版嵁
- if (data.expertconclusion) {
+ if (
+ data.expertconclusion !== null &&
+ data.expertconclusion !== undefined &&
+ data.expertconclusion !== ""
+ ) {
form.value.expertconclusion = data.expertconclusion.toString();
}
if (data.expertopinion) {
@@ -588,7 +616,7 @@
}
};
-// ==================== 鏂板锛氳幏鍙栧畬鏁碪RL锛堝钩鍙板畨鍏ㄧ増锛� ====================
+// ============== 鏂板锛氳幏鍙栧畬鏁碪RL锛堝钩鍙板畨鍏ㄧ増锛� ==============
const getFullUrl = (path) => {
if (!path) return '';
@@ -627,7 +655,7 @@
return `${baseUrlHt}${path.startsWith('/') ? '' : '/'}${path}`;
};
-// ==================== 淇敼锛歳eplaceUrlDomain 浣跨敤 getFullUrl ====================
+// ============== 淇敼锛歳eplaceUrlDomain 浣跨敤 getFullUrl ==============
const replaceUrlDomain = (url) => {
return getFullUrl(url);
};
@@ -757,7 +785,7 @@
}
};
-// 鎵撳紑绛惧悕闈㈡澘
+// 鎵撳紑绛惧悕闈㈡澘锛堝叏灞忓脊妗嗭級
const openSignaturePanel = () => {
if (isReadonly.value) {
uni.showToast({
@@ -768,132 +796,435 @@
}
showSignaturePanel.value = true;
+ // 姣忔鎵撳紑閮介噸缃鍚嶇姸鎬侊紝閲嶆柊鍒濆鍖栫敾甯�
+ strokes.value = [];
+ currentStroke = [];
+ hasSignature.value = false;
+ isDrawing = false;
+ ctx = null;
+ canvasNode = null;
+ // 绛夊緟鍏ㄥ睆寮规 DOM 娓叉煋瀹屾垚鍚庡啀鍒濆鍖栫敾甯�
nextTick(() => {
- initCanvas();
+ setTimeout(() => {
+ initCanvas();
+ }, 100);
});
};
// 鍏抽棴绛惧悕闈㈡澘
const closeSignaturePanel = () => {
showSignaturePanel.value = false;
- clearCanvas();
+ // #ifdef H5
+ // 绉婚櫎鍘熺敓浜嬩欢鐩戝惉锛岄伩鍏嶉噸澶嶇粦瀹�
+ if (canvasNode) {
+ canvasNode.removeEventListener("touchstart", onH5TouchStart);
+ canvasNode.removeEventListener("touchmove", onH5TouchMove);
+ canvasNode.removeEventListener("touchend", onH5TouchEnd);
+ canvasNode.removeEventListener("touchcancel", onH5TouchEnd);
+ canvasNode.removeEventListener("mousedown", onH5MouseDown);
+ canvasNode.removeEventListener("mousemove", onH5MouseMove);
+ canvasNode.removeEventListener("mouseup", onH5MouseUp);
+ }
+ // #endif
+ ctx = null;
+ canvasNode = null;
};
-// 鍒濆鍖栫敾甯�
+// 鍒濆鍖栫敾甯冿紙Canvas 2D 鍚屾 API锛�
const initCanvas = () => {
- ctx = uni.createCanvasContext("signatureCanvas");
- clearCanvas();
+ // #ifdef H5
+ initH5Canvas();
+ // #endif
+
+ // #ifndef H5
+ initMPCanvas();
+ // #endif
};
-// 娓呯┖鐢诲竷
-const clearCanvas = () => {
- if (!ctx) return;
+// #ifdef H5
+// ============== H5 绔細鍘熺敓 canvas 鏂规 ==============
+// 涓嶇敤 uni-app 鐨� canvas 缁勪欢锛堝叾缁勪欢灞傚 type="2d" 鐨勮妭鐐�/鍧愭爣澶勭悊鍚勭増鏈笉涓�鑷达級锛�
+// 鑰屾槸鐢� JS 鍔ㄦ�佸垱寤哄師鐢� canvas + 鍘熺敓浜嬩欢缁戝畾锛屽潗鏍囨崲绠楀畬鍏ㄥ彈鎺э紝浠庢牴涓婃秷闄ょ瑪杩瑰亸绉汇��
+const h5CanvasWrap = ref(null);
- ctx.clearRect(0, 0, canvasWidth, canvasHeight);
- ctx.setStrokeStyle("#000000");
- ctx.setLineWidth(3);
- ctx.setLineCap("round");
- ctx.setLineJoin("round");
- ctx.draw();
- strokeHistory = [];
- tempSignatureData.value = "";
-};
+const initH5Canvas = () => {
+ // 鎷垮鍣ㄧ湡瀹� DOM锛歶ni-app H5 閲� <view> 缂栬瘧鎴� uni-view 缁勪欢锛宺ef 鎷垮埌鐨勬槸缁勪欢瀹炰緥锛�
+ // 蹇呴』鐢� getElementById 鎴� .$el 鎵嶈兘鎷垮埌鐪熷疄 DOM锛屽惁鍒� appendChild 浼氭姤閿欍�乧anvas 鍒涘缓涓嶅嚭鏉ャ��
+ let wrap = document.getElementById("h5CanvasWrap");
+ if (!wrap && h5CanvasWrap.value) {
+ wrap = h5CanvasWrap.value.$el || h5CanvasWrap.value;
+ }
+ if (!wrap) {
+ console.error("[绛惧悕] H5 鐢诲竷瀹瑰櫒鑾峰彇澶辫触锛坕d=h5CanvasWrap 鏈壘鍒帮級");
+ return;
+ }
+ // 娓呯┖瀹瑰櫒锛岄伩鍏嶉噸澶嶅垵濮嬪寲浜х敓澶氫釜 canvas
+ wrap.innerHTML = "";
+ const canvas = document.createElement("canvas");
+ canvas.style.display = "block";
+ canvas.style.background = "#ffffff";
+ canvas.style.touchAction = "none";
+ wrap.appendChild(canvas);
-// 鎾ら攢涓婁竴姝�
-const undoLastStroke = () => {
- if (strokeHistory.length == 0) return;
+ // 璇诲彇瀹瑰櫒瀹為檯娓叉煋灏哄骞惰 canvas 鎾戞弧锛堜笉渚濊禆鐧惧垎姣旓紝閬垮厤 flex 瀹瑰櫒涓В鏋愬紓甯稿鑷村昂瀵镐负 0锛�
+ const fit = () => {
+ const wr = wrap.getBoundingClientRect();
+ if (!wr.width || !wr.height) return false;
+ canvas.style.width = wr.width + "px";
+ canvas.style.height = wr.height + "px";
+ return true;
+ };
- // 绉婚櫎鏈�鍚庝竴姝�
- strokeHistory.pop();
+ const bind = () => {
+ try {
+ const rect = canvas.getBoundingClientRect();
+ canvasNode = canvas;
+ canvasCssWidth = rect.width;
+ canvasCssHeight = rect.height;
+ canvasRect = { left: rect.left, top: rect.top };
+ const dpr = window.devicePixelRatio || 2;
+ canvas.width = rect.width * dpr;
+ canvas.height = rect.height * dpr;
+ ctx = canvas.getContext("2d");
+ ctx.scale(dpr, dpr);
+ console.log("[绛惧悕] H5 鐢诲竷鍒濆鍖�", {
+ cssW: canvasCssWidth,
+ cssH: canvasCssHeight,
+ dpr,
+ rect: canvasRect,
+ });
+ redraw();
- // 閲嶆柊缁樺埗
- ctx.clearRect(0, 0, canvasWidth, canvasHeight);
- ctx.setStrokeStyle("#000000");
- ctx.setLineWidth(3);
- ctx.setLineCap("round");
- ctx.setLineJoin("round");
+ // 瑙︽懜浜嬩欢锛堟墜鏈�/骞虫澘锛�
+ canvas.addEventListener("touchstart", onH5TouchStart, { passive: false });
+ canvas.addEventListener("touchmove", onH5TouchMove, { passive: false });
+ canvas.addEventListener("touchend", onH5TouchEnd);
+ canvas.addEventListener("touchcancel", onH5TouchEnd);
+ // 榧犳爣浜嬩欢锛圥C 娴忚鍣ㄨ皟璇曪級
+ canvas.addEventListener("mousedown", onH5MouseDown);
+ canvas.addEventListener("mousemove", onH5MouseMove);
+ canvas.addEventListener("mouseup", onH5MouseUp);
+ } catch (err) {
+ console.error("[绛惧悕] H5 鐢诲竷鍒濆鍖栧け璐�:", err);
+ }
+ };
- // 缁樺埗鍘嗗彶绗旇抗
- strokeHistory.forEach((stroke) => {
- ctx.beginPath();
- ctx.moveTo(stroke.startX, stroke.startY);
- ctx.lineTo(stroke.endX, stroke.endY);
- ctx.stroke();
- });
-
- ctx.draw();
-
- // 鏇存柊棰勮
- if (strokeHistory.length == 0) {
- tempSignatureData.value = "";
+ // 甯冨眬鍙兘灏氭湭绋冲畾锛堝脊妗嗗垰鏄剧ず锛夛紝灏哄涓� 0 鏃堕噸璇曞嚑娆�
+ if (fit()) {
+ bind();
} else {
- getCanvasImage();
+ let tries = 0;
+ const timer = setInterval(() => {
+ tries++;
+ if (fit() || tries >= 10) {
+ clearInterval(timer);
+ if (fit()) {
+ bind();
+ } else {
+ console.error("[绛惧悕] H5 鐢诲竷瀹瑰櫒灏哄濮嬬粓涓� 0锛屽垵濮嬪寲澶辫触");
+ }
+ }
+ }, 50);
}
};
-// 瑙︽懜寮�濮�
-const onTouchStart = (e) => {
- if (isReadonly.value) return;
-
- isDrawing = true;
- const touch = e.touches[0];
- lastX = touch.x;
- lastY = touch.y;
- ctx.beginPath();
- ctx.moveTo(lastX, lastY);
+// H5 瑙︽懜鍧愭爣锛氬疄鏃跺彇 getBoundingClientRect锛屼笌瑙︽懜瑙嗗彛鍧愭爣鍚屾簮鎹㈢畻
+let lastH5TouchEndTime = 0; // 璁板綍瑙︽懜缁撴潫鏃堕棿锛岀敤浜庡睆钄借Е鎽稿悗娴忚鍣ㄦ淳鍙戠殑鍏煎 mouse 浜嬩欢
+const onH5TouchStart = (e) => {
+ if (!ctx || isReadonly.value) return;
+ const t = e.touches[0];
+ if (!t) return;
+ const rect = canvasNode.getBoundingClientRect();
+ beginStroke({ x: t.clientX - rect.left, y: t.clientY - rect.top });
};
-// 瑙︽懜绉诲姩
-const onTouchMove = (e) => {
- if (!isDrawing || isReadonly.value) return;
+const onH5TouchMove = (e) => {
+ e.preventDefault();
+ if (!isDrawing || !ctx) return;
+ const t = e.touches[0];
+ if (!t) return;
+ const rect = canvasNode.getBoundingClientRect();
+ continueStroke({ x: t.clientX - rect.left, y: t.clientY - rect.top });
+};
- const touch = e.touches[0];
- const currentX = touch.x;
- const currentY = touch.y;
+const onH5TouchEnd = () => {
+ lastH5TouchEndTime = Date.now();
+ endStroke();
+};
- ctx.lineTo(currentX, currentY);
- ctx.stroke();
- ctx.draw(true);
+// H5 榧犳爣浜嬩欢锛圥C 璋冭瘯鐢級
+let h5MouseDown = false;
+const onH5MouseDown = (e) => {
+ // 瑙︽懜缁撴潫鍚� 500ms 鍐呯殑鍏煎 mouse 浜嬩欢鐩存帴蹇界暐锛岄伩鍏嶅钩鏉�/鎵嬫満涓婄敾澶氫綑鐨勭偣
+ if (Date.now() - lastH5TouchEndTime < 500) return;
+ if (!ctx || isReadonly.value) return;
+ h5MouseDown = true;
+ const rect = canvasNode.getBoundingClientRect();
+ beginStroke({ x: e.clientX - rect.left, y: e.clientY - rect.top });
+};
- // 淇濆瓨绗旇抗鍒板巻鍙茶褰�
- strokeHistory.push({
- startX: lastX,
- startY: lastY,
- endX: currentX,
- endY: currentY,
+const onH5MouseMove = (e) => {
+ if (!h5MouseDown || !isDrawing || !ctx) return;
+ const rect = canvasNode.getBoundingClientRect();
+ continueStroke({ x: e.clientX - rect.left, y: e.clientY - rect.top });
+};
+
+const onH5MouseUp = () => {
+ h5MouseDown = false;
+ endStroke();
+};
+// #endif
+
+// #ifndef H5
+// ============== 灏忕▼搴�/App 绔細canvas 2d ==============
+// 涓�娆� fields({ node, rect }) 鏌ヨ鍚屾椂鎷垮埌 node 鍜屻�岄�昏緫鍍忕礌銆嶄綅缃�/灏哄锛�
+// 閬垮厤 node 涓� boundingClientRect 涓ゆ鏌ヨ涔嬮棿甯冨眬鍙樺寲瀵艰嚧鍩哄噯閿欎綅銆�
+const initMPCanvas = () => {
+ const instance = getCurrentInstance().proxy;
+ const query = uni.createSelectorQuery().in(instance);
+ query
+ .select("#signatureCanvas")
+ .fields({ node: true, rect: true })
+ .exec((res) => {
+ const node = res && res[0] && res[0].node;
+ const rect = res && res[0] && res[0].rect;
+ if (!node) {
+ console.error("[绛惧悕] 鐢诲竷鑺傜偣鑾峰彇澶辫触:", res);
+ uni.showToast({ title: "绛惧悕鍒濆鍖栧け璐ワ紝璇烽噸璇�", icon: "none" });
+ return;
+ }
+ if (rect && rect.width > 0) {
+ // 涓�娆℃煡璇㈠悓鏃舵嬁鍒拌妭鐐瑰拰浣嶇疆锛堥�昏緫鍍忕礌锛夛紝閬垮厤涓ゆ鏌ヨ闂村竷灞�鍙樺寲瀵艰嚧鍩哄噯閿欎綅
+ canvasRect = { left: rect.left, top: rect.top };
+ setupCanvas(node, rect.width, rect.height);
+ return;
+ }
+ // 閮ㄥ垎鍩虹搴� fields 鎷夸笉鍒� rect锛屽厹搴曞崟鐙煡涓�娆� boundingClientRect
+ uni
+ .createSelectorQuery()
+ .in(instance)
+ .select("#signatureCanvas")
+ .boundingClientRect((r) => {
+ if (r && r.width > 0) {
+ canvasRect = { left: r.left, top: r.top };
+ setupCanvas(node, r.width, r.height);
+ } else {
+ console.error("[绛惧悕] 鐢诲竷灏哄鑾峰彇澶辫触:", r);
+ uni.showToast({ title: "绛惧悕鍒濆鍖栧け璐ワ紝璇烽噸璇�", icon: "none" });
+ }
+ })
+ .exec();
+ });
+};
+
+// 姣忔钀界瑪鍓嶅埛鏂扮敾甯冨熀鍑嗕綅缃紝闃插尽椤甸潰婊氬姩/甯冨眬鍙樺寲瀵艰嚧鐨勫亸绉�
+const refreshCanvasRect = () => {
+ uni
+ .createSelectorQuery()
+ .in(getCurrentInstance().proxy)
+ .select("#signatureCanvas")
+ .boundingClientRect((rect) => {
+ if (rect && rect.left !== undefined) {
+ canvasRect = { left: rect.left, top: rect.top };
+ }
+ })
+ .exec();
+};
+// #endif
+
+// 閰嶇疆鐢诲竷锛堣缃墿鐞嗗儚绱狅紝闃叉妯$硦锛�
+const setupCanvas = (node, cssW, cssH) => {
+ canvasNode = node;
+ canvasCssWidth = cssW;
+ canvasCssHeight = cssH;
+ const dpr = uni.getSystemInfoSync().pixelRatio || 2;
+ node.width = cssW * dpr;
+ node.height = cssH * dpr;
+ ctx = node.getContext("2d");
+ ctx.scale(dpr, dpr);
+ // 璋冭瘯鐢細鎵撳嵃鐢诲竷灏哄锛屾帓鏌ョ鍚嶅亸绉伙紙鍚屾椂鍙嵁姝ゅ垽鏂祻瑙堝櫒璺戠殑鏄笉鏄渶鏂板寘锛�
+ console.log("[绛惧悕] 鐢诲竷鍒濆鍖�", {
+ cssW,
+ cssH,
+ dpr,
+ bufferW: node.width,
+ bufferH: node.height,
});
+ redraw();
+};
- lastX = currentX;
- lastY = currentY;
+// 閲嶇粯鎵�鏈夌瑪鐢伙紙Canvas 2D 鍚屾 API锛屾棤涓㈠抚闂锛�
+const redraw = () => {
+ if (!ctx) return;
+
+ // 鐧借壊鑳屾櫙锛堝鍑哄浘鐗囨椂鍗充负鐧藉簳榛戝瓧锛夛紱鍏� clearRect 褰诲簳娓呯┖鍐嶉摵鐧藉簳锛岀‘淇濇挙閿�/娓呯┖鐢熸晥
+ ctx.clearRect(0, 0, canvasCssWidth, canvasCssHeight);
+ ctx.fillStyle = "#ffffff";
+ ctx.fillRect(0, 0, canvasCssWidth, canvasCssHeight);
+
+ // 绾挎潯閫氱敤鏍峰紡
+ ctx.strokeStyle = "#000000";
+ ctx.lineCap = "round";
+ ctx.lineJoin = "round";
+
+ // 閲嶇粯姣忎竴绗旓紙姣忕瑪璁板綍鑷繁鐨勭矖缁嗭紝鍒囨崲绮楃粏涓嶅奖鍝嶅凡鐢荤瑪鐢伙級
+ strokes.value.forEach((stroke) => {
+ const points = stroke.points;
+ ctx.lineWidth = stroke.width;
+ if (points.length == 1) {
+ drawDot(points[0], stroke.width);
+ } else if (points.length > 1) {
+ ctx.beginPath();
+ ctx.moveTo(points[0].x, points[0].y);
+ for (let i = 1; i < points.length; i++) {
+ ctx.lineTo(points[i].x, points[i].y);
+ }
+ ctx.stroke();
+ }
+ });
+};
+
+// 鐢讳竴涓渾鐐癸紙澶勭悊鍗曞嚮涓嶅嚭澧ㄧ殑鎯呭喌锛屽崐寰勯殢绗旇Е绮楃粏锛�
+const drawDot = (p, w) => {
+ const r = Math.max(1, (w || 3) / 2);
+ ctx.beginPath();
+ ctx.arc(p.x, p.y, r, 0, Math.PI * 2);
+ ctx.fillStyle = "#000000";
+ ctx.fill();
+};
+
+// 鑾峰彇瑙︽懜鐐圭浉瀵圭敾甯冪殑鍧愭爣锛堝皬绋嬪簭/App 绔細瑙嗗彛鍧愭爣 - 鐢诲竷浣嶇疆锛�
+// #ifndef H5
+const getTouchPos = (e) => {
+ const t = e.touches[0] || e.changedTouches[0];
+ if (!t) return { x: 0, y: 0 };
+ const cx = typeof t.clientX == "number" ? t.clientX : t.pageX;
+ const cy = typeof t.clientY == "number" ? t.clientY : t.pageY;
+ return { x: cx - canvasRect.left, y: cy - canvasRect.top };
+};
+// #endif
+
+// ============== 鍏辩敤缁樺埗閫昏緫锛圚5 鍘熺敓浜嬩欢涓庡皬绋嬪簭缁勪欢浜嬩欢鍏辩敤锛� ==============
+// 钀界瑪
+const beginStroke = (pos) => {
+ if (!ctx || isReadonly.value) return;
+ isDrawing = true;
+ currentStroke = [pos];
+ currentStrokeWidth = strokeWidth.value; // 璁板綍鏈瑪鐨勭矖缁�
+ strokes.value.push({ points: currentStroke, width: currentStrokeWidth });
+ hasSignature.value = true;
+ ctx.lineWidth = currentStrokeWidth;
+ drawDot(pos, currentStrokeWidth);
+};
+
+// 缁瑪
+const continueStroke = (pos) => {
+ if (!isDrawing || !ctx) return;
+ const prev = currentStroke[currentStroke.length - 1];
+ if (prev) {
+ ctx.beginPath();
+ ctx.lineWidth = currentStrokeWidth;
+ ctx.moveTo(prev.x, prev.y);
+ ctx.lineTo(pos.x, pos.y);
+ ctx.stroke();
+ }
+ currentStroke.push(pos);
+};
+
+// 鏀剁瑪
+const endStroke = () => {
+ if (!isDrawing) return;
+ isDrawing = false;
+ currentStroke = [];
+};
+
+// 瑙︽懜寮�濮嬶紙灏忕▼搴�/App 绔粍浠朵簨浠讹級
+// #ifndef H5
+const onTouchStart = (e) => {
+ if (!ctx || isReadonly.value) return;
+ // 钀界瑪鍓嶅紓姝ュ埛鏂扮敾甯冨熀鍑嗕綅缃紝闃插尽椤甸潰婊氬姩/甯冨眬鍙樺寲瀵艰嚧鐨勫亸绉�
+ refreshCanvasRect();
+ const pos = getTouchPos(e);
+ beginStroke(pos);
+};
+
+// 瑙︽懜绉诲姩锛圕anvas 2D 鍚屾缁樺埗锛岀嚎鏉″疄鏃惰繛缁級
+const onTouchMove = (e) => {
+ if (!isDrawing || !ctx) return;
+ const pos = getTouchPos(e);
+ continueStroke(pos);
};
// 瑙︽懜缁撴潫
const onTouchEnd = () => {
- if (!isDrawing) return;
+ endStroke();
+};
+// #endif
- isDrawing = false;
- ctx.closePath();
-
- // 鏇存柊棰勮
- getCanvasImage();
+// 娓呯┖鐢诲竷
+const clearCanvas = () => {
+ strokes.value = [];
+ currentStroke = [];
+ hasSignature.value = false;
+ redraw();
};
-// 鑾峰彇鐢诲竷鍥剧墖
+// 鎾ら攢涓婁竴绗�
+const undoLastStroke = () => {
+ if (strokes.value.length == 0) return;
+ strokes.value.pop();
+ hasSignature.value = strokes.value.length > 0;
+ redraw();
+};
+
+// 鐢熸垚绛惧悕鍥剧墖锛圥romise 褰㈠紡锛岃繑鍥炰复鏃舵枃浠惰矾寰勶級
const getCanvasImage = () => {
- uni.canvasToTempFilePath({
- canvasId: "signatureCanvas",
- success: (res) => {
- tempSignatureData.value = res.tempFilePath;
- },
- fail: (err) => {
- console.error("鑾峰彇鐢诲竷鍥剧墖澶辫触:", err);
- },
+ return new Promise((resolve, reject) => {
+ if (!canvasNode) {
+ reject(new Error("鐢诲竷鏈垵濮嬪寲"));
+ return;
+ }
+ // #ifdef MP-WEIXIN
+ uni.canvasToTempFilePath({
+ canvas: canvasNode,
+ fileType: "png",
+ success: (res) => resolve(res.tempFilePath),
+ fail: (err) => {
+ console.error("鑾峰彇鐢诲竷鍥剧墖澶辫触:", err);
+ reject(err);
+ },
+ });
+ // #endif
+ // #ifndef MP-WEIXIN
+ try {
+ canvasNode.toBlob(
+ (blob) => {
+ if (blob) {
+ // H5 绔細鐢熸垚甯� .png 鎵╁睍鍚嶇殑 File 瀵硅薄锛屼笂浼犳椂鎵嶈兘淇濈暀鍥剧墖鏍煎紡
+ if (typeof File !== "undefined") {
+ const file = new File([blob], `signature_${Date.now()}.png`, {
+ type: "image/png",
+ });
+ resolve(file);
+ } else {
+ resolve(URL.createObjectURL(blob));
+ }
+ } else {
+ reject(new Error("鐢熸垚鍥剧墖澶辫触"));
+ }
+ },
+ "image/png",
+ );
+ } catch (err) {
+ reject(err);
+ }
+ // #endif
});
};
// 纭绛惧悕
const confirmSignature = async () => {
- if (!tempSignatureData.value) {
+ if (!hasSignature.value) {
uni.showToast({
title: "璇峰厛绛惧悕",
icon: "none",
@@ -904,8 +1235,11 @@
try {
uni.showLoading({ title: "淇濆瓨绛惧悕涓�..." });
+ // 鐢熸垚绛惧悕鍥剧墖
+ const filePath = await getCanvasImage();
+
// 涓婁紶绛惧悕鏂囦欢
- const uploadResult = await uploadSignature(tempSignatureData.value);
+ const uploadResult = await uploadSignature(filePath);
if (uploadResult) {
// 浣跨敤 getFullUrl 澶勭悊绛惧悕URL
@@ -925,7 +1259,8 @@
});
showSignaturePanel.value = false;
- clearCanvas();
+ ctx = null;
+ canvasNode = null;
} else {
uni.hideLoading();
uni.showToast({
@@ -953,6 +1288,53 @@
const expertName =
userInfo?.nickName || userInfo?.userName || expertInfo.value.name;
+ // 缁熶竴瑙f瀽涓婁紶鎴愬姛鐨勫搷搴�
+ const parseUploadData = (data) => {
+ console.log("绛惧悕涓婁紶鎴愬姛:", data);
+ if (data.code == 200) {
+ resolve({
+ url: data.url,
+ fileName: data.fileName,
+ newFileName: data.newFileName,
+ originalFilename: data.originalFilename,
+ filePath: data.filePath || data.fileName,
+ size: data.size,
+ });
+ } else {
+ reject(new Error(data.msg || "涓婁紶澶辫触"));
+ }
+ };
+
+ // #ifdef H5
+ // H5 绔� filePath 涓哄甫 .png 鎵╁睍鍚嶇殑 File 瀵硅薄锛岀敤 FormData 鎵嬪姩涓婁紶浠ヤ繚鐣欏浘鐗囨牸寮�
+ if (typeof File !== "undefined" && filePath instanceof File) {
+ const formData = new FormData();
+ formData.append("file", filePath, filePath.name);
+ formData.append("bizType", "expert_review_signature");
+ formData.append("caseNo", caseInfo.value.caseNo || "");
+ formData.append("expertName", expertName);
+ formData.append("uploadType", "signature");
+
+ const xhr = new XMLHttpRequest();
+ xhr.open("POST", "/api/common/upload");
+ xhr.setRequestHeader("Authorization", `Bearer ${token}`);
+ xhr.onload = () => {
+ if (xhr.status === 200) {
+ try {
+ parseUploadData(JSON.parse(xhr.responseText));
+ } catch (e) {
+ reject(new Error("涓婁紶鍝嶅簲瑙f瀽澶辫触"));
+ }
+ } else {
+ reject(new Error(`涓婁紶澶辫触锛岀姸鎬佺爜: ${xhr.status}`));
+ }
+ };
+ xhr.onerror = () => reject(new Error("涓婁紶澶辫触"));
+ xhr.send(formData);
+ return;
+ }
+ // #endif
+
uni.uploadFile({
url: "/api/common/upload",
filePath: filePath,
@@ -970,20 +1352,7 @@
success: (res) => {
if (res.statusCode == 200) {
const data = JSON.parse(res.data);
- console.log("绛惧悕涓婁紶鎴愬姛:", data);
-
- if (data.code == 200) {
- resolve({
- url: data.url,
- fileName: data.fileName,
- newFileName: data.newFileName,
- originalFilename: data.originalFilename,
- filePath: data.filePath || data.fileName,
- size: data.size,
- });
- } else {
- reject(new Error(data.msg || "涓婁紶澶辫触"));
- }
+ parseUploadData(data);
} else {
reject(new Error(`涓婁紶澶辫触锛岀姸鎬佺爜: ${res.statusCode}`));
}
@@ -1038,7 +1407,7 @@
});
};
-// ==================== 淇敼锛氶瑙堢鍚� ====================
+// ============== 淇敼锛氶瑙堢鍚� ==============
const previewSignature = () => {
if (signatureData.signatureUrl) {
// 浣跨敤 getFullUrl 澶勭悊URL
@@ -1060,7 +1429,7 @@
}
};
-// ==================== 淇敼锛氶瑙堟潗鏂� ====================
+// ============== 淇敼锛氶瑙堟潗鏂� ==============
const previewMaterial = (material) => {
if (material.url) {
uni.showLoading({ title: "鍔犺浇涓�..." });
@@ -1069,7 +1438,21 @@
material.type || material.url.split(".").pop().toLowerCase();
// 浣跨敤 getFullUrl 澶勭悊URL
- const fileUrl = getFullUrl(material.url);
+ let fileUrl = getFullUrl(material.url);
+
+ // URL 缂栫爜锛堝鐞嗕腑鏂囨枃浠跺悕锛岄伩鍏嶅弻閲嶇紪鐮侊級
+ try {
+ const urlObj = new URL(fileUrl);
+ // decodeURI 鍏堣В鐮佸凡鏈夌殑缂栫爜锛宔ncodeURI 閲嶆柊缂栫爜锛岀‘淇濆彧缂栫爜涓�娆�
+ fileUrl = urlObj.origin + encodeURI(decodeURI(urlObj.pathname)) + (urlObj.search || "");
+ } catch {
+ // 闄嶇骇
+ try {
+ fileUrl = encodeURI(decodeURI(fileUrl));
+ } catch {
+ fileUrl = encodeURI(fileUrl);
+ }
+ }
// 鍒ゆ柇鏂囦欢绫诲瀷
if (["jpg", "jpeg", "png", "gif", "bmp", "webp"].includes(fileExt)) {
@@ -1096,9 +1479,35 @@
fileExt,
)
) {
- // 鏂囨。鏂囦欢涓嬭浇鍚庢墦寮�
+ // 鏂囨。鏂囦欢澶勭悊
+ // #ifdef H5
+ // H5 鐜锛氱洿鎺ョ敤娴忚鍣ㄦ墦寮�锛屾敮鎸� PDF 鍦ㄧ嚎棰勮
+ uni.hideLoading();
+ if (fileExt == "pdf") {
+ // PDF 鐢� pdf.js 缁勪欢鍐呭祵棰勮锛岄伩鍏嶆墜鏈烘祻瑙堝櫒鐩存帴瑙﹀彂涓嬭浇
+ pdfPreview.url = fileUrl;
+ pdfPreview.title = material.name || "PDF 棰勮";
+ pdfPreview.show = true;
+ } else {
+ // 鍏朵粬鏂囨。鐢� <a> 鏍囩瑙﹀彂涓嬭浇
+ const link = document.createElement("a");
+ link.href = fileUrl;
+ link.download = material.name || material.url.split("/").pop();
+ link.target = "_blank";
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ }
+ // #endif
+
+ // #ifdef MP-WEIXIN
+ // 灏忕▼搴忕幆澧冿細涓嬭浇鍚庣敤 openDocument 鎵撳紑
+ const token = uni.getStorageSync("token") || "";
uni.downloadFile({
url: fileUrl,
+ header: {
+ Authorization: token ? `Bearer ${token}` : "",
+ },
success: (res) => {
if (res.statusCode == 200) {
const filePath = res.tempFilePath;
@@ -1117,19 +1526,28 @@
});
},
});
+ } else {
+ console.error("涓嬭浇鐘舵�佺爜寮傚父:", res.statusCode);
+ uni.showToast({
+ title: `鏈嶅姟鍣ㄨ繑鍥炲紓甯�(${res.statusCode})`,
+ icon: "none",
+ });
}
},
fail: (err) => {
console.error("涓嬭浇鏂囦欢澶辫触:", err);
+ console.error("涓嬭浇URL:", fileUrl);
uni.showToast({
- title: "鏂囦欢涓嬭浇澶辫触",
+ title: "鏂囦欢涓嬭浇澶辫触锛岃妫�鏌ョ綉缁滄垨鍩熷悕閰嶇疆",
icon: "none",
+ duration: 3000,
});
},
complete: () => {
uni.hideLoading();
},
});
+ // #endif
} else {
// 鍏朵粬鏂囦欢绫诲瀷
uni.showToast({
@@ -1236,8 +1654,11 @@
expertopinion: form.value.expertopinion,
sigin: signatureData.signatureUrl,
expertType: caseInfo.value.expertType,
- // 鏍规嵁缁撹璁剧疆鐘舵��
- receiveStatus: form.value.expertconclusion == "1" ? "5" : "6", // 5-瀹屾垚, 6-椹冲洖
+ // 鏍规嵁缁撹璁剧疆鐘舵�侊細鍚屾剰/淇敼鍚庡悓鎰� 鈫� 瀹屾垚(5)锛屼笉鍚屾剰/寮冩潈 鈫� 椹冲洖(6)
+ receiveStatus:
+ form.value.expertconclusion == "1" || form.value.expertconclusion == "4"
+ ? "5"
+ : "6",
conclusiontime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
};
@@ -1289,14 +1710,8 @@
return false;
}
console.log(3);
+ // 瀹℃煡鎰忚涓洪潪蹇呭~锛屼笉鍐嶆牎楠�
- if (!form.value.expertopinion.trim() && !isDraft) {
- uni.showToast({
- title: "璇疯緭鍏ュ鏌ユ剰瑙�",
- icon: "none",
- });
- return false;
- }
console.log(signatureData, "signatureData");
if (!signatureData.signatureUrl && !isDraft) {
@@ -1796,111 +2211,172 @@
}
}
-// 绛惧悕妯℃�佹鏍峰紡
-.signature-modal {
- padding: 30rpx;
- background: #fff;
- border-radius: 20rpx 20rpx 0 0;
- max-height: 80vh;
- overflow: hidden;
+// 鍏ㄥ睆绛惧悕寮规鏍峰紡
+.fullscreen-signature {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 10080;
+ background: #f5f7fa;
+ display: flex;
+ flex-direction: column;
+ // 閫傞厤鍒樻捣灞�/鐘舵�佹爮
+ padding-top: constant(safe-area-inset-top);
+ padding-top: env(safe-area-inset-top);
- .modal-header {
- text-align: center;
- margin-bottom: 30rpx;
+ .fs-header {
+ height: 88rpx;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 30rpx;
+ background: #fff;
+ border-bottom: 1rpx solid #ebeef5;
- .modal-title {
+ .fs-title {
font-size: 32rpx;
font-weight: 600;
color: #303133;
- display: block;
- margin-bottom: 8rpx;
}
- .modal-subtitle {
- font-size: 24rpx;
- color: #909399;
+ .fs-header-btn {
+ font-size: 28rpx;
+ padding: 10rpx 20rpx;
+
+ &.fs-cancel {
+ color: #606266;
+ }
+
+ &.fs-clear {
+ color: #f56c6c;
+ }
}
}
- .signature-canvas-container {
- .signature-canvas {
+ .fs-body {
+ flex: 1;
+ position: relative;
+ margin: 20rpx;
+ border-radius: 12rpx;
+ overflow: hidden;
+ box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
+
+ .fs-canvas {
+ width: 100%;
+ height: 100%;
display: block;
- margin: 0 auto;
- border: 2rpx solid #e4e7ed;
- border-radius: 8rpx;
background: #fff;
+ // H5 绔槻姝㈣Е鎽告椂椤甸潰婊氬姩
touch-action: none;
}
- .canvas-actions {
- display: flex;
- gap: 20rpx;
- margin: 20rpx 0;
- padding: 0 20rpx;
-
- .action-btn {
- flex: 1;
- height: 60rpx;
- border-radius: 30rpx;
- border: 1rpx solid #dcdfe6;
- background: #fff;
- font-size: 24rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 8rpx;
-
- &.clear-btn {
- color: #f56c6c;
- border-color: #f56c6c;
- }
-
- &.redo-btn {
- color: #1890ff;
- border-color: #1890ff;
-
- &:disabled {
- color: #c0c4cc;
- border-color: #e4e7ed;
- }
- }
-
- &.confirm-btn {
- background: linear-gradient(135deg, #0f95b0, #89c4c1);
- color: #fff;
- border: none;
-
- &:disabled {
- background: #c0c4cc;
- opacity: 0.6;
- }
- }
-
- &:active:not(:disabled) {
- transform: scale(0.98);
- }
- }
+ // H5 绔師鐢� canvas 瀹瑰櫒锛坈anvas 鐢� JS 鍒涘缓骞舵拺婊★級
+ .fs-canvas-wrap {
+ width: 100%;
+ height: 100%;
+ background: #fff;
}
- .signature-preview {
- margin-top: 20rpx;
- padding: 20rpx;
- background: #f8f9fa;
- border-radius: 8rpx;
+ .fs-hint {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 16rpx;
+ color: #c0c4cc;
+ font-size: 28rpx;
+ pointer-events: none;
+ }
+ }
- .preview-title {
- display: block;
- font-size: 24rpx;
- color: #606266;
- margin-bottom: 12rpx;
+ // 绗旇Е绮楃粏閫夋嫨鏍�
+ .fs-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 48rpx;
+ padding: 16rpx 30rpx;
+ background: #fff;
+ border-top: 1rpx solid #f0f2f5;
+
+ .toolbar-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8rpx;
+ padding: 8rpx 16rpx;
+
+ .size-dot {
+ border-radius: 50%;
+ transition: background 0.2s;
}
- .preview-image {
- width: 200rpx;
- height: 80rpx;
- border: 1rpx solid #dcdfe6;
- border-radius: 4rpx;
+ .size-label {
+ font-size: 22rpx;
+ color: #909399;
+
+ &.active {
+ color: #0f95b0;
+ font-weight: 600;
+ }
+ }
+
+ &:active {
+ opacity: 0.7;
+ }
+ }
+ }
+
+ .fs-footer {
+ display: flex;
+ gap: 24rpx;
+ padding: 20rpx 30rpx;
+ padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
+ padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+ background: #fff;
+ border-top: 1rpx solid #ebeef5;
+
+ .fs-btn {
+ flex: 1;
+ height: 88rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 30rpx;
+ border-radius: 44rpx;
+ margin: 0;
+ line-height: 1;
+
+ &.fs-undo {
+ color: #1890ff;
background: #fff;
+ border: 1rpx solid #1890ff;
+
+ &:disabled {
+ color: #c0c4cc;
+ border-color: #e4e7ed;
+ background: #f5f7fa;
+ }
+ }
+
+ &.fs-confirm {
+ background: linear-gradient(135deg, #0f95b0, #89c4c1);
+ color: #fff;
+ border: none;
+
+ &:disabled {
+ background: #c0c4cc;
+ opacity: 0.6;
+ }
+ }
+
+ &::after {
+ border: none;
}
}
}
@@ -1927,25 +2403,14 @@
}
}
- .signature-modal {
- padding: 20rpx;
+ .fullscreen-signature {
+ .fs-body {
+ margin: 12rpx;
+ }
- .signature-canvas-container {
- .signature-canvas {
- width: 100% !important;
- height: 250rpx !important;
- }
-
- .canvas-actions {
- // flex-direction: column;
- gap: 12rpx;
- padding: 0;
-
- .action-btn {
- height: 72rpx;
- }
- }
+ .fs-footer {
+ gap: 16rpx;
}
}
}
-</style>
+</style>
\ No newline at end of file
--
Gitblit v1.9.3