The model outputs a lot of meaningless 666666 endings.

#14
by tom123888777 - opened

Hi

I’ve recently been testing the chat model using Qwen2-72B-instruct. In some specific cases, after outputting a segment of normal content, it ends up outputting a large amount of meaningless “66666” content.

I ran the model with newest llama.cpp and followed the manual with the -fa parameter, tried all the Qwen/Qwen2-72B-Instruct-GGUF files from Q4 to Q8.

The current feeling for me is that Qwen/Qwen2-72B-Instruct may output a lot of meaningless 666 endings when the context is too long, but the strange thing is that I use this badcase to hugging face Qwen2-72B-Instruct playground without the same problem? I guess this might be an issue caused by the model being incompatible with llama.cpp?

Here's my badcase curl:


curl -L 'http://$IP:$PORT/completions' \
-H 'accept: application/jsonstream' \
-H 'Content-Type: application/json' \
--data-raw '{
    "n_predict": 1920,
    "temperature": 0.1,
    "presence_penalty": 0.0,
    "system_prompt": "You are a helpful assistant.",
    "prompt": "```<template>\n\n  <div\n\n    class=\\\"ns-senior-table\\\"\n\n    :class=\\\"[\n\n      {\n\n        [customClass]: customClass\n\n      }\n\n    ]\\\"\n\n  >\n\n    <div class=\\\"ns-senior-table__toolbox\\\">\n\n      <div class=\\\"toolbox__top\\\">\n\n        <div class=\\\"toolbox__left\\\">\n\n          <div class=\\\"content\\\">\n\n            <slot name=\\\"header-prepend\\\" />\n\n            <div class=\\\"search\\\">\n\n              <el-input\n\n                v-if=\\\"useSearch\\\"\n\n                ref=\\\"searchInput\\\"\n\n                v-model.trim=\\\"keywords\\\"\n\n                :placeholder=\\\"searchText\\\"\n\n                :suffix-icon=\\\"Search\\\"\n\n                clearable\n\n                v-bind=\\\"filterInputProps\\\"\n\n                

@input

	=\\\"(...args) => handleInputEvent('\''input'\'', ...args)\\\"\n\n                

@change

	=\\\"(...args) => handleInputEvent('\''change'\'', ...args)\\\"\n\n                

@focus

	=\\\"(...args) => handleInputEvent('\''focus'\'', ...args)\\\"\n\n                

@clear

	=\\\"handleClear\\\"\n\n              >\n\n                <!-- <template #append>\n\n                    <el-button @click=\\\"handleShowSeniorSearch\\\" >高级查询</el-button>\n\n                  </template> -->\n\n              </el-input>\n\n            </div>\n\n          </div>\n\n          <slot name=\\\"header-append\\\" />\n\n        </div>\n\n        <div class=\\\"toolbox__right\\\">\n\n          <slot name=\\\"toolbox-prepend\\\" />\n\n          <el-tooltip v-if=\\\"useRefresh\\\" effect=\\\"dark\\\" content=\\\"刷新\\\" placement=\\\"top\\\">\n\n            <div class=\\\"operation\\\" @click=\\\"handleRefresh\\\">\n\n              <el-icon>\n\n                <Refresh />\n\n              </el-icon>\n\n            </div>\n\n          </el-tooltip>\n\n\n\n          <el-tooltip v-if=\\\"useExport\\\" effect=\\\"dark\\\" content=\\\"导出表格\\\" placement=\\\"top\\\">\n\n            <div class=\\\"operation\\\" @click=\\\"exportExcelFile\\\">\n\n              <el-icon>\n\n                <Download />\n\n              </el-icon>\n\n            </div>\n\n          </el-tooltip>\n\n\n\n          <el-tooltip v-if=\\\"useCustomColumn\\\" effect=\\\"dark\\\" content=\\\"自定义列\\\" placement=\\\"top\\\">\n\n            <div ref=\\\"customColumnsTriggerRef\\\" class=\\\"operation\\\" @click=\\\"handleOpenCustomColumns\\\">\n\n              <el-icon>\n\n                <Grid />\n\n              </el-icon>\n\n            </div>\n\n          </el-tooltip>\n\n\n\n          <el-popover\n\n            placement=\\\"bottom\\\"\n\n            title=\\\"自定义列\\\"\n\n            :width=\\\"180\\\"\n\n            trigger=\\\"click\\\"\n\n            virtual-triggering\n\n            :virtual-ref=\\\"customColumnsTriggerRef\\\"\n\n            :disabled=\\\"!useCustomColumn\\\"\n\n          >\n\n            <div class=\\\"custom-columns\\\">\n\n              <el-checkbox\n\n                v-model=\\\"customColumnsAll\\\"\n\n                label=\\\"all\\\"\n\n                value=\\\"all\\\"\n\n                :indeterminate=\\\"notCompleteCheckAll\\\"\n\n                

