Jelajahi Sumber

🌈 style(代理、账号池): 优化展示样式

dodo hold 3 bulan lalu
induk
melakukan
c770cbad5e
8 mengubah file dengan 2754 tambahan dan 1766 penghapusan
  1. 1 1
      .env.development
  2. 3 2
      src/api/jd.ts
  3. 7 5
      src/api/pdd.ts
  4. 1 3
      src/api/taobao.ts
  5. 704 498
      src/views/jd/list.vue
  6. 907 635
      src/views/pdd/list.vue
  7. 326 92
      src/views/settings/proxyNodes.vue
  8. 805 530
      src/views/taobao/list.vue

+ 1 - 1
.env.development

@@ -1,4 +1,4 @@
-VITE_API_BASE_URL= 'http://localhost:8186'
 VITE_API_BASE_URL= 'https://adminapi.molilian.com'
+VITE_API_BASE_URL= 'http://localhost:8186'
 
 VITE_API_BASE_SCOPE = 'admin'

+ 3 - 2
src/api/jd.ts

@@ -42,6 +42,7 @@ export interface JdPoolRecord {
     work_mode: boolean;
     end_point: string;
     nodeName: string;
+    proxyStatus?: boolean | null;
     enable_parse: boolean;
     enable_coupon: boolean;
     enable_sync_report: boolean;
@@ -127,10 +128,10 @@ export interface JdEstimateCommRecord {
 
     feeType: number;
     feeTypeStr: string;
-    
+
     platform: number;
     platformStr: string;
-    
+
     unionType: number;
     unionTypeStr: string;
 }

+ 7 - 5
src/api/pdd.ts

@@ -35,8 +35,6 @@ export function updateCookiesWithId(data: UpdateCookieWithIdModel) {
     return axios.post<FormRes>('/api/PddUnion/updateCookies', data);
 }
 
-
-
 // list
 export interface PddPoolRecord {
     id: number;
@@ -67,6 +65,7 @@ export interface PddPoolRecord {
     work_mode: boolean;
     end_point: string;
     nodeName: string;
+    proxyStatus?: boolean | null;
     enable_parse: boolean;
     enable_coupon: boolean;
     enable_sync_order: boolean;
@@ -114,8 +113,8 @@ export interface PddEstimateRevenueRecord {
     pidName: string;
 }
 
-
-export interface PddEstimateRevenueParams extends Partial<PddEstimateRevenueRecord> {
+export interface PddEstimateRevenueParams
+    extends Partial<PddEstimateRevenueRecord> {
     keyword?: string;
     query_date?: string[]; // 覆盖 report_date 的类型为字符串数组
     current: number;
@@ -134,7 +133,10 @@ export function queryPddEstimateRevenueTotal(data: PddEstimateRevenueParams) {
     );
 }
 export function queryPddEstimateRevenue(data: PddEstimateRevenueParams) {
-    return axios.post<PddEstimateRevenueRes>('/api/PddUnion/estimate_revenue', data);
+    return axios.post<PddEstimateRevenueRes>(
+        '/api/PddUnion/estimate_revenue',
+        data
+    );
 }
 
 export function rechargeAllOnlineAccountUsage() {

+ 1 - 3
src/api/taobao.ts

@@ -33,7 +33,6 @@ export interface UpdateConfigModel {
     dp_style_percentage: number;
     dp_style_default_str: string;
 
-
     tk_limit_per_ip_24h: number;
     tk_limit_per_oaid_24h: number;
     tk_parse_retry_count: number;
@@ -48,7 +47,6 @@ export interface UpdateConfigModel {
     pdd_limit_per_ip_24h: number;
     pdd_blacklist_regular: string;
 
-
     ks_limit_per_ip_24h: number;
     ks_limit_per_oaid_24h: number;
     ksIgnorePercentageCity: string;
@@ -117,6 +115,7 @@ export interface TkPoolRecord {
     last_time: Date;
     login_time: Date;
     nodeName: string;
+    proxyStatus?: boolean | null;
     suspended_endpoint: string;
     refpid: string;
     status: boolean;
@@ -134,7 +133,6 @@ export interface TkPoolRecord {
     appSecret: string;
     open_pid: string;
 
-
     daily_income_limit: number;
     daily_calls_limit: number;
     current_hourly_calls: number;

+ 704 - 498
src/views/jd/list.vue

@@ -4,23 +4,44 @@
         <a-card class="general-card" :title="$t('menu.jd.list')">
             <a-row>
                 <a-col :flex="1">
-                    <a-form :model="formModel" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }"
-                        label-align="left">
+                    <a-form
+                        :model="formModel"
+                        :label-col-props="{ span: 6 }"
+                        :wrapper-col-props="{ span: 18 }"
+                        label-align="left"
+                    >
                         <a-row :gutter="16">
                             <a-col :span="8">
                                 <a-form-item field="name" label="账号名">
-                                    <a-input v-model="formModel.name" placeholder="输入关键词搜索" />
+                                    <a-input
+                                        v-model="formModel.name"
+                                        placeholder="输入关键词搜索"
+                                    />
                                 </a-form-item>
                             </a-col>
                             <a-col :span="8">
-                                <a-form-item field="lastTime" :label="$t('searchTable.form.lastTime')">
-                                    <a-range-picker v-model="formModel.lastTime" style="width: 100%" />
+                                <a-form-item
+                                    field="lastTime"
+                                    :label="$t('searchTable.form.lastTime')"
+                                >
+                                    <a-range-picker
+                                        v-model="formModel.lastTime"
+                                        style="width: 100%"
+                                    />
                                 </a-form-item>
                             </a-col>
                             <a-col :span="8">
-                                <a-form-item field="status" :label="$t('searchTable.form.status')">
-                                    <a-select v-model="formModel.status" :options="statusOptions" :placeholder="$t('searchTable.form.selectDefault')
-                                        " />
+                                <a-form-item
+                                    field="status"
+                                    :label="$t('searchTable.form.status')"
+                                >
+                                    <a-select
+                                        v-model="formModel.status"
+                                        :options="statusOptions"
+                                        :placeholder="
+                                            $t('searchTable.form.selectDefault')
+                                        "
+                                    />
                                 </a-form-item>
                             </a-col>
                         </a-row>
@@ -50,45 +71,73 @@
                         </a-button>
                     </a-space>
                 </a-col>
-                <a-col :span="12" style="
+                <a-col
+                    :span="12"
+                    style="
                         display: flex;
                         align-items: center;
                         justify-content: end;
-                    ">
+                    "
+                >
                     <a-tooltip :content="$t('searchTable.actions.refresh')">
-                        <div class="action-icon" @click="search"><icon-refresh size="18" /></div>
+                        <div class="action-icon" @click="search"
+                            ><icon-refresh size="18"
+                        /></div>
                     </a-tooltip>
                     <a-dropdown @select="handleSelectDensity">
                         <a-tooltip :content="$t('searchTable.actions.density')">
-                            <div class="action-icon"><icon-line-height size="18" /></div>
+                            <div class="action-icon"
+                                ><icon-line-height size="18"
+                            /></div>
                         </a-tooltip>
                         <template #content>
-                            <a-doption v-for="item in densityList" :key="item.value" :value="item.value"
-                                :class="{ active: item.value === size }">
+                            <a-doption
+                                v-for="item in densityList"
+                                :key="item.value"
+                                :value="item.value"
+                                :class="{ active: item.value === size }"
+                            >
                                 <span>{{ item.name }}</span>
                             </a-doption>
                         </template>
                     </a-dropdown>
-                    <a-tooltip :content="$t('searchTable.actions.columnSetting')">
-                        <a-popover trigger="click" position="bl" @popup-visible-change="popupVisibleChange">
-                            <div class="action-icon"><icon-settings size="18" /></div>
+                    <a-tooltip
+                        :content="$t('searchTable.actions.columnSetting')"
+                    >
+                        <a-popover
+                            trigger="click"
+                            position="bl"
+                            @popup-visible-change="popupVisibleChange"
+                        >
+                            <div class="action-icon"
+                                ><icon-settings size="18"
+                            /></div>
                             <template #content>
                                 <div id="tableSetting">
-                                    <div v-for="(item, index) in showColumns" :key="item.dataIndex" class="setting">
-                                        <div style="
+                                    <div
+                                        v-for="(item, index) in showColumns"
+                                        :key="item.dataIndex"
+                                        class="setting"
+                                    >
+                                        <div
+                                            style="
                                                 margin-right: 4px;
                                                 cursor: move;
-                                            ">
+                                            "
+                                        >
                                             <icon-drag-arrow />
                                         </div>
                                         <div>
-                                            <a-checkbox v-model="item.checked" @change="
-                                                handleChange(
-                                                    $event,
-                                                    item as TableColumnData,
-                                                    index
-                                                )
-                                                ">
+                                            <a-checkbox
+                                                v-model="item.checked"
+                                                @change="
+                                                    handleChange(
+                                                        $event,
+                                                        item as TableColumnData,
+                                                        index
+                                                    )
+                                                "
+                                            >
                                             </a-checkbox>
                                         </div>
                                         <div class="title">
@@ -106,9 +155,20 @@
                 </a-col>
             </a-row>
 
-            <a-table row-key="id" :loading="loading" :pagination="pagination" :summary="true" summary-text="汇总"
-                :columns="(cloneColumns as TableColumnData[])" :data="renderData" :bordered="{ headerCell: true }"
-                :row-class="getRowClass" :size="size" @page-change="onPageChange" @page-size-change="onPageSizeChange">
+            <a-table
+                row-key="id"
+                :loading="loading"
+                :pagination="pagination"
+                :summary="true"
+                summary-text="汇总"
+                :columns="(cloneColumns as TableColumnData[])"
+                :data="renderData"
+                :bordered="{ headerCell: true }"
+                :row-class="getRowClass"
+                :size="size"
+                @page-change="onPageChange"
+                @page-size-change="onPageSizeChange"
+            >
                 <template #index="{ record }">
                     {{ record.id }}
                 </template>
@@ -116,9 +176,19 @@
                     <a-list-item-meta>
                         <template #title>
                             {{ record.company }}
-                            <a-tag color="blue" v-if="record.work_mode == 1">网站推广</a-tag>
-                            <a-tag color="orange" v-else-if="record.work_mode == 2">媒体导购</a-tag>
-                            <a-tag color="blue" v-else-if="record.work_mode == 4">订单侠</a-tag>
+                            <a-tag color="blue" v-if="record.work_mode == 1"
+                                >网站推广</a-tag
+                            >
+                            <a-tag
+                                color="orange"
+                                v-else-if="record.work_mode == 2"
+                                >媒体导购</a-tag
+                            >
+                            <a-tag
+                                color="blue"
+                                v-else-if="record.work_mode == 4"
+                                >订单侠</a-tag
+                            >
                             <a-tag color="purple" v-else>爬虫</a-tag>
                         </template>
                         <template #description>
@@ -127,17 +197,44 @@
                     </a-list-item-meta>
                 </template>
                 <template #nodeName="{ record }">
-                    <a-tag color="gray">{{ record.end_point }} - {{ record.nodeName }} </a-tag>
+                    <div>
+                        <a-tag
+                            :color="
+                                record.proxyStatus === true ? 'green' : 'gray'
+                            "
+                        >
+                            <template v-if="record.proxyStatus === true" #icon>
+                                <icon-check />
+                            </template>
+                            <template
+                                v-else-if="record.proxyStatus === false"
+                                #icon
+                            >
+                                <icon-stop />
+                            </template>
+                            {{ record.end_point }} - {{ record.nodeName }}
+                        </a-tag>
+                    </div>
                 </template>
 
                 <template #status="{ record }">
-                    <a-tag v-if="record.status" bordered color="green" @click="changeStatus(record.id, false)">
+                    <a-tag
+                        v-if="record.status"
+                        bordered
+                        color="green"
+                        @click="changeStatus(record.id, false)"
+                    >
                         <template #icon>
                             <icon-check />
                         </template>
                         在线
                     </a-tag>
-                    <a-tag v-else bordered color="" @click="changeStatus(record.id, true)">
+                    <a-tag
+                        v-else
+                        bordered
+                        color=""
+                        @click="changeStatus(record.id, true)"
+                    >
                         <template #icon>
                             <icon-stop />
                         </template>
@@ -145,559 +242,668 @@
                     </a-tag>
                 </template>
                 <template #actions="{ record }">
-                    <a-tag v-if="record.enable_parse" size="small" bordered color="red"
-                        @click="changeAttr(record.id, 'enable_parse', false)">
+                    <a-tag
+                        v-if="record.enable_parse"
+                        size="small"
+                        bordered
+                        color="red"
+                        @click="changeAttr(record.id, 'enable_parse', false)"
+                    >
                         转链
                     </a-tag>
-                    <a-tag v-else size="small" bordered color="" @click="changeAttr(record.id, 'enable_parse', true)">
+                    <a-tag
+                        v-else
+                        size="small"
+                        bordered
+                        color=""
+                        @click="changeAttr(record.id, 'enable_parse', true)"
+                    >
                         转链
                     </a-tag>
-                    <span style="margin: 5px;">
-                        <a-tag v-if="record.enable_coupon" size="small" bordered color="orange"
-                            @click="changeAttr(record.id, 'enable_coupon', false)">
+                    <span style="margin: 5px">
+                        <a-tag
+                            v-if="record.enable_coupon"
+                            size="small"
+                            bordered
+                            color="orange"
+                            @click="
+                                changeAttr(record.id, 'enable_coupon', false)
+                            "
+                        >
                             优惠券
                         </a-tag>
-                        <a-tag v-else size="small" bordered color=""
-                            @click="changeAttr(record.id, 'enable_coupon', true)">
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color=""
+                            @click="
+                                changeAttr(record.id, 'enable_coupon', true)
+                            "
+                        >
                             优惠券
                         </a-tag>
                     </span>
-                    <a-tag v-if="record.enable_sync_report" size="small" bordered color="blue"
-                        @click="changeAttr(record.id, 'enable_sync_report', false)">
+                    <a-tag
+                        v-if="record.enable_sync_report"
+                        size="small"
+                        bordered
+                        color="blue"
+                        @click="
+                            changeAttr(record.id, 'enable_sync_report', false)
+                        "
+                    >
                         同步收益
                     </a-tag>
-                    <a-tag v-else size="small" bordered color="gray"
-                        @click="changeAttr(record.id, 'enable_sync_report', true)">
+                    <a-tag
+                        v-else
+                        size="small"
+                        bordered
+                        color="gray"
+                        @click="
+                            changeAttr(record.id, 'enable_sync_report', true)
+                        "
+                    >
                         同步收益
                     </a-tag>
-                    <span style="margin:0 5px;">
-                        <a-tag v-if="record.enable_sync_order" size="small" bordered color="arcoblue"
-                            @click="changeAttr(record.id, 'enable_sync_order', false)">
+                    <span style="margin: 0 5px">
+                        <a-tag
+                            v-if="record.enable_sync_order"
+                            size="small"
+                            bordered
+                            color="arcoblue"
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_sync_order',
+                                    false
+                                )
+                            "
+                        >
                             同步订单
                         </a-tag>
-                        <a-tag v-else size="small" bordered color="gray"
-                            @click="changeAttr(record.id, 'enable_sync_order', true)">
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color="gray"
+                            @click="
+                                changeAttr(record.id, 'enable_sync_order', true)
+                            "
+                        >
                             同步订单
                         </a-tag>
                     </span>
-
                 </template>
                 <template #tags="{ record }">
-                    <a-tag v-if="record.parse_type" size="small" bordered color="blue">
+                    <a-tag
+                        v-if="record.parse_type"
+                        size="small"
+                        bordered
+                        color="blue"
+                    >
                         {{ record.parse_type }}
                     </a-tag>
 
-                    <a-tag v-if="record.riskStrategy" size="small" bordered color="orange">
+                    <a-tag
+                        v-if="record.riskStrategy"
+                        size="small"
+                        bordered
+                        color="orange"
+                    >
                         {{ record.riskStrategy }}-{{ record.launchScene }}
                     </a-tag>
-                    <a-tag v-if="record.riskCookie" size="small" bordered color="red">
+                    <a-tag
+                        v-if="record.riskCookie"
+                        size="small"
+                        bordered
+                        color="red"
+                    >
                         {{ record.riskCookie }}
                     </a-tag>
                 </template>
                 <template #time="{ record }">
-                    <div style="color:gray;">
-                        <div>注册:{{ dayjs(record.create_time).format('MM-DD HH:mm') }}</div>
-                        <div>更新:{{ dayjs(record.last_time).format('MM-DD HH:mm') }}</div>
-                        <div v-if="dayjs().diff(dayjs(record.login_time), 'hours') < 48">
-                            登录:{{ dayjs(record.login_time).format('MM-DD HH:mm') }}</div>
+                    <div style="color: gray">
+                        <div
+                            >注册:{{
+                                dayjs(record.create_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
+                        <div
+                            >更新:{{
+                                dayjs(record.last_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
+                        <div
+                            v-if="
+                                dayjs().diff(
+                                    dayjs(record.login_time),
+                                    'hours'
+                                ) < 48
+                            "
+                        >
+                            登录:{{
+                                dayjs(record.login_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
                     </div>
                 </template>
                 <template #summary-cell="{ column, record }">
-                    <div style="margin:10px auto" v-if="column.slotName == 'hourly_calls_limit'">
+                    <div
+                        style="margin: 10px auto"
+                        v-if="column.slotName == 'hourly_calls_limit'"
+                    >
                         {{ numberFormat(record.current_hourly_calls) }}
                     </div>
-                    <div style="margin:10px auto" v-if="column.slotName == 'daily_calls_limit'">
+                    <div
+                        style="margin: 10px auto"
+                        v-if="column.slotName == 'daily_calls_limit'"
+                    >
                         {{ numberFormat(record.current_daily_calls) }}
                     </div>
 
-
-                    <template v-if="column.dataIndex == 'today_clickNum' ||
-                        column.dataIndex == 'today_orderNum' ||
-                        column.dataIndex == 'today_finishOrderNum' ||
-                        column.dataIndex == 'today_finishCosPrice'">
-
+                    <template
+                        v-if="
+                            column.dataIndex == 'today_clickNum' ||
+                            column.dataIndex == 'today_orderNum' ||
+                            column.dataIndex == 'today_finishOrderNum' ||
+                            column.dataIndex == 'today_finishCosPrice'
+                        "
+                    >
                         <div>{{ numberFormat(record[column.dataIndex]) }}</div>
                     </template>
 
-
-
-                    <template v-if="column.dataIndex == 'today_cosPrice' ||
-                        column.dataIndex == 'today_finishCosFee' ||
-                        column.dataIndex == 'today_cosFee'">
-
+                    <template
+                        v-if="
+                            column.dataIndex == 'today_cosPrice' ||
+                            column.dataIndex == 'today_finishCosFee' ||
+                            column.dataIndex == 'today_cosFee'
+                        "
+                    >
                         <div>{{ amountFormat(record[column.dataIndex]) }}</div>
                     </template>
-
-
-
                 </template>
                 <template #time_range="{ record }">
-                    <WorkHourModel :path="updatePath" :record="record" @change="search" />
+                    <WorkHourModel
+                        :path="updatePath"
+                        :record="record"
+                        @change="search"
+                    />
                 </template>
                 <template #hourly_calls_limit="{ record }">
-                    <a-tag bordered
-                        :color="record.current_hourly_calls > record.hourly_calls_limit && record.hourly_calls_limit > 0 ? 'red' : ''">
+                    <a-tag
+                        bordered
+                        :color="
+                            record.current_hourly_calls >
+                                record.hourly_calls_limit &&
+                            record.hourly_calls_limit > 0
+                                ? 'red'
+                                : ''
+                        "
+                    >
                         {{ record.current_hourly_calls }} /
                         {{ record.hourly_calls_limit }}
                     </a-tag>
                 </template>
 
                 <template #daily_calls_limit="{ record }">
-                    <a-tag bordered
-                        :color="record.current_daily_calls > record.daily_calls_limit && record.daily_calls_limit > 0 ? 'red' : ''">
+                    <a-tag
+                        bordered
+                        :color="
+                            record.current_daily_calls >
+                                record.daily_calls_limit &&
+                            record.daily_calls_limit > 0
+                                ? 'red'
+                                : ''
+                        "
+                    >
                         {{ record.current_daily_calls }} /
                         {{ record.daily_calls_limit }}
                     </a-tag>
                 </template>
-
             </a-table>
         </a-card>
     </div>
 </template>
 
 <script lang="ts" setup>
-import { useRouter, useRoute } from 'vue-router';
-import { computed, ref, reactive, watch, nextTick } from 'vue';
-import { useI18n } from 'vue-i18n';
-import dayjs from 'dayjs';
-import useLoading from '@/hooks/loading';
-import { queryJdPool, JdPoolRecord, JdPoolParams } from '@/api/jd';
-
-import { Pagination } from '@/types/global';
-import { Modal, Message } from '@arco-design/web-vue';
-import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
-import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
-import cloneDeep from 'lodash/cloneDeep';
-import Sortable from 'sortablejs';
-import { numberFormat, amountFormat } from '@/utils/util';
-import { UpdateAccountModel, UpdateAccount } from '@/api/app';
-import WorkHourModel from '@/components/WorkHourModel.vue';
-
-const updatePath = '/api/JdUnion/update';
-type SizeProps = 'mini' | 'small' | 'medium' | 'large';
-type Column = TableColumnData & { checked?: true };
-
-
-const generateFormModel = () => {
-    return {
-        name: '',
-        lastTime: [],
-        status: '',
-        show_hide: false,
-        sort: 'status',
-        order: 'descending',
+    import { useRouter, useRoute } from 'vue-router';
+    import { computed, ref, reactive, watch, nextTick } from 'vue';
+    import { useI18n } from 'vue-i18n';
+    import dayjs from 'dayjs';
+    import useLoading from '@/hooks/loading';
+    import { queryJdPool, JdPoolRecord, JdPoolParams } from '@/api/jd';
+
+    import { Pagination } from '@/types/global';
+    import { Modal, Message } from '@arco-design/web-vue';
+    import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
+    import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
+    import cloneDeep from 'lodash/cloneDeep';
+    import Sortable from 'sortablejs';
+    import { numberFormat, amountFormat } from '@/utils/util';
+    import { UpdateAccountModel, UpdateAccount } from '@/api/app';
+    import WorkHourModel from '@/components/WorkHourModel.vue';
+
+    const updatePath = '/api/JdUnion/update';
+    type SizeProps = 'mini' | 'small' | 'medium' | 'large';
+    type Column = TableColumnData & { checked?: true };
+
+    const generateFormModel = () => {
+        return {
+            name: '',
+            lastTime: [],
+            status: '',
+            show_hide: false,
+            sort: 'status',
+            order: 'descending',
+        };
     };
-};
-const router = useRouter();
-const route = useRoute();
-
-const { loading, setLoading } = useLoading(true);
-const { t } = useI18n();
-const renderData = ref<JdPoolRecord[]>([]);
-const formModel = ref(generateFormModel());
-const cloneColumns = ref<Column[]>([]);
-const showColumns = ref<Column[]>([]);
-
-
-const size = ref<SizeProps>('small');
-
-const basePagination: Pagination = {
-    current: 1,
-    pageSize: 50,
-    showPageSize: true,
-    showTotal: true,
-    pageSizeOptions: [10, 20, 50, 100, 200, 500]
-};
-const pagination = reactive({
-    ...basePagination,
-});
-const densityList = computed(() => [
-    {
-        name: t('searchTable.size.mini'),
-        value: 'mini',
-    },
-    {
-        name: t('searchTable.size.small'),
-        value: 'small',
-    },
-    {
-        name: t('searchTable.size.medium'),
-        value: 'medium',
-    },
-    {
-        name: t('searchTable.size.large'),
-        value: 'large',
-    },
-]);
-
-const columns = computed<TableColumnData[]>(() => [
-    {
-        title: '#',
-        dataIndex: 'index',
-        slotName: 'index',
-        width: 50,
-    },
-    {
-        title: '账号名',
-        dataIndex: 'name',
-        slotName: 'name',
-        width: 250,
-    },
-    {
-        title: '',
-        slotName: 'tags',
-        width: 40,
-    },
-    {
-        title: '工作时间',
-        dataIndex: 'time_range',
-        slotName: 'time_range',
-        align: 'right',
-        width: 200,
-    },
-    {
-        title: '当日推广效果',
-        children: [
-            {
-                title: '点击量',
-                dataIndex: 'today_clickNum',
-                width: 100,
-                align: 'right',
-                render: (e: any) => numberFormat(e.record.today_clickNum)
-            },
-            {
-                title: '有效订单',
-                dataIndex: 'today_orderNum',
-                width: 100,
-                align: 'right',
-                render: (e: any) => numberFormat(e.record.today_orderNum)
-            },
-            {
-                title: '订单金额',
-                dataIndex: 'today_cosPrice',
-                width: 150,
-                align: 'right',
-                render: (e: any) => amountFormat(e.record.today_cosPrice)
-            },
-            {
-                title: '预估收入',
-                dataIndex: 'today_cosFee',
-                width: 150,
-                align: 'right',
-                render: (e: any) => amountFormat(e.record.today_cosFee)
-            },
+    const router = useRouter();
+    const route = useRoute();
 
-            // 
-
-        ]
-    },
-    {
-        title: '小时调用',
-        slotName: 'hourly_calls_limit',
-        dataIndex: 'current_hourly_calls',
-        align: 'right',
-        width: 120,
-    },
-    {
-        title: '当日调用',
-        slotName: 'daily_calls_limit',
-        dataIndex: 'current_daily_calls',
-        align: 'right',
-        width: 150,
-    },
-    {
-        title: '运行节点',
-        slotName: 'nodeName',
-        width: 120,
-    },
-    {
-        title: '状态',
-        slotName: 'status',
-        width: 100,
-    },
-    {
-        title: '分类',
-        slotName: 'actions',
-        width: 200,
-        align: 'center',
-    },
-    {
-        title: '时间',
-        slotName: 'time',
-        width: 170,
-    },
-]);
-
-const statusOptions = computed<SelectOptionData[]>(() => [
-    {
-        label: '全部',
-        value: '',
-    },
-    {
-        label: '在线',
-        value: 'online',
-    },
-    {
-        label: '下线',
-        value: 'offline',
-    },
-]);
-
-const getRowClass = (record: JdPoolRecord) => {
-    return record.is_hide ? 'special-table-row' : '';
-};
-
-
-if (route.query.show_hide === '1') {
-    formModel.value.show_hide = true;
-}
-
-const fetchData = async (
-    params: JdPoolParams = {
+    const { loading, setLoading } = useLoading(true);
+    const { t } = useI18n();
+    const renderData = ref<JdPoolRecord[]>([]);
+    const formModel = ref(generateFormModel());
+    const cloneColumns = ref<Column[]>([]);
+    const showColumns = ref<Column[]>([]);
+
+    const size = ref<SizeProps>('small');
+
+    const basePagination: Pagination = {
         current: 1,
         pageSize: 50,
-        show_hide: false,
-        sort: 'status',
-        order: 'descending',
-        getTotal: true,
-    }
-) => {
+        showPageSize: true,
+        showTotal: true,
+        pageSizeOptions: [10, 20, 50, 100, 200, 500],
+    };
+    const pagination = reactive({
+        ...basePagination,
+    });
+    const densityList = computed(() => [
+        {
+            name: t('searchTable.size.mini'),
+            value: 'mini',
+        },
+        {
+            name: t('searchTable.size.small'),
+            value: 'small',
+        },
+        {
+            name: t('searchTable.size.medium'),
+            value: 'medium',
+        },
+        {
+            name: t('searchTable.size.large'),
+            value: 'large',
+        },
+    ]);
+
+    const columns = computed<TableColumnData[]>(() => [
+        {
+            title: '#',
+            dataIndex: 'index',
+            slotName: 'index',
+            width: 50,
+        },
+        {
+            title: '账号名',
+            dataIndex: 'name',
+            slotName: 'name',
+            width: 250,
+        },
+        {
+            title: '',
+            slotName: 'tags',
+            width: 40,
+        },
+        {
+            title: '工作时间',
+            dataIndex: 'time_range',
+            slotName: 'time_range',
+            align: 'right',
+            width: 200,
+        },
+        {
+            title: '当日推广效果',
+            children: [
+                {
+                    title: '点击量',
+                    dataIndex: 'today_clickNum',
+                    width: 100,
+                    align: 'right',
+                    render: (e: any) => numberFormat(e.record.today_clickNum),
+                },
+                {
+                    title: '有效订单',
+                    dataIndex: 'today_orderNum',
+                    width: 100,
+                    align: 'right',
+                    render: (e: any) => numberFormat(e.record.today_orderNum),
+                },
+                {
+                    title: '订单金额',
+                    dataIndex: 'today_cosPrice',
+                    width: 150,
+                    align: 'right',
+                    render: (e: any) => amountFormat(e.record.today_cosPrice),
+                },
+                {
+                    title: '预估收入',
+                    dataIndex: 'today_cosFee',
+                    width: 150,
+                    align: 'right',
+                    render: (e: any) => amountFormat(e.record.today_cosFee),
+                },
+
+                //
+            ],
+        },
+        {
+            title: '小时调用',
+            slotName: 'hourly_calls_limit',
+            dataIndex: 'current_hourly_calls',
+            align: 'right',
+            width: 120,
+        },
+        {
+            title: '当日调用',
+            slotName: 'daily_calls_limit',
+            dataIndex: 'current_daily_calls',
+            align: 'right',
+            width: 150,
+        },
+        {
+            title: '运行节点',
+            slotName: 'nodeName',
+            width: 120,
+        },
+        {
+            title: '状态',
+            slotName: 'status',
+            width: 100,
+        },
+        {
+            title: '分类',
+            slotName: 'actions',
+            width: 200,
+            align: 'center',
+        },
+        {
+            title: '时间',
+            slotName: 'time',
+            width: 170,
+        },
+    ]);
+
+    const statusOptions = computed<SelectOptionData[]>(() => [
+        {
+            label: '全部',
+            value: '',
+        },
+        {
+            label: '在线',
+            value: 'online',
+        },
+        {
+            label: '下线',
+            value: 'offline',
+        },
+    ]);
+
+    const getRowClass = (record: JdPoolRecord) => {
+        return record.is_hide ? 'special-table-row' : '';
+    };
+
     if (route.query.show_hide === '1') {
-        params.show_hide = true;
+        formModel.value.show_hide = true;
     }
 
-    setLoading(true);
-    try {
-        const { data } = await queryJdPool(params);
-        if (!data) return;
-        // const { data } = await queryJdPool(params);
-        renderData.value = data.list;
-        pagination.current = data.page;
-        pagination.total = data.count;
-    } catch (err) {
-        console.log(err);
-        // you can report use errorHandler or other
-    } finally {
-        setLoading(false);
-    }
-};
-
-const changeItem = async (data: JdPoolRecord) => {
-    router.push({ name: 'updateCookies' });
-};
-
-const billView = async (data: JdPoolRecord) => {
-    router.push({ name: 'taobao_bill_dailys', query: { name: data.company } });
-};
-
-
-const changeStatus = async (id: number, val: any) => {
-    const args = {
-        id,
-        name: 'status',
-        val
-    } as UpdateAccountModel;
-
-    Modal.confirm({
-        title: '确认提示',
-        content: '确定要更改状态吗?',
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
-
-            try {
-                const { data } = await UpdateAccount(updatePath, args);
-                console.log(data, data.msg);
-                const msg = data.msg || '更新成功!';
-                if (data.success) {
-                    Message.success(msg);
-                    search();
-                } else {
-                    Message.error(data.msg);
-                }
+    const fetchData = async (
+        params: JdPoolParams = {
+            current: 1,
+            pageSize: 50,
+            show_hide: false,
+            sort: 'status',
+            order: 'descending',
+            getTotal: true,
+        }
+    ) => {
+        if (route.query.show_hide === '1') {
+            params.show_hide = true;
+        }
 
-            } catch (e) { console.log(e) }
+        setLoading(true);
+        try {
+            const { data } = await queryJdPool(params);
+            if (!data) return;
+            // const { data } = await queryJdPool(params);
+            renderData.value = data.list;
+            pagination.current = data.page;
+            pagination.total = data.count;
+        } catch (err) {
+            console.log(err);
+            // you can report use errorHandler or other
+        } finally {
             setLoading(false);
         }
-    });
-};
-
-
-const changeAttr = async (id: number, name: string, val: any) => {
-    const args = {
-        id,
-        name,
-        val
-    } as UpdateAccountModel;
-
-    Modal.confirm({
-        title: '确认提示',
-        content: '确定要更改状态吗?',
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
-            try {
-                const { data } = await UpdateAccount(updatePath, args);
-                console.log(data, data.msg);
-                const msg = data.msg || '更新成功!';
-                if (data.success) {
-                    Message.success(msg);
-                    search();
-                } else {
-                    Message.error(data.msg);
+    };
+
+    const changeItem = async (data: JdPoolRecord) => {
+        router.push({ name: 'updateCookies' });
+    };
+
+    const billView = async (data: JdPoolRecord) => {
+        router.push({
+            name: 'taobao_bill_dailys',
+            query: { name: data.company },
+        });
+    };
+
+    const changeStatus = async (id: number, val: any) => {
+        const args = {
+            id,
+            name: 'status',
+            val,
+        } as UpdateAccountModel;
+
+        Modal.confirm({
+            title: '确认提示',
+            content: '确定要更改状态吗?',
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+
+                try {
+                    const { data } = await UpdateAccount(updatePath, args);
+                    console.log(data, data.msg);
+                    const msg = data.msg || '更新成功!';
+                    if (data.success) {
+                        Message.success(msg);
+                        search();
+                    } else {
+                        Message.error(data.msg);
+                    }
+                } catch (e) {
+                    console.log(e);
                 }
-            } catch (e) { console.log(e) }
-            setLoading(false);
-        }
-    });
-};
+                setLoading(false);
+            },
+        });
+    };
 
+    const changeAttr = async (id: number, name: string, val: any) => {
+        const args = {
+            id,
+            name,
+            val,
+        } as UpdateAccountModel;
+
+        Modal.confirm({
+            title: '确认提示',
+            content: '确定要更改状态吗?',
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+                try {
+                    const { data } = await UpdateAccount(updatePath, args);
+                    console.log(data, data.msg);
+                    const msg = data.msg || '更新成功!';
+                    if (data.success) {
+                        Message.success(msg);
+                        search();
+                    } else {
+                        Message.error(data.msg);
+                    }
+                } catch (e) {
+                    console.log(e);
+                }
+                setLoading(false);
+            },
+        });
+    };
 
+    const search = () => {
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+        } as unknown as JdPoolParams);
+    };
+    const onPageChange = (current: number) => {
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+            current,
+        } as unknown as JdPoolParams);
+    };
 
+    const onPageSizeChange = (current: number) => {
+        basePagination.pageSize = current;
+        pagination.pageSize = current;
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+            current: 1,
+        } as unknown as JdPoolParams);
+    };
 
+    fetchData();
+    const reset = () => {
+        formModel.value = generateFormModel();
+    };
 
-const search = () => {
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-    } as unknown as JdPoolParams);
-};
-const onPageChange = (current: number) => {
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-        current
-    } as unknown as JdPoolParams);
-};
-
-const onPageSizeChange = (current: number) => {
-    basePagination.pageSize = current;
-    pagination.pageSize = current;
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-        current: 1,
-    } as unknown as JdPoolParams);
-};
-
-fetchData();
-const reset = () => {
-    formModel.value = generateFormModel();
-};
-
-const handleSelectDensity = (
-    val: string | number | Record<string, any> | undefined,
-    e: Event
-) => {
-    size.value = val as SizeProps;
-};
-
-const handleChange = (
-    checked: boolean | (string | boolean | number)[],
-    column: Column,
-    index: number
-) => {
-    if (!checked) {
-        cloneColumns.value = showColumns.value.filter(
-            (item) => item.dataIndex !== column.dataIndex
-        );
-    } else {
-        cloneColumns.value.splice(index, 0, column);
-    }
-};
-
-const exchangeArray = <T extends Array<any>>(
-    array: T,
-    beforeIdx: number,
-    newIdx: number,
-    isDeep = false
-): T => {
-    const newArray = isDeep ? cloneDeep(array) : array;
-    if (beforeIdx > -1 && newIdx > -1) {
-        // 先替换后面的,然后拿到替换的结果替换前面的
-        newArray.splice(
-            beforeIdx,
-            1,
-            newArray.splice(newIdx, 1, newArray[beforeIdx]).pop()
-        );
-    }
-    return newArray;
-};
-
-const popupVisibleChange = (val: boolean) => {
-    if (val) {
-        nextTick(() => {
-            const el = document.getElementById(
-                'tableSetting'
-            ) as HTMLElement;
-            const sortable = new Sortable(el, {
-                onEnd(e: any) {
-                    const { oldIndex, newIndex } = e;
-                    exchangeArray(cloneColumns.value, oldIndex, newIndex);
-                    exchangeArray(showColumns.value, oldIndex, newIndex);
-                },
+    const handleSelectDensity = (
+        val: string | number | Record<string, any> | undefined,
+        e: Event
+    ) => {
+        size.value = val as SizeProps;
+    };
+
+    const handleChange = (
+        checked: boolean | (string | boolean | number)[],
+        column: Column,
+        index: number
+    ) => {
+        if (!checked) {
+            cloneColumns.value = showColumns.value.filter(
+                (item) => item.dataIndex !== column.dataIndex
+            );
+        } else {
+            cloneColumns.value.splice(index, 0, column);
+        }
+    };
+
+    const exchangeArray = <T extends Array<any>>(
+        array: T,
+        beforeIdx: number,
+        newIdx: number,
+        isDeep = false
+    ): T => {
+        const newArray = isDeep ? cloneDeep(array) : array;
+        if (beforeIdx > -1 && newIdx > -1) {
+            // 先替换后面的,然后拿到替换的结果替换前面的
+            newArray.splice(
+                beforeIdx,
+                1,
+                newArray.splice(newIdx, 1, newArray[beforeIdx]).pop()
+            );
+        }
+        return newArray;
+    };
+
+    const popupVisibleChange = (val: boolean) => {
+        if (val) {
+            nextTick(() => {
+                const el = document.getElementById(
+                    'tableSetting'
+                ) as HTMLElement;
+                const sortable = new Sortable(el, {
+                    onEnd(e: any) {
+                        const { oldIndex, newIndex } = e;
+                        exchangeArray(cloneColumns.value, oldIndex, newIndex);
+                        exchangeArray(showColumns.value, oldIndex, newIndex);
+                    },
+                });
             });
-        });
-    }
-};
-
-watch(
-    () => columns.value,
-    (val) => {
-        cloneColumns.value = cloneDeep(val);
-        cloneColumns.value.forEach((item, index) => {
-            item.checked = true;
-        });
-        showColumns.value = cloneDeep(cloneColumns.value);
-    },
-    { deep: true, immediate: true }
-);
+        }
+    };
+
+    watch(
+        () => columns.value,
+        (val) => {
+            cloneColumns.value = cloneDeep(val);
+            cloneColumns.value.forEach((item, index) => {
+                item.checked = true;
+            });
+            showColumns.value = cloneDeep(cloneColumns.value);
+        },
+        { deep: true, immediate: true }
+    );
 </script>
 
 <script lang="ts">
-export default {
-    name: 'SearchTable',
-};
+    export default {
+        name: 'SearchTable',
+    };
 </script>
 
 <style scoped lang="less">
-.container {
-    padding: 0 20px 20px 20px;
-}
-
-:deep(.arco-table-th) {
-    &:last-child {
-        .arco-table-th-item-title {
-            margin-left: 16px;
-        }
+    .container {
+        padding: 0 20px 20px 20px;
     }
-}
-
-.action-icon {
-    margin-left: 12px;
-    cursor: pointer;
-}
-
-.active {
-    color: #0960bd;
-    background-color: #e3f4fc;
-}
 
-.setting {
-    display: flex;
-    align-items: center;
-    width: 200px;
+    :deep(.arco-table-th) {
+        &:last-child {
+            .arco-table-th-item-title {
+                margin-left: 16px;
+            }
+        }
+    }
 
-    .title {
+    .action-icon {
         margin-left: 12px;
         cursor: pointer;
     }
-}
 
+    .active {
+        color: #0960bd;
+        background-color: #e3f4fc;
+    }
 
-:deep(.special-table-row td) {
-    background-color: var(--color-warning-light-2) !important;
-}
+    .setting {
+        display: flex;
+        align-items: center;
+        width: 200px;
+
+        .title {
+            margin-left: 12px;
+            cursor: pointer;
+        }
+    }
+
+    :deep(.special-table-row td) {
+        background-color: var(--color-warning-light-2) !important;
+    }
 </style>

+ 907 - 635
src/views/pdd/list.vue

@@ -4,23 +4,44 @@
         <a-card class="general-card" :title="$t('menu.pdd.list')">
             <a-row>
                 <a-col :flex="1">
-                    <a-form :model="formModel" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }"
-                        label-align="left">
+                    <a-form
+                        :model="formModel"
+                        :label-col-props="{ span: 6 }"
+                        :wrapper-col-props="{ span: 18 }"
+                        label-align="left"
+                    >
                         <a-row :gutter="16">
                             <a-col :span="8">
                                 <a-form-item field="name" label="账号名">
-                                    <a-input v-model="formModel.name" placeholder="输入关键词搜索" />
+                                    <a-input
+                                        v-model="formModel.name"
+                                        placeholder="输入关键词搜索"
+                                    />
                                 </a-form-item>
                             </a-col>
                             <a-col :span="8">
-                                <a-form-item field="lastTime" :label="$t('searchTable.form.lastTime')">
-                                    <a-range-picker v-model="formModel.lastTime" style="width: 100%" />
+                                <a-form-item
+                                    field="lastTime"
+                                    :label="$t('searchTable.form.lastTime')"
+                                >
+                                    <a-range-picker
+                                        v-model="formModel.lastTime"
+                                        style="width: 100%"
+                                    />
                                 </a-form-item>
                             </a-col>
                             <a-col :span="8">
-                                <a-form-item field="status" :label="$t('searchTable.form.status')">
-                                    <a-select v-model="formModel.status" :options="statusOptions" :placeholder="$t('searchTable.form.selectDefault')
-                                        " />
+                                <a-form-item
+                                    field="status"
+                                    :label="$t('searchTable.form.status')"
+                                >
+                                    <a-select
+                                        v-model="formModel.status"
+                                        :options="statusOptions"
+                                        :placeholder="
+                                            $t('searchTable.form.selectDefault')
+                                        "
+                                    />
                                 </a-form-item>
                             </a-col>
                         </a-row>
@@ -48,57 +69,89 @@
                             </template>
                             {{ $t('searchTable.operation.create') }}
                         </a-button>
-                        <a-button type="outline" @click="handleRechargeAllOnlineAccountUsage">
+                        <a-button
+                            type="outline"
+                            @click="handleRechargeAllOnlineAccountUsage"
+                        >
                             重置账号当日分配权重
                         </a-button>
                         <a-button
                             type="primary"
                             status="warning"
                             :disabled="selectedRows.length === 0"
-                            @click="handleBatchUpdateBalance">
+                            @click="handleBatchUpdateBalance"
+                        >
                             批量更新余额 ({{ selectedRows.length }})
                         </a-button>
                     </a-space>
                 </a-col>
-                <a-col :span="12" style="
+                <a-col
+                    :span="12"
+                    style="
                         display: flex;
                         align-items: center;
                         justify-content: end;
-                    ">
+                    "
+                >
                     <a-tooltip :content="$t('searchTable.actions.refresh')">
-                        <div class="action-icon" @click="search"><icon-refresh size="18" /></div>
+                        <div class="action-icon" @click="search"
+                            ><icon-refresh size="18"
+                        /></div>
                     </a-tooltip>
                     <a-dropdown @select="handleSelectDensity">
                         <a-tooltip :content="$t('searchTable.actions.density')">
-                            <div class="action-icon"><icon-line-height size="18" /></div>
+                            <div class="action-icon"
+                                ><icon-line-height size="18"
+                            /></div>
                         </a-tooltip>
                         <template #content>
-                            <a-doption v-for="item in densityList" :key="item.value" :value="item.value"
-                                :class="{ active: item.value === size }">
+                            <a-doption
+                                v-for="item in densityList"
+                                :key="item.value"
+                                :value="item.value"
+                                :class="{ active: item.value === size }"
+                            >
                                 <span>{{ item.name }}</span>
                             </a-doption>
                         </template>
                     </a-dropdown>
-                    <a-tooltip :content="$t('searchTable.actions.columnSetting')">
-                        <a-popover trigger="click" position="bl" @popup-visible-change="popupVisibleChange">
-                            <div class="action-icon"><icon-settings size="18" /></div>
+                    <a-tooltip
+                        :content="$t('searchTable.actions.columnSetting')"
+                    >
+                        <a-popover
+                            trigger="click"
+                            position="bl"
+                            @popup-visible-change="popupVisibleChange"
+                        >
+                            <div class="action-icon"
+                                ><icon-settings size="18"
+                            /></div>
                             <template #content>
                                 <div id="tableSetting">
-                                    <div v-for="(item, index) in showColumns" :key="item.dataIndex" class="setting">
-                                        <div style="
+                                    <div
+                                        v-for="(item, index) in showColumns"
+                                        :key="item.dataIndex"
+                                        class="setting"
+                                    >
+                                        <div
+                                            style="
                                                 margin-right: 4px;
                                                 cursor: move;
-                                            ">
+                                            "
+                                        >
                                             <icon-drag-arrow />
                                         </div>
                                         <div>
-                                            <a-checkbox v-model="item.checked" @change="
-                                                handleChange(
-                                                    $event,
-                                                    item as TableColumnData,
-                                                    index
-                                                )
-                                                ">
+                                            <a-checkbox
+                                                v-model="item.checked"
+                                                @change="
+                                                    handleChange(
+                                                        $event,
+                                                        item as TableColumnData,
+                                                        index
+                                                    )
+                                                "
+                                            >
                                             </a-checkbox>
                                         </div>
                                         <div class="title">
@@ -116,15 +169,25 @@
                 </a-col>
             </a-row>
 
-            <a-table row-key="id" :loading="loading" :pagination="pagination" :summary="true" summary-text="汇总"
-                :columns="(cloneColumns as TableColumnData[])" :data="renderData" :bordered="{ headerCell: true }"
-                :row-class="getRowClass" :size="size"
+            <a-table
+                row-key="id"
+                :loading="loading"
+                :pagination="pagination"
+                :summary="true"
+                summary-text="汇总"
+                :columns="(cloneColumns as TableColumnData[])"
+                :data="renderData"
+                :bordered="{ headerCell: true }"
+                :row-class="getRowClass"
+                :size="size"
                 v-model:selectedKeys="selectedRowKeys"
                 :row-selection="{
                     type: 'checkbox',
-                    showCheckedAll: true
+                    showCheckedAll: true,
                 }"
-                @page-change="onPageChange" @page-size-change="onPageSizeChange">
+                @page-change="onPageChange"
+                @page-size-change="onPageSizeChange"
+            >
                 <template #index="{ record }">
                     {{ record.id }}
                 </template>
@@ -132,8 +195,14 @@
                     <a-list-item-meta>
                         <template #title>
                             {{ record.company }}
-                            <a-tag color="blue" v-if="record.work_mode == 1">网站推广</a-tag>
-                            <a-tag color="orange" v-else-if="record.work_mode == 2">媒体导购</a-tag>
+                            <a-tag color="blue" v-if="record.work_mode == 1"
+                                >网站推广</a-tag
+                            >
+                            <a-tag
+                                color="orange"
+                                v-else-if="record.work_mode == 2"
+                                >媒体导购</a-tag
+                            >
                             <a-tag color="purple" v-else>爬虫</a-tag>
                         </template>
                         <template #description>
@@ -142,29 +211,71 @@
                     </a-list-item-meta>
                 </template>
                 <template #nodeName="{ record }">
-                    <a-tag color="gray">{{ record.end_point }} - {{ record.nodeName }} </a-tag>
+                    <div>
+                        <a-tag
+                            :color="
+                                record.proxyStatus === true ? 'green' : 'gray'
+                            "
+                        >
+                            <template v-if="record.proxyStatus === true" #icon>
+                                <icon-check />
+                            </template>
+                            <template
+                                v-else-if="record.proxyStatus === false"
+                                #icon
+                            >
+                                <icon-stop />
+                            </template>
+                            {{ record.end_point }} - {{ record.nodeName }}
+                        </a-tag>
+                    </div>
                 </template>
 
                 <template #tags="{ record }">
-                    <a-tag v-if="record.parse_type" size="small" bordered color="blue">
+                    <a-tag
+                        v-if="record.parse_type"
+                        size="small"
+                        bordered
+                        color="blue"
+                    >
                         {{ record.parse_type }}
                     </a-tag>
 
-                    <a-tag v-if="record.riskStrategy" size="small" bordered color="orange">
+                    <a-tag
+                        v-if="record.riskStrategy"
+                        size="small"
+                        bordered
+                        color="orange"
+                    >
                         {{ record.riskStrategy }}-{{ record.launchScene }}
                     </a-tag>
-                    <a-tag v-if="record.riskCookie" size="small" bordered color="red">
+                    <a-tag
+                        v-if="record.riskCookie"
+                        size="small"
+                        bordered
+                        color="red"
+                    >
                         {{ record.riskCookie }}
                     </a-tag>
                 </template>
                 <template #status="{ record }">
-                    <a-tag v-if="record.status" bordered color="green" @click="changeStatus(record.id, false)">
+                    <a-tag
+                        v-if="record.status"
+                        bordered
+                        color="green"
+                        @click="changeStatus(record.id, false)"
+                    >
                         <template #icon>
                             <icon-check />
                         </template>
                         在线
                     </a-tag>
-                    <a-tag v-else bordered color="" @click="changeStatus(record.id, true)">
+                    <a-tag
+                        v-else
+                        bordered
+                        color=""
+                        @click="changeStatus(record.id, true)"
+                    >
                         <template #icon>
                             <icon-stop />
                         </template>
@@ -177,95 +288,201 @@
                         离线
                     </a-tag>
                     <template v-else>
-                        <a-tag v-if="record.cookie_status" bordered color="blue"
-                            @click="changeAttr(record.id, 'cookie_status', true)">
+                        <a-tag
+                            v-if="record.cookie_status"
+                            bordered
+                            color="blue"
+                            @click="
+                                changeAttr(record.id, 'cookie_status', true)
+                            "
+                        >
                             正常
                         </a-tag>
-                        <a-tag v-else bordered color="" @click="changeAttr(record.id, 'cookie_status', true)">
+                        <a-tag
+                            v-else
+                            bordered
+                            color=""
+                            @click="
+                                changeAttr(record.id, 'cookie_status', true)
+                            "
+                        >
                             离线
                         </a-tag>
                     </template>
                 </template>
                 <template #actions="{ record }">
-                    <a-tag v-if="record.enable_parse" size="small" bordered color="red"
-                        @click="changeAttr(record.id, 'enable_parse', false)">
+                    <a-tag
+                        v-if="record.enable_parse"
+                        size="small"
+                        bordered
+                        color="red"
+                        @click="changeAttr(record.id, 'enable_parse', false)"
+                    >
                         转链
                     </a-tag>
-                    <a-tag v-else size="small" bordered color="" @click="changeAttr(record.id, 'enable_parse', true)">
+                    <a-tag
+                        v-else
+                        size="small"
+                        bordered
+                        color=""
+                        @click="changeAttr(record.id, 'enable_parse', true)"
+                    >
                         转链
                     </a-tag>
-                    <span style="margin: 5px;">
-                        <a-tag v-if="record.enable_coupon" size="small" bordered color="orange"
-                            @click="changeAttr(record.id, 'enable_coupon', false)">
+                    <span style="margin: 5px">
+                        <a-tag
+                            v-if="record.enable_coupon"
+                            size="small"
+                            bordered
+                            color="orange"
+                            @click="
+                                changeAttr(record.id, 'enable_coupon', false)
+                            "
+                        >
                             优惠券
                         </a-tag>
-                        <a-tag v-else size="small" bordered color=""
-                            @click="changeAttr(record.id, 'enable_coupon', true)">
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color=""
+                            @click="
+                                changeAttr(record.id, 'enable_coupon', true)
+                            "
+                        >
                             优惠券
                         </a-tag>
                     </span>
-                    <span style="margin: 5px;">
-                        <a-tag v-if="record.enable_sync_revenue" size="small" bordered color="blue"
-                            @click="changeAttr(record.id, 'enable_sync_revenue', false)">
+                    <span style="margin: 5px">
+                        <a-tag
+                            v-if="record.enable_sync_revenue"
+                            size="small"
+                            bordered
+                            color="blue"
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_sync_revenue',
+                                    false
+                                )
+                            "
+                        >
                             同步收益
                         </a-tag>
-                        <a-tag v-else size="small" bordered color=""
-                            @click="changeAttr(record.id, 'enable_sync_revenue', true)">
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color=""
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_sync_revenue',
+                                    true
+                                )
+                            "
+                        >
                             同步收益
                         </a-tag>
                     </span>
-                    <span style="margin: 5px;">
-                        <a-tag v-if="record.enable_sync_order" size="small" bordered color="blue"
-                            @click="changeAttr(record.id, 'enable_sync_order', false)">
+                    <span style="margin: 5px">
+                        <a-tag
+                            v-if="record.enable_sync_order"
+                            size="small"
+                            bordered
+                            color="blue"
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_sync_order',
+                                    false
+                                )
+                            "
+                        >
                             同步订单
                         </a-tag>
-                        <a-tag v-else size="small" bordered color=""
-                            @click="changeAttr(record.id, 'enable_sync_order', true)">
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color=""
+                            @click="
+                                changeAttr(record.id, 'enable_sync_order', true)
+                            "
+                        >
                             同步订单
                         </a-tag>
                     </span>
                 </template>
                 <template #time="{ record }">
-                    <div style="color:gray;">
-                        <div>注册:{{ dayjs(record.create_time).format('MM-DD HH:mm') }}</div>
-                        <div>更新:{{ dayjs(record.last_time).format('MM-DD HH:mm') }}</div>
-                        <div v-if="dayjs().diff(dayjs(record.login_time), 'hours') < 48">
-                            登录:{{ dayjs(record.login_time).format('MM-DD HH:mm') }}</div>
+                    <div style="color: gray">
+                        <div
+                            >注册:{{
+                                dayjs(record.create_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
+                        <div
+                            >更新:{{
+                                dayjs(record.last_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
+                        <div
+                            v-if="
+                                dayjs().diff(
+                                    dayjs(record.login_time),
+                                    'hours'
+                                ) < 48
+                            "
+                        >
+                            登录:{{
+                                dayjs(record.login_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
                     </div>
                 </template>
                 <template #action="{ record }">
-                    <a-button type="text" size="small" @click="openCookieModal(record)">
+                    <a-button
+                        type="text"
+                        size="small"
+                        @click="openCookieModal(record)"
+                    >
                         更新cookie
                     </a-button>
                 </template>
                 <template #summary-cell="{ column, record }">
-                    <div style="margin:10px auto" v-if="column.slotName == 'hourly_calls_limit'">
+                    <div
+                        style="margin: 10px auto"
+                        v-if="column.slotName == 'hourly_calls_limit'"
+                    >
                         {{ numberFormat(record.current_hourly_calls) }}
                     </div>
-                    <div style="margin:10px auto" v-if="column.slotName == 'daily_calls_limit'">
+                    <div
+                        style="margin: 10px auto"
+                        v-if="column.slotName == 'daily_calls_limit'"
+                    >
                         {{ numberFormat(record.current_daily_calls) }}
                     </div>
 
-
-                    <template v-if="column.dataIndex == 'today_clickNum' ||
-                        column.dataIndex == 'today_orderNum' ||
-                        column.dataIndex == 'today_finishOrderNum' ||
-                        column.dataIndex == 'today_finishCosPrice'">
-
+                    <template
+                        v-if="
+                            column.dataIndex == 'today_clickNum' ||
+                            column.dataIndex == 'today_orderNum' ||
+                            column.dataIndex == 'today_finishOrderNum' ||
+                            column.dataIndex == 'today_finishCosPrice'
+                        "
+                    >
                         <div>{{ numberFormat(record[column.dataIndex]) }}</div>
                     </template>
 
-
-
-                    <template v-if="column.dataIndex == 'today_cosPrice' ||
-                        column.dataIndex == 'today_finishCosFee' ||
-                        column.dataIndex == 'today_cosFee'">
-
+                    <template
+                        v-if="
+                            column.dataIndex == 'today_cosPrice' ||
+                            column.dataIndex == 'today_finishCosFee' ||
+                            column.dataIndex == 'today_cosFee'
+                        "
+                    >
                         <div>{{ amountFormat(record[column.dataIndex]) }}</div>
                     </template>
-
-
-
                 </template>
                 <template #time_range="{ record }">
                     <WorkHourModel :record="record" @change="search" />
@@ -276,31 +493,58 @@
                     </a-tag>
                 </template>
                 <template #hourly_calls_limit="{ record }">
-                    <a-tag bordered
-                        :color="record.current_hourly_calls > record.hourly_calls_limit && record.hourly_calls_limit > 0 ? 'red' : ''">
+                    <a-tag
+                        bordered
+                        :color="
+                            record.current_hourly_calls >
+                                record.hourly_calls_limit &&
+                            record.hourly_calls_limit > 0
+                                ? 'red'
+                                : ''
+                        "
+                    >
                         {{ record.current_hourly_calls }} /
                         {{ record.hourly_calls_limit }}
                     </a-tag>
                 </template>
 
                 <template #daily_calls_limit="{ record }">
-                    <a-tag bordered
-                        :color="record.current_daily_calls > record.daily_calls_limit && record.daily_calls_limit > 0 ? 'red' : ''">
+                    <a-tag
+                        bordered
+                        :color="
+                            record.current_daily_calls >
+                                record.daily_calls_limit &&
+                            record.daily_calls_limit > 0
+                                ? 'red'
+                                : ''
+                        "
+                    >
                         {{ record.current_daily_calls }} /
                         {{ record.daily_calls_limit }}
                     </a-tag>
                 </template>
-
             </a-table>
         </a-card>
 
         <!-- Cookie 更新 Modal -->
-        <a-modal v-model:visible="cookieModalVisible" title="更新Cookie" @ok="handleCookieUpdate"
-            @cancel="handleCookieCancel" :confirm-loading="cookieLoading">
+        <a-modal
+            v-model:visible="cookieModalVisible"
+            title="更新Cookie"
+            @ok="handleCookieUpdate"
+            @cancel="handleCookieCancel"
+            :confirm-loading="cookieLoading"
+        >
             <a-form ref="cookieFormRef" :model="cookieFormData">
-                <a-form-item field="cookie" label="Cookie" :rules="[{ required: true, message: '请输入Cookie' }]">
-                    <a-textarea v-model="cookieFormData.cookie" placeholder="请粘贴Cookie内容"
-                        :auto-size="{ minRows: 10, maxRows: 20 }" />
+                <a-form-item
+                    field="cookie"
+                    label="Cookie"
+                    :rules="[{ required: true, message: '请输入Cookie' }]"
+                >
+                    <a-textarea
+                        v-model="cookieFormData.cookie"
+                        placeholder="请粘贴Cookie内容"
+                        :auto-size="{ minRows: 10, maxRows: 20 }"
+                    />
                 </a-form-item>
             </a-form>
         </a-modal>
@@ -308,601 +552,629 @@
 </template>
 
 <script lang="ts" setup>
-import { useRouter, useRoute } from 'vue-router';
-import { computed, ref, reactive, watch, nextTick } from 'vue';
-import { useI18n } from 'vue-i18n';
-import dayjs from 'dayjs';
-import useLoading from '@/hooks/loading';
-import { queryPddPool, PddPoolRecord, PddPoolParams, PddUpdateAccountModel, PddUpdateAccount, UpdateCookieWithIdModel, updateCookiesWithId, rechargeAllOnlineAccountUsage } from '@/api/pdd';
-import { Pagination } from '@/types/global';
-import { Modal, Message } from '@arco-design/web-vue';
-import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
-import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
-import { FormInstance } from '@arco-design/web-vue/es/form';
-import cloneDeep from 'lodash/cloneDeep';
-import Sortable from 'sortablejs';
-import { numberFormat, amountFormat } from '@/utils/util';
-import WorkHourModel from './components/WorkHourModel.vue';
-
-type SizeProps = 'mini' | 'small' | 'medium' | 'large';
-type Column = TableColumnData & { checked?: true };
-
-const generateFormModel = () => {
-    return {
-        name: '',
-        lastTime: [],
-        status: '',
-        show_hide: false,
-        sort: 'status',
-        order: 'descending',
+    import { useRouter, useRoute } from 'vue-router';
+    import { computed, ref, reactive, watch, nextTick } from 'vue';
+    import { useI18n } from 'vue-i18n';
+    import dayjs from 'dayjs';
+    import useLoading from '@/hooks/loading';
+    import {
+        queryPddPool,
+        PddPoolRecord,
+        PddPoolParams,
+        PddUpdateAccountModel,
+        PddUpdateAccount,
+        UpdateCookieWithIdModel,
+        updateCookiesWithId,
+        rechargeAllOnlineAccountUsage,
+    } from '@/api/pdd';
+    import { Pagination } from '@/types/global';
+    import { Modal, Message } from '@arco-design/web-vue';
+    import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
+    import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
+    import { FormInstance } from '@arco-design/web-vue/es/form';
+    import cloneDeep from 'lodash/cloneDeep';
+    import Sortable from 'sortablejs';
+    import { numberFormat, amountFormat } from '@/utils/util';
+    import WorkHourModel from './components/WorkHourModel.vue';
+
+    type SizeProps = 'mini' | 'small' | 'medium' | 'large';
+    type Column = TableColumnData & { checked?: true };
+
+    const generateFormModel = () => {
+        return {
+            name: '',
+            lastTime: [],
+            status: '',
+            show_hide: false,
+            sort: 'status',
+            order: 'descending',
+        };
     };
-};
-const router = useRouter();
-const route = useRoute();
-
-
-const { loading, setLoading } = useLoading(true);
-const { t } = useI18n();
-const renderData = ref<PddPoolRecord[]>([]);
-const formModel = ref(generateFormModel());
-const cloneColumns = ref<Column[]>([]);
-const showColumns = ref<Column[]>([]);
-
-const size = ref<SizeProps>('small');
-
-// Cookie modal related data
-const cookieModalVisible = ref(false);
-const cookieLoading = ref(false);
-const cookieFormRef = ref<FormInstance>();
-const cookieFormData = ref<UpdateCookieWithIdModel>({
-    id: 0,
-    cookie: '',
-});
-const currentRecord = ref<PddPoolRecord | null>(null);
-
-// 行选择相关
-const selectedRowKeys = ref<(string | number)[]>([]);
-const selectedRows = ref<PddPoolRecord[]>([]);
-
-// 监听选中的行keys变化,同步更新选中的行数据
-watch(selectedRowKeys, (newKeys) => {
-    selectedRows.value = renderData.value.filter(item => newKeys.includes(item.id));
-});
-
-const basePagination: Pagination = {
-    current: 1,
-    pageSize: 50,
-    showPageSize: true,
-    showTotal: true,
-    pageSizeOptions: [10, 20, 50, 100, 200, 500]
-
-};
-const pagination = reactive({
-    ...basePagination,
-});
-const densityList = computed(() => [
-    {
-        name: t('searchTable.size.mini'),
-        value: 'mini',
-    },
-    {
-        name: t('searchTable.size.small'),
-        value: 'small',
-    },
-    {
-        name: t('searchTable.size.medium'),
-        value: 'medium',
-    },
-    {
-        name: t('searchTable.size.large'),
-        value: 'large',
-    },
-]);
-
-const columns = computed<TableColumnData[]>(() => [
-    {
-        title: '#',
-        dataIndex: 'index',
-        slotName: 'index',
-        width: 60,
-    },
-    {
-        title: '账号名',
-        dataIndex: 'name',
-        slotName: 'name',
-        width: 250,
-    },
-    {
-        title: '',
-        slotName: 'tags',
-        width: 60,
-    },
-    {
-        title: '工作时间',
-        dataIndex: 'time_range',
-        slotName: 'time_range',
-        align: 'right',
-        width: 200,
-    },
-    {
-        title: '账户余额',
-        dataIndex: 'draw_balance',
-        slotName: 'draw_balance',
-        align: 'right',
-        width: 120,
-    },
-    {
-        title: '小时调用',
-        slotName: 'hourly_calls_limit',
-        dataIndex: 'current_hourly_calls',
-        align: 'right',
-        width: 120,
-    },
-    {
-        title: '当日调用',
-        slotName: 'daily_calls_limit',
-        dataIndex: 'current_daily_calls',
-        align: 'right',
-        width: 150,
-    },
-    {
-        title: '运行节点',
-        slotName: 'nodeName',
-        width: 120,
-    },
-    {
-        title: '状态',
-        slotName: 'status',
-        width: 100,
-    },
-    {
-        title: 'Cookie状态',
-        slotName: 'cookie_status',
-        align: 'center',
-        width: 100,
-    },
-    {
-        title: '分类',
-        slotName: 'actions',
-        width: 200,
-        align: 'center',
-    },
-    {
-        title: '时间',
-        slotName: 'time',
-        width: 170,
-    },
-    {
-        title: '操作',
-        slotName: 'action',
-        width: 120,
-    },
-]);
-
-const statusOptions = computed<SelectOptionData[]>(() => [
-    {
-        label: '全部',
-        value: '',
-    },
-    {
-        label: '在线',
-        value: 'online',
-    },
-    {
-        label: '下线',
-        value: 'offline',
-    },
-]);
-
-const getRowClass = (record: PddPoolRecord) => {
-    return record.is_hide ? 'special-table-row' : '';
-};
-
-if (route.query.show_hide === '1') {
-    formModel.value.show_hide = true;
-}
-
-const fetchData = async (
-    params: PddPoolParams = {
+    const router = useRouter();
+    const route = useRoute();
+
+    const { loading, setLoading } = useLoading(true);
+    const { t } = useI18n();
+    const renderData = ref<PddPoolRecord[]>([]);
+    const formModel = ref(generateFormModel());
+    const cloneColumns = ref<Column[]>([]);
+    const showColumns = ref<Column[]>([]);
+
+    const size = ref<SizeProps>('small');
+
+    // Cookie modal related data
+    const cookieModalVisible = ref(false);
+    const cookieLoading = ref(false);
+    const cookieFormRef = ref<FormInstance>();
+    const cookieFormData = ref<UpdateCookieWithIdModel>({
+        id: 0,
+        cookie: '',
+    });
+    const currentRecord = ref<PddPoolRecord | null>(null);
+
+    // 行选择相关
+    const selectedRowKeys = ref<(string | number)[]>([]);
+    const selectedRows = ref<PddPoolRecord[]>([]);
+
+    // 监听选中的行keys变化,同步更新选中的行数据
+    watch(selectedRowKeys, (newKeys) => {
+        selectedRows.value = renderData.value.filter((item) =>
+            newKeys.includes(item.id)
+        );
+    });
+
+    const basePagination: Pagination = {
         current: 1,
         pageSize: 50,
-        show_hide: false,
-        sort: 'status',
-        order: 'descending',
-        getTotal: true,
-    }
-) => {
+        showPageSize: true,
+        showTotal: true,
+        pageSizeOptions: [10, 20, 50, 100, 200, 500],
+    };
+    const pagination = reactive({
+        ...basePagination,
+    });
+    const densityList = computed(() => [
+        {
+            name: t('searchTable.size.mini'),
+            value: 'mini',
+        },
+        {
+            name: t('searchTable.size.small'),
+            value: 'small',
+        },
+        {
+            name: t('searchTable.size.medium'),
+            value: 'medium',
+        },
+        {
+            name: t('searchTable.size.large'),
+            value: 'large',
+        },
+    ]);
+
+    const columns = computed<TableColumnData[]>(() => [
+        {
+            title: '#',
+            dataIndex: 'index',
+            slotName: 'index',
+            width: 60,
+        },
+        {
+            title: '账号名',
+            dataIndex: 'name',
+            slotName: 'name',
+            width: 250,
+        },
+        {
+            title: '',
+            slotName: 'tags',
+            width: 60,
+        },
+        {
+            title: '工作时间',
+            dataIndex: 'time_range',
+            slotName: 'time_range',
+            align: 'right',
+            width: 200,
+        },
+        {
+            title: '账户余额',
+            dataIndex: 'draw_balance',
+            slotName: 'draw_balance',
+            align: 'right',
+            width: 120,
+        },
+        {
+            title: '小时调用',
+            slotName: 'hourly_calls_limit',
+            dataIndex: 'current_hourly_calls',
+            align: 'right',
+            width: 120,
+        },
+        {
+            title: '当日调用',
+            slotName: 'daily_calls_limit',
+            dataIndex: 'current_daily_calls',
+            align: 'right',
+            width: 150,
+        },
+        {
+            title: '运行节点',
+            slotName: 'nodeName',
+            width: 120,
+        },
+        {
+            title: '状态',
+            slotName: 'status',
+            width: 100,
+        },
+        {
+            title: 'Cookie状态',
+            slotName: 'cookie_status',
+            align: 'center',
+            width: 100,
+        },
+        {
+            title: '分类',
+            slotName: 'actions',
+            width: 200,
+            align: 'center',
+        },
+        {
+            title: '时间',
+            slotName: 'time',
+            width: 170,
+        },
+        {
+            title: '操作',
+            slotName: 'action',
+            width: 120,
+        },
+    ]);
+
+    const statusOptions = computed<SelectOptionData[]>(() => [
+        {
+            label: '全部',
+            value: '',
+        },
+        {
+            label: '在线',
+            value: 'online',
+        },
+        {
+            label: '下线',
+            value: 'offline',
+        },
+    ]);
+
+    const getRowClass = (record: PddPoolRecord) => {
+        return record.is_hide ? 'special-table-row' : '';
+    };
+
     if (route.query.show_hide === '1') {
-        params.show_hide = true;
+        formModel.value.show_hide = true;
     }
 
-    setLoading(true);
-    try {
-        const { data } = await queryPddPool(params);
-        if (!data) return;
-        // const { data } = await queryPddPool(params);
-        renderData.value = data.list;
-        pagination.current = data.page;
-        pagination.total = data.count;
-    } catch (err) {
-        console.log(err);
-        // you can report use errorHandler or other
-    } finally {
-        setLoading(false);
-    }
-};
+    const fetchData = async (
+        params: PddPoolParams = {
+            current: 1,
+            pageSize: 50,
+            show_hide: false,
+            sort: 'status',
+            order: 'descending',
+            getTotal: true,
+        }
+    ) => {
+        if (route.query.show_hide === '1') {
+            params.show_hide = true;
+        }
 
-const changeItem = async (data: PddPoolRecord) => {
-    router.push({ name: 'updateCookies' });
-};
+        setLoading(true);
+        try {
+            const { data } = await queryPddPool(params);
+            if (!data) return;
+            // const { data } = await queryPddPool(params);
+            renderData.value = data.list;
+            pagination.current = data.page;
+            pagination.total = data.count;
+        } catch (err) {
+            console.log(err);
+            // you can report use errorHandler or other
+        } finally {
+            setLoading(false);
+        }
+    };
 
-const billView = async (data: PddPoolRecord) => {
-    router.push({ name: 'taobao_bill_dailys', query: { name: data.company } });
-};
+    const changeItem = async (data: PddPoolRecord) => {
+        router.push({ name: 'updateCookies' });
+    };
 
+    const billView = async (data: PddPoolRecord) => {
+        router.push({
+            name: 'taobao_bill_dailys',
+            query: { name: data.company },
+        });
+    };
 
-const changeStatus = async (id: number, val: any) => {
-    const args = {
-        id,
-        name: 'status',
-        val
-    } as PddUpdateAccountModel;
+    const changeStatus = async (id: number, val: any) => {
+        const args = {
+            id,
+            name: 'status',
+            val,
+        } as PddUpdateAccountModel;
+
+        Modal.confirm({
+            title: '确认提示',
+            content: '确定要更改状态吗?',
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+
+                try {
+                    const { data } = await PddUpdateAccount(args);
+                    console.log(data, data.msg);
+                    const msg = data.msg || '更新成功!';
+                    if (data.success) {
+                        Message.success(msg);
+                        search();
+                    } else {
+                        Message.error(data.msg);
+                    }
+                } catch (e) {
+                    console.log(e);
+                }
+                setLoading(false);
+            },
+        });
+    };
 
+    const changeAttr = async (id: number, name: string, val: any) => {
+        const args = {
+            id,
+            name,
+            val,
+        } as PddUpdateAccountModel;
+
+        Modal.confirm({
+            title: '确认提示',
+            content: '确定要更改状态吗?',
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+                try {
+                    const { data } = await PddUpdateAccount(args);
+                    console.log(data, data.msg);
+                    const msg = data.msg || '更新成功!';
+                    if (data.success) {
+                        Message.success(msg);
+                        search();
+                    } else {
+                        Message.error(data.msg);
+                    }
+                } catch (e) {
+                    console.log(e);
+                }
+                setLoading(false);
+            },
+        });
+    };
 
-    Modal.confirm({
-        title: '确认提示',
-        content: '确定要更改状态吗?',
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
+    const search = () => {
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+        } as unknown as PddPoolParams);
+    };
+    const onPageChange = (current: number) => {
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+            current,
+        } as unknown as PddPoolParams);
+    };
 
-            try {
-                const { data } = await PddUpdateAccount(args);
-                console.log(data, data.msg);
-                const msg = data.msg || '更新成功!';
-                if (data.success) {
-                    Message.success(msg);
-                    search();
-                } else {
-                    Message.error(data.msg);
-                }
+    const onPageSizeChange = (current: number) => {
+        basePagination.pageSize = current;
+        pagination.pageSize = current;
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+            current: 1,
+        } as unknown as PddPoolParams);
+    };
 
-            } catch (e) { console.log(e) }
-            setLoading(false);
+    fetchData();
+    const reset = () => {
+        formModel.value = generateFormModel();
+    };
+
+    const handleSelectDensity = (
+        val: string | number | Record<string, any> | undefined,
+        e: Event
+    ) => {
+        size.value = val as SizeProps;
+    };
+
+    const handleChange = (
+        checked: boolean | (string | boolean | number)[],
+        column: Column,
+        index: number
+    ) => {
+        if (!checked) {
+            cloneColumns.value = showColumns.value.filter(
+                (item) => item.dataIndex !== column.dataIndex
+            );
+        } else {
+            cloneColumns.value.splice(index, 0, column);
         }
-    });
-};
-
-const changeAttr = async (id: number, name: string, val: any) => {
-    const args = {
-        id,
-        name,
-        val
-    } as PddUpdateAccountModel;
-
-    Modal.confirm({
-        title: '确认提示',
-        content: '确定要更改状态吗?',
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
-            try {
+    };
+
+    const exchangeArray = <T extends Array<any>>(
+        array: T,
+        beforeIdx: number,
+        newIdx: number,
+        isDeep = false
+    ): T => {
+        const newArray = isDeep ? cloneDeep(array) : array;
+        if (beforeIdx > -1 && newIdx > -1) {
+            // 先替换后面的,然后拿到替换的结果替换前面的
+            newArray.splice(
+                beforeIdx,
+                1,
+                newArray.splice(newIdx, 1, newArray[beforeIdx]).pop()
+            );
+        }
+        return newArray;
+    };
+
+    const popupVisibleChange = (val: boolean) => {
+        if (val) {
+            nextTick(() => {
+                const el = document.getElementById(
+                    'tableSetting'
+                ) as HTMLElement;
+                const sortable = new Sortable(el, {
+                    onEnd(e: any) {
+                        const { oldIndex, newIndex } = e;
+                        exchangeArray(cloneColumns.value, oldIndex, newIndex);
+                        exchangeArray(showColumns.value, oldIndex, newIndex);
+                    },
+                });
+            });
+        }
+    };
 
-                const { data } = await PddUpdateAccount(args);
-                console.log(data, data.msg);
+    // Cookie modal methods
+    const openCookieModal = (record: PddPoolRecord) => {
+        currentRecord.value = record;
+        cookieFormData.value = {
+            id: record.id,
+            cookie: '',
+        };
+        cookieModalVisible.value = true;
+    };
+
+    const handleCookieUpdate = async () => {
+        const res = await cookieFormRef.value?.validate();
+        if (!res) {
+            cookieLoading.value = true;
+            try {
+                const { data } = await updateCookiesWithId(
+                    cookieFormData.value
+                );
                 const msg = data.msg || '更新成功!';
                 if (data.success) {
                     Message.success(msg);
-                    search();
+                    cookieModalVisible.value = false;
+                    search(); // 刷新列表
                 } else {
                     Message.error(data.msg);
                 }
-            } catch (e) { console.log(e) }
-            setLoading(false);
+            } catch (err) {
+                console.error(err);
+                Message.error('更新失败');
+            } finally {
+                cookieLoading.value = false;
+            }
         }
-    });
-};
-
-
-
-const search = () => {
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-    } as unknown as PddPoolParams);
-};
-const onPageChange = (current: number) => {
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-        current
-    } as unknown as PddPoolParams);
-};
-
-
-const onPageSizeChange = (current: number) => {
-    basePagination.pageSize = current;
-    pagination.pageSize = current;
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-        current: 1,
-    } as unknown as PddPoolParams);
-};
-
-fetchData();
-const reset = () => {
-    formModel.value = generateFormModel();
-};
-
-const handleSelectDensity = (
-    val: string | number | Record<string, any> | undefined,
-    e: Event
-) => {
-    size.value = val as SizeProps;
-};
-
-const handleChange = (
-    checked: boolean | (string | boolean | number)[],
-    column: Column,
-    index: number
-) => {
-    if (!checked) {
-        cloneColumns.value = showColumns.value.filter(
-            (item) => item.dataIndex !== column.dataIndex
-        );
-    } else {
-        cloneColumns.value.splice(index, 0, column);
-    }
-};
-
-const exchangeArray = <T extends Array<any>>(
-    array: T,
-    beforeIdx: number,
-    newIdx: number,
-    isDeep = false
-): T => {
-    const newArray = isDeep ? cloneDeep(array) : array;
-    if (beforeIdx > -1 && newIdx > -1) {
-        // 先替换后面的,然后拿到替换的结果替换前面的
-        newArray.splice(
-            beforeIdx,
-            1,
-            newArray.splice(newIdx, 1, newArray[beforeIdx]).pop()
-        );
-    }
-    return newArray;
-};
-
-const popupVisibleChange = (val: boolean) => {
-    if (val) {
-        nextTick(() => {
-            const el = document.getElementById(
-                'tableSetting'
-            ) as HTMLElement;
-            const sortable = new Sortable(el, {
-                onEnd(e: any) {
-                    const { oldIndex, newIndex } = e;
-                    exchangeArray(cloneColumns.value, oldIndex, newIndex);
-                    exchangeArray(showColumns.value, oldIndex, newIndex);
-                },
-            });
-        });
-    }
-};
-
-// Cookie modal methods
-const openCookieModal = (record: PddPoolRecord) => {
-    currentRecord.value = record;
-    cookieFormData.value = {
-        id: record.id,
-        cookie: '',
     };
-    cookieModalVisible.value = true;
-};
 
