Selaa lähdekoodia

Merge remote-tracking branch 'origin/master'

YPZ 4 viikkoa sitten
vanhempi
sitoutus
7fe71bc9c5

+ 45 - 34
ui/smarttrade-platform/src/views/CustomersView.vue

@@ -36,10 +36,10 @@
     <div style="display: flex; gap: 16px; margin-bottom: 20px;">
       <div class="search-box" style="flex: 1;">
         <i class="fas fa-search search-icon"></i>
-        <input type="text" v-model="searchQuery" class="search-input" placeholder="搜索公司名称、联系人、邮箱..." @input="getCustomer">
+        <input type="text" v-model="searchQuery" class="search-input" placeholder="搜索公司名称、联系人、邮箱..." @change="getCustomerData">
       </div>
-      <div style="display: flex; gap: 8px;">
-        <el-cascader class="form-select" style="width: auto; padding: 0;" placeholder="区域名称" :options="region"
+      <div style="display: flex; gap: 8px;" class="form-select">
+        <el-cascader placeholder="区域名称" :options="region"
           v-model="regionValue" clearable filterable @change="getRegion" />
         <!-- <select v-model="industryFilter" class="form-select" style="width: auto; padding: 8px 16px;">
           <option value="">全部行业</option>
@@ -50,7 +50,7 @@
         <button class="btn btn-secondary"><i class="fas fa-sliders-h"></i> 高级筛选</button> -->
       </div>
     </div>
-
+    
     <!-- Tabs -->
     <div style="display: flex; gap: 4px; margin-bottom: 20px; border-bottom: 1px solid var(--border); padding-bottom: 12px;">
       <div v-for="tab in tabs" :key="tab.key" 
@@ -70,39 +70,41 @@
 
     <!-- Customer List -->
     <!-- <div style="flex: 1; overflow-y: auto;"> -->
+    <div v-loading="dataLoading" element-loading-background="rgba(0, 0, 0, 0.8)">
       <div v-for="customer in customers" :key="customer.id" 
            class="customer-card"
            @click="showCustomerDetail(customer)">
-        <div class="customer-flag">{{ customer.flag }}</div>
-        <div class="customer-info">
-          <div class="customer-header">
-            <span class="customer-name">{{ customer.customerName }}</span>
-            <!-- 客户类型标识 -->
-            <!-- <span class="customer-status" :style="{ background: getStatusBg(customer.status), color: getStatusColor(customer.status) }">
-              {{ getStatusLabel(customer.status) }}
-            </span> -->
-          </div>
-          <div class="customer-contact">
-            <i class="fas fa-user"></i> {{ customer.liaison?.name }}<span v-if="customer.liaison?.departmentPosition"> · </span>{{ customer.liaison?.departmentPosition }}
+          <div class="customer-flag">{{ customer.flag }}</div>
+          <div class="customer-info">
+            <div class="customer-header">
+              <span class="customer-name">{{ customer.customerName }}</span>
+              <!-- 客户类型标识 -->
+              <!-- <span class="customer-status" :style="{ background: getStatusBg(customer.status), color: getStatusColor(customer.status) }">
+                {{ getStatusLabel(customer.status) }}
+              </span> -->
+            </div>
+            <div class="customer-contact">
+              <i class="fas fa-user"></i> {{ customer.liaison?.name }}<span v-if="customer.liaison?.departmentPosition"> · </span>{{ customer.liaison?.departmentPosition }}
+            </div>
+            <div class="customer-meta">
+              <span><i class="fas fa-map-marker-alt"></i> {{ customer.continent }} · {{ customer.country }}</span>
+              <span><i class="fas fa-industry"></i> {{ customer.customerCompany?.industry }}</span>
+              <!-- <span><i class="fas fa-dollar-sign"></i> {{ customer.annualPurchase }}</span> -->
+            </div>
           </div>
-          <div class="customer-meta">
-            <span><i class="fas fa-map-marker-alt"></i> {{ customer.continent }} · {{ customer.country }}</span>
-            <span><i class="fas fa-industry"></i> {{ customer.customerCompany?.industry }}</span>
-            <!-- <span><i class="fas fa-dollar-sign"></i> {{ customer.annualPurchase }}</span> -->
+          <!-- <div class="customer-score">
+            <div class="score-circle" :class="getScoreClass(customer.score)">{{ customer.score }}</div>
+            <div class="score-label">意向分</div>
+          </div> -->
+          <div class="customer-actions" @click.stop>
+            <button class="btn btn-secondary btn-sm" @click="showCustomerDetail(customer)"><i class="fas fa-eye"></i>更多详情</button>
           </div>
         </div>
-        <!-- <div class="customer-score">
-          <div class="score-circle" :class="getScoreClass(customer.score)">{{ customer.score }}</div>
-          <div class="score-label">意向分</div>
-        </div> -->
-        <div class="customer-actions" @click.stop>
-          <button class="btn btn-secondary btn-sm" @click="showCustomerDetail(customer)"><i class="fas fa-eye"></i>更多详情</button>
-        </div>
       </div>
       <div class="pagination-area">
         <el-pagination
           background
-          :total="customerStats.total"
+          :total="customerTotal"
           style="text-align: right;"
           :current-page="params.pageIndex"
           :page-size="params.pageSize"