@change

	=\\\"checkAllColumns\\\"\n\n                >显示全部</el-checkbox\n\n              >\n\n              <el-checkbox-group v-model=\\\"customColumnsValues\\\" 

@change

	=\\\"handleCheckColumn\\\">\n\n                <ul>\n\n                  <li v-for=\\\"(col, i) in customShowColumns\\\" :key=\\\"i\\\">\n\n                    <el-checkbox :label=\\\"col.props.prop\\\" :value=\\\"col.props.prop\\\" :title=\\\"col.props.label\\\">\n\n                      {{ col.props.label }}\n\n                    </el-checkbox>\n\n                  </li>\n\n                </ul>\n\n              </el-checkbox-group>\n\n            </div>\n\n          </el-popover>\n\n          <slot name=\\\"toolbox-append\\\" />\n\n        </div>\n\n      </div>\n\n      <div class=\\\"toolbox__bottom\\\">\n\n        <slot name=\\\"header-bottom\\\" />\n\n        <slot name=\\\"advance-query\\\">\n\n          <NsLogicalQuery v-if=\\\"logicalQueryVisible\\\" class=\\\"mb-[10px]\\\" :fields=\\\"logicalFields\\\" />\n\n        </slot>\n\n        <ul v-if=\\\"filters.length\\\" class=\\\"filter-tags\\\">\n\n          <li v-for=\\\"(filter, i) in filters\\\" :key=\\\"i\\\">\n\n            <span class=\\\"filter-tag__label\\\">{{ filter.label }}</span>\n\n            <span class=\\\"filter-tag__value\\\">\n\n              {{ filterMethods[filter.type].getShowValue(filter.value, filter.config.valueFormat) }}\n\n            </span>\n\n            <el-icon class=\\\"filter-tag__close\\\" @click=\\\"filterMethods[filter.type].removeFilter(filter.key)\\\">\n\n              <Close />\n\n            </el-icon>\n\n          </li>\n\n          <li v-if=\\\"filters?.length\\\" class=\\\"clear-filter-btn\\\" @click=\\\"handleClearFilters\\\">清除</li>\n\n        </ul>\n\n      </div>\n\n    </div>\n\n\n\n    <el-card\n\n      v-loading=\\\"isLoading\\\"\n\n      class=\\\"table-card ns-senior-table__body\\\"\n\n      :element-loading-text=\\\"loadingText\\\"\n\n      :element-loading-spinner=\\\"LoadingIcon\\\"\n\n      element-loading-svg-view-box=\\\"0, 0, 32, 32\\\"\n\n    >\n\n      <div class=\\\"ns-senior-table__body\\\">\n\n        <el-table\n\n          id=\\\"tableId\\\"\n\n          ref=\\\"tableRef\\\"\n\n          class=\\\"table-body\\\"\n\n          :class=\\\"[\n\n            {\n\n              [elTableClass]: elTableClass\n\n            }\n\n          ]\\\"\n\n          :data=\\\"paginData\\\"\n\n          :empty-text=\\\"emptyText\\\"\n\n          :show-overflow-tooltip=\\\"showOverflowTooltip\\\"\n\n          :tooltip-options=\\\"tooltipOptions\\\"\n\n          :height=\\\"tableHeight\\\"\n\n          @sort-change=\\\"handleSortChange\\\"\n\n          @selection-change=\\\"handleSelectionChange\\\"\n\n          @row-click=\\\"handleRowClick\\\"\n\n        >\n\n          <el-table-column v-if=\\\"$slots.expand\\\" type=\\\"expand\\\">\n\n            <template #default=\\\"args\\\">\n\n              <slot name=\\\"expand\\\" :row=\\\"args.row\\\" />\n\n            </template>\n\n          </el-table-column>\n\n          <el-table-column v-if=\\\"selectMode === '\''multiple'\''\\\" type=\\\"selection\\\" :width=\\\"selectionWidth\\\" fixed=\\\"left\\\" />\n\n          <slot name=\\\"columns\\\">\n\n            <template v-for=\\\"(col, i) in tableColumns\\\" :key=\\\"i\\\">\n\n              <el-table-column v-bind=\\\"col.props\\\">\n\n                <template #header=\\\"scope\\\">\n\n                  <div class=\\\"ns-senior-table__cell\\\" @click.stop>\n\n                    <VNode v-if=\\\"col.headerRender\\\" :content=\\\"col.headerRender\\\" :params=\\\"[scope]\\\" />\n\n                    <div v-else class=\\\"cell-content\\\">\n\n                      {{ scope.column.label }}\n\n                    </div>\n\n                    <template v-if=\\\"col.filter\\\">\n\n                      <el-popover placement=\\\"bottom\\\" :width=\\\"col.filter.layout?.width ?? 200\\\" trigger=\\\"click\\\">\n\n                        <template v-if=\\\"col.filter.type === '\''input'\''\\\">\n\n                          <el-input\n\n                            v-model.trim=\\\"filterState[col.props.prop].value\\\"\n\n                            v-bind=\\\"col.filter.props\\\"\n\n                            