-const handleCookieUpdate = async () => {
-    const res = await cookieFormRef.value?.validate();
-    if (!res) {
-        cookieLoading.value = true;
+    const updateBalance = async (record: PddPoolRecord) => {
+        const args = {
+            id: record.id,
+            name: 'balance',
+        } as PddUpdateAccountModel;
+
+        setLoading(true);
         try {
-            const { data } = await updateCookiesWithId(cookieFormData.value);
+            const { data } = await PddUpdateAccount(args);
+            console.log(data, data.msg);
             const msg = data.msg || '更新成功!';
             if (data.success) {
                 Message.success(msg);
-                cookieModalVisible.value = false;
-                search(); // 刷新列表
+                search();
             } else {
                 Message.error(data.msg);
             }
-        } catch (err) {
-            console.error(err);
-            Message.error('更新失败');
-        } finally {
-            cookieLoading.value = false;
+        } catch (e) {
+            console.log(e);
         }
-    }
-};
-
-
-const updateBalance = async (record: PddPoolRecord) => {
-    const args = {
-        id: record.id,
-        name: 'balance',
-    } as PddUpdateAccountModel;
-
-    setLoading(true);
-    try {
-        const { data } = await PddUpdateAccount(args);
-        console.log(data, data.msg);
-        const msg = data.msg || '更新成功!';
-        if (data.success) {
-            Message.success(msg);
-            search();
-        } else {
-            Message.error(data.msg);
-        }
-
-    } catch (e) { console.log(e) }
-    setLoading(false);
-};
+        setLoading(false);
+    };
 
