| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 | <script lang="ts" setup>/** * @Name: createKeyword.vue * @Description: 谷歌关键词添加 * @Author: xinyan */import { deleteKeyword, getKeyword, postCreateKeyword, UpdateKeyword } from '/@/views/googleTrends/api';import { Delete, Plus } from '@element-plus/icons-vue';import { ref } from 'vue';import { VxeGridInstance } from 'vxe-table';const emit = defineEmits([ 'updateKeyword' ]);const keywordInput = ref('');const btnLoading = ref(false);const isCancel = ref(false); // 是否取消编辑const isEditing = ref(false); // 是否正在编辑const keywordList = ref([]); // 关键词列表const xGrid = ref<VxeGridInstance>();const gridOptions = reactive({  border: 'inner',  keepSource: true,  loading: false,  height: 555,  columnConfig: {    resizable: true  },  rowConfig: {    isHover: true,    height: 38,  },  editConfig: {    trigger: 'manual',    showIcon: false,    // autoFocus: true,    autoClear: false,  },  pagerConfig: {    enabled: true,    total: 20,    currentPage: 1,    pageSize: 20,    pageSizes: [10, 20, 30],  },  columns: [    { field: 'keyword', title: '关键词', editRender: { name: 'input' }, slots: { edit: 'keyword_edit' } },    { field: 'insert_time', title: '添加时间' },    { title: '操作', width: 120, slots: { default: 'operate' }, align: 'center' },  ],  data: []});const gridEvents = {  pageChange({ currentPage, pageSize }) {    if (gridOptions.pagerConfig) {      gridOptions.pagerConfig.currentPage = currentPage;      gridOptions.pagerConfig.pageSize = pageSize;    }    getList();  }};const hasActiveEditRow = (row) => {  const $grid = xGrid.value;  if ($grid) {    return $grid.isEditByRow(row);  }  return false;};function editRowEvent(row) {  isCancel.value = false;  isEditing.value = true;  const $grid = xGrid.value;  if ($grid) {    $grid.setEditRow(row);    row.original_keyword = row.keyword;  }}function handelEditClosed({ row }) {  isEditing.value = false;  if (isCancel.value)return;  if (row.original_keyword !== row.keyword){    updateKeyword(row);  }}async function getList() {  gridOptions.loading = true;  try {    const resp = await getKeyword({      page: gridOptions.pagerConfig.currentPage,      limit: gridOptions.pagerConfig.pageSize,    });    gridOptions.data = resp.data;    keywordList.value = resp.data.map(item => item.keyword);    emit('updateKeyword',keywordList.value);    gridOptions.pagerConfig.total = resp.total;    gridOptions.loading = false;  } catch (error) {    console.log(error);  }}async function handleAdd() {  const keywordsInput = keywordInput.value.trim();  if (!keywordsInput) {    return;  }  // 按行拆分关键词,并过滤掉空行  const keywords = keywordsInput.split('\n').map(keyword => keyword.trim()).filter(keyword => keyword.length > 0);  try {    btnLoading.value = true;    const resp = await postCreateKeyword({ keyword: keywords.join(',') });    if (resp.code === 2000) {      ElMessage.success('关键词添加成功');      keywordInput.value = ''; // 清空输入框      await getList();    }  } catch (error) {    ElMessage.error('添加关键词失败,请重试!'); // 提示失败消息  } finally {    btnLoading.value = false;  }}async function updateKeyword(row) {  try {    gridOptions.loading = true;    const resp = await UpdateKeyword({      id: row.id,      new_keyword: row.keyword    });    if (resp.code === 2000) {      await getList();      ElMessage.success('关键词更新成功');    }  } catch (error) {    ElMessage.error('更新关键词失败,请重试!'); // 提示失败消息  } finally {    gridOptions.loading = false;  }}function cancel(row) {  isCancel.value = true;  const $grid = xGrid.value;  if ($grid) {    $grid.clearEdit().then(() => {      $grid.revertData(row)    })  }}async function handleDelete(row) {  try {    gridOptions.loading = true;    const resp = await deleteKeyword({ keyword: row.keyword });    if (resp.code === 2000) {      ElMessage.success('关键词删除成功');      await getList();    }  } catch (error) {    ElMessage.error('删除关键词失败,请重试!'); // 提示失败消息  } finally {    gridOptions.loading = false;  }}function handleClear() {  keywordInput.value = '';}const cellStyle = () => {  return {    fontSize: '13px',    fontWeight: '500',  };};const headerCellStyle = () => {  return {    fontSize: '13px',    backgroundColor: '#f0f1f3',    height: 10,  };};onMounted(() => {  getList();});</script><template>  <el-card class="mx-2 my-5">    <div class="my-4 mx-1.5" style="font-size: 18px;font-weight: bold;color: #464646">谷歌关键词添加</div>    <div class="mx-2">      <el-row :gutter="20">        <el-col :span="8" class="input-section">          <div class="input-container">            <el-input                v-model="keywordInput"                :rows="26"                class="textarea"                placeholder="添加谷歌趋势关键词,一行一个关键词......(关键词添加上限200个)"                type="textarea"            />            <!-- 按钮组 -->            <div class="button-group">              <el-popconfirm                :icon="InfoFilled"                icon-color="#626AEF"                title="确认清空关键词?"                width="220"                @confirm="handleClear"            >              <template #reference>                <el-button :icon="Delete" bg size="small" text type="danger">清空</el-button>              </template>            </el-popconfirm>              <el-button :icon="Plus" :loading="btnLoading" bg size="small" text type="primary" @click="handleAdd">添加              </el-button>            </div>          </div>        </el-col>        <el-col :span="16">          <el-card body-style="padding: 0" shadow="never">            <vxe-grid ref="xGrid" :cell-style="cellStyle" :header-cell-style="headerCellStyle" show-overflow                      v-bind="gridOptions" v-on="gridEvents" @edit-closed="handelEditClosed">              <template #operate="{ row }">                <template v-if="hasActiveEditRow(row)">                  <el-button link size="small" @click="cancel(row)">取消</el-button>                  <el-button link size="small" type="warning" @click="updateKeyword(row)">保存</el-button>                </template>                <template v-else>                  <el-button link size="small" type="primary" @click="editRowEvent(row)">编辑</el-button>                  <el-popconfirm                      :icon="InfoFilled"                      icon-color="#626AEF"                      title="确认删除关键词?"                      width="220"                      @confirm="handleDelete(row)"                  >                    <template #reference>                      <el-button :disabled="isEditing" link size="small" type="danger">删除</el-button>                    </template>                  </el-popconfirm>                </template>              </template>              <template #keyword_edit="{ row }">                <el-input v-model="row.keyword"/>              </template>            </vxe-grid>          </el-card>        </el-col>      </el-row>    </div>  </el-card></template><style scoped>.input-container {  position: relative;}.textarea {  width: 100%;  padding-bottom: 40px; /* 为按钮腾出空间 */}.button-group {  position: absolute;  bottom: 50px;  right: 10px;  /* display: flex; */  /* gap: 5px; */}</style>
 |