@input

	=\\\"(value) => handleFilterValueChange(col, value)\\\"\n\n                          />\n\n                        </template>\n\n                        <template v-if=\\\"col.filter.type === '\''checkbox'\''\\\">\n\n                          <el-checkbox-group\n\n                            v-model=\\\"filterState[col.props.prop].value\\\"\n\n                            

@change

	=\\\"(value) => handleFilterValueChange(col, value)\\\"\n\n                          >\n\n                            <ul>\n\n                              <li v-for=\\\"(option, j) in col.filter.options ?? []\\\" :key=\\\"j\\\">\n\n                                <el-checkbox\n\n                                  :label=\\\"option.value\\\"\n\n                                  :value=\\\"option.value\\\"\n\n                                  :disabled=\\\"!!option.disabled\\\"\n\n                                  >{{ option.label }}</el-checkbox\n\n                                >\n\n                              </li>\n\n                            </ul>\n\n                          </el-checkbox-group>\n\n                        </template>\n\n                        <template #reference>\n\n                          <div\n\n                            class=\\\"filter-arrow\\\"\n\n                            :class=\\\"[\n\n                              {\n\n                                '\''is-active'\'': filterMethods[filterState[col.props.prop].type].isActive(\n\n                                  filterState[col.props.prop].value\n\n                                )\n\n                              }\n\n                            ]\\\"\n\n                          >\n\n                            <el-icon><Filter /></el-icon>\n\n                          </div>\n\n                        </template>\n\n                      </el-popover>\n\n                    </template>\n\n                  </div>\n\n                </template>\n\n                <template #default=\\\"scope\\\">\n\n                  <VNode v-if=\\\"col.render\\\" :content=\\\"col.render\\\" :params=\\\"[scope]\\\" />\n\n                  <NsTableOperations\n\n                    v-else-if=\\\"col.props.prop === '\''opt'\''\\\"\n\n                    :operations=\\\"col.moreOperations?.operations ?? col.moreOperations(scope.row)\\\"\n\n                    :data=\\\"scope.row\\\"\n\n                    

