From ea6ad9ddc3d5b33897e93276282245f7023836ff Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 28 八月 2025 17:45:28 +0800
Subject: [PATCH] 大数据市场分析

---
 src/views/invoiceCollaboration/components/TaxControlSyncDialog.vue |  362 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 362 insertions(+), 0 deletions(-)

diff --git a/src/views/invoiceCollaboration/components/TaxControlSyncDialog.vue b/src/views/invoiceCollaboration/components/TaxControlSyncDialog.vue
new file mode 100644
index 0000000..19bcfcd
--- /dev/null
+++ b/src/views/invoiceCollaboration/components/TaxControlSyncDialog.vue
@@ -0,0 +1,362 @@
+<template>
+  <el-dialog
+    :model-value="dialogSyncVisible"
+    @update:model-value="$emit('update:dialogSyncVisible', $event)"
+    title="绋庢帶骞冲彴鍚屾"
+    width="800px"
+    :close-on-click-modal="false"
+  >
+    <div class="sync-container">
+      <!-- 鍚屾鐘舵�� -->
+      <el-card class="sync-status" shadow="never">
+        <template #header>
+          <div class="card-header">
+            <span>鍚屾鐘舵��</span>
+          </div>
+        </template>
+        
+        <div class="status-content">
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <div class="status-item">
+                <div class="status-icon success">
+                  <el-icon><Check /></el-icon>
+                </div>
+                <div class="status-text">
+                  <div class="status-title">宸插悓姝�</div>
+                  <div class="status-count">{{ syncedCount }}</div>
+                </div>
+              </div>
+            </el-col>
+            <el-col :span="8">
+              <div class="status-item">
+                <div class="status-icon warning">
+                  <el-icon><Clock /></el-icon>
+                </div>
+                <div class="status-text">
+                  <div class="status-title">寰呭悓姝�</div>
+                  <div class="status-count">{{ pendingCount }}</div>
+                </div>
+              </div>
+            </el-col>
+            <el-col :span="8">
+              <div class="status-item">
+                <div class="status-icon danger">
+                  <el-icon><Close /></el-icon>
+                </div>
+                <div class="status-text">
+                  <div class="status-title">鍚屾澶辫触</div>
+                  <div class="status-count">{{ failedCount }}</div>
+                </div>
+              </div>
+            </el-col>
+          </el-row>
+        </div>
+      </el-card>
+
+      <!-- 鍚屾閰嶇疆 -->
+      <el-card class="sync-config" shadow="never">
+        <template #header>
+          <div class="card-header">
+            <span>鍚屾閰嶇疆</span>
+          </div>
+        </template>
+        
+        <el-form :model="syncConfig" label-width="120px">
+          <el-form-item label="绋庢帶骞冲彴鍦板潃">
+            <el-input
+              v-model="syncConfig.taxControlUrl"
+              placeholder="璇疯緭鍏ョ◣鎺у钩鍙板湴鍧�"
+              style="width: 100%"
+            />
+          </el-form-item>
+          <el-form-item label="鍚屾棰戠巼">
+            <el-select
+              v-model="syncConfig.syncFrequency"
+              placeholder="璇烽�夋嫨鍚屾棰戠巼"
+              style="width: 100%"
+            >
+              <el-option label="瀹炴椂鍚屾" value="realtime" />
+              <el-option label="姣忓皬鏃跺悓姝�" value="hourly" />
+              <el-option label="姣忓ぉ鍚屾" value="daily" />
+              <el-option label="鎵嬪姩鍚屾" value="manual" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鑷姩閲嶈瘯">
+            <el-switch
+              v-model="syncConfig.autoRetry"
+              active-text="寮�鍚�"
+              inactive-text="鍏抽棴"
+            />
+          </el-form-item>
+          <el-form-item label="閲嶈瘯娆℃暟" v-if="syncConfig.autoRetry">
+            <el-input-number
+              v-model="syncConfig.retryCount"
+              :min="1"
+              :max="10"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-form>
+      </el-card>
+
+      <!-- 鍚屾鏃ュ織 -->
+      <el-card class="sync-log" shadow="never">
+        <template #header>
+          <div class="card-header">
+            <span>鍚屾鏃ュ織</span>
+            <el-button type="primary" size="small" @click="refreshLog">
+              鍒锋柊鏃ュ織
+            </el-button>
+          </div>
+        </template>
+        
+        <el-table :data="syncLogs" border style="width: 100%" max-height="300">
+          <el-table-column label="鏃堕棿" prop="time" width="160" />
+          <el-table-column label="鎿嶄綔" prop="action" width="120" />
+          <el-table-column label="鐘舵��" prop="status" width="100">
+            <template #default="scope">
+              <el-tag :type="getLogStatusType(scope.row.status)">
+                {{ getLogStatusText(scope.row.status) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="璇︽儏" prop="detail" show-overflow-tooltip />
+        </el-table>
+      </el-card>
+    </div>
+
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="handleClose">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleSync" :loading="syncLoading">
+          寮�濮嬪悓姝�
+        </el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage } from "element-plus";
+import { Check, Clock, Close } from "@element-plus/icons-vue";
+
+// Props
+const props = defineProps({
+  dialogSyncVisible: {
+    type: Boolean,
+    default: false
+  }
+});
+
+// Emits
+const emit = defineEmits(['update:dialogSyncVisible', 'success']);
+
+// 鍝嶅簲寮忔暟鎹�
+const syncLoading = ref(false);
+const syncedCount = ref(15);
+const pendingCount = ref(8);
+const failedCount = ref(2);
+
+// 鍚屾閰嶇疆
+const syncConfig = reactive({
+  taxControlUrl: "https://tax-control.example.com/api",
+  syncFrequency: "manual",
+  autoRetry: true,
+  retryCount: 3
+});
+
+// 鍚屾鏃ュ織
+const syncLogs = ref([
+  {
+    time: "2024-12-01 15:30:00",
+    action: "鍙戠エ鍚屾",
+    status: "success",
+    detail: "鎴愬姛鍚屾15寮犲彂绁ㄥ埌绋庢帶骞冲彴"
+  },
+  {
+    time: "2024-12-01 15:25:00",
+    action: "鍙戠エ鍚屾",
+    status: "success",
+    detail: "鎴愬姛鍚屾8寮犲彂绁ㄥ埌绋庢帶骞冲彴"
+  },
+  {
+    time: "2024-12-01 15:20:00",
+    action: "鍙戠エ鍚屾",
+    status: "failed",
+    detail: "鍚屾澶辫触锛氱綉缁滆繛鎺ヨ秴鏃�"
+  },
+  {
+    time: "2024-12-01 15:15:00",
+    action: "鍙戠エ鍚屾",
+    status: "success",
+    detail: "鎴愬姛鍚屾12寮犲彂绁ㄥ埌绋庢帶骞冲彴"
+  }
+]);
+
+// 鑾峰彇鏃ュ織鐘舵�佺被鍨�
+const getLogStatusType = (status) => {
+  const statusMap = {
+    success: "success",
+    failed: "danger",
+    pending: "warning"
+  };
+  return statusMap[status] || "";
+};
+
+// 鑾峰彇鏃ュ織鐘舵�佹枃鏈�
+const getLogStatusText = (status) => {
+  const statusMap = {
+    success: "鎴愬姛",
+    failed: "澶辫触",
+    pending: "杩涜涓�"
+  };
+  return statusMap[status] || status;
+};
+
+// 鍒锋柊鏃ュ織
+const refreshLog = () => {
+  ElMessage.success("鏃ュ織宸插埛鏂�");
+};
+
+// 寮�濮嬪悓姝�
+const handleSync = async () => {
+  if (!syncConfig.taxControlUrl) {
+    ElMessage.warning("璇峰厛閰嶇疆绋庢帶骞冲彴鍦板潃");
+    return;
+  }
+
+  syncLoading.value = true;
+
+  try {
+    // 妯℃嫙鍚屾杩囩▼
+    await new Promise(resolve => setTimeout(resolve, 2000));
+
+    // 鏇存柊鍚屾鐘舵��
+    const newSynced = Math.min(pendingCount.value, 5);
+    syncedCount.value += newSynced;
+    pendingCount.value -= newSynced;
+
+    // 娣诲姞鍚屾鏃ュ織
+    syncLogs.value.unshift({
+      time: new Date().toLocaleString(),
+      action: "鍙戠エ鍚屾",
+      status: "success",
+      detail: `鎴愬姛鍚屾${newSynced}寮犲彂绁ㄥ埌绋庢帶骞冲彴`
+    });
+
+    ElMessage.success("鍚屾瀹屾垚");
+    emit('success');
+  } catch (error) {
+    ElMessage.error("鍚屾澶辫触");
+    failedCount.value++;
+    
+    // 娣诲姞澶辫触鏃ュ織
+    syncLogs.value.unshift({
+      time: new Date().toLocaleString(),
+      action: "鍙戠エ鍚屾",
+      status: "failed",
+      detail: "鍚屾澶辫触锛氱郴缁熼敊璇�"
+    });
+  } finally {
+    syncLoading.value = false;
+  }
+};
+
+// 鍏抽棴瀵硅瘽妗�
+const handleClose = () => {
+  emit('update:dialogSyncVisible', false);
+};
+
+// 缁勪欢鎸傝浇鏃跺垵濮嬪寲鏁版嵁
+onMounted(() => {
+  // 鍙互鍦ㄨ繖閲屽姞杞藉垵濮嬫暟鎹�
+});
+</script>
+
+<style scoped>
+.sync-container {
+  padding: 0;
+}
+
+.sync-status,
+.sync-config,
+.sync-log {
+  margin-bottom: 20px;
+}
+
+.sync-status:last-child,
+.sync-config:last-child,
+.sync-log:last-child {
+  margin-bottom: 0;
+}
+
+.card-header {
+  font-weight: bold;
+  font-size: 16px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.status-content {
+  padding: 20px 0;
+}
+
+.status-item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 20px;
+  text-align: center;
+}
+
+.status-icon {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 15px;
+  font-size: 24px;
+  color: white;
+}
+
+.status-icon.success {
+  background-color: #67c23a;
+}
+
+.status-icon.warning {
+  background-color: #e6a23c;
+}
+
+.status-icon.danger {
+  background-color: #f56c6c;
+}
+
+.status-text {
+  text-align: left;
+}
+
+.status-title {
+  font-size: 14px;
+  color: #606266;
+  margin-bottom: 5px;
+}
+
+.status-count {
+  font-size: 24px;
+  font-weight: bold;
+  color: #303133;
+}
+
+.dialog-footer {
+  text-align: right;
+}
+
+.el-table {
+  margin-top: 10px;
+}
+</style>

--
Gitblit v1.9.3