-const handleCookieCancel = () => {
-    cookieModalVisible.value = false;
-    cookieFormData.value = {
-        id: 0,
-        cookie: '',
+    const handleCookieCancel = () => {
+        cookieModalVisible.value = false;
+        cookieFormData.value = {
+            id: 0,
+            cookie: '',
+        };
+        cookieFormRef.value?.resetFields();
     };
-    cookieFormRef.value?.resetFields();
-};
-
-const handleRechargeAllOnlineAccountUsage = async () => {
-    Modal.confirm({
-        title: '确认提示',
-        content: '确定要重置所有账号当日分配权重吗?',
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
-            try {
-                const data = await rechargeAllOnlineAccountUsage();
-                console.log(data);
-                if (data.code === 200) {
-                    Message.success(`重置成功!共处理 ${data.count} 个账号`);
-                    search(); // 刷新列表
-                } else {
-                    Message.error(data.msg || '重置失败');
-                }
-            } catch (err) {
-                console.error(err);
-                Message.error('重置失败');
-            } finally {
-                setLoading(false);
-            }
-        }
-    });
-};
 
-// 批量更新余额
-const handleBatchUpdateBalance = async () => {
-    if (selectedRows.value.length === 0) {
-        Message.warning('请先选择要更新的账号');
-        return;
-    }
+    const handleRechargeAllOnlineAccountUsage = async () => {
+        Modal.confirm({
+            title: '确认提示',
+            content: '确定要重置所有账号当日分配权重吗?',
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+                try {
+                    const data = await rechargeAllOnlineAccountUsage();
+                    console.log(data);
+                    if (data.code === 200) {
+                        Message.success(
+                            `重置成功!共处理 ${data.count} 个账号`
+                        );
+                        search(); // 刷新列表
+                    } else {
+                        Message.error(data.msg || '重置失败');
+                    }
+                } catch (err) {
+                    console.error(err);
+                    Message.error('重置失败');
+                } finally {
+                    setLoading(false);
+                }
+            },
+        });
+    };
 