@action

	=\\\"(value) => handleAction(value, scope.row)\\\"\n\n                  />\n\n                  <span v-else class=\\\"ns-senior-table__text\\\">\n\n                    {{ _.get(scope.row, col.props.prop) }}\n\n                  </span>\n\n                </template>\n\n                <template #empty>\n\n                  <slot name=\\\"empty\\\">\n\n                    <div class=\\\"ns-senior-table__empty\\\">\n\n                      <div class=\\\"message\\\">{{ emptyText }}</div>\n\n                    </div>\n\n                  </slot>\n\n                </template>\n\n              </el-table-column>\n\n            </template>\n\n          </slot>\n\n        </el-table>\n\n      </div>\n\n      <div ref=\\\"tableFooterRef\\\" class=\\\"ns-senior-table__footer\\\">\n\n        <el-pagination\n\n          v-model:current-page=\\\"paginIndex\\\"\n\n          v-model:page-size=\\\"pageSize\\\"\n\n          :page-sizes=\\\"sizeList\\\"\n\n          :background=\\\"false\\\"\n\n          small\n\n          :layout=\\\"plugins\\\"\n\n          :total=\\\"total\\\"\n\n          @current-change=\\\"handleCurrentPageChange\\\"\n\n          @size-change=\\\"sizeChange\\\"\n\n        />\n\n      </div>\n\n    </el-card>\n\n  </div>\n\n</template>\n\n\n\n<script setup>\n\nimport { computed, onMounted, ref, watch } from '\''vue'\''\n\nimport { Filter, Download, Grid, Refresh, Search, Close } from '\''@element-plus/icons-vue'\''\n\nimport { useDebounceFn, useElementBounding } from '\''@vueuse/core'\''\n\nimport _ from '\''lodash'\''\n\nimport VNode from '\''../vnode'\''\n\nimport {\n\n  COMPONENT_NAME,\n\n  LoadingIcon,\n\n  TableConfig,\n\n  seniorTableEmits,\n\n  seniorTableProps,\n\n  useFilter,\n\n  usePagination\n\n} from '\''./__var__'\''\n\nimport { exportExcel } from '\''@/hooks'\''\n\nimport NsTableOperations from '\''@/components/common/table-operations.vue'\''\n\nimport NsLogicalQuery from '\''@/components/common/logical-query/logical-query.vue'\''\n\n\n\ndefineOptions({\n\n  name: COMPONENT_NAME\n\n})\n\n\n\n// const tableInstance = getCurrentInstance()\n\nconst tableRef = ref()\n\nconst tableFooterRef = ref()\n\nconst props = defineProps(seniorTableProps)\n\nconst emit = defineEmits(seniorTableEmits)\n\n\n\nconst sortInfo = ref({})\n\nconst handleSortChange = (info) => {\n\n  sortInfo.value = info\n\n}\n\n\n\nconst userData = computed(() => {\n\n  const { column, order, prop } = sortInfo.value\n\n  const sortMethod = _.get(column, '\''sortMethod'\'', null)\n\n  const fn = sortMethod ? sortMethod : (a, b) => (JSON.stringify(a[prop]) > JSON.stringify(b[prop]) ? 1 : -1)\n\n  const xs = _.cloneDeep(props.data)\n\n  if (order === '\''ascending'\'') {\n\n    xs.sort(fn)\n\n  } else if (order === '\''descending'\'') {\n\n    xs.sort((a, b) => -fn(a, b))\n\n  }\n\n  return xs\n\n})\n\nconst exceptColKeys = ['\''render'\'', '\''moreOperations'\'', '\''filter'\'']\n\n\n\nconst filterState = ref({})\n\nconst initFilterState = () => (filterState.value = {})\n\nconst handleClearFilters = () => {\n\n  initFilterState()\n\n  handleFilter()\n\n}\n\nconst filterMethods = {\n\n  string: {\n\n    isActive: (value) => !!value,\n\n    getShowValue: (value, format) => {\n\n      return _.isFunction(format) ? format(value) : value\n\n    },\n\n    removeFilter: (prop) => {\n\n      filterState.value[prop].value = '\'''\''\n\n      handleFilter()\n\n    }\n\n  },\n\n  array: {\n\n    isActive: (value) => !!value?.length,\n\n    getShowValue: (values, format) => {\n\n      const _values = values.map((val) => (_.isFunction(format) ? format(val) : val))\n\n      return _values.join('\'', '\'')\n\n    },\n\n    removeFilter: (prop) => {\n\n      filterState.value[prop].value = []\n\n      handleFilter()\n\n    }\n\n  }\n\n}\n\nconst activatedFilters = computed(() => {\n\n  return Object.keys(filterState.value).filter((key) => {\n\n    return filterMethods[filterState.value[key].type].isActive(filterState.value[key].value)\n\n  })\n\n})\n\nconst filters = computed(() => {\n\n  return activatedFilters.value.map((key) => {\n\n    return {\n\n      key,\n\n      ...filterState.value[key]\n\n    }\n\n  })\n\n})\n\nconst filterConditions = computed(() => {\n\n  return filters.value.reduce((conditions, current) => {\n\n    conditions[current.key] = current.value\n\n    return conditions\n\n  }, {})\n\n})\n\nwatch(\n\n  () => filterConditions.value,\n\n  (value) => {\n\n    setConditions(value)\n\n  }\n\n)\n\nconst initFilterFunc = {\n\n  input: (colConf) => {\n\n    const { filter, prop, label } = colConf\n\n    const { defaultValue } = filter\n\n    filterState.value[prop] = {\n\n      type: '\''string'\'',\n\n      value: defaultValue ?? '\'''\'',\n\n      label: label ?? prop,\n\n      config: filter\n\n    }\n\n  },\n\n  checkbox: (colConf) => {\n\n    const { filter, prop, label } = colConf\n\n    const { defaultValue } = filter\n\n    filterState.value[prop] = {\n\n      type: '\''array'\'',\n\n      value: _.isArray(defaultValue) ? defaultValue : [],\n\n      label: label ?? prop,\n\n      config: filter\n\n    }\n\n  }\n\n}\n\nconst userColumnsMappings = ref({})\n\nconst filterReturn = useFilter(userData, {\n\n  strategy: '\''debounce'\'',\n\n  props,\n\n  userColumnsMappings,\n\n  userFilterMethod: props.filterMethod\n\n})\n\nconst { keywords, data: filteredData, handleFilter, setConditions } = filterReturn\n\n\n\nconst handleFilterValueChange = useDebounceFn((col, value) => {\n\n  const colName = col.props.prop\n\n  filterState.value[colName].value = value\n\n  handleFilter()\n\n})\n\n\n\nconst userColumns = computed(() => {\n\n  const columns = props.columns ?? []\n\n  return columns.map((col) => {\n\n    const enableBindingProps = _.pickBy(col, (v, k) => !exceptColKeys.includes(k))\n\n    const columnNode = {\n\n      props: enableBindingProps\n\n    }\n\n    if (col.filter) {\n\n      initFilterFunc[col.filter.type]?.(col)\n\n      columnNode.filter = col.filter\n\n    }\n\n    if (col.render) columnNode.render = col.render\n\n    if (col.headerRender) columnNode.headerRender = col.headerRender\n\n    if (col.prop === '\''opt'\'') {\n\n      let operations = []\n\n      if (_.isFunction(col.moreOperations.getter)) {\n\n        operations = col.moreOperations.getter\n\n      } else if (_.isArray(col.moreOperations?.operations)) {\n\n        operations = col.moreOperations\n\n      }\n\n      columnNode.moreOperations = operations\n\n    }\n\n    if (['\''datetime'\'', '\''date'\'', '\''time'\''].includes(col.type)) {\n\n      const dtConfig = TableConfig.fields[col.type]\n\n      columnNode.props.width = dtConfig.width\n\n      columnNode.props.maxWidth = dtConfig.width\n\n    }\n\n    if (col.sortable) {\n\n      columnNode.sortable = '\''custom'\''\n\n    }\n\n    userColumnsMappings.value[col.prop] = columnNode\n\n    return columnNode\n\n  })\n\n})\n\n\n\nconst logicalFields = computed(() =>\n\n  props.columns?.map((column) => ({\n\n    key: column.prop,\n\n    label: column.label ?? column.prop\n\n  }))\n\n)\n\n\n\nconst handleInputEvent = useDebounceFn((name, ...args) => {\n\n  if (['\''input'\'', '\''change'\''].includes(props.filterTrigger) && (props.filterTrigger === name || name === '\''blur'\'')) {\n\n    if (_.isFunction(props.filterMethod)) {\n\n      props.filterMethod?.(keywords.value)\n\n    } else {\n\n      handleFilter?.(...args)\n\n    }\n\n  }\n\n  if (name === '\''clear'\'') handleFilter?.(...args)\n\n  emit(`search-${name}`, keywords.value, ...args)\n\n})\n\nconst handleClear = () => handleFilter()\n\n\n\nconst pagination = usePagination(filteredData, props)\n\nconst { index: paginIndex, data: paginData, pageSize, sizeList, plugins, total, handleSizeChange } = pagination\n\n\n\nconst handleCurrentPageChange = (...args) => {\n\n  emit('\''page-change'\'', ...args)\n\n}\n\n\n\nconst sizeChange = (...args) => {\n\n  handleSizeChange(...args)\n\n  emit('\''page-size-change'\'', ...args)\n\n}\n\n\n\nwatch(\n\n  userData,\n\n  (newUserData) => {\n\n    if (newUserData?.length) {\n\n      initFilterState()\n\n    }\n\n  },\n\n  {\n\n    immediate: true\n\n  }\n\n)\n\n\n\n// Loading\n\nconst isLoading = computed(() => props.loading)\n\n\n\n// Check rows\n\nconst toggleAllSelection = (isChecked) => {\n\n  if (isChecked) {\n\n    tableRef.value?.toggleAllSelection(isChecked)\n\n  } else {\n\n    tableRef.value?.clearSelection()\n\n  }\n\n}\n\n\n\nconst getSelections = () => {\n\n  return tableRef.value?.getSelectionRows()\n\n}\n\n\n\nconst handleSelectionChange = (...args) => {\n\n  emit('\''selection-change'\'', ...args)\n\n}\n\n\n\nconst logicalQueryVisible = ref(false)\n\n// const handleShowSeniorSearch = () => {\n\n//   logicalQueryVisible.value = !logicalQueryVisible.value\n\n// }\n\n\n\n// Table functions\n\nconst handleRefresh = () => {\n\n  emit('\''refresh'\'')\n\n}\n\n\n\nconst exportData = computed(() => {\n\n  const selections = getSelections()\n\n  if (selections?.length) return selections\n\n  return filteredData.value\n\n})\n\n\n\nconst exportColumns = computed(() => {\n\n  if (props.exportColumn === '\''visible'\'') return tableColumns.value\n\n  return userColumns.value\n\n})\n\n\n\nconst exportExcelFile = () => {\n\n  if (_.isFunction(props.exportMethod)) {\n\n    props.exportMethod?.()\n\n    return\n\n  }\n\n\n\n  // :export-filename=\\\"exportFilename\\\"\n\n  const exportParams = [\n\n    exportData.value,\n\n    exportColumns.value,\n\n    `${props.exportFilename ? `${props.exportFilename}` : '\'''\''}${Date.now()}`\n\n  ]\n\n  if (props.beforeExport && _.isFunction(props.beforeExport)) {\n\n    const result = props.beforeExport(...exportParams)\n\n    if (!result) return\n\n    if (result.then) {\n\n      result.then((userParams) => {\n\n        emit('\''export'\'')\n\n        exportExcel(...userParams)\n\n        emit('\''after-export'\'')\n\n      })\n\n      return\n\n    }\n\n  }\n\n  emit('\''export'\'')\n\n  exportExcel(...exportParams)\n\n  emit('\''after-export'\'')\n\n}\n\n\n\n// Custom columns\n\nconst customColumnsTriggerRef = ref()\n\nconst customColumnsVisible = ref(false)\n\nconst handleOpenCustomColumns = () => {\n\n  customColumnsVisible.value = !customColumnsVisible.value\n\n}\n\nconst customColumnsConfig = computed(() => props.customColumnsConfig)\n\n\n\n// 可以通过”自定义列“功能控制的列\n\nconst customShowColumns = computed(() => {\n\n  const excludes = customColumnsConfig.value.excludes ?? []\n\n  const showColumns = customColumnsConfig.value.showColumns\n\n  if (_.isArray(showColumns)) return showColumns\n\n  return userColumns.value.filter((col) => {\n\n    return !excludes.includes(col.props.prop)\n\n  })\n\n})\n\n\n\nconst customColumnsAll = ref(false)\n\nconst customColumnsValues = ref([])\n\nconst notCompleteCheckAll = computed(() => {\n\n  const checkedLength = customColumnsValues.value.length\n\n  return checkedLength !== 0 && checkedLength !== customShowColumns.value.length\n\n})\n\nconst checkAllColumns = (isCheckAll) => {\n\n  customColumnsValues.value = isCheckAll ? customShowColumns.value.map((col) => col.props.prop) : []\n\n  emit('\''custom-columns-change'\'', customColumnsValues.value)\n\n}\n\nconst handleCheckColumn = (columnProps) => {\n\n  customColumnsValues.value = columnProps\n\n  customColumnsAll.value = columnProps.length === customShowColumns.value.length\n\n  emit('\''custom-columns-change'\'', customColumnsValues.value)\n\n}\n\nconst handleAction = (...args) => emit('\''operate'\'', ...args)\n\n\n\nconst tableColumns = computed(() => {\n\n  const excludes = customColumnsConfig.value.excludes ?? []\n\n  return props.useCustomColumn\n\n    ? userColumns.value.filter((col) => {\n\n        return customColumnsValues.value.includes(col.props.prop) || excludes.includes(col.props.prop)\n\n      })\n\n    : userColumns.value\n\n})\n\nconst columnsProps = computed(() => {\n\n  return userColumns.value.map((col) => col.props.prop)\n\n})\n\n\n\nif (props.useCustomColumn) {\n\n  watch(\n\n    () => {\n\n      const config = customColumnsConfig.value\n\n      if (_.isArray(config?.defaultChecked)) {\n\n        return config.defaultChecked\n\n      }\n\n      if (_.isArray(config?.defaultChecked?.value)) {\n\n        return config.defaultChecked.value\n\n      }\n\n    },\n\n    (value) => {\n\n      if (!value?.length) {\n\n        handleCheckColumn(columnsProps.value)\n\n        return\n\n      }\n\n      handleCheckColumn(value ?? [])\n\n    },\n\n    {\n\n      immediate: true\n\n    }\n\n  )\n\n}\n\n\n\n// table events\n\nconst handleRowClick = (...args) => {\n\n  emit('\''row-click'\'', ...args)\n\n}\n\n\n\n// 检测页面高度\n\nconst tableBounding = ref()\n\nconst tableHeight = ref('\''100%'\'')\n\nconst bindingTest = () => {\n\n  tableBounding.value = useElementBounding(tableRef.value.$el)\n\n}\n\nconst tableBundingWatcher = useDebounceFn((tableTop) => {\n\n  const { height } = useElementBounding(tableFooterRef.value)\n\n  tableHeight.value = `calc(100vh - ${height.value + 24}px - ${tableTop}px)`\n\n})\n\nwatch(() => tableBounding.value?.top, tableBundingWatcher, { immediate: true })\n\n\n\n// Vue mounts\n\n\n\nonMounted(() => {\n\n  if (props.fixed) bindingTest()\n\n})\n\n\n\ndefineExpose({\n\n  getSelections,\n\n  toggleAllSelection\n\n})\n\n</script>\n\n\n\n<style lang=\\\"less\\\">\n\n@table: ns-senior-table;\n\n\n\n.@{table} {\n\n  --st-search-input-width: 300px;\n\n  .el-table__header-wrapper {\n\n    position: sticky;\n\n    top: 0;\n\n    z-index: 3;\n\n  }\n\n  &__toolbox {\n\n    display: flex;\n\n    flex-direction: column;\n\n    align-items: flex-start;\n\n    border-top: solid 1px transparent;\n\n    border-bottom: solid 1px transparent;\n\n    transition: var(--el-transition-all);\n\n    padding-right: 20px;\n\n    .toolbox__top {\n\n      display: flex;\n\n      width: 100%;\n\n      margin-bottom: 10px;\n\n      & > .toolbox__left,\n\n      & > .toolbox__right {\n\n        display: flex;\n\n        align-items: flex-start;\n\n        flex: 1;\n\n      }\n\n      & > .toolbox__left {\n\n        .content {\n\n          display: flex;\n\n          padding: 0;\n\n          .search {\n\n            .el-input {\n\n              width: var(--st-search-input-width);\n\n            }\n\n          }\n\n        }\n\n      }\n\n      & > .toolbox__right {\n\n        display: flex;\n\n        justify-content: flex-end;\n\n        align-items: center;\n\n        .operation {\n\n          font-size: 16px;\n\n          cursor: pointer;\n\n          &:not(&:first-child) {\n\n            margin-left: var(--n-small-space);\n\n          }\n\n        }\n\n      }\n\n    }\n\n    .toolbox__bottom {\n\n      .filter-tags {\n\n        display: flex;\n\n        margin-bottom: 10px;\n\n        li {\n\n          display: inline-flex;\n\n          align-items: center;\n\n          margin-right: 10px;\n\n          border: solid 1px var(--el-color-primary);\n\n          border-radius: var(--el-border-radius-round);\n\n          padding-left: 10px;\n\n          font-size: var(--el-font-size-base);\n\n          &.clear-filter-btn {\n\n            padding: 0 5px;\n\n            cursor: pointer;\n\n            border: none;\n\n            &:hover {\n\n              color: var(--el-color-danger);\n\n            }\n\n          }\n\n          .filter-tag__label {\n\n            color: var(--el-text-color-secondary);\n\n            margin-right: 4px;\n\n          }\n\n          .filter-tag__value {\n\n            color: var(--el-color-primary);\n\n          }\n\n          .filter-tag__close {\n\n            margin: 0 4px;\n\n            cursor: pointer;\n\n            transition: var(--el-transition-all);\n\n            &:hover {\n\n              color: var(--el-color-primary);\n\n            }\n\n          }\n\n        }\n\n      }\n\n    }\n\n    &.is-fixed {\n\n      background-color: #f3f4f7;\n\n      border-color: #f3f4f7;\n\n      margin-left: -20px;\n\n      margin-right: -20px;\n\n      padding: 20px 40px 20px 20px;\n\n    }\n\n  }\n\n  &__body {\n\n    border-top: solid 1px transparent;\n\n    transition: var(--el-transition-all);\n\n    &.is-fixed {\n\n      background-color: #f3f4f7;\n\n      border-color: #f3f4f7;\n\n      margin-left: -20px;\n\n      margin-right: -20px;\n\n      margin-top: 20px;\n\n      padding: 0 20px;\n\n    }\n\n  }\n\n  &__footer {\n\n    display: flex;\n\n    justify-content: flex-end;\n\n    height: 50px;\n\n    padding-right: var(--n-large-space);\n\n    z-index: 3;\n\n    background-color: white;\n\n    border-top: solid 1px #eee;\n\n    border-bottom: solid 1px #eee;\n\n    transition: var(--el-transition-all);\n\n    &.is-fixed {\n\n      background-color: white;\n\n      border-color: #eee;\n\n      margin-left: -20px;\n\n      margin-right: -20px;\n\n      padding: 0 40px;\n\n    }\n\n  }\n\n  &__empty {\n\n    display: flex;\n\n    justify-content: center;\n\n    align-items: center;\n\n    flex-direction: column;\n\n    line-height: normal;\n\n    height: 80px;\n\n    color: var(--el-color-primary);\n\n    .icon {\n\n      margin-bottom: 4px;\n\n    }\n\n  }\n\n  &__text {\n\n    display: -webkit-box;\n\n    text-overflow: ellipsis;\n\n    overflow: hidden;\n\n    -webkit-line-clamp: 3;\n\n    -webkit-box-orient: vertical;\n\n    white-space: pre-line;\n\n    font-size: 12px;\n\n  }\n\n  &__cell {\n\n    display: inline-flex;\n\n    align-items: center;\n\n    .filter-arrow {\n\n      display: inline-flex;\n\n      justify-content: center;\n\n      align-items: center;\n\n      margin-left: 10px;\n\n      cursor: pointer;\n\n      &.is-active {\n\n        color: var(--el-color-primary);\n\n      }\n\n    }\n\n  }\n\n}\n\n\n\n.custom-columns {\n\n  ul {\n\n    list-style: none;\n\n    margin: 0;\n\n    padding: 0;\n\n    li {\n\n      .el-checkbox {\n\n        width: 100%;\n\n      }\n\n      .el-checkbox__label {\n\n        overflow: hidden;\n\n        white-space: nowrap;\n\n        text-overflow: ellipsis;\n\n      }\n\n    }\n\n  }\n\n}\n\n\n\n.table-cell-tooltip {\n\n  width: 300px;\n\n}\n\n\n\n.table-cell-tooltip--large {\n\n  width: 800px;\n\n}\n\n</style>\n\n```\n给这段代码实现打个分,评价一下编写水平\n"
}'

