Sfoglia il codice sorgente

perf: 删除不必要的页面

曾坤森 3 mesi fa
parent
commit
69a71f16fc

+ 0 - 5
src/locale/en-US.ts

@@ -4,9 +4,6 @@ import localeLogin from '@/views/login/locale/en-US';
 import localeRecord from '@/views/dashboard/record-list/locale/en-US';
 import localeFace from '@/views/dashboard/face-list/locale/en-US';
 
-import localeSearchTable from '@/views/list/search-table/locale/en-US';
-import localeCardList from '@/views/list/card/locale/en-US';
-
 import locale403 from '@/views/exception/403/locale/en-US';
 import locale404 from '@/views/exception/404/locale/en-US';
 import locale500 from '@/views/exception/500/locale/en-US';
@@ -28,8 +25,6 @@ export default {
   ...localeLogin,
   ...localeRecord,
   ...localeFace,
-  ...localeSearchTable,
-  ...localeCardList,
   ...locale403,
   ...locale404,
   ...locale500,

+ 0 - 5
src/locale/zh-CN.ts

@@ -5,9 +5,6 @@ import localeFace from '@/views/dashboard/face-list/locale/zh-CN';
 
 import localeRecord from '@/views/dashboard/record-list/locale/zh-CN';
 
-import localeSearchTable from '@/views/list/search-table/locale/zh-CN';
-import localeCardList from '@/views/list/card/locale/zh-CN';
-
 import locale403 from '@/views/exception/403/locale/zh-CN';
 import locale404 from '@/views/exception/404/locale/zh-CN';
 import locale500 from '@/views/exception/500/locale/zh-CN';
@@ -29,8 +26,6 @@ export default {
   ...localeLogin,
   ...localeFace,
   ...localeRecord,
-  ...localeSearchTable,
-  ...localeCardList,
   ...locale403,
   ...locale404,
   ...locale500,

+ 0 - 3
src/mock/index.ts

@@ -3,9 +3,6 @@ import Mock from 'mockjs';
 import './user';
 import './message-box';
 
-import '@/views/list/card/mock';
-import '@/views/list/search-table/mock';
-
 Mock.setup({
   timeout: '600-1000',
 });

+ 0 - 38
src/router/routes/modules/list.ts

@@ -1,38 +0,0 @@
-import { DEFAULT_LAYOUT } from '../base';
-import { AppRouteRecordRaw } from '../types';
-
-const LIST: AppRouteRecordRaw = {
-  path: '/list',
-  name: 'list',
-  component: DEFAULT_LAYOUT,
-  meta: {
-    locale: 'menu.list',
-    requiresAuth: true,
-    icon: 'icon-list',
-    order: 2,
-  },
-  children: [
-    {
-      path: 'search-table', // The midline path complies with SEO specifications
-      name: 'SearchTable',
-      component: () => import('@/views/list/search-table/index.vue'),
-      meta: {
-        locale: 'menu.list.searchTable',
-        requiresAuth: true,
-        roles: ['*'],
-      },
-    },
-    {
-      path: 'card',
-      name: 'Card',
-      component: () => import('@/views/list/card/index.vue'),
-      meta: {
-        locale: 'menu.list.cardList',
-        requiresAuth: true,
-        roles: ['*'],
-      },
-    },
-  ],
-};
-
-export default LIST;

+ 0 - 218
src/views/list/card/components/card-wrap.vue

@@ -1,218 +0,0 @@
-<template>
-  <div class="card-wrap">
-    <a-card v-if="loading" :bordered="false" hoverable>
-      <slot name="skeleton"></slot>
-    </a-card>
-    <a-card v-else :bordered="false" hoverable>
-      <a-space align="start">
-        <a-avatar
-          v-if="icon"
-          :size="24"
-          style="margin-right: 8px; background-color: #626aea"
-        >
-          <icon-filter />
-        </a-avatar>
-        <a-card-meta>
-          <template #title>
-            <a-typography-text style="margin-right: 10px">
-              {{ title }}
-            </a-typography-text>
-            <template v-if="showTag">
-              <a-tag
-                v-if="open && isExpires === false"
-                size="small"
-                color="green"
-              >
-                <template #icon>
-                  <icon-check-circle-fill />
-                </template>
-                <span>{{ tagText }}</span>
-              </a-tag>
-              <a-tag v-else-if="isExpires" size="small" color="red">
-                <template #icon>
-                  <icon-check-circle-fill />
-                </template>
-                <span>{{ expiresTagText }}</span>
-              </a-tag>
-            </template>
-          </template>
-          <template #description>
-            {{ description }}
-            <slot></slot>
-          </template>
-        </a-card-meta>
-      </a-space>
-      <template #actions>
-        <a-switch v-if="actionType === 'switch'" v-model="open" />
-        <a-space v-else-if="actionType === 'button'">
-          <template v-if="isExpires">
-            <a-button type="outline" @click="renew">
-              {{ expiresText }}
-            </a-button>
-          </template>
-          <template v-else>
-            <a-button v-if="open" @click="handleToggle">
-              {{ closeTxt }}
-            </a-button>
-            <a-button v-else-if="!open" type="outline" @click="handleToggle">
-              {{ openTxt }}
-            </a-button>
-          </template>
-        </a-space>
-        <div v-else>
-          <a-space>
-            <a-button @click="handleToggle()">
-              {{ closeTxt }}
-            </a-button>
-            <a-button type="primary" @click="handleToggle()">
-              {{ openTxt }}
-            </a-button>
-          </a-space>
-        </div>
-      </template>
-    </a-card>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { ref } from 'vue';
-
-  const props = defineProps({
-    loading: {
-      type: Boolean,
-      default: false,
-    },
-    title: {
-      type: String,
-      default: '',
-    },
-    description: {
-      type: String,
-      default: '',
-    },
-    actionType: {
-      type: String,
-      default: '',
-    },
-    defaultValue: {
-      type: Boolean,
-      default: false,
-    },
-    openTxt: {
-      type: String,
-      default: '',
-    },
-    closeTxt: {
-      type: String,
-      default: '',
-    },
-    expiresText: {
-      type: String,
-      default: '',
-    },
-    icon: {
-      type: String,
-      default: '',
-    },
-    showTag: {
-      type: Boolean,
-      default: true,
-    },
-    tagText: {
-      type: String,
-      default: '',
-    },
-    expires: {
-      type: Boolean,
-      default: false,
-    },
-    expiresTagText: {
-      type: String,
-      default: '',
-    },
-  });
-  const open = ref(props.defaultValue);
-
-  const handleToggle = () => {
-    open.value = !open.value;
-  };
-
-  const isExpires = ref(props.expires);
-
-  const renew = () => {
-    isExpires.value = false;
-  };
-</script>
-
-<style scoped lang="less">
-  .card-wrap {
-    height: 100%;
-    border: 1px solid var(--color-neutral-3);
-    border-radius: 4px;
-    transition: all 0.3s;
-
-    &:hover {
-      transform: translateY(-4px);
-      // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1);
-    }
-
-    :deep(.arco-card) {
-      height: 100%;
-      border-radius: 4px;
-
-      .arco-card-body {
-        height: 100%;
-
-        .arco-space {
-          width: 100%;
-          height: 100%;
-
-          .arco-space-item {
-            height: 100%;
-
-            &:last-child {
-              flex: 1;
-            }
-
-            .arco-card-meta {
-              display: flex;
-              flex-flow: column;
-              height: 100%;
-
-              .arco-card-meta-content {
-                flex: 1;
-
-                .arco-card-meta-description {
-                  margin-top: 8px;
-                  color: rgb(var(--gray-6));
-                  font-size: 12px;
-                  line-height: 20px;
-                }
-              }
-
-              .arco-card-meta-footer {
-                margin-top: 0;
-              }
-            }
-          }
-        }
-      }
-    }
-
-    :deep(.arco-card-meta-title) {
-      display: flex;
-      align-items: center;
-
-      // To prevent the shaking
-      line-height: 28px;
-    }
-
-    :deep(.arco-skeleton-line) {
-      &:last-child {
-        display: flex;
-        justify-content: flex-end;
-        margin-top: 20px;
-      }
-    }
-  }
-</style>

+ 0 - 122
src/views/list/card/components/quality-inspection.vue

@@ -1,122 +0,0 @@
-<template>
-  <div class="list-wrap">
-    <a-typography-title class="block-title" :heading="6">
-      {{ $t('cardList.tab.title.content') }}
-    </a-typography-title>
-    <a-row class="list-row" :gutter="24">
-      <a-col
-        :xs="12"
-        :sm="12"
-        :md="12"
-        :lg="6"
-        :xl="6"
-        :xxl="6"
-        class="list-col"
-      >
-        <div class="card-wrap empty-wrap">
-          <a-card :bordered="false" hoverable>
-            <a-result :status="null" :title="$t('cardList.content.action')">
-              <template #icon>
-                <icon-plus style="font-size: 20px" />
-              </template>
-            </a-result>
-          </a-card>
-        </div>
-      </a-col>
-      <a-col
-        v-for="item in renderData"
-        :key="item.id"
-        class="list-col"
-        :xs="12"
-        :sm="12"
-        :md="12"
-        :lg="6"
-        :xl="6"
-        :xxl="6"
-      >
-        <CardWrap
-          :loading="loading"
-          :title="item.title"
-          :description="item.description"
-          :default-value="item.enable"
-          :action-type="item.actionType"
-          :icon="item.icon"
-          :open-txt="$t('cardList.content.inspection')"
-          :close-txt="$t('cardList.content.delete')"
-          :show-tag="false"
-        >
-          <a-descriptions
-            style="margin-top: 16px"
-            :data="item.data"
-            layout="inline-horizontal"
-            :column="2"
-          />
-          <template #skeleton>
-            <a-skeleton :animation="true">
-              <a-skeleton-line
-                :widths="['50%', '50%', '100%', '40%']"
-                :rows="4"
-              />
-              <a-skeleton-line :widths="['40%']" :rows="1" />
-            </a-skeleton>
-          </template>
-        </CardWrap>
-      </a-col>
-    </a-row>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { queryInspectionList, ServiceRecord } from '@/api/list';
-  import useRequest from '@/hooks/request';
-  import CardWrap from './card-wrap.vue';
-
-  const defaultValue: ServiceRecord[] = new Array(3).fill({});
-  const { loading, response: renderData } = useRequest<ServiceRecord[]>(
-    queryInspectionList,
-    defaultValue
-  );
-</script>
-
-<style scoped lang="less">
-  .card-wrap {
-    height: 100%;
-    border: 1px solid var(--color-neutral-3);
-    transition: all 0.3s;
-
-    &:hover {
-      transform: translateY(-4px);
-    }
-
-    :deep(.arco-card-meta-description) {
-      color: rgb(var(--gray-6));
-
-      .arco-descriptions-item-label-inline {
-        color: rgb(var(--gray-6));
-        font-weight: normal;
-        font-size: 12px;
-      }
-
-      .arco-descriptions-item-value-inline {
-        color: rgb(var(--gray-8));
-      }
-    }
-  }
-
-  .empty-wrap {
-    height: 200px;
-    border-radius: 4px;
-
-    :deep(.arco-card) {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      height: 100%;
-      border-radius: 4px;
-
-      .arco-result-title {
-        color: rgb(var(--gray-6));
-      }
-    }
-  }
-</style>

+ 0 - 51
src/views/list/card/components/rules-preset.vue

@@ -1,51 +0,0 @@
-<template>
-  <div class="list-wrap">
-    <a-typography-title class="block-title" :heading="6">
-      {{ $t('cardList.tab.title.preset') }}
-    </a-typography-title>
-    <a-row class="list-row" :gutter="24">
-      <a-col
-        v-for="item in renderData"
-        :key="item.id"
-        :xs="12"
-        :sm="12"
-        :md="12"
-        :lg="6"
-        :xl="6"
-        :xxl="6"
-        class="list-col"
-        style="min-height: 140px"
-      >
-        <CardWrap
-          :loading="loading"
-          :title="item.title"
-          :description="item.description"
-          :default-value="item.enable"
-          :action-type="item.actionType"
-          :tag-text="$t('cardList.preset.tag')"
-        >
-          <template #skeleton>
-            <a-skeleton :animation="true">
-              <a-skeleton-line :widths="['100%', '40%']" :rows="2" />
-              <a-skeleton-line :widths="['40%']" :rows="1" />
-            </a-skeleton>
-          </template>
-        </CardWrap>
-      </a-col>
-    </a-row>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { queryRulesPresetList, ServiceRecord } from '@/api/list';
-  import useRequest from '@/hooks/request';
-  import CardWrap from './card-wrap.vue';
-
-  const defaultValue: ServiceRecord[] = new Array(6).fill({});
-  const { loading, response: renderData } = useRequest<ServiceRecord[]>(
-    queryRulesPresetList,
-    defaultValue
-  );
-</script>
-
-<style scoped lang="less"></style>

+ 0 - 57
src/views/list/card/components/the-service.vue

@@ -1,57 +0,0 @@
-<template>
-  <div class="list-wrap">
-    <a-typography-title class="block-title" :heading="6">
-      {{ $t('cardList.tab.title.service') }}
-    </a-typography-title>
-    <a-row class="list-row" :gutter="24">
-      <a-col
-        v-for="item in renderData"
-        :key="item.id"
-        :xs="12"
-        :sm="12"
-        :md="12"
-        :lg="6"
-        :xl="6"
-        :xxl="6"
-        class="list-col"
-        style="min-height: 162px"
-      >
-        <CardWrap
-          :loading="loading"
-          :title="item.title"
-          :description="item.description"
-          :default-value="item.enable"
-          :action-type="item.actionType"
-          :expires="item.expires"
-          :open-txt="$t('cardList.service.open')"
-          :close-txt="$t('cardList.service.cancel')"
-          :expires-text="$t('cardList.service.renew')"
-          :tag-text="$t('cardList.service.tag')"
-          :expires-tag-text="$t('cardList.service.expiresTag')"
-          :icon="item.icon"
-        >
-          <template #skeleton>
-            <a-skeleton :animation="true">
-              <a-skeleton-line :widths="['100%', '40%', '100%']" :rows="3" />
-              <a-skeleton-line :widths="['40%']" :rows="1" />
-            </a-skeleton>
-          </template>
-        </CardWrap>
-      </a-col>
-    </a-row>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { queryTheServiceList, ServiceRecord } from '@/api/list';
-  import useRequest from '@/hooks/request';
-  import CardWrap from './card-wrap.vue';
-
-  const defaultValue: ServiceRecord[] = new Array(4).fill({});
-  const { loading, response: renderData } = useRequest<ServiceRecord[]>(
-    queryTheServiceList,
-    defaultValue
-  );
-</script>
-
-<style scoped lang="less"></style>

+ 0 - 97
src/views/list/card/index.vue

@@ -1,97 +0,0 @@
-<template>
-  <div class="container">
-    <Breadcrumb :items="['menu.list', 'menu.list.cardList']" />
-    <a-row :gutter="20" align="stretch">
-      <a-col :span="24">
-        <a-card class="general-card" :title="$t('menu.list.cardList')">
-          <a-row justify="space-between">
-            <a-col :span="24">
-              <a-tabs :default-active-tab="1" type="rounded">
-                <a-tab-pane key="1" :title="$t('cardList.tab.title.all')">
-                  <QualityInspection />
-                  <TheService />
-                  <RulesPreset />
-                </a-tab-pane>
-                <a-tab-pane key="2" :title="$t('cardList.tab.title.content')">
-                  <QualityInspection />
-                </a-tab-pane>
-                <a-tab-pane key="3" :title="$t('cardList.tab.title.service')">
-                  <TheService />
-                </a-tab-pane>
-                <a-tab-pane key="4" :title="$t('cardList.tab.title.preset')">
-                  <RulesPreset />
-                </a-tab-pane>
-              </a-tabs>
-            </a-col>
-            <a-input-search
-              :placeholder="$t('cardList.searchInput.placeholder')"
-              style="position: absolute; top: 60px; right: 20px; width: 240px"
-            />
-          </a-row>
-        </a-card>
-      </a-col>
-    </a-row>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import QualityInspection from './components/quality-inspection.vue';
-  import TheService from './components/the-service.vue';
-  import RulesPreset from './components/rules-preset.vue';
-</script>
-
-<script lang="ts">
-  export default {
-    name: 'Card',
-  };
-</script>
-
-<style scoped lang="less">
-  .container {
-    padding: 0 10px 20px;
-
-    :deep(.arco-list-content) {
-      overflow-x: hidden;
-    }
-
-    :deep(.arco-card-meta-title) {
-      font-size: 14px;
-    }
-  }
-
-  :deep(.arco-list-col) {
-    display: flex;
-    flex-flow: row wrap;
-    justify-content: space-between;
-  }
-
-  :deep(.arco-list-item) {
-    width: 33%;
-  }
-
-  :deep(.block-title) {
-    margin: 0 0 12px;
-    font-size: 14px;
-  }
-
-  :deep(.list-wrap) {
-    // min-height: 140px;
-    .list-row {
-      align-items: stretch;
-
-      .list-col {
-        margin-bottom: 16px;
-      }
-    }
-
-    :deep(.arco-space) {
-      width: 100%;
-
-      .arco-space-item {
-        &:last-child {
-          flex: 1;
-        }
-      }
-    }
-  }
-</style>

+ 0 - 19
src/views/list/card/locale/en-US.ts

@@ -1,19 +0,0 @@
-export default {
-  'menu.list.cardList': 'Card List',
-  'cardList.tab.title.all': 'All',
-  'cardList.tab.title.content': 'Quality Inspection',
-  'cardList.tab.title.service': 'The service',
-  'cardList.tab.title.preset': 'Rules Preset',
-  'cardList.searchInput.placeholder': 'Search',
-  'cardList.enable': 'Enable',
-  'cardList.disable': 'Disable',
-  'cardList.content.delete': 'Delete',
-  'cardList.content.inspection': 'Inspection',
-  'cardList.content.action': 'Click Create Qc Content queue',
-  'cardList.service.open': 'Open',
-  'cardList.service.cancel': 'Cancel',
-  'cardList.service.renew': 'Contract of service',
-  'cardList.service.tag': 'Opened',
-  'cardList.service.expiresTag': 'Expired',
-  'cardList.preset.tag': 'Enable',
-};

+ 0 - 19
src/views/list/card/locale/zh-CN.ts

@@ -1,19 +0,0 @@
-export default {
-  'menu.list.cardList': '卡片列表',
-  'cardList.tab.title.all': '全部',
-  'cardList.tab.title.content': '内容质检',
-  'cardList.tab.title.service': '开通服务',
-  'cardList.tab.title.preset': '规则预置',
-  'cardList.searchInput.placeholder': '搜索',
-  // 'cardList.statistic.enable': '已启用',
-  // 'cardList.statistic.disable': '未启用',
-  'cardList.content.delete': '删除',
-  'cardList.content.inspection': '质检',
-  'cardList.content.action': '点击创建质检内容队列',
-  'cardList.service.open': '开通服务',
-  'cardList.service.cancel': '取消服务',
-  'cardList.service.renew': '续约服务',
-  'cardList.service.tag': '已开通',
-  'cardList.service.expiresTag': '已过期',
-  'cardList.preset.tag': '已启用',
-};

+ 0 - 186
src/views/list/card/mock.ts

@@ -1,186 +0,0 @@
-import Mock from 'mockjs';
-import setupMock, { successResponseWrap } from '@/utils/setup-mock';
-import { ServiceRecord } from '@/api/list';
-
-const qualityInspectionList: ServiceRecord[] = [
-  {
-    id: 1,
-    name: 'quality',
-    title: '视频类-历史导入',
-    description: '2021-10-12 00:00:00',
-    data: [
-      {
-        label: '待质检数',
-        value: '120',
-      },
-      {
-        label: '积压时长',
-        value: '60s',
-      },
-      {
-        label: '待抽检数',
-        value: '0',
-      },
-    ],
-  },
-  {
-    id: 2,
-    name: 'quality',
-    title: '图文类-图片版权',
-    description: '2021-12-11 18:30:00',
-    data: [
-      {
-        label: '待质检数',
-        value: '120',
-      },
-      {
-        label: '积压时长',
-        value: '60s',
-      },
-      {
-        label: '待抽检数',
-        value: '0',
-      },
-    ],
-  },
-  {
-    id: 3,
-    name: 'quality',
-    title: '图文类-高清图片',
-    description: '2021-10-15 08:10:00',
-    data: [
-      {
-        label: '待质检数',
-        value: '120',
-      },
-      {
-        label: '积压时长',
-        value: '60s',
-      },
-      {
-        label: '待抽检数',
-        value: '0',
-      },
-    ],
-  },
-];
-const theServiceList: ServiceRecord[] = [
-  {
-    id: 1,
-    icon: 'code',
-    title: '漏斗分析',
-    description:
-      '用户行为分析之漏斗分析模型是企业实现精细化运营、进行用户行为分析的重要数据分析模型。',
-    enable: true,
-    actionType: 'button',
-  },
-  {
-    id: 2,
-    icon: 'edit',
-    title: '用户分布',
-    description:
-      '快速诊断用户人群,地域细分情况,了解数据分布的集中度,以及主要的数据分布的区间段是什么。',
-    enable: true,
-    actionType: 'button',
-    expires: true,
-  },
-  {
-    id: 3,
-    icon: 'user',
-    title: '资源分发',
-    description:
-      '移动端动态化资源分发解决方案。提供稳定大流量服务支持、灵活定制的分发圈选规则,通过离线化预加载。',
-    enable: false,
-    actionType: 'button',
-  },
-  {
-    id: 4,
-    icon: 'user',
-    title: '用户画像分析',
-    description:
-      '用户画像就是将典型用户信息标签化,根据用户特征、业务场景和用户行为等信息,构建一个标签化的用户模型。',
-    enable: true,
-    actionType: 'button',
-  },
-];
-const rulesPresetList: ServiceRecord[] = [
-  {
-    id: 1,
-    title: '内容屏蔽规则',
-    description:
-      '用户在执行特定的内容分发任务时,可使用内容屏蔽规则根据特定标签,过滤内容集合。',
-    enable: true,
-    actionType: 'switch',
-  },
-  {
-    id: 2,
-    title: '内容置顶规则',
-    description:
-      '该规则支持用户在执行特定内容分发任务时,对固定的几条内容置顶。',
-    enable: true,
-    actionType: 'switch',
-  },
-  {
-    id: 3,
-    title: '内容加权规则',
-    description: '选定内容加权规则后可自定义从不同内容集合获取内容的概率。',
-    enable: false,
-    actionType: 'switch',
-  },
-  {
-    id: 4,
-    title: '内容分发规则',
-    description: '内容分发时,对某些内容需要固定在C端展示的位置。',
-    enable: true,
-    actionType: 'switch',
-  },
-  {
-    id: 5,
-    title: '违禁内容识别',
-    description: '精准识别赌博、刀枪、毒品、造假、贩假等违规物品和违规行为。',
-    enable: false,
-    actionType: 'switch',
-  },
-  {
-    id: 6,
-    title: '多语言文字符号识别',
-    description:
-      '精准识别英语、维语、藏语、蒙古语、朝鲜语等多种语言以及emoji表情形态的语义识别。',
-    enable: false,
-    actionType: 'switch',
-  },
-];
-
-setupMock({
-  setup() {
-    // Quality Inspection
-    Mock.mock(new RegExp('/api/list/quality-inspection'), () => {
-      return successResponseWrap(
-        qualityInspectionList.map((_, index) => ({
-          ...qualityInspectionList[index % qualityInspectionList.length],
-          id: Mock.Random.guid(),
-        }))
-      );
-    });
-
-    // the service
-    Mock.mock(new RegExp('/api/list/the-service'), () => {
-      return successResponseWrap(
-        theServiceList.map((_, index) => ({
-          ...theServiceList[index % theServiceList.length],
-          id: Mock.Random.guid(),
-        }))
-      );
-    });
-
-    // rules preset
-    Mock.mock(new RegExp('/api/list/rules-preset'), () => {
-      return successResponseWrap(
-        rulesPresetList.map((_, index) => ({
-          ...rulesPresetList[index % rulesPresetList.length],
-          id: Mock.Random.guid(),
-        }))
-      );
-    });
-  },
-});

+ 0 - 519
src/views/list/search-table/index.vue

@@ -1,519 +0,0 @@
-<template>
-  <div class="container">
-    <Breadcrumb :items="['menu.list', 'menu.list.searchTable']" />
-    <a-card class="general-card" :title="$t('menu.list.searchTable')">
-      <a-row>
-        <a-col :flex="1">
-          <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="number"
-                  :label="$t('searchTable.form.number')"
-                >
-                  <a-input
-                    v-model="formModel.number"
-                    :placeholder="$t('searchTable.form.number.placeholder')"
-                  />
-                </a-form-item>
-              </a-col>
-              <a-col :span="8">
-                <a-form-item field="name" :label="$t('searchTable.form.name')">
-                  <a-input
-                    v-model="formModel.name"
-                    :placeholder="$t('searchTable.form.name.placeholder')"
-                  />
-                </a-form-item>
-              </a-col>
-              <a-col :span="8">
-                <a-form-item
-                  field="contentType"
-                  :label="$t('searchTable.form.contentType')"
-                >
-                  <a-select
-                    v-model="formModel.contentType"
-                    :options="contentTypeOptions"
-                    :placeholder="$t('searchTable.form.selectDefault')"
-                  />
-                </a-form-item>
-              </a-col>
-              <a-col :span="8">
-                <a-form-item
-                  field="filterType"
-                  :label="$t('searchTable.form.filterType')"
-                >
-                  <a-select
-                    v-model="formModel.filterType"
-                    :options="filterTypeOptions"
-                    :placeholder="$t('searchTable.form.selectDefault')"
-                  />
-                </a-form-item>
-              </a-col>
-              <a-col :span="8">
-                <a-form-item
-                  field="createdTime"
-                  :label="$t('searchTable.form.createdTime')"
-                >
-                  <a-range-picker
-                    v-model="formModel.createdTime"
-                    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>
-              </a-col>
-            </a-row>
-          </a-form>
-        </a-col>
-        <a-divider style="height: 84px" direction="vertical" />
-        <a-col :flex="'86px'" style="text-align: right">
-          <a-space direction="vertical" :size="18">
-            <a-button type="primary" @click="search">
-              <template #icon>
-                <icon-search />
-              </template>
-              {{ $t('searchTable.form.search') }}
-            </a-button>
-            <a-button @click="reset">
-              <template #icon>
-                <icon-refresh />
-              </template>
-              {{ $t('searchTable.form.reset') }}
-            </a-button>
-          </a-space>
-        </a-col>
-      </a-row>
-      <a-divider style="margin-top: 0" />
-      <a-row style="margin-bottom: 16px">
-        <a-col :span="12">
-          <a-space>
-            <a-button type="primary">
-              <template #icon>
-                <icon-plus />
-              </template>
-              {{ $t('searchTable.operation.create') }}
-            </a-button>
-            <a-upload action="/">
-              <template #upload-button>
-                <a-button>
-                  {{ $t('searchTable.operation.import') }}
-                </a-button>
-              </template>
-            </a-upload>
-          </a-space>
-        </a-col>
-        <a-col
-          :span="12"
-          style="display: flex; align-items: center; justify-content: end"
-        >
-          <a-button>
-            <template #icon>
-              <icon-download />
-            </template>
-            {{ $t('searchTable.operation.download') }}
-          </a-button>
-          <a-tooltip :content="$t('searchTable.actions.refresh')">
-            <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>
-            </a-tooltip>
-            <template #content>
-              <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>
-              <template #content>
-                <div id="tableSetting">
-                  <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>
-                    </div>
-                    <div class="title">
-                      {{ item.title === '#' ? '序列号' : item.title }}
-                    </div>
-                  </div>
-                </div>
-              </template>
-            </a-popover>
-          </a-tooltip>
-        </a-col>
-      </a-row>
-      <a-table
-        row-key="id"
-        :loading="loading"
-        :pagination="pagination"
-        :columns="(cloneColumns as TableColumnData[])"
-        :data="renderData"
-        :bordered="false"
-        :size="size"
-        @page-change="onPageChange"
-      >
-        <template #index="{ rowIndex }">
-          {{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
-        </template>
-        <template #contentType="{ record }">
-          <a-space>
-            <a-avatar
-              v-if="record.contentType === 'img'"
-              :size="16"
-              shape="square"
-            >
-              <img
-                alt="avatar"
-                src="//p3-armor.byteimg.com/tos-cn-i-49unhts6dw/581b17753093199839f2e327e726b157.svg~tplv-49unhts6dw-image.image"
-              />
-            </a-avatar>
-            <a-avatar
-              v-else-if="record.contentType === 'horizontalVideo'"
-              :size="16"
-              shape="square"
-            >
-              <img
-                alt="avatar"
-                src="//p3-armor.byteimg.com/tos-cn-i-49unhts6dw/77721e365eb2ab786c889682cbc721c1.svg~tplv-49unhts6dw-image.image"
-              />
-            </a-avatar>
-            <a-avatar v-else :size="16" shape="square">
-              <img
-                alt="avatar"
-                src="//p3-armor.byteimg.com/tos-cn-i-49unhts6dw/ea8b09190046da0ea7e070d83c5d1731.svg~tplv-49unhts6dw-image.image"
-              />
-            </a-avatar>
-            {{ $t(`searchTable.form.contentType.${record.contentType}`) }}
-          </a-space>
-        </template>
-        <template #filterType="{ record }">
-          {{ $t(`searchTable.form.filterType.${record.filterType}`) }}
-        </template>
-        <template #status="{ record }">
-          <span v-if="record.status === 'offline'" class="circle"></span>
-          <span v-else class="circle pass"></span>
-          {{ $t(`searchTable.form.status.${record.status}`) }}
-        </template>
-        <template #operations>
-          <a-button v-permission="['admin']" type="text" size="small">
-            {{ $t('searchTable.columns.operations.view') }}
-          </a-button>
-        </template>
-      </a-table>
-    </a-card>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { computed, ref, reactive, watch, nextTick } from 'vue';
-  import { useI18n } from 'vue-i18n';
-  import useLoading from '@/hooks/loading';
-  import { queryPolicyList, PolicyRecord, PolicyParams } from '@/api/list';
-  import { Pagination } from '@/types/global';
-  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';
-
-  type SizeProps = 'mini' | 'small' | 'medium' | 'large';
-  type Column = TableColumnData & { checked?: true };
-
-  const generateFormModel = () => {
-    return {
-      number: '',
-      name: '',
-      contentType: '',
-      filterType: '',
-      createdTime: [],
-      status: '',
-    };
-  };
-  const { loading, setLoading } = useLoading(true);
-  const { t } = useI18n();
-  const renderData = ref<PolicyRecord[]>([]);
-  const formModel = ref(generateFormModel());
-  const cloneColumns = ref<Column[]>([]);
-  const showColumns = ref<Column[]>([]);
-
-  const size = ref<SizeProps>('medium');
-
-  const basePagination = {
-    current: 1,
-    pageSize: 20,
-  };
-  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: t('searchTable.columns.index'),
-      dataIndex: 'index',
-      slotName: 'index',
-    },
-    {
-      title: t('searchTable.columns.number'),
-      dataIndex: 'number',
-    },
-    {
-      title: t('searchTable.columns.name'),
-      dataIndex: 'name',
-    },
-    {
-      title: t('searchTable.columns.contentType'),
-      dataIndex: 'contentType',
-      slotName: 'contentType',
-    },
-    {
-      title: t('searchTable.columns.filterType'),
-      dataIndex: 'filterType',
-    },
-    {
-      title: t('searchTable.columns.count'),
-      dataIndex: 'count',
-    },
-    {
-      title: t('searchTable.columns.createdTime'),
-      dataIndex: 'createdTime',
-    },
-    {
-      title: t('searchTable.columns.status'),
-      dataIndex: 'status',
-      slotName: 'status',
-    },
-    {
-      title: t('searchTable.columns.operations'),
-      dataIndex: 'operations',
-      slotName: 'operations',
-    },
-  ]);
-  const contentTypeOptions = computed<SelectOptionData[]>(() => [
-    {
-      label: t('searchTable.form.contentType.img'),
-      value: 'img',
-    },
-    {
-      label: t('searchTable.form.contentType.horizontalVideo'),
-      value: 'horizontalVideo',
-    },
-    {
-      label: t('searchTable.form.contentType.verticalVideo'),
-      value: 'verticalVideo',
-    },
-  ]);
-  const filterTypeOptions = computed<SelectOptionData[]>(() => [
-    {
-      label: t('searchTable.form.filterType.artificial'),
-      value: 'artificial',
-    },
-    {
-      label: t('searchTable.form.filterType.rules'),
-      value: 'rules',
-    },
-  ]);
-  const statusOptions = computed<SelectOptionData[]>(() => [
-    {
-      label: t('searchTable.form.status.online'),
-      value: 'online',
-    },
-    {
-      label: t('searchTable.form.status.offline'),
-      value: 'offline',
-    },
-  ]);
-  const fetchData = async (
-    params: PolicyParams = { current: 1, pageSize: 20 }
-  ) => {
-    setLoading(true);
-    try {
-      const { data } = await queryPolicyList(params);
-      renderData.value = data.list;
-      pagination.current = params.current;
-      pagination.pageSize = data.total;
-    } catch (err) {
-      // you can report use errorHandler or other
-    } finally {
-      setLoading(false);
-    }
-  };
-
-  const search = () => {
-    fetchData({
-      ...basePagination,
-      ...formModel.value,
-    } as unknown as PolicyParams);
-  };
-  const onPageChange = (current: number) => {
-    fetchData({ ...basePagination, current });
-  };
-
-  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 }
-  );
-</script>
-
-<script lang="ts">
-  export default {
-    name: 'SearchTable',
-  };
-</script>
-
-<style scoped lang="less">
-  .container {
-    padding: 0 10px 20px;
-  }
-
-  :deep(.arco-table-th) {
-    &:last-child {
-      .arco-table-th-item-title {
-        margin-left: 16px;
-      }
-    }
-  }
-
-  .action-icon {
-    margin-left: 12px;
-    cursor: pointer;
-  }
-
-  .active {
-    color: #0960bd;
-    background-color: #e3f4fc;
-  }
-
-  .setting {
-    display: flex;
-    align-items: center;
-    width: 200px;
-
-    .title {
-      margin-left: 12px;
-      cursor: pointer;
-    }
-  }
-</style>