-    Modal.confirm({
-        title: '确认提示',
-        content: `确定要批量更新选中的 ${selectedRows.value.length} 个账号的可提现余额吗?`,
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
-            let successCount = 0;
-            let failCount = 0;
-            const total = selectedRows.value.length;
+    // 批量更新余额
+    const handleBatchUpdateBalance = async () => {
+        if (selectedRows.value.length === 0) {
+            Message.warning('请先选择要更新的账号');
+            return;
+        }
 
-            try {
-                // 串行执行每个账号的余额更新
-                for (let i = 0; i < selectedRows.value.length; i += 1) {
-                    const record = selectedRows.value[i];
-                    try {
-                        const args = {
-                            id: record.id,
-                            name: 'balance',
-                        } as PddUpdateAccountModel;
-
-                        const { data } = await PddUpdateAccount(args);
-                        if (data.success) {
-                            successCount += 1;
-                            Message.info(`[${i + 1}/${total}] ${record.company} 更新成功`);
-                        } else {
+        Modal.confirm({
+            title: '确认提示',
+            content: `确定要批量更新选中的 ${selectedRows.value.length} 个账号的可提现余额吗?`,
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+                let successCount = 0;
+                let failCount = 0;
+                const total = selectedRows.value.length;
+
+                try {
+                    // 串行执行每个账号的余额更新
+                    for (let i = 0; i < selectedRows.value.length; i += 1) {
+                        const record = selectedRows.value[i];
+                        try {
+                            const args = {
+                                id: record.id,
+                                name: 'balance',
+                            } as PddUpdateAccountModel;
+
+                            const { data } = await PddUpdateAccount(args);
+                            if (data.success) {
+                                successCount += 1;
+                                Message.info(
+                                    `[${i + 1}/${total}] ${
+                                        record.company
+                                    } 更新成功`
+                                );
+                            } else {
+                                failCount += 1;
+                                Message.error(
+                                    `[${i + 1}/${total}] ${
+                                        record.company
+                                    } 更新失败: ${data.msg}`
+                                );
+                            }
+                        } catch (e) {
                             failCount += 1;
-                            Message.error(`[${i + 1}/${total}] ${record.company} 更新失败: ${data.msg}`);
+                            console.error(
+                                `更新账号 ${record.company} 失败:`,
+                                e
+                            );
+                            Message.error(
+                                `[${i + 1}/${total}] ${record.company} 更新失败`
+                            );
                         }
-                    } catch (e) {
-                        failCount += 1;
-                        console.error(`更新账号 ${record.company} 失败:`, e);
-                        Message.error(`[${i + 1}/${total}] ${record.company} 更新失败`);
                     }
-                }
 
-                // 显示总结信息
-                if (successCount > 0) {
-                    Message.success(`批量更新完成!成功: ${successCount}, 失败: ${failCount}`);
-                } else {
-                    Message.error(`批量更新失败!失败: ${failCount}`);
-                }
+                    // 显示总结信息
+                    if (successCount > 0) {
+                        Message.success(
+                            `批量更新完成!成功: ${successCount}, 失败: ${failCount}`
+                        );
+                    } else {
+                        Message.error(`批量更新失败!失败: ${failCount}`);
+                    }
 
-                // 清空选择并刷新列表
-                selectedRowKeys.value = [];
-                selectedRows.value = [];
-                search();
-            } catch (err) {
-                console.error(err);
-                Message.error('批量更新过程中发生错误');
-            } finally {
-                setLoading(false);
-            }
-        }
-    });
-};
-
-watch(
-    () => columns.value,
-    (val) => {
-        cloneColumns.value = cloneDeep(val);
-        cloneColumns.value.forEach((item, index) => {
-            item.checked = true;
+                    // 清空选择并刷新列表
+                    selectedRowKeys.value = [];
+                    selectedRows.value = [];
+                    search();
+                } catch (err) {
+                    console.error(err);
+                    Message.error('批量更新过程中发生错误');
+                } finally {
+                    setLoading(false);
+                }
+            },
         });
-        showColumns.value = cloneDeep(cloneColumns.value);
-    },
-    { deep: true, immediate: true }
-);
+    };
+
+    watch(
+        () => columns.value,
+        (val) => {
+            cloneColumns.value = cloneDeep(val);
+            cloneColumns.value.forEach((item, index) => {
+                item.checked = true;
+            });
+            showColumns.value = cloneDeep(cloneColumns.value);
+        },
+        { deep: true, immediate: true }
+    );
 </script>
 
 <script lang="ts">
-export default {
-    name: 'SearchTable',
-};
+    export default {
+        name: 'SearchTable',
+    };
 </script>
 
 <style scoped lang="less">
-.container {
-    padding: 0 20px 20px 20px;
-}
-
-:deep(.arco-table-th) {
-    &:last-child {
-        .arco-table-th-item-title {
-            margin-left: 16px;
+    .container {
+        padding: 0 20px 20px 20px;
+    }
+
+    :deep(.arco-table-th) {
+        &:last-child {
+            .arco-table-th-item-title {
+                margin-left: 16px;
+            }
         }
     }
-}
 
-.action-icon {
-    margin-left: 12px;
-    cursor: pointer;
-}
+    .action-icon {
+        margin-left: 12px;
+        cursor: pointer;
+    }
 
-.active {
-    color: #0960bd;
-    background-color: #e3f4fc;
-}
+    .active {
+        color: #0960bd;
+        background-color: #e3f4fc;
+    }
 
-.setting {
-    display: flex;
-    align-items: center;
-    width: 200px;
+    .setting {
+        display: flex;
+        align-items: center;
+        width: 200px;
 
-    .title {
-        margin-left: 12px;
-        cursor: pointer;
+        .title {
+            margin-left: 12px;
+            cursor: pointer;
+        }
     }
-}
 
-:deep(.special-table-row td) {
-    background-color: var(--color-warning-light-2) !important;
-}
+    :deep(.special-table-row td) {
+        background-color: var(--color-warning-light-2) !important;
+    }
 </style>

+ 326 - 92
src/views/settings/proxyNodes.vue

@@ -53,9 +53,9 @@
                 @page-size-change="onPageSizeChange"
             >
                 <template #columns>
-                    <a-table-column title="#" data-index="id" :width="70" />
+                    <a-table-column title="#" data-index="id" :width="50" />
 
-                    <a-table-column title="节点" :width="280">
+                    <a-table-column title="节点" :width="120">
                         <template #cell="{ record }">
                             <div class="node-name-row">
                                 <span
@@ -94,7 +94,7 @@
                         </template>
                     </a-table-column>
 
-                    <a-table-column title="代理地址" :width="300">
+                    <a-table-column title="代理地址" :width="200">
                         <template #cell="{ record }">
                             <div class="address-row">
                                 <span
@@ -279,7 +279,7 @@
                         </template>
                     </a-table-column>
 
-                    <a-table-column title="使用平台账号" :width="560">
+                    <a-table-column title="使用平台账号" :width="650">
                         <template #cell="{ record }">
                             <div class="account-summary">
                                 <a-tag color="blue"
@@ -303,74 +303,247 @@
 
                             <div v-else class="account-list">
                                 <div
-                                    v-for="account in getVisibleAccounts(
-                                        record
-                                    )"
-                                    :key="`${record.id}-${account.platform}-${account.id}`"
-                                    :class="[
-                                        'account-chip',
-                                        { 'is-offline': !account.status },
-                                    ]"
+                                    v-if="
+                                        getVisibleOnlineAccounts(record).length
+                                    "
+                                    class="account-row"
                                 >
-                                    <span
-                                        :class="[
-                                            'platform',
-                                            `platform-${account.platform}`,
-                                        ]"
-                                    >
-                                        {{
-                                            platformLabelMap[
-                                                account.platform
-                                            ] || account.platform
-                                        }}
-                                    </span>
-                                    <span
-                                        class="account-copy-content copyable-text"
-                                        @click.stop="
-                                            copyValue(
-                                                getAccountCopyText(account),
-                                                '平台账号'
-                                            )
-                                        "
+                                    <div
+                                        v-for="account in getVisibleOnlineAccounts(
+                                            record
+                                        )"
+                                        :key="`${record.id}-${account.platform}-${account.id}`"
+                                        class="account-chip"
                                     >