The returned content is stable with a large number of nonsensical 6666 endings, and I'll put one of them here:


这段代码是一个基于Vue 3和Element Plus的高级表格组件的实现,它包含了丰富的功能,如搜索、过滤、分页、排序、导出、自定义列显示等。以下是对这段代码实现的评价:

1. **组件化和模块化**:代码使用了Vue 3的Composition API,这使得状态管理和逻辑处理更加清晰和模块化。通过`defineProps`和`defineEmits`定义了组件的属性和事件,这有助于组件的复用和维护。

2. **状态管理**:使用了`ref`和`computed`来管理组件的状态,这使得状态的响应式和计算逻辑更加直观。例如,`userData`和`filteredData`的计算逻辑清晰地展示了数据的过滤和排序过程。

3. **事件处理和交互**:事件处理逻辑清晰,如`handleFilter`、`handleSelectionChange`等,这些函数的命名和实现都遵循了良好的实践,易于理解和维护。

4. **性能优化**:使用了`useDebounceFn`来防抖搜索和过滤操作,这有助于提高组件在大量数据下的性能。同时,通过`watch`监听数据变化,确保了组件状态的实时更新。

5. **自定义和扩展性**:组件提供了丰富的自定义选项,如`filterMethod`、`exportMethod`等,这使得组件可以适应不同的业务需求。同时,通过`useCustomColumn`支持了列的000066666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 66666666666666666666666666666666666666666666666666666666666666666666666666166666666666666666666666666666666666666666666666666666666666666666666666 666666666666666666666636666666666666666666666666 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 666666666666666666666666666666666666666666666666666666 6666666666666666666666666616666666666666666666666666 66666666666666666666616666666666666666666666666666666666666666666666666666666

Sign up or log in to comment