@@ -110,6 +112,7 @@
           @current-change="pageCurrentChange">
         </el-pagination>
       </div>
+    
     <!-- </div> -->
 
     <!-- 引入添加客户弹窗组件 -->
@@ -273,6 +276,7 @@ const industryFilter = ref('')
 const showToast = ref(false)
 const toastMessage = ref('')
 const toastType = ref('success')
+const dataLoading = ref(false)
 
 const customerStats = ref({
   total: 0,
@@ -297,19 +301,26 @@ const params = ref({
   blurry:null,
   country:null,
 })
-const getCustomer = () => {
+const getCustomer = (type) => {
+    dataLoading.value= true
     params.value.blurry = searchQuery.value
     getCustomerList(params.value).then(res => {
-    customerStats.value.total = tabs.value[0].count = res.result.total
+    dataLoading.value= false
+    if(type=='init'){ //页面初始记录客户总数量
+      customerStats.value.total = res.result.total
+    }
+    customerTotal.value = tabs.value[0].count = res.result.total
     customers.value = res.result.records
   })
 }
-getCustomer()
+getCustomer('init')
 const pageCurrentChange = (page) => {
     params.value.pageIndex = page
     getCustomer()
 }
-
+const getCustomerData = ()=>{
+  getCustomer()
+}
 const regionValue = ref([])
 const getRegion = (value) => {
     params.value.country = value?value[1]:''
@@ -530,8 +541,8 @@ const handleAddCustomer = (customerData) => {
 .search-icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-muted); }
 .search-input { width: 100%; padding: 10px 14px 10px 40px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px; color: var(--text-primary); font-size: 13px; }
 .search-input:focus { outline: none; border-color: var(--primary); }
-.form-select { background: var(--bg-card); border: 1px solid var(--border); color: var(--text-primary); }
-.form-select :deep(.el-input__wrapper){ background: var(--bg-card);}
+.form-select { background: var(--bg-card); border: none; color: var(--text-primary);width: auto;padding: 0; }
+.form-select :deep(.el-input__wrapper){ background: var(--bg-card);box-shadow:none;border: 1px solid var(--border);border-radius: 8px;padding: 3px 10px;}
 .customer-card { display: flex; align-items: center; gap: 16px; padding: 16px; background: var(--bg-card); border-radius: 12px; margin-bottom: 12px; border: 1px solid var(--border); cursor: pointer; transition: all 0.2s; }
 .customer-card:hover { border-color: var(--primary); }
 .customer-flag { font-size: 32px; }
@@ -553,7 +564,7 @@ const handleAddCustomer = (customerData) => {
 .customer-detail-modal { max-width: 800px; }
 .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-bottom: 1px solid var(--border); }
 .modal-title { display: flex; align-items: center; gap: 12px; font-size: 16px; font-weight: 600; }
-.modal-title h3 { font-size: 16px; font-weight: 600; margin: 0; }
+.modal-title h3 { font-size: 16px; font-weight: 600; margin: 0;word-break: break-all;}
 .modal-title p { font-size: 12px; color: var(--text-secondary); margin: 4px 0 0 0; }
 .detail-flag { font-size: 32px; }
 .modal-close { width: 32px; height: 32px; background: var(--bg-hover); border: none; border-radius: 8px; color: var(--text-secondary); cursor: pointer; display: flex; align-items: center; justify-content: center; }

+ 1 - 1
ui/smarttrade-platform/src/views/KnowledgeView.vue

@@ -1383,7 +1383,7 @@ const showToastMessage = (message, type = 'success') => {
 .import-modal { max-width: 500px; }
 .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-bottom: 1px solid var(--border); }
 .modal-title { display: flex; align-items: center; gap: 12px; font-size: 16px; font-weight: 600; }
-.modal-title h3 { font-size: 16px; font-weight: 600; margin: 0; }
+.modal-title h3 { font-size: 16px; font-weight: 600; margin: 0; word-break: break-all;}
 .modal-title p { font-size: 12px; color: var(--text-secondary); margin: 4px 0 0 0; }
 .detail-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 18px; }
 .modal-close { width: 32px; height: 32px; background: var(--bg-hover); border: none; border-radius: 8px; color: var(--text-secondary); cursor: pointer; display: flex; align-items: center; justify-content: center; }

+ 2 - 2
ui/smarttrade-platform/src/views/emails/edit.vue

@@ -21,7 +21,7 @@
                 </div>
                 <div class="send-input">
                     <span class="send-label">主题</span>
-                    <el-input v-model="form.subject" disabled></el-input>
+                    <el-input v-model="form.subject"></el-input>
                 </div>
                 <div class="msg-item" style="display: flex;flex: 1">
                     <div style="display: flex;flex-direction:column; flex: 1">
@@ -303,7 +303,7 @@
     const saveLoading = ref(false)
     const saveEmail = () => {
         saveLoading.value = true
-        editEmail({ id: queryData.id, content: form.value.content }).then(res => {
+        editEmail({ id: queryData.id, content: form.value.content, subject: form.value.subject }).then(res => {
             ElMessage.success('保存成功')
         }).catch((err) => {
             ElMessage.error(err.message || '保存失败')