-                                        <span class="account-name">{{
-                                            account.name
-                                        }}</span>
                                         <span
-                                            v-if="
-                                                shouldShowAccountCompany(
-                                                    account
-                                                )
-                                            "
-                                            class="account-company"
+                                            :class="[
+                                                'platform',
+                                                `platform-${account.platform}`,
+                                            ]"
                                         >
-                                            {{ account.company }}
-                                        </span>
-                                    </span>
-                                    <a-tooltip content="复制平台账号">
-                                        <a-button
-                                            type="text"
-                                            size="mini"
-                                            class="copy-btn account-copy-btn"
-                                            @click.stop="
-                                                copyValue(
-                                                    getAccountCopyText(account),
-                                                    '平台账号'
+                                            {{
+                                                getPlatformLabel(
+                                                    account.platform
                                                 )
-                                            "
-                                        >
-                                            <template #icon>
-                                                <icon-copy />
+                                            }}
+                                        </span>
+                                        <span class="account-id">
+                                            {{ account.id }}
+                                        </span>
+                                        <a-tooltip>
+                                            <span
+                                                class="account-copy-content copyable-text"
+                                                @click.stop="
+                                                    copyValue(
+                                                        getAccountCopyText(
+                                                            account
+                                                        ),
+                                                        '平台账号'
+                                                    )
+                                                "
+                                            >
+                                                <span class="account-name">{{
+                                                    getAccountDisplayText(
+                                                        account
+                                                    )
+                                                }}</span>
+                                            </span>
+                                            <template #content>
+                                                <div
+                                                    class="account-detail-tooltip"
+                                                >
+                                                    <div
+                                                        class="account-detail-row"
+                                                    >
+                                                        ID: {{ account.id }}
+                                                    </div>
+                                                    <div
+                                                        class="account-detail-row"
+                                                    >
+                                                        平台:
+                                                        {{
+                                                            getPlatformLabel(
+                                                                account.platform
+                                                            )
+                                                        }}
+                                                    </div>
+                                                    <div
+                                                        v-if="account.company"
+                                                        class="account-detail-row"
+                                                    >
+                                                        Company:
+                                                        {{ account.company }}
+                                                    </div>
+                                                    <div
+                                                        v-if="account.name"
+                                                        class="account-detail-row"
+                                                    >
+                                                        Name: {{ account.name }}
+                                                    </div>
+                                                    <div
+                                                        v-if="account.nodeName"
+                                                        class="account-detail-row"
+                                                    >
+                                                        节点:
+                                                        {{ account.nodeName }}
+                                                    </div>
+                                                    <div
+                                                        class="account-detail-row"
+                                                    >
+                                                        状态:
+                                                        {{
+                                                            account.status
+                                                                ? '在线'
+                                                                : '离线'
+                                                        }}
+                                                    </div>
+                                                </div>
                                             </template>
-                                        </a-button>
-                                    </a-tooltip>
+                                        </a-tooltip>
+                                        <a-tooltip content="复制平台账号">
+                                            <a-button
+                                                type="text"
+                                                size="mini"
+                                                class="copy-btn account-copy-btn"
+                                                @click.stop="
+                                                    copyValue(
+                                                        getAccountCopyText(
+                                                            account
+                                                        ),
+                                                        '平台账号'
+                                                    )
+                                                "
+                                            >
+                                                <template #icon>
+                                                    <icon-copy />
+                                                </template>
+                                            </a-button>
+                                        </a-tooltip>
+                                    </div>
                                 </div>
 
-                                <a-button
+                                <div
                                     v-if="
-                                        record.accounts.length >
-                                        defaultVisibleAccountCount
+                                        getVisibleOfflineAccounts(record).length
                                     "
+                                    class="account-row account-row-offline"
+                                >
+                                    <div
+                                        v-for="account in getVisibleOfflineAccounts(
+                                            record
+                                        )"
+                                        :key="`${record.id}-${account.platform}-${account.id}`"
+                                        class="account-chip is-offline"
+                                    >
+                                        <span
+                                            :class="[
+                                                'platform',
+                                                `platform-${account.platform}`,
+                                            ]"
+                                        >
+                                            {{
+                                                getPlatformLabel(
+                                                    account.platform
+                                                )
+                                            }}
+                                        </span>
+                                        <span class="account-id">
+                                            {{ account.id }}
+                                        </span>
+                                        <a-tooltip>
+                                            <span
+                                                class="account-copy-content copyable-text"
+                                                @click.stop="
+                                                    copyValue(
+                                                        getAccountCopyText(
+                                                            account
+                                                        ),
+                                                        '平台账号'
+                                                    )
+                                                "
+                                            >
+                                                <span class="account-name">{{
+                                                    getAccountDisplayText(
+                                                        account
+                                                    )
+                                                }}</span>
+                                            </span>
+                                            <template #content>
+                                                <div
+                                                    class="account-detail-tooltip"
+                                                >
+                                                    <div
+                                                        class="account-detail-row"
+                                                    >
+                                                        ID: {{ account.id }}
+                                                    </div>
+                                                    <div
+                                                        class="account-detail-row"
+                                                    >
+                                                        平台:
+                                                        {{
+                                                            getPlatformLabel(
+                                                                account.platform
+                                                            )
+                                                        }}
+                                                    </div>
+                                                    <div
+                                                        v-if="account.company"
+                                                        class="account-detail-row"
+                                                    >
+                                                        Company:
+                                                        {{ account.company }}
+                                                    </div>
+                                                    <div
+                                                        v-if="account.name"
+                                                        class="account-detail-row"
+                                                    >
+                                                        Name: {{ account.name }}
+                                                    </div>
+                                                    <div
+                                                        v-if="account.nodeName"
+                                                        class="account-detail-row"
+                                                    >
+                                                        节点:
+                                                        {{ account.nodeName }}
+                                                    </div>
+                                                    <div
+                                                        class="account-detail-row"
+                                                    >
+                                                        状态:
+                                                        {{
+                                                            account.status
+                                                                ? '在线'
+                                                                : '离线'
+                                                        }}
+                                                    </div>
+                                                </div>
+                                            </template>
+                                        </a-tooltip>
+                                        <a-tooltip content="复制平台账号">
+                                            <a-button
+                                                type="text"
+                                                size="mini"
+                                                class="copy-btn account-copy-btn"
+                                                @click.stop="
+                                                    copyValue(
+                                                        getAccountCopyText(
+                                                            account
+                                                        ),
+                                                        '平台账号'
+                                                    )
+                                                "
+                                            >
+                                                <template #icon>
+                                                    <icon-copy />
+                                                </template>
+                                            </a-button>
+                                        </a-tooltip>
+                                    </div>
+                                </div>
+
+                                <a-button
+                                    v-if="getHiddenAccountCount(record) > 0"
                                     type="text"
                                     size="mini"
                                     @click="toggleExpanded(record.id)"