+ 0 - 44
src/views/list/search-table/locale/en-US.ts

@@ -1,44 +0,0 @@
-export default {
-  'menu.list.searchTable': 'Search Table',
-  'searchTable.form.number': 'Set Number',
-  'searchTable.form.number.placeholder': 'Please enter Set Number',
-  'searchTable.form.name': 'Set Name',
-  'searchTable.form.name.placeholder': 'Please enter Set Name',
-  'searchTable.form.contentType': 'Content Type',
-  'searchTable.form.contentType.img': 'image-text',
-  'searchTable.form.contentType.horizontalVideo': 'Horizontal short video',
-  'searchTable.form.contentType.verticalVideo': 'Vertical short video',
-  'searchTable.form.filterType': 'Filter Type',
-  'searchTable.form.filterType.artificial': 'artificial',
-  'searchTable.form.filterType.rules': 'Rules',
-  'searchTable.form.createdTime': 'Create Date',
-  'searchTable.form.status': 'Status',
-  'searchTable.form.status.online': 'Online',
-  'searchTable.form.status.offline': 'Offline',
-  'searchTable.form.search': 'Search',
-  'searchTable.form.reset': 'Reset',
-  'searchTable.form.selectDefault': 'All',
-  'searchTable.operation.create': 'Create',
-  'searchTable.operation.import': 'Import',
-  'searchTable.operation.download': 'Download',
-  // columns
-  'searchTable.columns.index': '#',
-  'searchTable.columns.number': 'Set Number',
-  'searchTable.columns.name': 'Set Name',
-  'searchTable.columns.contentType': 'Content Type',
-  'searchTable.columns.filterType': 'Filter Type',
-  'searchTable.columns.count': 'Count',
-  'searchTable.columns.createdTime': 'CreatedTime',
-  'searchTable.columns.status': 'Status',
-  'searchTable.columns.operations': 'Operations',
-  'searchTable.columns.operations.view': 'View',
-  // size
-  'searchTable.size.mini': 'mini',
-  'searchTable.size.small': 'small',
-  'searchTable.size.medium': 'middle',
-  'searchTable.size.large': 'large',
-  // actions
-  'searchTable.actions.refresh': 'refresh',
-  'searchTable.actions.density': 'density',
-  'searchTable.actions.columnSetting': 'columnSetting',
-};

