From fa821ce7a7755dd0e13897cefc57071d4596431b Mon Sep 17 00:00:00 2001
From: jhzh <1628036192@qq.com>
Date: Wed, 14 Jan 2026 17:51:42 +0800
Subject: [PATCH] 1
---
dist.rar | 0
src/components/ImageViewer.vue | 187 ++++
src/page/newUser/smrz.vue | 21
.gitignore | 1
src/assets/img/wancheng.png | 0
src/axios/api.js | 32
src/locales/zh.js | 51 +
src/page/home/listcomponents/dazongjiaoyi.vue | 2
src/page/user/agreement.vue | 137 ++
src/assets/img/chicang.png | 0
src/page/user/Warehouse.vue | 53
src/page/login/login.vue | 4
src/page/newUser/about.vue | 788 ++++++++++++++++++--
src/page/authentication/index.vue | 14
src/page/newUser/index.vue | 37
src/components/PdfViewer.vue | 395 ++++++++++
src/page/login/register.vue | 94 +-
src/locales/tw.js | 43
src/page/home/home.vue | 4
src/components/PdfViewerModern.vue | 197 +++++
src/router/index.js | 8
src/locales/en.js | 49 +
src/assets/img/guadan.png | 0
src/page/kline/buyStock.vue | 2
src/page/user/Warehouse-detail.vue | 121 ++
25 files changed, 1,976 insertions(+), 264 deletions(-)
diff --git a/.gitignore b/.gitignore
index 541a820..efaa890 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@
*.ntvs*
*.njsproj
*.sln
+qd_ym.rar
diff --git a/dist.rar b/dist.rar
index 5b1b2cc..f0fe47c 100644
--- a/dist.rar
+++ b/dist.rar
Binary files differ
diff --git a/src/assets/img/chicang.png b/src/assets/img/chicang.png
new file mode 100644
index 0000000..3135fc8
--- /dev/null
+++ b/src/assets/img/chicang.png
Binary files differ
diff --git a/src/assets/img/guadan.png b/src/assets/img/guadan.png
new file mode 100644
index 0000000..88e6c6f
--- /dev/null
+++ b/src/assets/img/guadan.png
Binary files differ
diff --git a/src/assets/img/wancheng.png b/src/assets/img/wancheng.png
new file mode 100644
index 0000000..31c3ee0
--- /dev/null
+++ b/src/assets/img/wancheng.png
Binary files differ
diff --git a/src/axios/api.js b/src/axios/api.js
index 4d49a42..67e7f41 100644
--- a/src/axios/api.js
+++ b/src/axios/api.js
@@ -422,6 +422,38 @@
}
// 获取网站设置信息
+export function generateAgreementPdf(options) {
+ return post('/user/generateAgreementPdf.do', options)
+}
+
+export function viewAgreementPdf() {
+ return get('/user/viewAgreementPdf.do')
+}
+
+export function saveAgreementSignature(formData) {
+ return post('/user/saveAgreementSignature.do', formData, {
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+export function generateAgreementContractPdf(options) {
+ return post('/user/generateAgreementContractPdf.do', options)
+}
+
+export function viewAgreementContractPdf() {
+ return get('/user/viewAgreementContractPdf.do')
+}
+
+export function saveAgreementContractSignature(formData) {
+ return post('/user/saveAgreementContractSignature.do', formData, {
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
export function getInfoSite(options) {
return post('/api/site/getInfo.do', options)
}
diff --git a/src/components/ImageViewer.vue b/src/components/ImageViewer.vue
new file mode 100644
index 0000000..1c8ba27
--- /dev/null
+++ b/src/components/ImageViewer.vue
@@ -0,0 +1,187 @@
+<template>
+ <div class="image-viewer-wrapper">
+ <div class="image-toolbar">
+ <button @click="zoomOut" class="toolbar-btn" :disabled="scale <= 0.5">
+ <span class="icon">−</span>
+ </button>
+ <span class="zoom-info">{{ Math.round(scale * 100) }}%</span>
+ <button @click="zoomIn" class="toolbar-btn" :disabled="scale >= 3">
+ <span class="icon">+</span>
+ </button>
+ <div class="toolbar-divider"></div>
+ <button @click="prevPage" class="toolbar-btn" :disabled="currentPage <= 1">
+ <span class="icon">‹</span>
+ </button>
+ <span class="page-info">{{ currentPage }} / {{ totalPages }}</span>
+ <button @click="nextPage" class="toolbar-btn" :disabled="currentPage >= totalPages">
+ <span class="icon">›</span>
+ </button>
+ </div>
+ <div class="image-content" ref="imageContainer">
+ <img
+ :src="currentImageUrl"
+ :style="{ transform: `scale(${scale})`, transformOrigin: 'top left' }"
+ class="viewer-image"
+ @load="onImageLoad"
+ @error="onImageError"
+ />
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: 'ImageViewer',
+ props: {
+ imageUrls: {
+ type: Array,
+ required: true,
+ default: () => []
+ }
+ },
+ data() {
+ return {
+ currentPage: 1,
+ scale: 1.0,
+ loading: false,
+ error: null
+ }
+ },
+ computed: {
+ totalPages() {
+ return this.imageUrls.length
+ },
+ currentImageUrl() {
+ if (this.imageUrls.length === 0) return ''
+ const url = this.imageUrls[this.currentPage - 1]
+ // 添加token
+ const token = typeof window !== 'undefined' && window.localStorage ? window.localStorage.getItem('USERTOKEN') || '' : ''
+ if (url && url.indexOf('token=') === -1) {
+ return url + (url.indexOf('?') > -1 ? '&' : '?') + 'token=' + encodeURIComponent(token)
+ }
+ return url
+ }
+ },
+ methods: {
+ zoomIn() {
+ this.scale = Math.min(this.scale + 0.2, 3)
+ },
+ zoomOut() {
+ this.scale = Math.max(this.scale - 0.2, 0.5)
+ },
+ prevPage() {
+ if (this.currentPage > 1) {
+ this.currentPage--
+ this.scale = 1.0
+ }
+ },
+ nextPage() {
+ if (this.currentPage < this.totalPages) {
+ this.currentPage++
+ this.scale = 1.0
+ }
+ },
+ onImageLoad() {
+ this.loading = false
+ this.error = null
+ },
+ onImageError() {
+ this.loading = false
+ this.error = '图片加载失败'
+ }
+ }
+}
+</script>
+
+<style scoped>
+.image-viewer-wrapper {
+ width: 100%;
+ height: 80%;
+ background: #f5f5f5;
+ display: flex;
+ flex-direction: column;
+}
+
+.image-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 10px;
+ background: #fff;
+ border-bottom: 1px solid #e0e0e0;
+ gap: 10px;
+}
+
+.toolbar-btn {
+ width: 36px;
+ height: 36px;
+ border: 1px solid rgb(50, 145, 113);
+ background: linear-gradient(-55deg, rgb(50, 145, 113), rgb(50, 145, 113));
+ border-radius: 4px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 18px;
+ color: #fff;
+ font-weight: bold;
+ box-shadow: 0 2px 4px rgba(241, 22, 20, 0.3);
+ transition: all 0.3s ease;
+}
+
+.toolbar-btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ background: #ccc;
+ border-color: #999;
+ box-shadow: none;
+}
+
+.toolbar-btn:not(:disabled):hover {
+ background: linear-gradient(-55deg, rgb(50, 145, 113), rgb(50, 145, 113));
+ box-shadow: 0 2px 8px rgba(241, 22, 20, 0.5);
+ transform: translateY(-1px);
+}
+
+.toolbar-btn:not(:disabled):active {
+ transform: translateY(0);
+ box-shadow: 0 1px 3px rgba(241, 22, 20, 0.4);
+}
+
+.zoom-info {
+ min-width: 50px;
+ text-align: center;
+ font-size: 14px;
+ color: #666;
+}
+
+.toolbar-divider {
+ width: 1px;
+ height: 24px;
+ background: #e0e0e0;
+ margin: 0 5px;
+}
+
+.page-info {
+ min-width: 60px;
+ text-align: center;
+ font-size: 14px;
+ color: #666;
+}
+
+.image-content {
+ flex: 1;
+ overflow: auto;
+ display: flex;
+ align-items: flex-start;
+ justify-content: center;
+ padding: 20px;
+}
+
+.viewer-image {
+ max-width: 100%;
+ height: auto;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ transition: transform 0.2s;
+}
+</style>
diff --git a/src/components/PdfViewer.vue b/src/components/PdfViewer.vue
new file mode 100644
index 0000000..984ee8a
--- /dev/null
+++ b/src/components/PdfViewer.vue
@@ -0,0 +1,395 @@
+<template>
+ <div class="pdf-viewer-wrapper">
+ <div v-if="loading" class="pdf-loading">
+ <div class="loading-spinner"></div>
+ <p>加载中...</p>
+ </div>
+ <div v-else-if="error" class="pdf-error">
+ <p>{{ error }}</p>
+ <button @click="loadPdf" class="retry-btn">重试</button>
+ </div>
+ <div v-else class="pdf-container">
+ <div class="pdf-toolbar">
+ <button @click="zoomOut" class="toolbar-btn" :disabled="scale <= 0.5">
+ <span class="icon">−</span>
+ </button>
+ <span class="zoom-info">{{ Math.round(scale * 100) }}%</span>
+ <button @click="zoomIn" class="toolbar-btn" :disabled="scale >= 3">
+ <span class="icon">+</span>
+ </button>
+ <div class="toolbar-divider"></div>
+ <button @click="prevPage" class="toolbar-btn" :disabled="currentPage <= 1">
+ <span class="icon">‹</span>
+ </button>
+ <span class="page-info">{{ currentPage }} / {{ totalPages }}</span>
+ <button @click="nextPage" class="toolbar-btn" :disabled="currentPage >= totalPages">
+ <span class="icon">›</span>
+ </button>
+ </div>
+ <div class="pdf-content" ref="pdfContainer">
+ <canvas ref="pdfCanvas" class="pdf-canvas"></canvas>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import PDFJS from 'pdfjs-dist'
+
+// 使用本地worker
+PDFJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min.js')
+
+export default {
+ name: 'PdfViewer',
+ props: {
+ pdfUrl: {
+ type: String,
+ required: true,
+ default: ''
+ }
+ },
+ data() {
+ return {
+ loading: true,
+ error: null,
+ pdfDoc: null,
+ currentPage: 1,
+ totalPages: 0,
+ scale: 1.0,
+ renderTask: null
+ }
+ },
+ mounted() {
+ this.loadPdf()
+ },
+ watch: {
+ pdfUrl() {
+ this.loadPdf()
+ }
+ },
+ methods: {
+ async loadPdf() {
+ if (!this.pdfUrl) {
+ this.error = 'PDF地址为空'
+ this.loading = false
+ return
+ }
+
+ this.loading = true
+ this.error = null
+
+ try {
+ console.log('开始加载PDF,URL:', this.pdfUrl)
+
+ // 获取PDF数据,确保携带认证信息
+ const token = typeof window !== 'undefined' && window.localStorage ? window.localStorage.getItem('USERTOKEN') || '' : ''
+ const url = this.pdfUrl + (this.pdfUrl.indexOf('?') > -1 ? '&' : '?') + 'token=' + encodeURIComponent(token)
+
+ console.log('请求URL:', url)
+
+ const response = await fetch(url, {
+ credentials: 'include',
+ headers: {
+ 'USERTOKEN': token
+ }
+ })
+
+ if (!response.ok) {
+ throw new Error('加载PDF失败: ' + response.status)
+ }
+
+ const arrayBuffer = await response.arrayBuffer()
+ console.log('PDF数据大小:', arrayBuffer.byteLength)
+
+ if (arrayBuffer.byteLength === 0) {
+ throw new Error('PDF文件为空')
+ }
+
+ // 加载PDF文档
+ const loadingTask = PDFJS.getDocument({
+ data: arrayBuffer,
+ verbosity: 0
+ })
+
+ this.pdfDoc = await loadingTask.promise
+ this.totalPages = this.pdfDoc.numPages
+ console.log('PDF加载成功,总页数:', this.totalPages)
+
+ // 计算适合H5的初始缩放比例
+ await this.calculateInitialScale()
+
+ await this.renderPage(this.currentPage)
+ this.loading = false
+ } catch (error) {
+ console.error('加载PDF失败:', error)
+ this.error = '加载PDF失败,请稍后重试'
+ this.loading = false
+ }
+ },
+ async calculateInitialScale() {
+ if (!this.pdfDoc) return
+
+ try {
+ const page = await this.pdfDoc.getPage(1)
+ const viewport = page.getViewport({ scale: 1.0 })
+
+ // 获取容器宽度(H5适配)
+ const containerWidth = this.$refs.pdfContainer ? this.$refs.pdfContainer.clientWidth : window.innerWidth - 40
+ const containerHeight = window.innerHeight - 200
+
+ // 计算适合的缩放比例
+ const scaleX = containerWidth / viewport.width
+ const scaleY = containerHeight / viewport.height
+ this.scale = Math.min(scaleX, scaleY, 1.2) // 初始缩放不超过1.2倍
+ console.log('计算初始缩放比例:', this.scale)
+ } catch (error) {
+ console.error('计算缩放比例失败:', error)
+ this.scale = 1.0
+ }
+ },
+ async renderPage(pageNum) {
+ if (!this.pdfDoc || !this.$refs.pdfCanvas) return
+
+ // 取消之前的渲染任务
+ if (this.renderTask) {
+ this.renderTask.cancel()
+ }
+
+ try {
+ const page = await this.pdfDoc.getPage(pageNum)
+ const canvas = this.$refs.pdfCanvas
+ const context = canvas.getContext('2d')
+
+ const viewport = page.getViewport({ scale: this.scale })
+
+ // 设置canvas尺寸(H5高清适配)
+ const dpr = window.devicePixelRatio || 1
+ canvas.width = viewport.width * dpr
+ canvas.height = viewport.height * dpr
+ canvas.style.width = viewport.width + 'px'
+ canvas.style.height = viewport.height + 'px'
+
+ context.scale(dpr, dpr)
+
+ const renderContext = {
+ canvasContext: context,
+ viewport: viewport
+ }
+
+ this.renderTask = page.render(renderContext)
+ await this.renderTask.promise
+ this.currentPage = pageNum
+ console.log('渲染第', pageNum, '页完成,缩放比例:', this.scale)
+ } catch (error) {
+ if (error.name !== 'RenderingCancelledException') {
+ console.error('渲染PDF页面失败:', error)
+ }
+ }
+ },
+ zoomIn() {
+ this.scale = Math.min(this.scale + 0.2, 3)
+ this.renderPage(this.currentPage)
+ },
+ zoomOut() {
+ this.scale = Math.max(this.scale - 0.2, 0.5)
+ this.renderPage(this.currentPage)
+ },
+ prevPage() {
+ if (this.currentPage > 1) {
+ this.renderPage(this.currentPage - 1)
+ }
+ },
+ nextPage() {
+ if (this.currentPage < this.totalPages) {
+ this.renderPage(this.currentPage + 1)
+ }
+ }
+ },
+ beforeDestroy() {
+ if (this.renderTask) {
+ this.renderTask.cancel()
+ }
+ }
+}
+</script>
+
+<style scoped>
+.pdf-viewer-wrapper {
+ width: 100%;
+ height: 100%;
+ background: #f5f5f5;
+}
+
+.pdf-loading {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 60vh;
+ color: #666;
+}
+
+.loading-spinner {
+ width: 40px;
+ height: 40px;
+ border: 4px solid #f3f3f3;
+ border-top: 4px solid #f11514;
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+ margin-bottom: 15px;
+}
+
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+}
+
+.pdf-error {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 60vh;
+ color: #f56c6c;
+ padding: 20px;
+ text-align: center;
+}
+
+.retry-btn {
+ margin-top: 15px;
+ padding: 10px 20px;
+ background: linear-gradient(-55deg, rgb(241, 22, 20), rgb(240, 40, 37));
+ color: #fff;
+ border: none;
+ border-radius: 5px;
+ font-size: 14px;
+ cursor: pointer;
+}
+
+.pdf-container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ background: #525252;
+}
+
+.pdf-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 10px 5px;
+ background: #fff;
+ border-bottom: 1px solid #e0e0e0;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+ position: sticky;
+ top: 0;
+ z-index: 10;
+ flex-shrink: 0;
+}
+
+.toolbar-btn {
+ width: 36px;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #f5f5f5;
+ border: 1px solid #e0e0e0;
+ border-radius: 4px;
+ margin: 0 3px;
+ cursor: pointer;
+ font-size: 20px;
+ color: #333;
+ transition: all 0.2s;
+ -webkit-tap-highlight-color: transparent;
+}
+
+.toolbar-btn:active {
+ background: #e0e0e0;
+ transform: scale(0.95);
+}
+
+.toolbar-btn:disabled {
+ opacity: 0.4;
+ cursor: not-allowed;
+}
+
+.toolbar-btn .icon {
+ line-height: 1;
+ font-weight: bold;
+ user-select: none;
+}
+
+.zoom-info,
+.page-info {
+ min-width: 55px;
+ text-align: center;
+ font-size: 13px;
+ color: #666;
+ margin: 0 6px;
+ user-select: none;
+}
+
+.toolbar-divider {
+ width: 1px;
+ height: 24px;
+ background: #e0e0e0;
+ margin: 0 6px;
+}
+
+.pdf-content {
+ flex: 1;
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+ background: #525252;
+ display: flex;
+ align-items: flex-start;
+ justify-content: center;
+ padding: 15px 10px;
+ min-height: calc(100vh - 280px);
+}
+
+.pdf-canvas {
+ display: block;
+ margin: 0 auto;
+ background: #fff;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
+ max-width: 100%;
+ height: auto;
+ touch-action: pan-x pan-y pinch-zoom;
+}
+
+/* H5移动端优化 */
+@media (max-width: 768px) {
+ .pdf-toolbar {
+ padding: 8px 3px;
+ }
+
+ .toolbar-btn {
+ width: 32px;
+ height: 32px;
+ margin: 0 2px;
+ font-size: 18px;
+ }
+
+ .zoom-info,
+ .page-info {
+ font-size: 12px;
+ margin: 0 4px;
+ min-width: 50px;
+ }
+
+ .pdf-content {
+ padding: 10px 5px;
+ min-height: calc(100vh - 160px);
+ }
+}
+
+/* 横屏适配 */
+@media (orientation: landscape) {
+ .pdf-content {
+ min-height: calc(100vh - 140px);
+ }
+}
+</style>
diff --git a/src/components/PdfViewerModern.vue b/src/components/PdfViewerModern.vue
new file mode 100644
index 0000000..ffa8005
--- /dev/null
+++ b/src/components/PdfViewerModern.vue
@@ -0,0 +1,197 @@
+<template>
+ <div class="pdf-viewer-modern">
+ <div v-if="loading" class="loading-wrapper">
+ <div class="loading-content">
+ <div class="spinner"></div>
+ <p class="loading-text">正在加载PDF...</p>
+ </div>
+ </div>
+ <div v-else-if="error" class="error-wrapper">
+ <div class="error-content">
+ <div class="error-icon">⚠️</div>
+ <p class="error-text">{{ error }}</p>
+ <button @click="loadPdf" class="retry-button">重新加载</button>
+ </div>
+ </div>
+ <div v-else class="viewer-container">
+ <iframe
+ :src="pdfSrc"
+ class="pdf-iframe"
+ frameborder="0"
+ @load="onPdfLoad"
+ @error="onPdfError"
+ ></iframe>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: 'PdfViewerModern',
+ props: {
+ pdfUrl: {
+ type: String,
+ required: true,
+ default: ''
+ }
+ },
+ data() {
+ return {
+ loading: true,
+ error: null,
+ pdfSrc: ''
+ }
+ },
+ mounted() {
+ this.loadPdf()
+ },
+ watch: {
+ pdfUrl() {
+ this.loadPdf()
+ }
+ },
+ computed: {
+ finalPdfUrl() {
+ if (!this.pdfUrl) return ''
+
+ let url = this.pdfUrl
+
+ // 如果URL不包含http,需要添加基础URL
+ if (!url.startsWith('http')) {
+ const APIUrl = require('@/axios/api.url').default
+ url = APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url)
+ }
+
+ // 添加token
+ const token = typeof window !== 'undefined' && window.localStorage ? window.localStorage.getItem('USERTOKEN') || '' : ''
+ url = url + (url.indexOf('?') > -1 ? '&' : '?') + 'token=' + encodeURIComponent(token)
+
+ // 保留工具栏(包含缩放工具),但隐藏导航面板
+ url = url + '#toolbar=1&navpanes=0'
+
+ return url
+ }
+ },
+ methods: {
+ loadPdf() {
+ if (!this.pdfUrl) {
+ this.error = 'PDF地址为空'
+ this.loading = false
+ return
+ }
+
+ this.loading = true
+ this.error = null
+
+ // 设置iframe的src,浏览器会自动加载
+ this.pdfSrc = this.finalPdfUrl
+
+ // 延迟隐藏loading,给iframe一些加载时间
+ setTimeout(() => {
+ this.loading = false
+ }, 500)
+ },
+ onPdfLoad() {
+ this.loading = false
+ this.error = null
+ },
+ onPdfError() {
+ this.loading = false
+ this.error = 'PDF加载失败,请检查文件是否存在'
+ }
+ }
+}
+</script>
+
+<style scoped>
+.pdf-viewer-modern {
+ width: 100%;
+ height: 100%;
+ max-height: calc(100vh - 400px);
+ background: #f5f5f5;
+ display: flex;
+ flex-direction: column;
+}
+
+.loading-wrapper,
+.error-wrapper {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #f8f9fa;
+}
+
+.loading-content,
+.error-content {
+ text-align: center;
+ padding: 40px;
+}
+
+.spinner {
+ width: 50px;
+ height: 50px;
+ margin: 0 auto 20px;
+ border: 4px solid rgba(102, 126, 234, 0.1);
+ border-top-color: #667eea;
+ border-radius: 50%;
+ animation: spin 0.8s linear infinite;
+}
+
+@keyframes spin {
+ to { transform: rotate(360deg); }
+}
+
+.loading-text {
+ color: #667eea;
+ font-size: 16px;
+ font-weight: 500;
+}
+
+.error-icon {
+ font-size: 48px;
+ margin-bottom: 16px;
+}
+
+.error-text {
+ color: #e74c3c;
+ font-size: 16px;
+ margin-bottom: 20px;
+}
+
+.retry-button {
+ padding: 12px 24px;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: #fff;
+ border: none;
+ border-radius: 8px;
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: transform 0.2s, box-shadow 0.2s;
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
+}
+
+.retry-button:active {
+ transform: scale(0.95);
+}
+
+.viewer-container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ background: #f5f5f5;
+ overflow: hidden;
+ position: relative;
+ max-height: calc(100vh - 200px);
+ height: calc(100vh - 200px);
+}
+
+.pdf-iframe {
+ width: 100%;
+ height: 100%;
+ border: none;
+ background: #fff;
+ min-height: 0;
+}
+</style>
diff --git a/src/locales/en.js b/src/locales/en.js
index 5e73c28..a98c0ea 100644
--- a/src/locales/en.js
+++ b/src/locales/en.js
@@ -127,6 +127,7 @@
"hj21": "Invitation code",
"hj210": "Submitted successfully!",
"hj211": "Bind bank card",
+ "hj2111": "Address",
"hj212": "bank card information",
"hj213": "Bank name",
"hj214": "Account opening branch",
@@ -729,9 +730,9 @@
"jy80": "Baiyun Airport",
"jy81": "Dongfeng Motor",
"jy82": "China International Trade",
- "jy83": "deep",
- "jy84": "Shanghai",
- "jy85": "north",
+ "jy83": "sz",
+ "jy84": "sh",
+ "jy85": "bj",
"jy86": "Large transactions",
"jy87": "Please enter the quantity",
"jy88": "purchasing price",
@@ -793,7 +794,8 @@
jy517: "ID card front",
jy518: "Upload the front of your ID",
jy519: "Please type in your name",
- jy520: "Please enter ID number",
+ jy520: "My Commission",
+ jy561: "Please enter ID number",
jy521: "deposit funds",
// jy521: "Mobile banking deposit",
jy522: "withdraw funds",
@@ -801,11 +803,11 @@
jy523: "Account number",
jy524: "Under certification",
jy525: "Number of winning shares",
- jy526: "Payment date",
- jy527: "Bank securities transfer",
- jy528: "Mobile banking deposit",
- jy529: "UnionPay deduction",
- jy530: "Maintaining and updating",
+ jy526: "Generating contract, please wait...",
+ jy527: "Please complete the electronic signature",
+ jy528: "Clear signature",
+ jy529: "Confirm signature",
+ jy530: "You have completed the signature",
jy531: "Leverage ratio",
jy532: "Margin leverage",
jy533: "Buy/Sell handling fee",
@@ -821,6 +823,28 @@
jy543: "Failed to get platform transfer information",
jy544: "Please enter transfer user name",
jy545: "Please upload transfer screenshot",
+ jy546: "Online contract",
+ jy547: "Non-Disclosure Agreement",
+ jy548: "Margin Trading and Securities Lending Account",
+ jy549: "Margin Trading Withdrawable Funds",
+ jy550: "Margin Trading Available Funds",
+ jy551: "Please verify your identity first",
+ jy552: "Shareholder Reduction",
+ jy553: "Profit Calendar",
+ jy554: "Please complete the electronic signature first!",
+ jy555: "Signature component not initialized, please try again later!",
+ jy556: "Signature saved successfully",
+ jy557: "Signature save failed",
+ jy558: "Contract generated successfully",
+ jy559: "Generation failed: No image data returned",
+ jy560: "Generation failed",
+ jy565: "Profit and Loss Ratio",
+ jy566: "Bank securities transfer",
+ jy567: "Mobile banking deposit",
+ jy568: "UnionPay deduction",
+ jy569: "Maintaining and updating",
+ jy570: "Payment date",
+
// Profit Calendar
profitCalendar_title: "General Asset Analysis",
profitCalendar_monthProfit: "Monthly Account Profit①",
@@ -844,7 +868,7 @@
dz_share: "Share",
dz_completed: "Completed",
dz_buySuccess: "Buy Success",
-
+
// Login and Register page new keys
login_phoneNumber: "Phone Number",
login_loginPassword: "Login Password",
@@ -868,7 +892,10 @@
register_professionalService: "Professional Service",
register_investmentAdvisor: "Investment Advisor",
register_verificationCodeSentSuccess: "Verification code sent successfully",
-
+ jy562: "Position Details",
+ jy563: "Commission Details",
+ jy564: "Close Position Details",
+
}
diff --git a/src/locales/tw.js b/src/locales/tw.js
index 098065d..891ee4e 100644
--- a/src/locales/tw.js
+++ b/src/locales/tw.js
@@ -128,6 +128,7 @@
"hj21": "邀請碼",
"hj210": "提交成功!",
"hj211": "綁定銀行卡",
+ "hj2111": "地址",
"hj212": "銀行卡信息",
"hj213": "銀行名稱",
"hj214": "開戶支行",
@@ -795,7 +796,8 @@
jy517: "身份證正面",
jy518: "上傳您的身份證正面",
jy519: "請輸入姓名",
- jy520: "請輸入身份證號碼",
+ jy520: "我的委託",
+ jy561: "請輸入身份證號碼",
jy521: "銀轉證",
// jy521: "手機銀行入款",
jy522: "證轉銀",
@@ -803,12 +805,11 @@
jy523: "帳戶號碼",
jy524: "認證中",
jy525: "中簽股數",
- jy526: "繳費日期",
- jy527: "維護更新中",
- jy527: "銀證轉帳",
- jy528: "手機銀行入款",
- jy529: "銀聯劃扣",
- jy530: "維護更新中",
+ jy526: "正在生成合同,請稍候...",
+ jy527: "請完成電子簽名",
+ jy528: "清空簽名",
+ jy529: "確認簽名",
+ jy530: "您已完成簽名",
jy531: "槓桿倍數",
jy532: "選擇融資倍數",
jy533: "買入/賣出手續費",
@@ -824,6 +825,27 @@
jy543: "平台轉賬信息獲取失敗",
jy544: "請輸入轉賬用戶名",
jy545: "請上傳轉賬截圖",
+ jy546: "線上契约",
+ jy547: "保密協定",
+ jy548: "融資融券賬戶",
+ jy549: "兩融可取資金",
+ jy550: "兩融可用資金",
+ jy551: "請先實名認證",
+ jy552: "股東減持",
+ jy553: "收益日曆",
+ jy554: "請先完成電子簽名!",
+ jy555: "簽名組件未初始化,請稍候再試!",
+ jy556: "簽名保存成功",
+ jy557: "簽名保存失敗",
+ jy558: "合同生成成功",
+ jy559: "生成失敗:未返回圖片數據",
+ jy560: "生成失敗",
+ jy565: "盈虧比例",
+ jy566: "銀證轉帳",
+ jy567: "手機銀行入款",
+ jy568: "銀聯劃扣",
+ jy569: "維護更新中",
+ jy570: "繳費日期",
// 收益日曆
profitCalendar_title: "普通資產分析",
profitCalendar_monthProfit: "本月帳戶收益①",
@@ -847,7 +869,7 @@
dz_share: "份額",
dz_completed: "已完成",
dz_buySuccess: "買入成功",
-
+
// 登錄註冊頁面新增
login_phoneNumber: "手機號",
login_loginPassword: "登錄密碼",
@@ -871,5 +893,8 @@
register_professionalService: "專業服務",
register_investmentAdvisor: "投資顧問",
register_verificationCodeSentSuccess: "驗證碼發送成功",
-
+ jy562: "持倉詳情",
+ jy563: "委託詳情",
+ jy564: "平倉詳情",
+
}
diff --git a/src/locales/zh.js b/src/locales/zh.js
index 31329b4..fc94e4a 100644
--- a/src/locales/zh.js
+++ b/src/locales/zh.js
@@ -212,6 +212,7 @@
hj209: "请上传您的身份证照片",
hj210: "提交成功!",
hj211: "绑定银行卡",
+ hj2111: "地址",
hj212: "银行卡信息",
hj213: "银行名称",
hj214: "开户支行",
@@ -592,7 +593,7 @@
jy310: "点击注册",
jy311: "请输入手机号",
jy312: "请再次输入密码",
- jy313: "机构码",
+ jy313: "两融邀请码",
jy314: "关于我们",
jy315: "暂未开放",
jy316: "隐私协议",
@@ -782,6 +783,19 @@
jy498: "请输入转换数量",
jy499: "转换",
jy500: "港币",
+ jy520: "我的委托",
+ jy521: "挂单时间",
+ jy522: "平仓数量",
+ jy523: "部分平仓",
+ jy524: "格式错误",
+ jy525: "超过最大数量",
+ jy526: "正在生成合同,请稍候...",
+ jy527: "请完成电子签名",
+ jy528: "清空签名",
+ jy529: "确认签名",
+ jy530: "您已完成签名",
+ jy531: "生成用户合同",
+ jy532: "请输入价格",
jy501: "英文",
jy502: "简体中文",
jy503: "简体中文",
@@ -802,17 +816,17 @@
jy517: "身份证正面",
jy518: "上传您的身份证正面",
jy519: "请输入姓名",
- jy520: "请输入身份证号码",
+ jy561: "请输入身份证号码",
jy521: "证转银",
jy522: "银转证",
jy523: "账户号码",
jy524: "认证中",
jy525: "中签股数",
- jy526: "缴费日期",
- jy527: "银证转账",
- jy528: "手机银行入款",
- jy529: "银联划扣",
- jy530: "维护更新中",
+ jy570: "缴费日期",
+ jy566: "银证转账",
+ jy567: "手机银行入款",
+ jy568: "银联划扣",
+ jy569: "维护更新中",
jy531: "杠杆倍数",
jy532: "选择融资倍数",
jy533: "买入/卖出手续费",
@@ -828,6 +842,29 @@
jy543: "平台转账信息获取失败",
jy544: "请输入转账用户名",
jy545: "请上传转账截图",
+ jy546: "线上合同",
+ jy547: "保密协议",
+ jy548: "融资融券账户",
+ jy549: "两融可取资金",
+ jy550: "两融可用资金",
+ jy551: "请先实名认证",
+ jy552: "股东减持",
+ jy553: "收益日历",
+ jy554: "请先完成电子签名!",
+ jy555: "签名组件未初始化,请稍候再试!",
+ jy556: "签名保存成功",
+ jy557: "签名保存失败",
+ jy558: "合同生成成功",
+ jy559: "生成失败:未返回图片数据",
+ jy560: "生成失败",
+ jy562: "持仓详情",
+ jy563: "委托详情",
+ jy564: "平仓详情",
+ jy565: "盈亏比例",
+ jy566: "银证转账",
+ jy567: "手机银行入款",
+ jy568: "银联划扣",
+ jy569: "维护更新中",
// 收益日历
profitCalendar_title: "普通资产分析",
profitCalendar_monthProfit: "本月账户收益①",
diff --git a/src/page/authentication/index.vue b/src/page/authentication/index.vue
index 79cd473..c192bf9 100644
--- a/src/page/authentication/index.vue
+++ b/src/page/authentication/index.vue
@@ -28,6 +28,15 @@
<input v-if="!showBtn" type="text" v-model="form.idCard" readonly />
</div>
</div>
+ <div class="bank_name">
+ <div class="lefts">
+ <span>{{ $t('hj2111') + ':' }}</span>
+ </div>
+ <div class="rights">
+ <input v-if="showBtn" type="text" v-model="form.address" :placeholder="$t('hj2111')" />
+ <input v-if="!showBtn" type="text" v-model="form.address" readonly />
+ </div>
+ </div>
<div class="uploads">
<div class="lefts">
<el-upload :with-credentials="true" class="avatar-uploader" :action="admin + '/user/upload.do'"
@@ -88,6 +97,7 @@
phone: "",
name: "",
idCard: "",
+ address: "",
img1key: "",
img2key: "",
img3key: ""
@@ -170,6 +180,7 @@
) {
this.form.idCard = this.$store.state.userInfo.idCard;
this.form.name = this.$store.state.userInfo.realName;
+ this.form.address = this.$store.state.userInfo.regAddress || "";
this.form.img1key = this.$store.state.userInfo.img1Key;
this.form.img2key = this.$store.state.userInfo.img2Key;
// this.form.img3key = this.$store.state.userInfo.img3Key
@@ -215,6 +226,8 @@
Toast(this.$t('hj207'));
} else if (isNull(this.form.idCard) || !idCardReg(this.form.idCard)) {
Toast(this.$t('hj208'));
+ } else if (isNull(this.form.address)) {
+ Toast('请输入' + this.$t('hj2111'));
} else if (isNull(this.form.img1key) || isNull(this.form.img2key)) {
Toast(this.$t('hj209'));
} else {
@@ -226,6 +239,7 @@
let opts = {
realName: this.form.name,
idCard: this.form.idCard,
+ address: this.form.address,
img1key: this.form.img1key,
img2key: this.form.img2key,
img3key: this.form.img3key
diff --git a/src/page/home/home.vue b/src/page/home/home.vue
index c3f3f1b..02352ec 100644
--- a/src/page/home/home.vue
+++ b/src/page/home/home.vue
@@ -97,7 +97,7 @@
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA6CAYAAADhu0ooAAAAAXNSR0IArs4c6QAABWpJREFUaEPtWl1sFFUU/s7spluVH6m1y8xssDYEDcaAhCBsl5b+PIhoYkiA4Is/iUFRQR/EaDAYiA8mPmhAIRKivhCFaIwi8gCldtsCCmIwEkkqNs3u3S4tIDFgO9mZY+6GNrvD1s7uztKp7H2953zn++bcmbnn3Eu4RQbdIjpRFvp/y3Q5oyMZDQaDdwQCgQqvZnh4eNhIJpNXx+OXM6O6rrcw85MAlgNQxwPxwHwCwPdEtDcejx/JxSdLaDAYrPP5fB8DaPEA+UIpHDZNc10ymTyfCTAqNBQKLbIs6xCAGYVG8JDfJUVRlsdisR9HOKWF6roeYuafAdztIbLFUrloWdbC/v7+XgmUFqqq6ndE9OgYyNcAJImIi43stj8zS/5BALfnwmbmg4lEYkVaqKZpEQDRHIbnmHljIpE4DMB0m6SLeD5VVVuJ6AMA9+XAXSqE6JRCtwN4KdOAmf8IBAILe3t7/3KRUEmhamtr7zQM4ycAs22BdgghXpZCf8/xJNYKIT4vKbMSgGuatgaAnfc5IcT9Uug/ACoz4/r9/qq+vr7LJeBSUshZs2bNSKVSl2xBhoQQt0mhN3xkhBCTdms4lp6y0JKusRKClzNafkdLuLxKCV1euvksXU3TNgHYCEBzmJU+AFuFEHvGso9GIjN8FYosKGodYkqzAWbeHT4a3UxA1u+x6Izqur6CmQ/kQWbElBVFWZxZMo1OAHSsufErgJ8oABcMera+7YdPMn2LFqqq6jYi2lwIIbmXFkJ8aPftamrcQMRyM17o2BVu63jBVaGapj0O4JtCGCmK8rA9o53Lli1UFKsLQMH9KAI/s6Qt+qmrQiWYqqpvEtGrAKodCu4H8I4QYkem/cnW1umGZcj3ss4hjt3sCjPviVfP3LR6//6sErLopVsgoZxu3c0N+wCsyjH5Xrit47ViYnlGaFdT43oivuF9JcLxaVWDjQ/sP2tMeqHdrQ0PwUK3vSwEcJksZcGS9vZ0f6eYMeEZ7ayvn0oB30kC5tiEMIhXho9Evy5G4IjvhAvtbl66F6C1djEM3l7fFt3ghkiJ4YpQBuh4U2QRFP/UfIhZbC0mYNuNPnRq+l0DYflehkKhBy3Lkh09J+OaEEL2bFN246KF/rZqbsWVi9UHXeziXzHJWrD0SOd5TdPkx2m9E4UZNqcMw2gaHBz829X/aHdLwzowduVJZkxzYqxZcrRj33+0W52E2iKE2Oqq0GPNDVsYeNtJ9PFsGLyzvi2azqCqqiuJ6MvxfMaY/0gI8aKrQk+0ROaYrJweqyueB9HTw5YSbmpvH5I+VVVV0yorK88AuCcPDGlqKopSH4vFTrgqVIJFmyLz/EQbGTQlT1Kj5habb0WOdp3L9A+FQrplWW8AqHGIK49Jdgsh5F45axT9MXJIYMLNykLz6TBMeLocEChn9FbK6IC9kE6lUjMvXLiQdLBSPGVSU1MT9Pv9stjPHFeFEFPk2Yv8N87PnCGi9fF4fKenVDggo+v688xs531GCDGPdF1/X55s23AGFEUJx2KxHgf4njAJhUKzLcuStW7WPQx5Eh6Px1+h61XDLwAUG+OLALYA+FYIEffo8b5P0zQdgGzcye2pvZdlKYoyPxaL/Zo+B9U0TXbSnvJEatwl8ZkQ4mkJmRZaV1c3fWhoSO4Zc112cDf0zUPrud5mTZ+Aj55sB4PBe30+n+zEz715XEoW6axpmo8lk8k/RyJkHeFXV1dPraioeBfAcwD8JaNROmDZcdhtGMbr9oI8512F63cCVxPRI8wsr7PkvLBUOr55IV8joh5mPmSa5heZWcz6ZeYFOYmNJ+3tk3yfeVlovk/M6/bljHo9Q/ny+xcuWZRZFpiovgAAAABJRU5ErkJggg=="
/>
- <p>股东减持</p>
+ <p>{{ $t("jy552") }}</p>
</div>
<div class="xbox" @click="getHeaderlink(4)">
<img
@@ -128,7 +128,7 @@
<img
src="data:image/png;base64,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"
/>
- <p>收益日历</p>
+ <p>{{ $t("jy553") }}</p>
</div>
<!-- <div class="xbox" @click="getHeaderlink1(6)">
diff --git a/src/page/home/listcomponents/dazongjiaoyi.vue b/src/page/home/listcomponents/dazongjiaoyi.vue
index 5a93270..41b41e6 100644
--- a/src/page/home/listcomponents/dazongjiaoyi.vue
+++ b/src/page/home/listcomponents/dazongjiaoyi.vue
@@ -198,7 +198,7 @@
},
async getxiadan() {
if (!this.price) {
- this.$toast('请输入价格')
+ this.$toast(this.$t('jy532'))
return
}
if (!this.num) {
diff --git a/src/page/kline/buyStock.vue b/src/page/kline/buyStock.vue
index 07b43e8..e756c91 100644
--- a/src/page/kline/buyStock.vue
+++ b/src/page/kline/buyStock.vue
@@ -236,7 +236,7 @@
return
}
if (!this.buyPrice) {
- Toast('请输入价格')
+ Toast(this.$t('jy532'))
return
}
if (this.buyNum * 100 < this.settingdetail.buyMinNum) {
diff --git a/src/page/login/login.vue b/src/page/login/login.vue
index 6157d0e..7bf223c 100644
--- a/src/page/login/login.vue
+++ b/src/page/login/login.vue
@@ -91,7 +91,7 @@
class="agreement_checkbox"
/>
<label for="agreement" class="agreement_label">
- {{ $t('login_agreeToTerms') }}<span class="agreement_link" @click.stop="viewAgreement">《{{ $t('login_userAgreement') }}》</span>
+ {{ $t('login_agreeToTerms') }}<span class="agreement_link" @click.stop="viewAgreement">{{ $t('login_userAgreement') }}</span>
</label>
</div>
@@ -184,7 +184,7 @@
},
viewAgreement() {
// 跳转到用户协议页面
- this.$router.push('/about?e=2');
+ this.$router.push('/about?e=3');
},
async loginIN() {
if (!this.agreedToTerms) {
diff --git a/src/page/login/register.vue b/src/page/login/register.vue
index 59b7f2d..ccffe35 100644
--- a/src/page/login/register.vue
+++ b/src/page/login/register.vue
@@ -65,7 +65,7 @@
<input :placeholder="$t('jy311')" v-model="phone" class="field-input" />
</div>
</div>
-
+
<div class="form-field">
<label class="field-label">{{ $t('login_loginPassword') }}</label>
<input
@@ -75,7 +75,7 @@
class="field-input"
/>
</div>
-
+
<div class="form-field">
<label class="field-label">{{ $t('register_confirmPassword') }}</label>
<input
@@ -85,23 +85,23 @@
class="field-input"
/>
</div>
-
+
<div class="form-field">
<label class="field-label">{{ $t('register_inviteCode') }}</label>
<input :placeholder="$t('jy313')" v-model="userName" class="field-input" />
</div>
-
+
<div class="agreement">
<input type="checkbox" id="agreement" v-model="agree" />
<label for="agreement">
{{ $t('login_agreeToTerms') }} <span class="agreement-link" @click.stop="viewAgreement">{{ $t('login_userAgreement') }}</span>
</label>
</div>
-
+
<div class="loginBtn" v-loading="loginBtn" @click="gook">
{{ $t('register_openAccountNow') }}
</div>
-
+
<div class="login-link">
<span @click="$router.push('/login')">{{ $t('register_haveAccountLoginNow') }}</span>
</div>
@@ -119,7 +119,7 @@
<div class="feature-title">{{ $t('register_fastAccountOpening') }}</div>
<div class="feature-desc">{{ $t('register_completedIn3Minutes') }}</div>
</div>
-
+
<div class="feature-item">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -129,7 +129,7 @@
<div class="feature-title">{{ $t('register_bankLevelSecurity') }}</div>
<div class="feature-desc">{{ $t('register_fundProtection') }}</div>
</div>
-
+
<div class="feature-item">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -141,8 +141,8 @@
</div>
</div>
</div>
-
-
+
+
</div>
</div>
</template>
@@ -209,7 +209,7 @@
},
viewAgreement() {
// 跳转到用户协议页面
- this.$router.push('/about?e=2');
+ this.$router.push('/about?e=3');
},
getCodeRandom(){
const code = Math.floor(1000 + Math.random() * 9000).toString();
@@ -357,15 +357,17 @@
// }, 2000)
Toast(this.$t("hj28"));
this.loginBtn = false;
- } else if (isNull(this.yzmCode)) {
- // this.texts = this.$t('hj30')
- // this.alertShow = true
- // setTimeout(() => {
- // this.alertShow = false
- // }, 2000)
- Toast(this.$t("jy459"));
- this.loginBtn = false;
- } else if (isNull(this.userPassword)) {
+ }
+ // else if (isNull(this.yzmCode)) {
+ // // this.texts = this.$t('hj30')
+ // // this.alertShow = true
+ // // setTimeout(() => {
+ // // this.alertShow = false
+ // // }, 2000)
+ // Toast(this.$t("jy459"));
+ // this.loginBtn = false;
+ // }
+ else if (isNull(this.userPassword)) {
// this.texts = this.$t('hj30')
// this.alertShow = true
// setTimeout(() => {
@@ -752,7 +754,7 @@
.header-content {
padding-top: 1rem;
-
+
.page-title {
font-size: 0.65rem;
font-weight: 600;
@@ -760,20 +762,20 @@
margin: 0 0 0.5rem 0;
padding-left: 0.5rem;
}
-
+
.features {
display: flex;
flex-wrap: wrap;
gap: 0.3rem;
padding-left: 0.5rem;
-
+
.feature-item {
display: flex;
align-items: center;
gap: 0.2rem;
font-size: 0.28rem;
color: #666;
-
+
.check-icon {
width: 0.4rem;
height: 0.4rem;
@@ -804,7 +806,7 @@
.form-field {
margin-bottom: 1rem;
-
+
.field-label {
display: block;
font-size: 0.32rem;
@@ -812,7 +814,7 @@
color: #333;
margin-bottom: 0.3rem;
}
-
+
.input-wrapper {
display: flex;
align-items: center;
@@ -820,13 +822,13 @@
border-radius: 0.2rem;
overflow: hidden;
background: #F5F7FA;
-
+
.area-select {
width: 2rem;
border: none;
border-right: 1px solid #e0e0e0;
background: #F5F7FA;
-
+
/deep/ .el-input__inner {
border: none;
height: 1.3rem;
@@ -835,7 +837,7 @@
background: #F5F7FA;
}
}
-
+
.field-input {
flex: 1;
border: none;
@@ -845,7 +847,7 @@
background: #F5F7FA;
}
}
-
+
.field-input {
width: 100%;
height: 1.3rem;
@@ -854,7 +856,7 @@
padding: 0 0.3rem;
font-size: 0.32rem;
background: #F5F7FA;
-
+
&:focus {
outline: none;
border-color: #1890ff;
@@ -941,7 +943,7 @@
margin: 0.5rem 0;
font-size: 0.28rem;
color: #666;
-
+
input[type="checkbox"] {
width: 0.45rem;
height: 0.45rem;
@@ -955,11 +957,11 @@
position: relative;
flex-shrink: 0;
transition: all 0.3s ease;
-
+
&:checked {
background-color: #1890ff;
border-color: #1890ff;
-
+
&::after {
content: '✓';
position: absolute;
@@ -972,28 +974,28 @@
line-height: 1;
}
}
-
+
&:hover {
border-color: #1890ff;
}
-
+
&:focus {
outline: none;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
}
-
+
label {
display: flex;
align-items: center;
cursor: pointer;
user-select: none;
}
-
+
.agreement-link {
color: #1890ff;
text-decoration: none;
-
+
&:hover {
text-decoration: underline;
}
@@ -1018,12 +1020,12 @@
.login-link {
text-align: center;
margin-top: 0.5rem;
-
+
span {
font-size: 0.28rem;
color: #999;
cursor: pointer;
-
+
&:hover {
color: #1890ff;
}
@@ -1036,13 +1038,13 @@
align-items: center;
padding: 1rem 0.5rem;
background: #fff;
-
+
.feature-item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
-
+
.feature-icon {
width: 1rem;
height: 1rem;
@@ -1052,21 +1054,21 @@
align-items: center;
justify-content: center;
margin-bottom: 0.3rem;
-
+
svg {
width: 0.6rem;
height: 0.6rem;
color: #fff;
}
}
-
+
.feature-title {
font-size: 0.28rem;
font-weight: 600;
color: #333;
margin-bottom: 0.15rem;
}
-
+
.feature-desc {
font-size: 0.24rem;
color: #999;
diff --git a/src/page/newUser/about.vue b/src/page/newUser/about.vue
index 31737ab..97f65d5 100644
--- a/src/page/newUser/about.vue
+++ b/src/page/newUser/about.vue
@@ -11,68 +11,98 @@
<div class="hezi" v-show="type == '1'">
<img src="@/assets/img/yyzz.png" />
<h6>{{ $t("jy321") }}</h6>
- <p>{{ $t("jy320") }}:V1.1.2</p>
+ <p>{{ $t("jy320") }}: V1.1.2</p>
</div>
<div v-show="type != '1'" class="hezi" style="line-height: 0.5rem;">
- <div v-if="type == 2" v-html="userInfo.companyInfo"></div>
+ <div v-if="type == 2">
+ <div v-if="generating" class="loading-container">
+ <div class="loading-spinner"></div>
+ <p class="loading-text">{{ $t('jy526') }}</p>
+ </div>
+ <div v-else-if="!hasAgreementPdf" style="text-align: center; padding: 20px;">
+ <!-- <button @click="handleGeneratePdf" class="btn-generate" :disabled="generating">
+ 生成用户合同
+ </button> -->
+ </div>
+ <div v-else class="agreement-container">
+ <ImageViewer :imageUrls="imageUrls" v-if="imageUrls && imageUrls.length > 0" />
+ <div class="signature-section" v-if="showSignature && !isSigned">
+ <h4>{{ $t('jy527') }}</h4>
+ <vue-signature-pad
+ ref="mySignaturePad"
+ class="signature-canvas"
+ :options="signatureOptions"
+ ></vue-signature-pad>
+ <div class="signature-btns">
+ <button @click="clearSignature" class="btn-clear" :disabled="submittingSignature">{{ $t('jy528') }}</button>
+ <button @click="confirmSignature" class="btn-confirm" :disabled="submittingSignature">{{ $t('jy529') }}</button>
+ </div>
+ </div>
+ <div v-else-if="!isSigned" class="signature-action">
+ <button @click="showSignature = true" class="btn-signature">{{ $t('jy529') }}</button>
+ </div>
+ <div v-if="isSigned" class="signature-tip">
+ <p>{{ $t('jy530') }}</p>
+ </div>
+ </div>
+ </div>
<div v-else-if="type == 3" v-html="userInfo.certImg1"></div>
<div v-else-if="type == 4" v-html="userInfo.certImg2"></div>
<div v-else-if="type == 5" v-html="userInfo.tradeAgreeText"></div>
<div v-else-if="type == 6">{{ $t("jy319") }}</div>
+ <div v-else-if="type == 7">
+ <div v-if="generatingContract" class="loading-container">
+ <div class="loading-spinner"></div>
+ <p class="loading-text">{{ $t('jy526') }}</p>
+ </div>
+ <div v-else-if="!hasContractPdf" style="text-align: center; padding: 20px;">
+ <!-- <button @click="handleGenerateContractPdf" class="btn-generate" :disabled="generatingContract">
+ 生成用户合同
+ </button> -->
+ </div>
+ <div v-else class="agreement-container">
+ <ImageViewer :imageUrls="contractImageUrls" v-if="contractImageUrls && contractImageUrls.length > 0" />
+ <div class="signature-section" v-if="showContractSignature && !isContractSigned">
+ <h4>{{ $t('jy527') }}</h4>
+ <vue-signature-pad
+ ref="contractSignaturePad"
+ class="signature-canvas"
+ :options="signatureOptions"
+ ></vue-signature-pad>
+ <div class="signature-btns">
+ <button @click="clearContractSignature" class="btn-clear" :disabled="submittingContractSignature">{{ $t('jy528') }}</button>
+ <button @click="confirmContractSignature" class="btn-confirm" :disabled="submittingContractSignature">{{ $t('jy529') }}</button>
+ </div>
+ </div>
+ <div v-else-if="!isContractSigned" class="signature-action">
+ <button @click="showContractSignature = true" class="btn-signature">{{ $t('jy529') }}</button>
+ </div>
+ <div v-if="isContractSigned" class="signature-tip">
+ <p>{{ $t('jy530') }}</p>
+ </div>
+ </div>
+ </div>
<div v-else></div>
<!-- <img src="@/assets/img/yyzz.png" style="width: 100%;" /> -->
-
- </div>
- <div>
- <!-- 原始图片,点击可放大 -->
- <img
- src="@/assets/img/yyzz.png"
- style="width: 100%; cursor: pointer;"
- @click="showModal = true"
- />
-<!-- <div class="signature-area">
- <h4>请完成电子签名</h4>
- <vue-signature-pad
- ref="mySignaturePad"
- class="signature-canvas"
- :options="signatureOptions"
- ></vue-signature-pad>
- <div class="signature-btns">
- <button @click="clearSignature" class="btn-clear">清空签名</button>
- <button @click="confirmSignature" class="btn-confirm" :disabled="!isAgree || !hasSignature">确认签名</button>
- </div>
</div>
-
- <div class="signature-preview" v-if="signatureImg">
- <h4>签名预览</h4>
- <img :src="signatureImg" alt="电子签名" />
- </div> -->
-
-
- <!-- 模态框,用于显示放大的图片 -->
- <div
- v-if="showModal"
- class="modal"
- @click.self="showModal = false"
- >
- <div class="modal-content">
- <img
- :src="require('@/assets/img/yyzz.png')"
- class="enlarged-image"
- />
- </div>
- </div>
- </div>
</div>
</template>
<script>
import * as api from "@/axios/api";
import VueSignaturePad from 'vue-signature-pad'
+import PdfViewerModern from '@/components/PdfViewerModern.vue'
+import ImageViewer from '@/components/ImageViewer.vue'
+import axios from '@/axios/index'
+import APIUrl from '@/axios/api.url'
+import { Toast } from 'mint-ui'
+
export default {
name: "about",
components: {
- VueSignaturePad
+ VueSignaturePad,
+ PdfViewerModern,
+ ImageViewer
},
created() {
var that = this;
@@ -84,7 +114,7 @@
this.title = this.$t("jy318");
break;
case "2":
- this.title = this.$t("jy317");
+ this.title = this.$t("jy546");
break;
case "3":
this.title = this.$t("jy316");
@@ -98,6 +128,9 @@
case "6":
this.title = this.$t("jy315");
break;
+ case "7":
+ this.title = this.$t("jy547");
+ break;
default:
break;
}
@@ -109,75 +142,513 @@
title: this.$t("jy314"),
type: 0,
userInfo: {},
- showModal: false,
- signatureImg: '',
- isAgree: false,
- hasSignature: false,
- signatureOptions: {
- penColor: '#000000',
- penWidth: 2,
- },
- signatureInstance: null
+ signatureImg: '',
+ hasSignature: false,
+ signatureOptions: {
+ penColor: '#000000',
+ penWidth: 2,
+ },
+ signatureInstance: null,
+ hasAgreementPdf: false,
+ generating: false,
+ pdfUrl: '',
+ imageUrls: [],
+ showSignature: false,
+ currentUser: null,
+ hasContractPdf: false,
+ generatingContract: false,
+ contractPdfUrl: '',
+ contractImageUrls: [],
+ showContractSignature: false,
+ contractSignatureInstance: null,
+ submittingSignature: false,
+ submittingContractSignature: false
};
},
- mounted() {
- this.getUserInfo();
- // vue-signature-pad@2.x 的实例在 this.$refs.xxx.signaturePad 里
- this.signatureInstance = this.$refs.mySignaturePad.signaturePad
- // 监听签名变化,更新 hasSignature 状态
- this.$refs.mySignaturePad.$on('signatureChanged', (isEmpty) => {
- this.hasSignature = !isEmpty
- })
+ computed: {
+ isSigned() {
+ // 判断是否已签名:检查isSignedContract字段是否不为空
+ return this.currentUser && this.currentUser.isSignedContract && this.currentUser.isSignedContract.trim() !== '';
+ },
+ isContractSigned() {
+ // 判断保密协议是否已签名:检查isSignedAgreement字段是否等于'Y'
+ return this.currentUser && this.currentUser.isSignedAgreement === 'Y';
+ },
+ pdfIframeSrc() {
+ if (!this.pdfUrl) return '';
+ const token = typeof window !== 'undefined' && window.localStorage ? window.localStorage.getItem('USERTOKEN') || '' : '';
+ return this.pdfUrl + '?token=' + token;
+ }
+ },
+ async mounted() {
+ if(this.type != 3) {
+ await this.getUserInfo();
+ }else{
+ let data = await api.getInfoSite();
+ if (data.status === 0) {
+ this.userInfo = data.data;
+ }
+ }
+ if (this.type == 2) {
+ this.checkAgreementPdf();
+ } else if (this.type == 7) {
+ this.checkContractPdf();
+ }
+ },
+ watch: {
+ showSignature(newVal) {
+ if (newVal) {
+ // 当显示签名区域时,初始化签名组件
+ this.$nextTick(() => {
+ this.initSignaturePad();
+ });
+ }
+ },
+ showContractSignature(newVal) {
+ if (newVal) {
+ // 当显示合同签名区域时,初始化签名组件
+ this.$nextTick(() => {
+ this.initContractSignaturePad();
+ });
+ }
+ }
},
methods: {
+ isAuthenticated() {
+ // 判断是否已实名认证:isActive === 1 (审核中) 或 isActive === 2 (已通过)
+ const userInfo = this.currentUser || this.$store.state.userInfo;
+ return userInfo && (userInfo.isActive === 1 || userInfo.isActive === 2);
+ },
async getUserInfo() {
// 获取用户信息
let data = await api.getInfoSite();
if (data.status === 0) {
this.userInfo = data.data;
- } else {
+ }
+ // 获取当前登录用户信息
+ let userData = await api.getUserInfo();
+ if (userData.status === 0) {
+ this.currentUser = userData.data;
+ this.$store.state.userInfo = userData.data;
}
},
- // 清空签名(调用真实实例的方法)
- clearSignature() {
- if (this.signatureInstance) {
- this.signatureInstance.clear()
- this.signatureImg = ''
- this.hasSignature = false
- } else {
- alert('签名组件未初始化!')
- }
- },
- // 确认签名(调用真实实例的方法)
- confirmSignature() {
- if (!this.isAgree) {
- alert('请先阅读并同意用户协议!')
- return
- }
- if (this.signatureInstance) {
- // 检查是否有签名
- if (!this.signatureInstance.isEmpty()) {
- // 导出 Base64 图片
- this.signatureImg = this.signatureInstance.toDataURL('image/png')
- this.hasSignature = true
- this.submitAgreement()
- } else {
- alert('请先完成电子签名!')
+ initSignaturePad() {
+ this.$nextTick(() => {
+ if (this.$refs.mySignaturePad) {
+ this.signatureInstance = this.$refs.mySignaturePad.signaturePad;
}
- } else {
- alert('签名组件未初始化!')
+ });
+ },
+ clearSignature() {
+ this.$nextTick(() => {
+ if (!this.signatureInstance && this.$refs.mySignaturePad) {
+ this.signatureInstance = this.$refs.mySignaturePad.signaturePad;
+ }
+ if (this.signatureInstance) {
+ this.signatureInstance.clear();
+ this.signatureImg = '';
+ this.hasSignature = false;
+ }
+ });
+ },
+ confirmSignature() {
+ // 防止重复点击
+ if (this.submittingSignature) {
+ return;
+ }
+ this.$nextTick(() => {
+ if (!this.signatureInstance && this.$refs.mySignaturePad) {
+ this.signatureInstance = this.$refs.mySignaturePad.signaturePad;
+ }
+ if (this.signatureInstance) {
+ if (!this.signatureInstance.isEmpty()) {
+ this.signatureImg = this.signatureInstance.toDataURL('image/png');
+ this.hasSignature = true;
+ this.submitAgreement();
+ } else {
+ this.$message.error(this.$t('jy554'));
+ }
+ } else {
+ this.$message.error(this.$t('jy555'));
+
+ }
+ });
+ },
+ async submitAgreement() {
+ // 防止重复提交
+ if (this.submittingSignature) {
+ return;
+ }
+ this.submittingSignature = true;
+ try {
+ const blob = await this.dataURLtoBlob(this.signatureImg);
+ const formData = new FormData();
+ formData.append('signature', blob, 'signature.png');
+
+ const config = {
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ };
+
+ if (window.localStorage.getItem("USERTOKEN")) {
+ config.headers["USERTOKEN"] = window.localStorage.getItem("USERTOKEN");
+ }
+
+ const result = await axios.post(APIUrl.baseURL + '/user/saveAgreementSignature.do', formData, config);
+
+ if (result.data.status === 0) {
+ this.$message.success(this.$t('jy556'));
+ this.showSignature = false;
+ // 重新获取用户信息,更新签名状态
+ let userData = await api.getUserInfo();
+ if (userData.status === 0) {
+ this.currentUser = userData.data;
+ this.$store.state.userInfo = userData.data;
+ }
+ // 延迟跳转,让用户看到成功提示
+ setTimeout(() => {
+ this.$router.push('/User');
+ }, 1500);
+ } else {
+ this.$message.error(result.data.msg || this.$t('jy557'));
+ this.submittingSignature = false;
+ }
+ } catch (error) {
+ console.error('提交签名失败:', error);
+ this.$message.error(this.$t('jy557'));
+ this.submittingSignature = false;
}
},
- // 提交协议
- submitAgreement() {
- const submitData = {
- userId: '当前用户ID',
- isAgree: this.isAgree,
- signature: this.signatureImg,
- agreeTime: new Date().getTime()
+ dataURLtoBlob(dataurl) {
+ const arr = dataurl.split(',');
+ const mime = arr[0].match(/:(.*?);/)[1];
+ const bstr = atob(arr[1]);
+ let n = bstr.length;
+ const u8arr = new Uint8Array(n);
+ while (n--) {
+ u8arr[n] = bstr.charCodeAt(n);
}
- console.log('提交数据:', submitData)
- alert('签名成功,协议已提交!')
+ return new Blob([u8arr], { type: mime });
+ },
+ async checkAgreementPdf() {
+ try {
+ // type == 2 是线上合同
+ if (this.type == 2) {
+ const APIUrl = require('@/axios/api.url').default;
+
+ // 如果已签名(isSignedContract === 'Y'),调用viewAgreementPdf接口获取已签名的图片
+ if (this.currentUser && this.currentUser.isSignedContract === 'Y') {
+ this.generating = true;
+ let result = await api.viewAgreementPdf();
+ console.log('viewAgreementPdf返回结果:', result);
+ if (result.status === 0) {
+ this.hasAgreementPdf = true;
+ // result.data 现在是图片数组
+ if (Array.isArray(result.data) && result.data.length > 0) {
+ this.imageUrls = result.data.map(url => {
+ if (!url.startsWith('http')) {
+ return APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url);
+ }
+ return url;
+ });
+ console.log('处理后的图片URLs:', this.imageUrls);
+ } else {
+ console.warn('未返回图片数据或数据为空');
+ this.hasAgreementPdf = false;
+ }
+ } else {
+ console.error('接口返回错误:', result.msg);
+ this.hasAgreementPdf = false;
+ }
+ this.generating = false;
+ return;
+ }
+
+ // 如果未签名(isSignedContract为空),调用generateAgreementPdf接口生成并渲染图片
+ this.generating = true;
+ let result = await api.generateAgreementPdf();
+ if (result.status === 0) {
+ this.hasAgreementPdf = true;
+ // result.data 现在是图片数组
+ if (Array.isArray(result.data) && result.data.length > 0) {
+ this.imageUrls = result.data.map(url => {
+ if (!url.startsWith('http')) {
+ return APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url);
+ }
+ return url;
+ });
+ } else {
+ this.hasAgreementPdf = false;
+ }
+ } else {
+ this.hasAgreementPdf = false;
+ }
+ this.generating = false;
+ return;
+ }
+
+ // 其他type的处理逻辑
+ // 如果已签名,直接使用已签名的PDF
+ if (this.isSigned && this.currentUser && this.currentUser.isSignedContract) {
+ this.hasAgreementPdf = true;
+ let url = this.currentUser.isSignedContract;
+ if (!url.startsWith('http')) {
+ url = APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url);
+ }
+ this.pdfUrl = url;
+ return;
+ }
+
+ // 未签名,生成新的PDF
+ this.generating = true;
+ let result = await api.generateAgreementPdf();
+ if (result.status === 0) {
+ this.hasAgreementPdf = true;
+ // result.data 现在是图片数组
+ if (Array.isArray(result.data) && result.data.length > 0) {
+ this.imageUrls = result.data.map(url => {
+ if (!url.startsWith('http')) {
+ return APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url);
+ }
+ return url;
+ });
+ } else {
+ this.hasAgreementPdf = false;
+ }
+ } else {
+ this.hasAgreementPdf = false;
+ }
+ } catch (e) {
+ this.hasAgreementPdf = false;
+ } finally {
+ this.generating = false;
+ }
+ },
+ async handleGeneratePdf() {
+ this.generating = true;
+ try {
+ let result = await api.generateAgreementPdf();
+ if (result.status === 0) {
+ this.hasAgreementPdf = true;
+ // result.data 现在是图片数组
+ if (Array.isArray(result.data) && result.data.length > 0) {
+ this.imageUrls = result.data.map(url => {
+ if (!url.startsWith('http')) {
+ return APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url);
+ }
+ return url;
+ });
+ this.$message.success(this.$t('jy558'));
+ } else {
+ this.$message.error(this.$t('jy559'));
+ }
+ } else {
+ this.$message.error(result.msg || this.$t('jy560'));
+ }
+ } catch (e) {
+ this.$message.error(this.$t('jy560') + ': ' + e.message);
+ } finally {
+ this.generating = false;
+ }
+ },
+ initContractSignaturePad() {
+ this.$nextTick(() => {
+ if (this.$refs.contractSignaturePad) {
+ this.contractSignatureInstance = this.$refs.contractSignaturePad.signaturePad;
+ }
+ });
+ },
+ clearContractSignature() {
+ this.$nextTick(() => {
+ if (!this.contractSignatureInstance && this.$refs.contractSignaturePad) {
+ this.contractSignatureInstance = this.$refs.contractSignaturePad.signaturePad;
+ }
+ if (this.contractSignatureInstance) {
+ this.contractSignatureInstance.clear();
+ }
+ });
+ },
+ confirmContractSignature() {
+ // 防止重复点击
+ if (this.submittingContractSignature) {
+ return;
+ }
+ this.$nextTick(() => {
+ if (!this.contractSignatureInstance && this.$refs.contractSignaturePad) {
+ this.contractSignatureInstance = this.$refs.contractSignaturePad.signaturePad;
+ }
+ if (this.contractSignatureInstance) {
+ if (!this.contractSignatureInstance.isEmpty()) {
+ const signatureImg = this.contractSignatureInstance.toDataURL('image/png');
+ this.submitContractAgreement(signatureImg);
+ } else {
+ this.$message.error(this.$t('jy554'));
+ }
+ } else {
+ this.$message.error(this.$t('jy555'));
+ }
+ });
+ },
+ async submitContractAgreement(signatureImg) {
+ // 防止重复提交
+ if (this.submittingContractSignature) {
+ return;
+ }
+ this.submittingContractSignature = true;
+ try {
+ const blob = await this.dataURLtoBlob(signatureImg);
+ const formData = new FormData();
+ formData.append('signature', blob, 'signature.png');
+
+ const config = {
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ };
+
+ if (window.localStorage.getItem("USERTOKEN")) {
+ config.headers["USERTOKEN"] = window.localStorage.getItem("USERTOKEN");
+ }
+
+ const result = await axios.post(APIUrl.baseURL + '/user/saveAgreementContractSignature.do', formData, config);
+
+ if (result.data.status === 0) {
+ this.$message.success(this.$t('jy556'));
+ this.showContractSignature = false;
+ // 重新获取用户信息,更新签名状态
+ let userData = await api.getUserInfo();
+ if (userData.status === 0) {
+ this.currentUser = userData.data;
+ this.$store.state.userInfo = userData.data;
+ }
+ // 延迟跳转,让用户看到成功提示
+ setTimeout(() => {
+ this.$router.push('/User');
+ }, 1500);
+ } else {
+ this.$message.error(result.data.msg || this.$t('jy557'));
+ this.submittingContractSignature = false;
+ }
+ } catch (error) {
+ console.error('提交合同签名失败:', error);
+ this.$message.error(this.$t('jy557'));
+ this.submittingContractSignature = false;
+ }
+ },
+ async checkContractPdf() {
+ try {
+ // type == 7 是保密协议
+ if (this.type == 7) {
+ const APIUrl = require('@/axios/api.url').default;
+
+ // 判断是否已签名:isSignedAgreement === 'Y'
+ const isSigned = this.currentUser && this.currentUser.isSignedAgreement === 'Y';
+
+ if (isSigned) {
+ // 如果已签名,调用viewAgreementContractPdf接口获取已签名的图片(从数据库查询)
+ this.generatingContract = true;
+ let result = await api.viewAgreementContractPdf();
+ console.log('viewAgreementContractPdf返回结果:', result);
+ if (result.status === 0) {
+ this.hasContractPdf = true;
+ // result.data 现在是图片数组
+ if (Array.isArray(result.data) && result.data.length > 0) {
+ this.contractImageUrls = result.data.map(url => {
+ if (!url.startsWith('http')) {
+ return APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url);
+ }
+ return url;
+ });
+ console.log('处理后的图片URLs:', this.contractImageUrls);
+ } else {
+ console.warn('未返回图片数据或数据为空');
+ this.hasContractPdf = false;
+ }
+ } else {
+ console.error('接口返回错误:', result.msg);
+ this.hasContractPdf = false;
+ }
+ this.generatingContract = false;
+ return;
+ }
+
+ // 如果未签名(isSignedAgreement为空),调用generateAgreementContractPdf接口生成并渲染图片
+ this.generatingContract = true;
+ let result = await api.generateAgreementContractPdf();
+ if (result.status === 0) {
+ this.hasContractPdf = true;
+ // result.data 现在是图片数组
+ if (Array.isArray(result.data) && result.data.length > 0) {
+ this.contractImageUrls = result.data.map(url => {
+ if (!url.startsWith('http')) {
+ return APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url);
+ }
+ return url;
+ });
+ } else {
+ this.hasContractPdf = false;
+ }
+ } else {
+ this.hasContractPdf = false;
+ }
+ this.generatingContract = false;
+ return;
+ }
+ } catch (e) {
+ console.error('checkContractPdf错误:', e);
+ this.hasContractPdf = false;
+ } finally {
+ this.generatingContract = false;
+ }
+ },
+ async handleGenerateContractPdf() {
+ this.generatingContract = true;
+ try {
+ let result = await api.generateAgreementContractPdf();
+ if (result.status === 0) {
+ this.hasContractPdf = true;
+ // result.data 现在是图片数组
+ if (Array.isArray(result.data) && result.data.length > 0) {
+ this.contractImageUrls = result.data.map(url => {
+ if (!url.startsWith('http')) {
+ return APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url);
+ }
+ return url;
+ });
+ this.$message.success(this.$t('jy558'));
+ } else {
+ this.$message.error(this.$t('jy559'));
+ }
+ } else {
+ this.$message.error(result.msg || this.$t('jy560'));
+ }
+ } catch (e) {
+ this.$message.error(this.$t('jy560') + ': ' + e.message);
+ } finally {
+ this.generatingContract = false;
+ }
+ },
+ async handleGenerateContractPdfOld() {
+ this.generatingContract = true;
+ try {
+ let result = await api.generateAgreementContractPdf();
+ if (result.status === 0) {
+ this.hasContractPdf = true;
+ let url = result.data || '/user/viewAgreementContractPdf.do';
+ if (!url.startsWith('http')) {
+ url = APIUrl.baseURL + url;
+ }
+ this.contractPdfUrl = url;
+ this.$message.success(this.$t('jy558'));
+ } else {
+ this.$message.error(result.msg || this.$t('jy560'));
+ }
+ } catch (e) {
+ this.$message.error(this.$t('jy560') + ': ' + e.message);
+ } finally {
+ this.generatingContract = false;
+ }
}
}
};
@@ -270,6 +741,9 @@
.bijnm {
background: #fff;
min-height: 100vh;
+ width: 100%;
+ max-width: 100%;
+ box-sizing: border-box;
}
.headf {
@@ -311,14 +785,128 @@
}
.hezi {
- width: 9.2115rem;
+ width: 100%;
+ max-width: 100%;
+ padding: 0 20px;
border-bottom: 0.0267rem solid #e0e0e0;
margin: 0 auto;
margin-top: 1.1748rem;
padding-bottom: 0.534rem;
+ box-sizing: border-box;
}
.hezi img {
width: 5rem;
}
+
+.btn-generate, .btn-view {
+ padding: 10px 20px;
+ background: linear-gradient(-55deg, rgb(241, 22, 20), rgb(240, 40, 37));
+ color: #fff;
+ border: none;
+ border-radius: 5px;
+ font-size: 16px;
+ cursor: pointer;
+}
+
+.btn-generate:disabled {
+ background: #ccc;
+ cursor: not-allowed;
+}
+
+.agreement-container {
+ padding: 0;
+ width: 100%;
+ max-width: 100%;
+ box-sizing: border-box;
+ height: calc(100vh - 1.1748rem - 100px);
+ max-height: calc(100vh - 1.1748rem - 100px);
+ margin-top: -20px;
+}
+
+
+.signature-section {
+ margin-top: 20px;
+ padding: 20px;
+ background: #f9f9f9;
+ border-radius: 5px;
+}
+
+.signature-section h4 {
+ margin-bottom: 15px;
+ font-size: 18px;
+ font-weight: bold;
+}
+
+.signature-canvas {
+ width: 100%;
+ height: 300px;
+ border: 2px dashed #ccc;
+ margin: 15px 0;
+ background: #fff;
+ border-radius: 5px;
+}
+
+.signature-btns {
+ display: flex;
+ gap: 10px;
+ margin-top: 10px;
+}
+
+.btn-signature {
+ padding: 10px 20px;
+ background: linear-gradient(-55deg, rgb(241, 22, 20), rgb(240, 40, 37));
+ color: #fff;
+ border: none;
+ border-radius: 5px;
+ font-size: 16px;
+ cursor: pointer;
+ width: 100%;
+ margin-top: 20px;
+}
+
+.signature-tip {
+ margin-top: 20px;
+ padding: 15px;
+ background: #e8f5e9;
+ border-radius: 5px;
+ text-align: center;
+}
+
+.signature-tip p {
+ margin: 0;
+ color: #4caf50;
+ font-size: 16px;
+ font-weight: bold;
+}
+
+.loading-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 60px 20px;
+ min-height: 300px;
+}
+
+.loading-spinner {
+ width: 50px;
+ height: 50px;
+ border: 4px solid #f3f3f3;
+ border-top: 4px solid rgb(241, 22, 20);
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+ margin-bottom: 20px;
+}
+
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+}
+
+.loading-text {
+ color: #666;
+ font-size: 16px;
+ margin-top: 10px;
+}
</style>
diff --git a/src/page/newUser/index.vue b/src/page/newUser/index.vue
index fb335c5..81dd076 100644
--- a/src/page/newUser/index.vue
+++ b/src/page/newUser/index.vue
@@ -238,7 +238,7 @@
</div>
</div>
<div class="zijk">
- <h5>{{ $t("jy334") }}(融资融券账户)</h5>
+ <h5>{{ $t("jy334") }}({{ $t("jy548") }})</h5>
<div class="kunk">
<van-circle
v-model="currentRate"
@@ -306,7 +306,7 @@
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABVVJREFUWEfFl2tsk2UUx3/Pu7Zrd2FjwNaNSwYbasAAKsotYKYSEUk0GAKSoEZGApKYaKKSGMOInyYfQINfQESjYUrw8gGMCmQagqiJiiMgchsXGYONiVvbbe3Wx5w+79Z27dsVQ+JJlqXt85zzf87lf85RZCmaEwWQ9zhEa0DNACYCRfb1f4Bm0MfAaoTQfsXUQDaq1XCHNGerwXoNeBrIH+68/XsQaIBovaL6bKY7jgA0zV6I1oF6CfBkaXjosTDorWBtVEzsSacjLQDNmSrI2QuIq2+HHIPosnTeSAGguXAvRL8Cym6H5QQd18BarKj8NVFvEgA73j8AY26z8QF1bRCdm+iJQQCayz6IHAWmpxif4IIn82C+F6Z6wJ8DIyzQGjo1XO2D4xE43ANfBqGlPxP+JnDPVozvlkMJAM7Vg3o16WaVGzaXwBN5YAFX+uH3XrjcDzej5uhoC8a6YIYNTGx/HoRXOuBinwMQ/ZaiSirLALCT7g/APXhjZi586wefgnc6YWcXnI5kjswUN6wuhHUjIKRhQQucTHsnAtEpEgobwPkdQG2S9p8rjKsfboUzwxgeCusuN3xfDk1hWNjqBHqnYlKt0pwqBM/VFJIJVcKHAVjX/t/ycW8pLPBC6SWn+0EIlytN83LQn6Sc+qIMHvVBbTvszopVjQrx6foRsHUUNARgVVuGB6gVSnN+O7Am5dRDPjjkN18fDxtvNHbDiQj06uTjXmWSUO48UwB32qk0swV+6c3kwR0C4EdgVsqpoxVQ5YK3O2FVglJJ/pY+6NbmtT4LKnLi9SRx3xuEDcWmLBc55oCY/EkAiI9GpwDoqYT3u+CFG+YneZXE9A43jHdBgZLygYCGS31wKgJHeuKVIjnwoBfGOOaAaG0XAOKj1GZzwA8P5MLS63AoxhmZRQA+WwDTPCAhmes17p8v+e0oYWcAs3NBwiCv/KYbPgoYINfSsFzdSHi9CJSCE2HDAXe7ocCC/SFY2QadNnElY4kBSB8C8YC8YkcXLMs3cY45rd8wYUc/WArKckAI6NMgvHwjTsN5Cl4sgjeL4Ts7F1Kxx0KQPgklB4T91t8Al4I5uTA3N54D0guEhoWu9wRhxXXjLXF/oQVttrU1hbB9NDzfDru6hsYiloTpy3CgCoQJpQzTycZieGMkTLhkXl5kwUG/ASUMKDkglXJynAG0ICUfpAwdiGiAB8LaxF/+jvaCfB6QfWUwThrRFchVcLgcpnugPQoSgnl2L9g2Cp4rhIILQ54RIyIHKhYmfMwH+0KwJM8YkNr/MwIXhAeiUOMzHW92CxRbcHqcMSC9Y5bXcMDBbtgyCtYWgi8JQAjC/oFm9B6wOglebyXsCsDadiix4BGfmQek3OTVEmtpViJjLkJQm1mh0Q8lOVDbBh/YFH6kHPIt46m4mGYkn+1J6GRSO/5trDEscXPq61Ilorzub9h006iuFoA5JvNFBLhU1IYOqJfpPSYR0FMVVWecB5J5Xvi6DGSm2NYJHweM+4fKnlJYmm9KUM4llvtCHzSUmpK954rxkpHNikmx4WfoSCYlOW3QxmQ3bC2BRfZE9Jc9esn/jqjhzwoXLLfXBYn9ge7Y+7jfY3hEQC9uhfOD01ETeOcoKkJJABJCkTqUTnKZREzMASm5fg1d2oToVNiAuc9jeEOmJ2nj73ZBYNAtzkPpwKv/17E8DiK2jn2WFI7U6N/KN00QfSqrxSQOIraabbJXs/iweitmTbZvueXVLNGG5txke1xfCeRlaV/6927Q9VJqme4Mux3HPRJbz5eArrF3RlnPi+3fhQSagWOgZD3fl+16/i91NuTW6o8hHwAAAABJRU5ErkJggg=="
style="width: 0.4272rem; height: 0.4272rem; margin-right: 0.1602rem;"
/>
- 两融可取资金
+ {{ $t("jy549") }}
</p>
<h6>
¥
@@ -324,7 +324,7 @@
src="data:image/png;base64,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"
style="width: 0.4272rem; height: 0.4272rem; margin-right: 0.1602rem;"
/>
- 两融可用资金
+ {{ $t("jy550") }}
</p>
<h6 style="margin-left: 0.534rem;">
<span class="bzz" v-if="!selectUserFlag">{{
@@ -434,12 +434,21 @@
</div>
<span></span>
</li>
- <li @click="$router.push('/about?e=2')">
+ <li @click="goToUserAgreement">
<div class="le">
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAD6klEQVRYhc2YTWhVRxTH/3NfFm5sNxVFdxakhaL4xYuIduPKNqGbQnEhWHDZrWRbCqIrF7oTFBWxha7is4t007SV1iR+YIpgXUmycSM0RZPcOTNH5n5l3ryZefP0EfOH5H7P+d1zzzlz5gk4OvzFH5cBfAsgs69w/U+ItWNzCNHs19viHnaO68eL+7nnfs2sBcSVuc7oadtuF0TxEPOp9YYz+5nIMgZOuTwj7gkhRKsCfQFgpguOuRl4x/YdxzVzca8256trrLk41lqXntG6OH796vW0JLnUA8dswEdZYEttOwpogc7dvXNkPHT90nVeJoWWUoAkQGlASkCqtW2eEyQRFCmsrK58d/PCR/O+sfZ/+fevAjjGnmtBQN/NtgxQChxJs5Ugouh4IXtewOazRmTsuXB5DuSEAsaFkxHAMj79JnsA3YQIyYbLZXkcgsvlMD2YAAeE4QyMiTkDJ6UsYRM96LPbU2bcUhLSIHCkVBSwsesxGo7BPlrJyySx4cxnJUVeOAPeF87jQX8MVkU1JgO3KjkYc6oCM4AGztTCoMpK7b3q9aA9Q4TkSwif57TS5b6JiZgHU7M4BQ5FDMq+MVfD1edi4oHKTEqSVHGVAqe0Lqa0kGK2erM4MUlkbjyYu3B/kVI/a6XZ9pyJx5gHG6eklBm3CwkCkpRNDBI9J6VOLCwuHp66tutrUuooEc0aqLpZyLIsj41XwqXUQYRrki0iOieJnimlJpTWn/5y5eNb81OfF09N//jZn/8tLbW11ic180MA11dWV//tB5fWLLj9XEA/Xdx2FsDZ0PV/po6aIW5Uf30k0pMkBW7YioXVW8fgMMVY66z7Aq43XG0v/RMnNgvDVGx6DTYL7s37j9/dmbVaP2jmzb7Fkrtosl/UrnNCZAuSaOLJnfb/tr0sNYvd1VetrNWaYOBEJrKuDtjeNnCZu/qr4CqI1sjIIwCXm3eKZHFPDPrgUK7cJgXE0tt6ziolCwz87jqlTpQEDzrr1kr3O4c6AD70vOQ7q3yvAbJ4vevgQFkcqoPtr+Y2SaJvhBAfhD5rsWBnfvS40+76hP0Uc4h/XexxNyn1vRDiTCzmUCQC9O7x2U8eTx58NghgOUrioslXZpj5ZWJCLDNjORXOMpy+JvF11Q86o+f3jd37zdRBaO76rcbJ1qfztw8uDgPOCxhr+R/cbt8bzHCiIrNXsFl4bx2Now1RZgZak7wvD4a0MQp1RBuiYY0pXKg1H9g7NjOJ+MTfNU2JwPlq0Fi27gkx+uqgEoyWyLKtAMZCLROcCd7u5+zzzQzR9WO6X8zcs3j2tVtXIYReJ8+tOYbZ2LzadRLAG2TYR+L1rz8MAAAAAElFTkSuQmCC"
/>
- <p>{{ $t("jy317") }}</p>
+ <p>{{ $t("jy546") }}</p>
+ </div>
+ <span></span>
+ </li>
+ <li @click="goToUserContract">
+ <div class="le">
+ <img
+ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAD6klEQVRYhc2YTWhVRxTH/3NfFm5sNxVFdxakhaL4xYuIduPKNqGbQnEhWHDZrWRbCqIrF7oTFBWxha7is4t007SV1iR+YIpgXUmycSM0RZPcOTNH5n5l3ryZefP0EfOH5H7P+d1zzzlz5gk4OvzFH5cBfAsgs69w/U+ItWNzCNHs19viHnaO68eL+7nnfs2sBcSVuc7oadtuF0TxEPOp9YYz+5nIMgZOuTwj7gkhRKsCfQFgpguOuRl4x/YdxzVzca8256trrLk41lqXntG6OH796vW0JLnUA8dswEdZYEttOwpogc7dvXNkPHT90nVeJoWWUoAkQGlASkCqtW2eEyQRFCmsrK58d/PCR/O+sfZ/+fevAjjGnmtBQN/NtgxQChxJs5Ugouh4IXtewOazRmTsuXB5DuSEAsaFkxHAMj79JnsA3YQIyYbLZXkcgsvlMD2YAAeE4QyMiTkDJ6UsYRM96LPbU2bcUhLSIHCkVBSwsesxGo7BPlrJyySx4cxnJUVeOAPeF87jQX8MVkU1JgO3KjkYc6oCM4AGztTCoMpK7b3q9aA9Q4TkSwif57TS5b6JiZgHU7M4BQ5FDMq+MVfD1edi4oHKTEqSVHGVAqe0Lqa0kGK2erM4MUlkbjyYu3B/kVI/a6XZ9pyJx5gHG6eklBm3CwkCkpRNDBI9J6VOLCwuHp66tutrUuooEc0aqLpZyLIsj41XwqXUQYRrki0iOieJnimlJpTWn/5y5eNb81OfF09N//jZn/8tLbW11ic180MA11dWV//tB5fWLLj9XEA/Xdx2FsDZ0PV/po6aIW5Uf30k0pMkBW7YioXVW8fgMMVY66z7Aq43XG0v/RMnNgvDVGx6DTYL7s37j9/dmbVaP2jmzb7Fkrtosl/UrnNCZAuSaOLJnfb/tr0sNYvd1VetrNWaYOBEJrKuDtjeNnCZu/qr4CqI1sjIIwCXm3eKZHFPDPrgUK7cJgXE0tt6ziolCwz87jqlTpQEDzrr1kr3O4c6AD70vOQ7q3yvAbJ4vevgQFkcqoPtr+Y2SaJvhBAfhD5rsWBnfvS40+76hP0Uc4h/XexxNyn1vRDiTCzmUCQC9O7x2U8eTx58NghgOUrioslXZpj5ZWJCLDNjORXOMpy+JvF11Q86o+f3jd37zdRBaO76rcbJ1qfztw8uDgPOCxhr+R/cbt8bzHCiIrNXsFl4bx2Now1RZgZak7wvD4a0MQp1RBuiYY0pXKg1H9g7NjOJ+MTfNU2JwPlq0Fi27gkx+uqgEoyWyLKtAMZCLROcCd7u5+zzzQzR9WO6X8zcs3j2tVtXIYReJ8+tOYbZ2LzadRLAG2TYR+L1rz8MAAAAAElFTkSuQmCC"
+ />
+ <p>{{ $t("jy547") }}</p>
</div>
<span></span>
</li>
@@ -513,6 +522,24 @@
this.getInfoSite();
},
methods: {
+ goToUserAgreement() {
+ // 判断是否已实名认证
+ const userInfo = this.userInfo && this.userInfo.length > 0 ? this.userInfo : this.$store.state.userInfo;
+ if (!userInfo || userInfo.isActive !== 2) {
+ Toast(this.$t('jy551'));
+ return;
+ }
+ this.$router.push('/about?e=2');
+ },
+ goToUserContract() {
+ // 判断是否已实名认证
+ const userInfo = this.userInfo && this.userInfo.length > 0 ? this.userInfo : this.$store.state.userInfo;
+ if (!userInfo || userInfo.isActive !== 2) {
+ Toast(this.$t('jy551'));
+ return;
+ }
+ this.$router.push('/about?e=7');
+ },
rechargeMsg(msg){
Toast(this.$t("jy527"));
},
diff --git a/src/page/newUser/smrz.vue b/src/page/newUser/smrz.vue
index 34f4d01..5aaaf71 100644
--- a/src/page/newUser/smrz.vue
+++ b/src/page/newUser/smrz.vue
@@ -29,12 +29,24 @@
</li>
<li class="verli">
<input
- :placeholder="$t('jy520')"
+ :placeholder="$t('jy561')"
v-model="form.idCard"
v-if="showBtn"
/><input
- :placeholder="$t('jy520')"
+ :placeholder="$t('jy561')"
v-model="form.idCard"
+ v-if="!showBtn"
+ readonly
+ />
+ </li>
+ <li class="verli">
+ <input
+ :placeholder="$t('hj2111')"
+ v-model="form.address"
+ v-if="showBtn"
+ /><input
+ :placeholder="$t('hj2111')"
+ v-model="form.address"
v-if="!showBtn"
readonly
/>
@@ -127,6 +139,7 @@
phone: "",
name: "",
idCard: "",
+ address: "",
img1key: "",
img2key: "",
img3key: ""
@@ -220,6 +233,7 @@
) {
this.form.idCard = this.$store.state.userInfo.idCard;
this.form.name = this.$store.state.userInfo.realName;
+ this.form.address = this.$store.state.userInfo.regAddress || "";
this.form.img1key = this.$store.state.userInfo.img1Key;
this.form.img2key = this.$store.state.userInfo.img2Key;
// this.form.img3key = this.$store.state.userInfo.img3Key
@@ -265,6 +279,8 @@
Toast(this.$t("hj207"));
} else if (isNull(this.form.idCard) || !idCardReg(this.form.idCard)) {
Toast(this.$t("hj208"));
+ } else if (isNull(this.form.address)) {
+ Toast('请输入' + this.$t('hj2111'));
} else if (isNull(this.form.img1key)) {
Toast(this.$t("jy516"));
} else if (isNull(this.form.img2key)) {
@@ -278,6 +294,7 @@
let opts = {
realName: this.form.name,
idCard: this.form.idCard,
+ address: this.form.address,
img1key: this.form.img1key,
img2key: this.form.img2key,
img3key: this.form.img3key
diff --git a/src/page/user/Warehouse-detail.vue b/src/page/user/Warehouse-detail.vue
index 68a83e1..343f1de 100644
--- a/src/page/user/Warehouse-detail.vue
+++ b/src/page/user/Warehouse-detail.vue
@@ -3,33 +3,46 @@
<div class="trade-record-detail">
<div class="headf">
<div>
- <h2><span class="hbnh"><a class="fan" @click="$router.back()"></a></span>{{ $t('jy453') }}</h2>
+ <h2 v-if="this.$route.query.type == 'pingcang'"><span class="hbnh"><a class="fan" @click="$router.back()"></a></span>{{ $t('jy564') }}</h2>
+ <h2 v-if="this.$route.query.type == 'weituo'"><span class="hbnh"><a class="fan" @click="$router.back()"></a></span>{{ $t('jy563') }}</h2>
+ <h2 v-if="this.$route.query.type == 'chicang'"><span class="hbnh"><a class="fan" @click="$router.back()"></a></span>{{ $t('jy562') }}</h2>
</div>
</div>
<!-- 新内容 -->
<div class="stock">
- <div class="stock-name PingFang-Regular-crude">{{detail.stockName}}</div>
+ <!-- <div class="stock-name PingFang-Regular-crude">{{detail.stockName}}</div>
<div class="stock-code PingFang-Regular-crude">({{detail.stockCode}})</div>
<div class="stock-order-price PingFang-Regular">{{detail.orderTotalPrice}}</div>
<div class="stock-price PingFang-Regular">
<div class="stock-price-item">{{ $t('hj85') }}: {{detail.buyOrderPrice}}</div>
<div class="stock-price-item">{{ $t('hj84') }}: {{detail.sellOrderPrice}}</div>
- </div>
+ </div> -->
<div class="stock-jywc">
- <img v-if="detail.allProfitAndLose > 0" style="width: 60px;" src="@/assets/img/jywc.png" />
- <img v-else style="width: 60px;" src="@/assets/img/jywc-d.png" />
+ <img v-if="this.$route.query.type == 'pingcang'" style="width: 150px;" src="@/assets/img/wancheng.png" />
+ <img v-if="this.$route.query.type == 'weituo'" style="width: 150px;" src="@/assets/img/guadan.png" />
+ <img v-if="this.$route.query.type == 'chicang'" style="width: 150px;" src="@/assets/img/chicang.png" />
+
</div>
</div>
- <div class="partition">
+ <div class="partition" style="display: none;">
<div class="partition-item" v-for="item in 15" :key="item">
<div class="partition-point"></div>
</div>
</div>
- <div class="detail-con PingFang-Regular-crude">
+ <div class="detail-con">
<div class="detail-item flex col-center row-between page-warper">
- <div class="name">{{ $t('jy24') }}</div>
- <div class="value">{{detail.buyOrderTime}}</div>
+ <div class="name">{{ $t('jy161') }}</div>
+ <div class="value">
+ <span class="sz" v-show="(detail.stockGid.indexOf('sz')>=0)">{{ $t('jy83') }}</span>
+ <span class="sh" v-show="(detail.stockGid.indexOf('sh')>=0)">{{ $t('jy84') }}</span>
+ <span class="bj" v-show="(detail.stockGid.indexOf('bj')>=0)">{{ $t('jy85') }}</span>
+ {{detail.stockCode}}</div>
</div>
+ <div class="detail-item flex col-center row-between page-warper">
+ <div class="name">{{ $t('jy160') }}</div>
+ <div class="value">{{detail.stockName}}</div>
+ </div>
+
<div class="detail-item flex col-center row-between page-warper">
<div class="name">{{ $t('jy19') }}</div>
<div class="value">{{detail.buyOrderPrice}}</div>
@@ -46,11 +59,7 @@
<div class="name">{{ $t('jy450') }}</div>
<div class="value">{{detail.orderNum}}</div>
</div>
- <div class="detail-item flex col-center row-between page-warper">
- <div class="name">{{ $t('jy449') }}</div>
- <div class="value">{{detail.sellOrderTime}}</div>
- </div>
- <div class="detail-item flex col-center row-between page-warper">
+ <div class="detail-item flex col-center row-between page-warper" v-if="this.$route.query.type == 'pingcang' ">
<div class="name">{{ $t('jy25') }}</div>
<div class="value">{{detail.sellOrderPrice}}</div>
</div>
@@ -62,13 +71,25 @@
<div class="name">{{ $t('jy16') }}</div>
<div class="value">{{detail.orderSpread}}</div>
</div>
- <div class="detail-item flex col-center row-between page-warper">
+ <div class="detail-item flex col-center row-between page-warper" v-if="this.$route.query.type == 'pingcang'">
<div class="name">{{ $t('jy448') }}</div>
<div class="value">{{detail.profitAndLose}}</div>
</div>
- <div class="detail-item flex col-center row-between page-warper">
+ <div class="detail-item flex col-center row-between page-warper" v-if="this.$route.query.type !== 'weituo'">
<div class="name">{{ $t('jy12') }}</div>
- <div class="value" style="color: #098C26;">{{detail.allProfitAndLose}}</div>
+ <div class="value" :class="{'profit-red': parseFloat(detail.allProfitAndLose) > 0, 'profit-green': parseFloat(detail.allProfitAndLose) < 0}">{{detail.allProfitAndLose}}</div>
+ </div>
+ <div class="detail-item flex col-center row-between page-warper" v-if="this.$route.query.type == 'chicang'">
+ <div class="name">{{ $t('jy565') }}</div>
+ <div class="value" :class="{'profit-red': parseFloat(detail.allProfitAndLoseStr) > 0, 'profit-green': parseFloat(detail.allProfitAndLoseStr) < 0}">{{detail.allProfitAndLoseStr}}</div>
+ </div>
+ <div class="detail-item flex col-center row-between page-warper">
+ <div class="name">{{ $t('jy24') }}</div>
+ <div class="value">{{detail.buyOrderTime}}</div>
+ </div>
+ <div class="detail-item flex col-center row-between page-warper" v-if="this.$route.query.type == 'pingcang' ">
+ <div class="name">{{ $t('jy449') }}</div>
+ <div class="value">{{detail.sellOrderTime}}</div>
</div>
</div>
</div>
@@ -81,10 +102,13 @@
export default {
data() {
return {
- detail: {}
+ detail: {},
+ fromType: '' // 接收来源类型:chicang-持仓, pingcang-平仓, weituo-委托
}
},
mounted() {
+ // 接收来源类型参数
+ this.fromType = this.$route.query.type || '';
this.getDetail()
},
methods: {
@@ -103,6 +127,34 @@
</script>
<style lang="less" scoped>
+.sz {
+ color: #fff;
+ padding: 3px;
+ background: #3b4fde;
+}
+.bj {
+ color: #fff;
+ padding: 3px;
+ background: #ea6248;
+}
+
+.sh {
+ color: #fff;
+ padding: 3px;
+ background: #aa3bde;
+}
+
+.shbg {
+ color: #aa3bde;
+ padding: 3px;
+ background: rgba(170, 59, 222, .1);
+}
+
+.bjbg {
+ padding: 3px;
+ color: #ea6248;
+ background: rgba(234, 98, 72, .1);
+}
.partition{
width: 100%;
height: 20rpx;
@@ -206,8 +258,8 @@
}
.stock-jywc{
position: absolute;
- right: 50px;
- top: 50px;
+ right: 142px;
+ top: 130px;
color: #11183C;
}
@@ -250,17 +302,34 @@
}
}
.detail-con{
- padding: 20px;
+ background-color: #fff;
+ border-radius: 12px;
+ overflow: hidden;
+ margin: 16px;
.detail-item{
- padding-top: 10px;
- padding-bottom: 10px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 20px 16px;
+ border-bottom: 1px solid #E5E5E5;
.name{
- font-size: 14px;
- color: #11183C;
+ font-size: 18px;
+ color: #999999;
+ font-weight: 400;
}
.value{
- font-size: 14px;
+ font-size: 18px;
color: #11183C;
+ font-weight: 500;
+ &.profit-red{
+ color: #F11614;
+ }
+ &.profit-green{
+ color: #09A028;
+ }
+ }
+ &:last-child{
+ border-bottom: none;
}
}
}
diff --git a/src/page/user/Warehouse.vue b/src/page/user/Warehouse.vue
index 15616ba..654c88a 100644
--- a/src/page/user/Warehouse.vue
+++ b/src/page/user/Warehouse.vue
@@ -8,7 +8,7 @@
<div class="sert">
<span v-for="(item, index) in chicangList" :key="index" @click="chicangidx = index"
:class="chicangidx == index ? 'sdpl' : ''">{{ item.name }}</span>
- <a :style="{ left: getIndicatorLeft() + 'rem' }"></a>
+ <a :style="{ left: getIndicatorLeft() }"></a>
</div>
<div class="bnm"></div>
</div>
@@ -17,7 +17,7 @@
<van-list v-model="loading" :finished="finished" :finished-text="$t('hj43')"
v-show="chicangidx === 0" @load="onLoad" :immediate-check="immediate">
<!-- <div class="cichang" v-for="(item,index) in tabsPositionNumArr" :key="item.buyOrderId"> -->
- <div class="cichang" v-for="(item, key) in tabsPositionObj" :key="item.buyOrderId">
+ <div class="cichang" v-for="(item, key) in tabsPositionObj" :key="item.buyOrderId" @click="goDetail(item)">
<div class="dingbu">
<div class="dl">
<h6>{{ item.stockName ? item.stockName : item.indexName }}</h6>
@@ -31,7 +31,7 @@
<div class="button-container">
<!-- <div class="dr" style="margin-right: 16px" v-if="chicangidx == 0" @click="goBuyDetail(item)">买入</div>
<div class="dr-blue" style="margin-right: 16px" v-if="chicangidx == 0" @click="getpingcangbf(item.positionSn,item.orderNum)"> 部分平仓 </div> -->
- <div class="dr-blue" style="margin-right: 16px" v-if="chicangidx == 0" @click="getpingcang(item.positionSn)"> {{ $t('hj121') }} </div>
+ <div class="dr-blue" style="margin-right: 16px" v-if="chicangidx == 0" @click.stop="getpingcang(item.positionSn)"> {{ $t('hj121') }} </div>
</div>
</div>
@@ -58,7 +58,7 @@
<!-- <p v-if="chicangidx == 1"><span>{{ $t('jy19') }}</span><a class="red">5.49/{{ $t('jy96') }}</a></p>
<p v-if="chicangidx == 1"><span>{{ $t('jy15') }}</span><a class="red">49959.00</a></p> -->
<!-- <p><span>{{ $t('jy531') }}</span><a class="red">{{item.orderLever}}</a></p> -->
- <p><span>{{ $t('jy37') }}</span><a class="red">{{item.buyAmtAutual}}</a></p>
+ <!-- <p><span>{{ $t('jy37') }}</span><a class="red">{{item.buyAmtAutual}}</a></p> -->
</div>
</div>
</van-list>
@@ -99,7 +99,7 @@
<p><span>{{ $t('jy533') }}</span><a class="red">{{item.orderFee}}</a></p>
<p><span>{{ $t('jy17') }}</span><a class="red">{{item.orderTotalPrice}}</a></p>
<p><span>{{ $t('jy153') }}</span><a class="red">{{item.orderSpread}}</a></p>
- <p v-if="chicangidx == 1"><span>{{ $t('jy15') }}</span><a class="red">{{item.orderStayFee}}</a></p>
+ <!-- <p v-if="chicangidx == 1"><span>{{ $t('jy15') }}</span><a class="red">{{item.orderStayFee}}</a></p> -->
</div>
</div>
</van-list>
@@ -137,7 +137,7 @@
<p><span>{{ $t('jy19') }}</span><a class="red">{{item.buyOrderPrice}}/{{ $t('jy96') }}</a></p>
<p v-if="chicangidx == 1"><span>{{ $t('jy25') }}</span><a class="red">{{item.sellOrderPrice}}/{{ $t('jy96') }}</a></p>
<p><span>{{ $t('jy18') }}</span><a class="red">{{item.orderNum}}</a></p>
- <p><span>挂单时间</span><a class="red">{{ item.buyOrderTime | gettime }}</a></p>
+ <p><span>{{ $t('jy521') }}</span><a class="red">{{ item.buyOrderTime | gettime }}</a></p>
<p><span>{{ $t('jy17') }}</span><a class="red">{{item.orderTotalPrice}}</a></p>
<!-- <p><span>{{ $t('jy153') }}</span><a class="red">{{item.orderSpread}}</a></p> -->
<p v-if="chicangidx == 1"><span>{{ $t('jy15') }}</span><a class="red">{{item.orderStayFee}}</a></p>
@@ -170,7 +170,7 @@
name: this.$t('jy410')
},
{
- name: '我的委托'
+ name: this.$t('jy520')
}
],
chicangidx: 0,
@@ -206,19 +206,22 @@
methods: {
// 计算滑动指示器的位置
getIndicatorLeft() {
- const totalWidth = 5.34 // .sert 的总宽度(rem)
const tabCount = this.chicangList.length
- const indicatorWidth = 0.53 // 指示器宽度(rem)
- // 计算每个标签的中心位置
- const tabWidth = totalWidth / tabCount
- const centerPosition = (this.chicangidx + 0.7) * tabWidth
+ // 每个标签占的百分比
+ const tabWidthPercent = 100 / tabCount
- // 减去指示器宽度的一半,使其居中
- return centerPosition - indicatorWidth / 2
+ // 当前选中标签的中心位置(百分比)
+ const centerPositionPercent = (this.chicangidx + 0.5) * tabWidthPercent
+
+ // 返回百分比,指示器会自动居中
+ return centerPositionPercent + '%'
},
goDetail(item) {
- this.$router.push(`/WarehouseDetail?positionSn=${item.positionSn}`)
+ // 根据当前的tab索引传递不同的类型值
+ // chicangidx: 0-持仓, 1-平仓, 2-委托
+ const type = this.chicangidx === 1 ? 'pingcang' : this.chicangidx === 2 ? 'weituo' : 'chicang';
+ this.$router.push(`/WarehouseDetail?positionSn=${item.positionSn}&type=${type}`)
},
onLoad() {
//持仓
@@ -308,20 +311,20 @@
// 如果 chicangidx 为 0,表示是沪深京市场(可能是股票市场的不同板块)
if (this.chicangidx == 0) {
// 先弹出一个选择平仓数量的输入框
- this.$prompt('平仓数量', '部分平仓', {
+ this.$prompt(this.$t('jy522'), this.$t('jy523'), {
confirmButtonText: this.$t('hj161'),
cancelButtonText: this.$t('hj106'),
inputPattern: /^[0-9]*[1-9][0-9]*$/, // 限制输入为正整数
- inputErrorMessage: '格式错误' // 输入不合法时的错误提示
+ inputErrorMessage: this.$t('jy524') // 输入不合法时的错误提示
}).then(async ({ value }) => {
const selectedQuantity = Number(value); // 用户选择的平仓数量
if (selectedQuantity <= 0) {
- Toast('格式错误'); // 如果输入无效数量,提示错误
+ Toast(this.$t('jy524')); // 如果输入无效数量,提示错误
return;
}
if(selectedQuantity > orderNum){
- Toast('超过最大数量'+orderNum); // 如果输入无效数量,提示错误
+ Toast(this.$t('jy525') + orderNum); // 如果输入无效数量,提示错误
return;
}
// 弹出确认框,询问用户是否确认平仓
@@ -580,14 +583,17 @@
border-radius: 0.4rem 0.4rem 0 0;
margin-top: -0.4rem;
background: #fff;
+ padding: 0 0.4rem;
+ box-sizing: border-box;
.sert {
- width: 5.34rem;
+ width: 100%;
margin: 0 auto;
display: flex;
justify-content: space-between;
position: relative;
height: 1.07rem;
+ box-sizing: border-box;
span {
text-align: center;
@@ -595,6 +601,11 @@
font-size: .4rem;
font-weight: 550;
line-height: 1.07rem;
+ flex: 1;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ min-width: 0;
}
.sdpl {
@@ -608,7 +619,7 @@
border-radius: 0.05rem;
position: absolute;
bottom: 0;
- margin-left: -0.266rem;
+ transform: translateX(-50%);
transition: all .5s;
}
}
diff --git a/src/page/user/agreement.vue b/src/page/user/agreement.vue
index c31a494..dc6d02d 100644
--- a/src/page/user/agreement.vue
+++ b/src/page/user/agreement.vue
@@ -5,57 +5,140 @@
<router-link to="" slot="left">
<mt-button @click="goBack" icon="back"></mt-button>
</router-link>
- <!-- <mt-button icon="more" slot="right"></mt-button> -->
</mt-header>
</div>
- <div style="margin:12px 20px;">
- <div class="risk_text">
- <p v-for="item in siteInfo.tradeAgreeText.split('。')" :key="item">{{item}}。</p>
+ <div class="agreement-content">
+ <div v-if="loading" class="loading-container">
+ <div class="loading-spinner"></div>
+ <p>加载中...</p>
</div>
-
+ <div v-else-if="error" class="error-container">
+ <p>{{ error }}</p>
+ <button @click="loadPdf" class="retry-btn">重试</button>
+ </div>
+ <div v-else class="pdf-wrapper">
+ <ImageViewer :imageUrls="imageUrls" v-if="imageUrls && imageUrls.length > 0" />
+ </div>
</div>
</div>
-
</template>
<script>
+import * as api from '@/axios/api'
+import ImageViewer from '@/components/ImageViewer.vue'
+
export default {
+ components: {
+ ImageViewer
+ },
data () {
- return {siteInfo: {}}
+ return {
+ loading: true,
+ error: null,
+ imageUrls: []
+ }
},
mounted () {
- this.getInfoSite()
+ this.loadPdf()
},
methods: {
goBack () {
this.$router.back(-1)
},
- async getInfoSite () {
- // 获取网站信息
- let result = await api.getInfoSite()
+ async loadPdf () {
+ this.loading = true
+ this.error = null
+ try {
+ const result = await api.viewAgreementPdf()
if (result.status === 0) {
- this.siteInfo = result.data
+ // result.data 现在是图片数组
+ if (Array.isArray(result.data) && result.data.length > 0) {
+ const APIUrl = require('@/axios/api.url').default
+ this.imageUrls = result.data.map(url => {
+ if (!url.startsWith('http')) {
+ return APIUrl.baseURL + (url.startsWith('/') ? url : '/' + url)
+ }
+ return url
+ })
+ this.loading = false
+ } else {
+ this.error = '未返回图片数据'
+ this.loading = false
+ }
} else {
- this.$message.error(result.msg)
+ this.error = result.msg || '加载合同失败'
+ this.loading = false
}
+ } catch (e) {
+ console.error('加载PDF失败:', e)
+ this.error = e.message || '加载失败,请稍后重试'
+ this.loading = false
+ }
}
}
}
</script>
<style lang="css" scoped>
- h1 {
- font-size: 0.25rem;
- text-align: center;
- }
+.wrapper {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background: #f5f5f5;
+}
- h4 {
- font-size: 13px;
- line-height: 25px;
- margin: 25px 0;
- }
+.header {
+ flex-shrink: 0;
+}
- p {
- font-size: 12px;
- line-height: 25px;
- text-indent: 2em;
- }
+.agreement-content {
+ flex: 1;
+ overflow: hidden;
+ position: relative;
+}
+
+.loading-container,
+.error-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+ color: #666;
+}
+
+.loading-spinner {
+ width: 40px;
+ height: 40px;
+ border: 4px solid #f3f3f3;
+ border-top: 4px solid #f11514;
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+ margin-bottom: 15px;
+}
+
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+}
+
+.error-container {
+ color: #f56c6c;
+ padding: 20px;
+ text-align: center;
+}
+
+.retry-btn {
+ margin-top: 15px;
+ padding: 10px 20px;
+ background: linear-gradient(-55deg, rgb(241, 22, 20), rgb(240, 40, 37));
+ color: #fff;
+ border: none;
+ border-radius: 5px;
+ font-size: 14px;
+ cursor: pointer;
+}
+
+.pdf-wrapper {
+ height: 100%;
+ width: 100%;
+}
</style>
diff --git a/src/router/index.js b/src/router/index.js
index 5605a97..daca248 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -269,7 +269,7 @@
name: 'about',
meta: {
title: '详情',
- requireAuth: true,
+ requireAuth: false,
hasHeader: false,
show: true,
index: 1
@@ -625,7 +625,7 @@
name: 'aggre',
meta: {
title: '合作协议',
- requireAuth: true,
+ requireAuth: false,
index: 30
},
component: Aggre
@@ -709,7 +709,7 @@
name: 'agree',
meta: {
title: '注册协议',
- requireAuth: true,
+ requireAuth: false,
index: 38
},
component: Agree
@@ -718,7 +718,7 @@
name: 'trade',
meta: {
title: '交易⻛险揭示书',
- requireAuth: true,
+ requireAuth: false,
index: 39
},
component: Trage
--
Gitblit v1.9.3