@@ -378,17 +551,16 @@
                                     {{
                                         expandedIds.includes(record.id)
                                             ? '收起'
-                                            : `展开 ${
-                                                  record.accounts.length -
-                                                  defaultVisibleAccountCount
-                                              } 个`
+                                            : `展开 ${getHiddenAccountCount(
+                                                  record
+                                              )} 个`
                                     }}
                                 </a-button>
                             </div>
                         </template>
                     </a-table-column>
 
-                    <a-table-column title="时间" :width="170">
+                    <a-table-column title="时间" :width="150">
                         <template #cell="{ record }">
                             <div class="sub-text">
                                 <div
@@ -565,18 +737,20 @@
         return normalized.trim().replace(/\s+/g, ' ').toLowerCase();
     };
 
-    const shouldShowAccountCompany = (account: ProxyNodeUsageAccount) => {
-        if (!account.company) return false;
-        return (
-            normalizeAccountCompareText(account.company) !==
-            normalizeAccountCompareText(account.name)
-        );
-    };
+    const getPlatformLabel = (platform: string) =>
+        platformLabelMap[platform] || platform;
+
+    const getAccountDisplayText = (account: ProxyNodeUsageAccount) =>
+        account.company?.trim() || account.name?.trim() || '-';
 
     const getAccountCopyText = (account: ProxyNodeUsageAccount) => {
-        const values = [account.name];
-        if (shouldShowAccountCompany(account)) {
-            values.push(account.company);
+        const values = [`${account.id}`, getAccountDisplayText(account)];
+        if (
+            account.name &&
+            normalizeAccountCompareText(account.name) !==
+                normalizeAccountCompareText(getAccountDisplayText(account))
+        ) {
+            values.push(account.name);
         }
         return values.filter(Boolean).join(' ');
     };
@@ -660,11 +834,44 @@
         );
     };
 