+ 0 - 45
src/views/list/search-table/locale/zh-CN.ts

@@ -1,45 +0,0 @@
-export default {
-  'menu.list.searchTable': '查询表格',
-  'searchTable.form.number': '集合编号',
-  'searchTable.form.number.placeholder': '请输入集合编号',
-  'searchTable.form.name': '集合名称',
-  'searchTable.form.name.placeholder': '请输入集合名称',
-  'searchTable.form.contentType': '内容体裁',
-  'searchTable.form.contentType.img': '图文',
-  'searchTable.form.contentType.horizontalVideo': '横版短视频',
-  'searchTable.form.contentType.verticalVideo': '竖版小视频',
-  'searchTable.form.filterType': '筛选方式',
-  'searchTable.form.filterType.artificial': '人工筛选',
-  'searchTable.form.filterType.rules': '规则筛选',
-  'searchTable.form.createdTime': '创建时间',
-  'searchTable.form.status': '状态',
-  'searchTable.form.status.online': '已上线',
-  'searchTable.form.status.offline': '已下线',
-  'searchTable.form.search': '查询',
-  'searchTable.form.reset': '重置',
-  'searchTable.form.selectDefault': '全部',
-  'searchTable.operation.create': '新建',
-  'searchTable.operation.import': '批量导入',
-  'searchTable.operation.download': '下载',
-  // columns
-  'searchTable.columns.index': '#',
-  'searchTable.columns.number': '集合编号',
-  'searchTable.columns.name': '集合名称',
-  'searchTable.columns.contentType': '内容体裁',
-  'searchTable.columns.filterType': '筛选方式',
-  'searchTable.columns.count': '内容量',
-  'searchTable.columns.createdTime': '创建时间',
-  'searchTable.columns.status': '状态',
-  'searchTable.columns.operations': '操作',
-  'searchTable.columns.operations.view': '查看',
-
-  // size
-  'searchTable.size.mini': '迷你',
-  'searchTable.size.small': '偏小',
-  'searchTable.size.medium': '中等',
-  'searchTable.size.large': '偏大',
-  // actions
-  'searchTable.actions.refresh': '刷新',
-  'searchTable.actions.density': '密度',
-  'searchTable.actions.columnSetting': '列设置',
-};