-    const getVisibleAccounts = (record: ProxyNodeRecord) => {
-        if (expandedIds.value.includes(record.id)) {
-            return record.accounts;
+    const isExpanded = (id: number) => expandedIds.value.includes(id);
+
+    const getOnlineAccounts = (record: ProxyNodeRecord) =>
+        record.accounts.filter((account) => account.status);
+
+    const getOfflineAccounts = (record: ProxyNodeRecord) =>
+        record.accounts.filter((account) => !account.status);
+
+    const getVisibleOnlineAccounts = (record: ProxyNodeRecord) => {
+        const accounts = getOnlineAccounts(record);
+        if (isExpanded(record.id)) {
+            return accounts;
         }
-        return record.accounts.slice(0, defaultVisibleAccountCount);
+        return accounts.slice(0, defaultVisibleAccountCount);
+    };
+
+    const getVisibleOfflineAccounts = (record: ProxyNodeRecord) => {
+        const accounts = getOfflineAccounts(record);
+        if (isExpanded(record.id)) {
+            return accounts;
+        }
+        return accounts.slice(0, defaultVisibleAccountCount);
+    };
+
+    const getHiddenAccountCount = (record: ProxyNodeRecord) => {
+        if (isExpanded(record.id)) {
+            return 0;
+        }
+        return (
+            Math.max(
+                0,
+                getOnlineAccounts(record).length - defaultVisibleAccountCount
+            ) +
+            Math.max(
+                0,
+                getOfflineAccounts(record).length - defaultVisibleAccountCount
+            )
+        );
     };
 
     const toggleExpanded = (id: number) => {
@@ -866,22 +1073,34 @@
     .account-summary {
         display: flex;
         flex-wrap: wrap;
-        gap: 8px;
-        margin-bottom: 8px;
+        gap: 6px;
+        margin-bottom: 6px;
     }
 
     .account-list {
+        display: flex;
+        flex-direction: column;
+        gap: 6px;
+        align-items: flex-start;
+    }
+
+    .account-row {
         display: flex;
         flex-wrap: wrap;
-        gap: 8px;
+        gap: 6px;
+        width: 100%;
         align-items: center;
     }
 
+    .account-row-offline {
+        color: var(--color-text-3);
+    }
+
     .account-chip {
         display: inline-flex;
-        gap: 6px;
+        gap: 4px;
         align-items: center;
-        padding: 4px 10px;
+        padding: 2px 6px;
         border-radius: 999px;
         background: var(--color-fill-2);
         color: var(--color-text-1);
@@ -892,14 +1111,18 @@
         color: var(--color-text-3);
     }
 
+    .account-row-offline .platform {
+        opacity: 0.8;
+    }
+
     .platform {
         display: inline-flex;
         align-items: center;
-        height: 20px;
-        padding: 0 6px;
+        height: 18px;
+        padding: 0 4px;
         border-radius: 999px;
         font-size: 12px;
-        line-height: 20px;
+        line-height: 18px;
     }
 
     .platform-tk {
@@ -921,14 +1144,25 @@
         font-weight: 500;
     }
 
+    .account-id {
+        color: var(--color-text-3);
+        font-family: Menlo, Monaco, Consolas, monospace;
+        font-size: 12px;
+    }
+
     .account-copy-content {
         display: inline-flex;
-        gap: 6px;
+        gap: 4px;
         align-items: center;
     }
 
-    .account-company {
-        font-size: 12px;
+    .account-detail-tooltip {
+        max-width: 360px;
+    }
+
+    .account-detail-row {
+        white-space: pre-wrap;
+        word-break: break-all;
     }
 
     .check-tooltip {

+ 805 - 530
src/views/taobao/list.vue

@@ -4,23 +4,44 @@
         <a-card class="general-card" :title="$t('menu.taobao.list')">
             <a-row>
                 <a-col :flex="1">
-                    <a-form :model="formModel" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }"
-                        label-align="left">
+                    <a-form
+                        :model="formModel"
+                        :label-col-props="{ span: 6 }"
+                        :wrapper-col-props="{ span: 18 }"
+                        label-align="left"
+                    >
                         <a-row :gutter="16">
                             <a-col :span="8">
                                 <a-form-item field="name" label="账号名">
-                                    <a-input v-model="formModel.name" placeholder="输入关键词搜索" />
+                                    <a-input
+                                        v-model="formModel.name"
+                                        placeholder="输入关键词搜索"
+                                    />
                                 </a-form-item>
                             </a-col>
                             <a-col :span="8">
-                                <a-form-item field="lastTime" :label="$t('searchTable.form.lastTime')">
-                                    <a-range-picker v-model="formModel.lastTime" style="width: 100%" />
+                                <a-form-item
+                                    field="lastTime"
+                                    :label="$t('searchTable.form.lastTime')"
+                                >
+                                    <a-range-picker
+                                        v-model="formModel.lastTime"
+                                        style="width: 100%"
+                                    />
                                 </a-form-item>
                             </a-col>
                             <a-col :span="8">
-                                <a-form-item field="status" :label="$t('searchTable.form.status')">
-                                    <a-select v-model="formModel.status" :options="statusOptions" :placeholder="$t('searchTable.form.selectDefault')
-                                        " />
+                                <a-form-item
+                                    field="status"
+                                    :label="$t('searchTable.form.status')"
+                                >
+                                    <a-select
+                                        v-model="formModel.status"
+                                        :options="statusOptions"
+                                        :placeholder="
+                                            $t('searchTable.form.selectDefault')
+                                        "
+                                    />
                                 </a-form-item>
                             </a-col>
                         </a-row>
@@ -50,45 +71,73 @@
                         </a-button>
                     </a-space>
                 </a-col>
-                <a-col :span="12" style="
+                <a-col
+                    :span="12"
+                    style="
                         display: flex;
                         align-items: center;
                         justify-content: end;
-                    ">
+                    "
+                >
                     <a-tooltip :content="$t('searchTable.actions.refresh')">
-                        <div class="action-icon" @click="search"><icon-refresh size="18" /></div>
+                        <div class="action-icon" @click="search"
+                            ><icon-refresh size="18"
+                        /></div>
                     </a-tooltip>
                     <a-dropdown @select="handleSelectDensity">
                         <a-tooltip :content="$t('searchTable.actions.density')">
-                            <div class="action-icon"><icon-line-height size="18" /></div>
+                            <div class="action-icon"
+                                ><icon-line-height size="18"
+                            /></div>
                         </a-tooltip>
                         <template #content>
-                            <a-doption v-for="item in densityList" :key="item.value" :value="item.value"
-                                :class="{ active: item.value === size }">
+                            <a-doption
+                                v-for="item in densityList"
+                                :key="item.value"
+                                :value="item.value"
+                                :class="{ active: item.value === size }"
+                            >
                                 <span>{{ item.name }}</span>
                             </a-doption>
                         </template>
                     </a-dropdown>
-                    <a-tooltip :content="$t('searchTable.actions.columnSetting')">
-                        <a-popover trigger="click" position="bl" @popup-visible-change="popupVisibleChange">
-                            <div class="action-icon"><icon-settings size="18" /></div>
+                    <a-tooltip
+                        :content="$t('searchTable.actions.columnSetting')"
+                    >
+                        <a-popover
+                            trigger="click"
+                            position="bl"
+                            @popup-visible-change="popupVisibleChange"
+                        >
+                            <div class="action-icon"
+                                ><icon-settings size="18"
+                            /></div>
                             <template #content>
                                 <div id="tableSetting">
-                                    <div v-for="(item, index) in showColumns" :key="item.dataIndex" class="setting">
-                                        <div style="
+                                    <div
+                                        v-for="(item, index) in showColumns"
+                                        :key="item.dataIndex"
+                                        class="setting"
+                                    >
+                                        <div
+                                            style="
                                                 margin-right: 4px;
                                                 cursor: move;
-                                            ">
+                                            "
+                                        >
                                             <icon-drag-arrow />
                                         </div>
                                         <div>
-                                            <a-checkbox v-model="item.checked" @change="
-                                                handleChange(
-                                                    $event,
-                                                    item as TableColumnData,
-                                                    index
-                                                )
-                                                ">
+                                            <a-checkbox
+                                                v-model="item.checked"
+                                                @change="
+                                                    handleChange(
+                                                        $event,
+                                                        item as TableColumnData,
+                                                        index
+                                                    )
+                                                "
+                                            >
                                             </a-checkbox>
                                         </div>
                                         <div class="title">
@@ -106,64 +155,142 @@
                 </a-col>
             </a-row>
 
-            <a-table row-key="id" :loading="loading" :pagination="pagination" :summary="true" summary-text="汇总"
-                :columns="(cloneColumns as TableColumnData[])" :data="renderData" :bordered="false" :size="size"
-                :row-class="getRowClass" @page-change="onPageChange" @page-size-change="onPageSizeChange">
+            <a-table
+                row-key="id"
+                :loading="loading"
+                :pagination="pagination"
+                :summary="true"
+                summary-text="汇总"
+                :columns="(cloneColumns as TableColumnData[])"
+                :data="renderData"
+                :bordered="false"
+                :size="size"
+                :row-class="getRowClass"
+                @page-change="onPageChange"
+                @page-size-change="onPageSizeChange"
+            >
                 <template #index="{ record }">
                     {{ record.id }}
                 </template>
                 <template #name="{ record }">
-                    <a-list-item-meta :title="record.company" :description="record.description" />
-
+                    <a-list-item-meta
+                        :title="record.company"
+                        :description="record.description"
+                    />
                 </template>
                 <template #daily_income_limit="{ record }">
-                    <a-tag bordered
-                        :color="record.current_amt > record.daily_income_limit && record.daily_income_limit > 0 ? 'red' : ''">
+                    <a-tag
+                        bordered
+                        :color="
+                            record.current_amt > record.daily_income_limit &&
+                            record.daily_income_limit > 0
+                                ? 'red'
+                                : ''
+                        "
+                    >
                         {{ record.current_amt }} /
                         {{ record.daily_income_limit }}
                     </a-tag>
                 </template>
 
                 <template #nodeName="{ record }">
-                    <a-tag color="gray" @click="changePublicIp(record.nodeName)">{{ record.end_point }} - {{
-                        record.nodeName }} </a-tag>
+                    <div>
+                        <a-tag
+                            :color="
+                                record.proxyStatus === true ? 'green' : 'gray'
+                            "
+                            @click="changePublicIp(record.nodeName)"
+                        >
+                            <template v-if="record.proxyStatus === true" #icon>
+                                <icon-check />
+                            </template>
+                            <template
+                                v-else-if="record.proxyStatus === false"
+                                #icon
+                            >
+                                <icon-stop />
+                            </template>
+                            {{ record.end_point }} - {{ record.nodeName }}
+                        </a-tag>
+                    </div>
                 </template>
 
                 <template #suspended_endpoint="{ record }">
-                    <a-tag v-if="record.suspended_endpoint" size="small" bordered color="red"
-                        @click="changeAttr(record.id, 'check_status', true)">
-                        暂停:{{ record.suspended_endpoint }}</a-tag>
-
-                    <a-tag v-else size="small" bordered color="gray"
-                        @click="changeAttr(record.id, 'check_status', true)">
-                        正常</a-tag>
-
+                    <a-tag
+                        v-if="record.suspended_endpoint"
+                        size="small"
+                        bordered
+                        color="red"
+                        @click="changeAttr(record.id, 'check_status', true)"
+                    >
+                        暂停:{{ record.suspended_endpoint }}</a-tag
+                    >
+
+                    <a-tag
+                        v-else
+                        size="small"
+                        bordered
+                        color="gray"
+                        @click="changeAttr(record.id, 'check_status', true)"
+                    >
+                        正常</a-tag
+                    >
                 </template>
                 <template #tags="{ record }">
-                    <a-tag v-if="record.is_banned" size="small" bordered color="red">
+                    <a-tag
+                        v-if="record.is_banned"
+                        size="small"
+                        bordered
+                        color="red"
+                    >
                         封号
                     </a-tag>
-                    <a-tag v-if="record.riskCookie" size="small" bordered color="red">
+                    <a-tag
+                        v-if="record.riskCookie"
+                        size="small"
+                        bordered
+                        color="red"
+                    >
                         {{ record.riskCookie }}
                     </a-tag>
                     <a-typography-text mark v-if="record.note">
                         {{ record.note }}
                     </a-typography-text>
-                    <a-tag v-if="record.parse_type" size="small" bordered color="blue">
+                    <a-tag
+                        v-if="record.parse_type"
+                        size="small"
+                        bordered
+                        color="blue"
+                    >
                         {{ record.parse_type }}
                     </a-tag>
-                    <a-tag v-if="record.riskStrategy" size="small" bordered color="orange">
+                    <a-tag
+                        v-if="record.riskStrategy"
+                        size="small"
+                        bordered
+                        color="orange"
+                    >
                         {{ record.riskStrategy }}-{{ record.launchScene }}
                     </a-tag>
                 </template>
                 <template #status="{ record }">
-                    <a-tag v-if="record.status" bordered color="green" @click="changeStatus(record, false)">
+                    <a-tag
+                        v-if="record.status"
+                        bordered
+                        color="green"
+                        @click="changeStatus(record, false)"
+                    >
                         <template #icon>
                             <icon-check />
                         </template>
                         在线
                     </a-tag>
-                    <a-tag v-else bordered color="" @click="changeStatus(record, true)">
+                    <a-tag
+                        v-else
+                        bordered
+                        color=""
+                        @click="changeStatus(record, true)"
+                    >
                         <template #icon>
                             <icon-stop />
                         </template>
@@ -171,587 +298,735 @@
                     </a-tag>
                 </template>
                 <template #actions="{ record }">
-                    <a-tag v-if="record.enable_parse" size="small" bordered color="red"
-                        @click="changeAttr(record.id, 'enable_parse', false)">
+                    <a-tag
+                        v-if="record.enable_parse"
+                        size="small"
+                        bordered
+                        color="red"
+                        @click="changeAttr(record.id, 'enable_parse', false)"
+                    >
                         转链
                     </a-tag>
-                    <a-tag v-else size="small" bordered color="" @click="changeAttr(record.id, 'enable_parse', true)">
+                    <a-tag
+                        v-else
+                        size="small"
+                        bordered
+                        color=""
+                        @click="changeAttr(record.id, 'enable_parse', true)"
+                    >
                         转链
                     </a-tag>
-                    <span style="margin: 5px;">
-                        <a-tag v-if="record.enable_coupon" size="small" bordered color="orange"
-                            @click="changeAttr(record.id, 'enable_coupon', false)">
+                    <span style="margin: 5px">
+                        <a-tag
+                            v-if="record.enable_coupon"
+                            size="small"
+                            bordered
+                            color="orange"
+                            @click="
+                                changeAttr(record.id, 'enable_coupon', false)
+                            "
+                        >
                             优惠券
                         </a-tag>
-                        <a-tag v-else size="small" bordered color=""
-                            @click="changeAttr(record.id, 'enable_coupon', true)">
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color=""
+                            @click="
+                                changeAttr(record.id, 'enable_coupon', true)
+                            "
+                        >
                             优惠券
                         </a-tag>
                     </span>
-                    <a-tag v-if="record.enable_sync_order" size="small" bordered color="arcoblue"
-                        @click="changeAttr(record.id, 'enable_sync_order', false)">
+                    <a-tag
+                        v-if="record.enable_sync_order"
+                        size="small"
+                        bordered
+                        color="arcoblue"
+                        @click="
+                            changeAttr(record.id, 'enable_sync_order', false)
+                        "
+                    >
                         同步订单
                     </a-tag>
-                    <a-tag v-else size="small" bordered color="gray"
-                        @click="changeAttr(record.id, 'enable_sync_order', true)">
+                    <a-tag
+                        v-else
+                        size="small"
+                        bordered
+                        color="gray"
+                        @click="
+                            changeAttr(record.id, 'enable_sync_order', true)
+                        "
+                    >
                         同步订单
                     </a-tag>
-                    <span style="margin:0 5px;">
-                        <a-tag v-if="record.enable_fake_click" size="small" bordered color="blue"
-                            @click="changeAttr(record.id, 'enable_fake_click', false)">
+                    <span style="margin: 0 5px">
+                        <a-tag
+                            v-if="record.enable_fake_click"
+                            size="small"
+                            bordered
+                            color="blue"
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_fake_click',
+                                    false
+                                )
+                            "
+                        >
                             补点击
                         </a-tag>
-                        <a-tag v-else size="small" bordered color="gray"
-                            @click="changeAttr(record.id, 'enable_fake_click', true)">
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color="gray"
+                            @click="
+                                changeAttr(record.id, 'enable_fake_click', true)
+                            "
+                        >
                             补点击
                         </a-tag>
                     </span>
 
-                    <span style="margin:0 5px;">
-                        <a-tag v-if="record.enable_promotionQuery" size="small" bordered color="orangered"
-                            @click="changeAttr(record.id, 'enable_promotionQuery', false)">
+                    <span style="margin: 0 5px">
+                        <a-tag
+                            v-if="record.enable_promotionQuery"
+                            size="small"
+                            bordered
+                            color="orangered"
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_promotionQuery',
+                                    false
+                                )
+                            "
+                        >
                             搜同款
                         </a-tag>
-                        <a-tag v-else size="small" bordered color="gray"
-                            @click="changeAttr(record.id, 'enable_promotionQuery', true)">
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color="gray"
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_promotionQuery',
+                                    true
+                                )
+                            "
+                        >
                             搜同款
                         </a-tag>
                     </span>
 
-                    <a-tag v-if="record.enable_deep_url" size="small" bordered color="blue"
-                        @click="changeAttr(record.id, 'enable_deep_url', false)">
+                    <a-tag
+                        v-if="record.enable_deep_url"
+                        size="small"
+                        bordered
+                        color="blue"
+                        @click="changeAttr(record.id, 'enable_deep_url', false)"
+                    >
                         下探网址
                     </a-tag>
-                    <a-tag v-else size="small" bordered color="gray"
-                        @click="changeAttr(record.id, 'enable_deep_url', true)">
+                    <a-tag
+                        v-else
+                        size="small"
+                        bordered
+                        color="gray"
+                        @click="changeAttr(record.id, 'enable_deep_url', true)"
+                    >
                         下探网址
                     </a-tag>
-
                 </template>
                 <template #time="{ record }">
-                    <div style="color:gray;">
-                        <div>注册:{{ dayjs(record.create_time).format('MM-DD HH:mm') }}</div>
-                        <div>更新:{{ dayjs(record.last_time).format('MM-DD HH:mm') }}</div>
-                        <div v-if="dayjs().diff(dayjs(record.login_time), 'hours') < 48">
-                            登录:{{ dayjs(record.login_time).format('MM-DD HH:mm') }}</div>
+                    <div style="color: gray">
+                        <div
+                            >注册:{{
+                                dayjs(record.create_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
+                        <div
+                            >更新:{{
+                                dayjs(record.last_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
+                        <div
+                            v-if="
+                                dayjs().diff(
+                                    dayjs(record.login_time),
+                                    'hours'
+                                ) < 48
+                            "
+                        >
+                            登录:{{
+                                dayjs(record.login_time).format('MM-DD HH:mm')
+                            }}</div
+                        >
                         <a-tooltip v-else>
                             <template #content>
-                                <div>登录:{{ dayjs(record.login_time).format('MM-DD HH:mm') }}</div>
+                                <div
+                                    >登录:{{
+                                        dayjs(record.login_time).format(
+                                            'MM-DD HH:mm'
+                                        )
+                                    }}</div
+                                >
                                 <div>登录状态即将掉线,请尽快处理</div>
                             </template>
-                            <div style="color:red;">
-                                预计 {{ 72 - dayjs().diff(dayjs(record.login_time), 'hours') }} 小时后掉线
+                            <div style="color: red">
+                                预计
+                                {{
+                                    72 -
+                                    dayjs().diff(
+                                        dayjs(record.login_time),
+                                        'hours'
+                                    )
+                                }}
+                                小时后掉线
                             </div>
                         </a-tooltip>
                     </div>
                 </template>
                 <template #operations="{ record }">
-                    <a-button type="text" size="small" @click="changeItem(record)">
+                    <a-button
+                        type="text"
+                        size="small"
+                        @click="changeItem(record)"
+                    >
                         更新
                     </a-button>
-                    <a-button type="text" size="small" @click="billView(record)">
+                    <a-button
+                        type="text"
+                        size="small"
+                        @click="billView(record)"
+                    >
                         预计收益
                     </a-button>
                 </template>
 
                 <template #summary-cell="{ column, record }">
-                    <div style="margin:10px auto" v-if="column.slotName == 'daily_income_limit'">
+                    <div
+                        style="margin: 10px auto"
+                        v-if="column.slotName == 'daily_income_limit'"
+                    >
                         预估: {{ amountFormat(record.current_amt) }}
                     </div>
                 </template>
 
                 <template #time_range="{ record }">
-                    <WorkHourModel :path="updatePath" :record="record" @change="search" />
+                    <WorkHourModel
+                        :path="updatePath"
+                        :record="record"
+                        @change="search"
+                    />
                 </template>
                 <template #hourly_calls_limit="{ record }">
-                    <a-tag bordered
-                        :color="record.current_hourly_calls > record.hourly_calls_limit && record.hourly_calls_limit > 0 ? 'red' : ''">
+                    <a-tag
+                        bordered
+                        :color="
+                            record.current_hourly_calls >
+                                record.hourly_calls_limit &&
+                            record.hourly_calls_limit > 0
+                                ? 'red'
+                                : ''
+                        "
+                    >
                         {{ record.current_hourly_calls }} /
                         {{ record.hourly_calls_limit }}
                     </a-tag>
                 </template>
 
                 <template #daily_calls_limit="{ record }">
-                    <a-tag bordered
-                        :color="record.current_daily_calls > record.daily_calls_limit && record.daily_calls_limit > 0 ? 'red' : ''">
+                    <a-tag
+                        bordered
+                        :color="
+                            record.current_daily_calls >
+                                record.daily_calls_limit &&
+                            record.daily_calls_limit > 0
+                                ? 'red'
+                                : ''
+                        "
+                    >
                         {{ record.current_daily_calls }} /
                         {{ record.daily_calls_limit }}
                     </a-tag>
                 </template>
-
             </a-table>
         </a-card>
     </div>
 </template>
 
 <script lang="ts" setup>
-import { useRouter, useRoute } from 'vue-router';
-import { computed, ref, reactive, watch, nextTick } from 'vue';
-import { useI18n } from 'vue-i18n';
-import dayjs from 'dayjs';
-import useLoading from '@/hooks/loading';
-import { queryTkPool, TkPoolRecord, TkPoolParams, TkUpdateAccountModel, TkUpdateAccount } from '@/api/taobao';
-import { changePublicIpByName } from '@/api/proxy';
-import { Pagination } from '@/types/global';
-import { Modal, Message } from '@arco-design/web-vue';
-import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
-import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
-import cloneDeep from 'lodash/cloneDeep';
-import Sortable from 'sortablejs';
-import { numberFormat, amountFormat } from '@/utils/util';
-import { UpdateAccountModel, UpdateAccount } from '@/api/app';
-import WorkHourModel from '@/components/WorkHourModel.vue';
-
-const updatePath = '/api/taobao/update';
-
-
-type SizeProps = 'mini' | 'small' | 'medium' | 'large';
-type Column = TableColumnData & { checked?: true };
-
-const generateFormModel = () => {
-    return {
-        name: '',
-        lastTime: [],
-        status: '',
-        show_hide: false,
-        sort: 'status',
-        order: 'descending',
+    import { useRouter, useRoute } from 'vue-router';
+    import { computed, ref, reactive, watch, nextTick } from 'vue';
+    import { useI18n } from 'vue-i18n';
+    import dayjs from 'dayjs';
+    import useLoading from '@/hooks/loading';
+    import {
+        queryTkPool,
+        TkPoolRecord,
+        TkPoolParams,
+        TkUpdateAccountModel,
+        TkUpdateAccount,
+    } from '@/api/taobao';
+    import { changePublicIpByName } from '@/api/proxy';
+    import { Pagination } from '@/types/global';
+    import { Modal, Message } from '@arco-design/web-vue';
+    import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
+    import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
+    import cloneDeep from 'lodash/cloneDeep';
+    import Sortable from 'sortablejs';
+    import { numberFormat, amountFormat } from '@/utils/util';
+    import { UpdateAccountModel, UpdateAccount } from '@/api/app';
+    import WorkHourModel from '@/components/WorkHourModel.vue';
+
+    const updatePath = '/api/taobao/update';
+
+    type SizeProps = 'mini' | 'small' | 'medium' | 'large';
+    type Column = TableColumnData & { checked?: true };
+
+    const generateFormModel = () => {
+        return {
+            name: '',
+            lastTime: [],
+            status: '',
+            show_hide: false,
+            sort: 'status',
+            order: 'descending',
+        };
     };
-};
-const router = useRouter();
-const route = useRoute();
-
-const { loading, setLoading } = useLoading(true);
-const { t } = useI18n();
-const renderData = ref<TkPoolRecord[]>([]);
-const formModel = ref(generateFormModel());
-
-
-const cloneColumns = ref<Column[]>([]);
-const showColumns = ref<Column[]>([]);
-
-const size = ref<SizeProps>('mini');
-
-const basePagination: Pagination = {
-    current: 1,
-    pageSize: 50,
-    showPageSize: true,
-    showTotal: true,
-    pageSizeOptions: [10, 20, 50, 100, 200, 500]
-};
-const pagination = reactive({
-    ...basePagination,
-});
-const densityList = computed(() => [
-    {
-        name: t('searchTable.size.mini'),
-        value: 'mini',
-    },
-    {
-        name: t('searchTable.size.small'),
-        value: 'small',
-    },
-    {
-        name: t('searchTable.size.medium'),
-        value: 'medium',
-    },
-    {
-        name: t('searchTable.size.large'),
-        value: 'large',
-    },
-]);
-
-const columns = computed<TableColumnData[]>(() => [
-    {
-        title: '#',
-        dataIndex: 'index',
-        slotName: 'index',
-        width: 50,
-    },
-    {
-        title: '账号名',
-        dataIndex: 'name',
-        slotName: 'name',
-        width: 200,
-    },
-    {
-        title: '',
-        slotName: 'tags',
-        width: 40,
-    },
-    {
-        title: '工作时间',
-        dataIndex: 'time_range',
-        slotName: 'time_range',
-        align: 'right',
-        width: 200,
-    },
-    {
-        title: '小时调用',
-        slotName: 'hourly_calls_limit',
-        dataIndex: 'current_hourly_calls',
-        align: 'right',
-        width: 120,
-    },
-    {
-        title: '当日调用',
-        slotName: 'daily_calls_limit',
-        dataIndex: 'current_daily_calls',
-        align: 'right',
-        width: 150,
-    },
-    {
-        title: '每日收益限额',
-        slotName: 'daily_income_limit',
-        dataIndex: 'current_amt',
-        align: 'right',
-        width: 180,
-    },
-    {
-        title: '可提现余额',
-        dataIndex: 'draw_balance',
-        width: 120,
-    },
-    {
-        title: '运行节点',
-        slotName: 'nodeName',
-        width: 120,
-    },
-    {
-        title: '挂起节点',
-        slotName: 'suspended_endpoint',
-        width: 120,
-    },
-    {
-        title: '状态',
-        slotName: 'status',
-        width: 100,
-    },
-    {
-        title: '分类',
-        slotName: 'actions',
-        width: 400,
-        align: 'center',
-    },
-    {
-        title: '时间',
-        slotName: 'time',
-        width: 170,
-    },
-    {
-        title: '操作',
-        dataIndex: 'operations',
-        slotName: 'operations',
-        align: 'right',
-        width: 150,
-    },
-]);
-
-const statusOptions = computed<SelectOptionData[]>(() => [
-    {
-        label: '全部',
-        value: '',
-    },
-    {
-        label: '在线',
-        value: 'online',
-    },
-    {
-        label: '下线',
-        value: 'offline',
-    },
-]);
-
-const getRowClass = (record: TkPoolRecord) => {
-    return record.is_hide ? 'special-table-row' : '';
-};
-
-
-if (route.query.show_hide === '1') {
-    formModel.value.show_hide = true;
-}
-const fetchData = async (
-    params: TkPoolParams = {
-        current: 1,
-        pageSize: 50,
-        show_hide: false,
-        sort: 'status',
-        order: 'descending',
-        getTotal: true,
-    }
-) => {
-    if (route.query.show_hide === '1') {
-        params.show_hide = true;
-    }
+    const router = useRouter();
+    const route = useRoute();
 
-    setLoading(true);
-    try {
-        const { data } = await queryTkPool(params);
-        if (!data) return;
-        // const { data } = await queryTkPool(params);
-        renderData.value = data.list;
-        pagination.current = data.page;
-        pagination.total = data.count;
-    } catch (err) {
-        console.log(err);
-        // you can report use errorHandler or other
-    } finally {
-        setLoading(false);
-    }
-};
-
-const changeItem = async (data: TkPoolRecord) => {
-    router.push({ name: 'updateCookies' });
-};
+    const { loading, setLoading } = useLoading(true);
+    const { t } = useI18n();
+    const renderData = ref<TkPoolRecord[]>([]);
+    const formModel = ref(generateFormModel());
 
-const billView = async (data: TkPoolRecord) => {
-    router.push({ name: 'taobao_bill_dailys', query: { name: data.company } });
-};
+    const cloneColumns = ref<Column[]>([]);
+    const showColumns = ref<Column[]>([]);
 
+    const size = ref<SizeProps>('mini');
 
+    const basePagination: Pagination = {
+        current: 1,
+        pageSize: 50,
+        showPageSize: true,
+        showTotal: true,
+        pageSizeOptions: [10, 20, 50, 100, 200, 500],
+    };
+    const pagination = reactive({
+        ...basePagination,
+    });
+    const densityList = computed(() => [
+        {
+            name: t('searchTable.size.mini'),
+            value: 'mini',
+        },
+        {
+            name: t('searchTable.size.small'),
+            value: 'small',
+        },
+        {
+            name: t('searchTable.size.medium'),
+            value: 'medium',
+        },
+        {
+            name: t('searchTable.size.large'),
+            value: 'large',
+        },
+    ]);
+
+    const columns = computed<TableColumnData[]>(() => [
+        {
+            title: '#',
+            dataIndex: 'index',
+            slotName: 'index',
+            width: 50,
+        },
+        {
+            title: '账号名',
+            dataIndex: 'name',
+            slotName: 'name',
+            width: 200,
+        },
+        {
+            title: '',
+            slotName: 'tags',
+            width: 40,
+        },
+        {
+            title: '工作时间',
+            dataIndex: 'time_range',
+            slotName: 'time_range',
+            align: 'right',
+            width: 200,
+        },
+        {
+            title: '小时调用',
+            slotName: 'hourly_calls_limit',
+            dataIndex: 'current_hourly_calls',
+            align: 'right',
+            width: 120,
+        },
+        {
+            title: '当日调用',
+            slotName: 'daily_calls_limit',
+            dataIndex: 'current_daily_calls',
+            align: 'right',
+            width: 150,
+        },
+        {
+            title: '每日收益限额',
+            slotName: 'daily_income_limit',
+            dataIndex: 'current_amt',
+            align: 'right',
+            width: 180,
+        },
+        {
+            title: '可提现余额',
+            dataIndex: 'draw_balance',
+            width: 120,
+        },
+        {
+            title: '运行节点',
+            slotName: 'nodeName',
+            width: 120,
+        },
+        {
+            title: '挂起节点',
+            slotName: 'suspended_endpoint',
+            width: 120,
+        },
+        {
+            title: '状态',
+            slotName: 'status',
+            width: 100,
+        },
+        {
+            title: '分类',
+            slotName: 'actions',
+            width: 400,
+            align: 'center',
+        },
+        {
+            title: '时间',
+            slotName: 'time',
+            width: 170,
+        },
+        {
+            title: '操作',
+            dataIndex: 'operations',
+            slotName: 'operations',
+            align: 'right',
+            width: 150,
+        },
+    ]);
+
+    const statusOptions = computed<SelectOptionData[]>(() => [
+        {
+            label: '全部',
+            value: '',
+        },
+        {
+            label: '在线',
+            value: 'online',
+        },
+        {
+            label: '下线',
+            value: 'offline',
+        },
+    ]);
+
+    const getRowClass = (record: TkPoolRecord) => {
+        return record.is_hide ? 'special-table-row' : '';
+    };
 
-const changeStatus = async (data: TkPoolRecord, val: any) => {
-    if (data.is_banned && val) {
-        Message.error('被封账号,不能上线!');
-        return;
+    if (route.query.show_hide === '1') {
+        formModel.value.show_hide = true;
     }
-    const args = {
-        id: data.id,
-        name: 'status',
-        val
-    } as TkUpdateAccountModel;
-
-
-    Modal.confirm({
-        title: '确认提示',
-        content: '确定要更改状态吗?',
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
-
-            try {
-                const { data } = await TkUpdateAccount(args);
-                console.log(data, data.msg);
-                const msg = data.msg || '更新成功!';
-                if (data.success) {
-                    Message.success(msg);
-                    search();
-                } else {
-                    Message.error(data.msg);
-                }
+    const fetchData = async (
+        params: TkPoolParams = {
+            current: 1,
+            pageSize: 50,
+            show_hide: false,
+            sort: 'status',
+            order: 'descending',
+            getTotal: true,
+        }
+    ) => {
+        if (route.query.show_hide === '1') {
+            params.show_hide = true;
+        }
 
-            } catch (e) {
-                console.log(e);
-            }
+        setLoading(true);
+        try {
+            const { data } = await queryTkPool(params);
+            if (!data) return;
+            // const { data } = await queryTkPool(params);
+            renderData.value = data.list;
+            pagination.current = data.page;
+            pagination.total = data.count;
+        } catch (err) {
+            console.log(err);
+            // you can report use errorHandler or other
+        } finally {
             setLoading(false);
         }
-    });
-};
-
-const changeAttr = async (id: number, name: string, val: any) => {
-    const args = {
-        id,
-        name,
-        val
-    } as TkUpdateAccountModel;
-
-
-    Modal.confirm({
-        title: '确认提示',
-        content: '确定要更改状态吗?',
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
-            try {
-
-                const { data } = await TkUpdateAccount(args);
-                console.log(data, data.msg);
-                const msg = data.msg || '更新成功!';
-                if (data.success) {
-                    Message.success(msg);
-                    search();
-                } else {
-                    Message.error(data.msg);
-                }
-            } catch (e) { console.log(e) }
-            setLoading(false);
+    };
+
+    const changeItem = async (data: TkPoolRecord) => {
+        router.push({ name: 'updateCookies' });
+    };
+
+    const billView = async (data: TkPoolRecord) => {
+        router.push({
+            name: 'taobao_bill_dailys',
+            query: { name: data.company },
+        });
+    };
+
+    const changeStatus = async (data: TkPoolRecord, val: any) => {
+        if (data.is_banned && val) {
+            Message.error('被封账号,不能上线!');
+            return;
         }
-    });
+        const args = {
+            id: data.id,
+            name: 'status',
+            val,
+        } as TkUpdateAccountModel;
+
+        Modal.confirm({
+            title: '确认提示',
+            content: '确定要更改状态吗?',
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+
+                try {
+                    const { data } = await TkUpdateAccount(args);
+                    console.log(data, data.msg);
+                    const msg = data.msg || '更新成功!';
+                    if (data.success) {
+                        Message.success(msg);
+                        search();
+                    } else {
+                        Message.error(data.msg);
+                    }
+                } catch (e) {
+                    console.log(e);
+                }
+                setLoading(false);
+            },
+        });
+    };
 
-};
-
-const changePublicIp = async (nodeName: string) => {
-    Modal.confirm({
-        title: '确认提示',
-        content: `确定要更改节点 ${nodeName} 的公网IP吗?`,
-        okText: '确认',
-        cancelText: '取消',
-        async onOk() {
-            setLoading(true);
-
-            try {
-                const { data } = await changePublicIpByName(nodeName);
-                console.log(data);
-                const msg = data.msg || '更新IP成功!';
-                if (data.success) {
-                    Message.success(msg);
-                    search();
-                } else {
-                    Message.error(data.msg);
+    const changeAttr = async (id: number, name: string, val: any) => {
+        const args = {
+            id,
+            name,
+            val,
+        } as TkUpdateAccountModel;
+
+        Modal.confirm({
+            title: '确认提示',
+            content: '确定要更改状态吗?',
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+                try {
+                    const { data } = await TkUpdateAccount(args);
+                    console.log(data, data.msg);
+                    const msg = data.msg || '更新成功!';
+                    if (data.success) {
+                        Message.success(msg);
+                        search();
+                    } else {
+                        Message.error(data.msg);
+                    }
+                } catch (e) {
+                    console.log(e);
                 }
-            } catch (e) {
-                console.log(e);
-            } finally {
                 setLoading(false);
-            }
-        }
-    });
-};
+            },
+        });
+    };
 
+    const changePublicIp = async (nodeName: string) => {
+        Modal.confirm({
+            title: '确认提示',
+            content: `确定要更改节点 ${nodeName} 的公网IP吗?`,
+            okText: '确认',
+            cancelText: '取消',
+            async onOk() {
+                setLoading(true);
+
+                try {
+                    const { data } = await changePublicIpByName(nodeName);
+                    console.log(data);
+                    const msg = data.msg || '更新IP成功!';
+                    if (data.success) {
+                        Message.success(msg);
+                        search();
+                    } else {
+                        Message.error(data.msg);
+                    }
+                } catch (e) {
+                    console.log(e);
+                } finally {
+                    setLoading(false);
+                }
+            },
+        });
+    };
 
+    const search = () => {
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+        } as unknown as TkPoolParams);
+    };
+    const onPageChange = (current: number) => {
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+            current,
+        } as unknown as TkPoolParams);
+    };
 
+    const onPageSizeChange = (current: number) => {
+        basePagination.pageSize = current;
+        pagination.pageSize = current;
+        fetchData({
+            ...basePagination,
+            ...formModel.value,
+            current: 1,
+        } as unknown as TkPoolParams);
+    };
 
-const search = () => {
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-    } as unknown as TkPoolParams);
-};
-const onPageChange = (current: number) => {
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-        current
-    } as unknown as TkPoolParams);
-};
-
-const onPageSizeChange = (current: number) => {
-    basePagination.pageSize = current;
-    pagination.pageSize = current;
-    fetchData({
-        ...basePagination,
-        ...formModel.value,
-        current: 1,
-    } as unknown as TkPoolParams);
-};
-
-fetchData();
-const reset = () => {
-    formModel.value = generateFormModel();
-};
-
-const handleSelectDensity = (
-    val: string | number | Record<string, any> | undefined,
-    e: Event
-) => {
-    size.value = val as SizeProps;
-};
-
-const handleChange = (
-    checked: boolean | (string | boolean | number)[],
-    column: Column,
-    index: number
-) => {
-    if (!checked) {
-        cloneColumns.value = showColumns.value.filter(
-            (item) => item.dataIndex !== column.dataIndex
-        );
-    } else {
-        cloneColumns.value.splice(index, 0, column);
-    }
-};
-
-const exchangeArray = <T extends Array<any>>(
-    array: T,
-    beforeIdx: number,
-    newIdx: number,
-    isDeep = false
-): T => {
-    const newArray = isDeep ? cloneDeep(array) : array;
-    if (beforeIdx > -1 && newIdx > -1) {
-        // 先替换后面的,然后拿到替换的结果替换前面的
-        newArray.splice(
-            beforeIdx,
-            1,
-            newArray.splice(newIdx, 1, newArray[beforeIdx]).pop()
-        );
-    }
-    return newArray;
-};
-
-const popupVisibleChange = (val: boolean) => {
-    if (val) {
-        nextTick(() => {
-            const el = document.getElementById(
-                'tableSetting'
-            ) as HTMLElement;
-            const sortable = new Sortable(el, {
-                onEnd(e: any) {
-                    const { oldIndex, newIndex } = e;
-                    exchangeArray(cloneColumns.value, oldIndex, newIndex);
-                    exchangeArray(showColumns.value, oldIndex, newIndex);
-                },
+    fetchData();
+    const reset = () => {
+        formModel.value = generateFormModel();
+    };
+
+    const handleSelectDensity = (
+        val: string | number | Record<string, any> | undefined,
+        e: Event
+    ) => {
+        size.value = val as SizeProps;
+    };
+
+    const handleChange = (
+        checked: boolean | (string | boolean | number)[],
+        column: Column,
+        index: number
+    ) => {
+        if (!checked) {
+            cloneColumns.value = showColumns.value.filter(
+                (item) => item.dataIndex !== column.dataIndex
+            );
+        } else {
+            cloneColumns.value.splice(index, 0, column);
+        }
+    };
+
+    const exchangeArray = <T extends Array<any>>(
+        array: T,
+        beforeIdx: number,
+        newIdx: number,
+        isDeep = false
+    ): T => {
+        const newArray = isDeep ? cloneDeep(array) : array;
+        if (beforeIdx > -1 && newIdx > -1) {
+            // 先替换后面的,然后拿到替换的结果替换前面的
+            newArray.splice(
+                beforeIdx,
+                1,
+                newArray.splice(newIdx, 1, newArray[beforeIdx]).pop()
+            );
+        }
+        return newArray;
+    };
+
+    const popupVisibleChange = (val: boolean) => {
+        if (val) {
+            nextTick(() => {
+                const el = document.getElementById(
+                    'tableSetting'
+                ) as HTMLElement;
+                const sortable = new Sortable(el, {
+                    onEnd(e: any) {
+                        const { oldIndex, newIndex } = e;
+                        exchangeArray(cloneColumns.value, oldIndex, newIndex);
+                        exchangeArray(showColumns.value, oldIndex, newIndex);
+                    },
+                });
             });
-        });
-    }
-};
-
-watch(
-    () => columns.value,
-    (val) => {
-        cloneColumns.value = cloneDeep(val);
-        cloneColumns.value.forEach((item, index) => {
-            item.checked = true;
-        });
-        showColumns.value = cloneDeep(cloneColumns.value);
-    },
-    { deep: true, immediate: true }
-);
+        }
+    };
+
+    watch(
+        () => columns.value,
+        (val) => {
+            cloneColumns.value = cloneDeep(val);
+            cloneColumns.value.forEach((item, index) => {
+                item.checked = true;
+            });
+            showColumns.value = cloneDeep(cloneColumns.value);
+        },
+        { deep: true, immediate: true }
+    );
 </script>
 
 <script lang="ts">
-export default {
-    name: 'SearchTable',
-};
+    export default {
+        name: 'SearchTable',
+    };
 </script>
 
 <style scoped lang="less">
-.container {
-    padding: 0 20px 20px 20px;
-}
-
-:deep(.arco-table-th) {
-    &:last-child {
-        .arco-table-th-item-title {
-            margin-left: 16px;
+    .container {
+        padding: 0 20px 20px 20px;
+    }
+
+    :deep(.arco-table-th) {
+        &:last-child {
+            .arco-table-th-item-title {
+                margin-left: 16px;
+            }
         }
     }
-}
 
-.action-icon {
-    margin-left: 12px;
-    cursor: pointer;
-}
+    .action-icon {
+        margin-left: 12px;
+        cursor: pointer;
+    }
 
-.active {
-    color: #0960bd;
-    background-color: #e3f4fc;
-}
+    .active {
+        color: #0960bd;
+        background-color: #e3f4fc;
+    }
 
-.setting {
-    display: flex;
-    align-items: center;
-    width: 200px;
+    .setting {
+        display: flex;
+        align-items: center;
+        width: 200px;
 
-    .title {
-        margin-left: 12px;
-        cursor: pointer;
+        .title {
+            margin-left: 12px;
+            cursor: pointer;
+        }
     }
-}
 
-:deep(.special-table-row td) {
-    background-color: var(--color-warning-light-2) !important;
-}
+    :deep(.special-table-row td) {
+        background-color: var(--color-warning-light-2) !important;
+    }
 </style>