+ 0 - 36
src/views/list/search-table/mock.ts

@@ -1,36 +0,0 @@
-import Mock from 'mockjs';
-import qs from 'query-string';
-import setupMock, { successResponseWrap } from '@/utils/setup-mock';
-import { GetParams } from '@/types/global';
-
-const { Random } = Mock;
-
-const data = Mock.mock({
-  'list|55': [
-    {
-      'id|8': /[A-Z][a-z][-][0-9]/,
-      'number|2-3': /[0-9]/,
-      'name|4-8': /[A-Z]/,
-      'contentType|1': ['img', 'horizontalVideo', 'verticalVideo'],
-      'count|2-3': /[0-9]/,
-      'status|1': ['online', 'offline'],
-      'filterType|1': ['artificial', 'rules'],
-      'createdTime': Random.datetime(),
-    },
-  ],
-});
-
-setupMock({
-  mock: false,
-  setup() {
-    Mock.mock(new RegExp('/api/list/policy'), (params: GetParams) => {
-      const { current = 1, pageSize = 10 } = qs.parseUrl(params.url).query;
-      const p = current as number;
-      const ps = pageSize as number;
-      return successResponseWrap({
-        list: data.list.slice((p - 1) * ps, p * ps),
-        total: 55,
-      });
-    });
-  },
-});