|
|
@@ -1,19 +1,158 @@
|
|
|
<script setup lang="ts">
|
|
|
import { type VxeGridProps } from 'vxe-table'
|
|
|
import { useCalculatingHeight } from '@/hooks/calculatingHeight'
|
|
|
+import FilterTabs from './components/FilterTabs.vue'
|
|
|
+import { cloneDeep } from 'lodash'
|
|
|
|
|
|
-const selectedPage = ref('destination-delivery')
|
|
|
-const pageList = [
|
|
|
- { label: 'Destination Delivery', value: 'destination-delivery', unverifiedNumber: 1 },
|
|
|
- { label: 'Page 2', value: 'page-2', unverifiedNumber: 1 },
|
|
|
- { label: 'Page 3', value: 'page-3', unverifiedNumber: 1 }
|
|
|
+const languageStatusList = [
|
|
|
+ 'englishStatus',
|
|
|
+ 'simplifiedChineseStatus',
|
|
|
+ 'traditionalChineseStatus',
|
|
|
+ 'frenchStatus',
|
|
|
+ 'spanishStatus',
|
|
|
+ 'portugueseStatus'
|
|
|
]
|
|
|
+
|
|
|
+const tabList = ref([
|
|
|
+ { name: 'All', checked: true, number: 0, type: 'all', statusKey: languageStatusList },
|
|
|
+ { name: 'English', checked: false, number: 0, type: 'english', statusKey: 'englishStatus' },
|
|
|
+ {
|
|
|
+ name: 'Chinese (Simplified)',
|
|
|
+ checked: false,
|
|
|
+ number: 0,
|
|
|
+ type: 'chinese-simplified',
|
|
|
+ statusKey: 'simplifiedChineseStatus'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'Chinese (Traditional)',
|
|
|
+ checked: false,
|
|
|
+ number: 0,
|
|
|
+ type: 'chinese-traditional',
|
|
|
+ statusKey: 'traditionalChineseStatus'
|
|
|
+ },
|
|
|
+ { name: 'Français', checked: false, number: 0, type: 'french', statusKey: 'frenchStatus' },
|
|
|
+ { name: 'Español', checked: false, number: 0, type: 'spanish', statusKey: 'spanishStatus' },
|
|
|
+ {
|
|
|
+ name: 'Português',
|
|
|
+ checked: false,
|
|
|
+ number: 0,
|
|
|
+ type: 'portuguese',
|
|
|
+ statusKey: 'portugueseStatus'
|
|
|
+ }
|
|
|
+])
|
|
|
+const currnentTab = computed(() => {
|
|
|
+ const checkedTab = tabList.value.filter((item) => item.checked)
|
|
|
+ let tabs = []
|
|
|
+ checkedTab.forEach((item) => {
|
|
|
+ if (item.name === 'All') {
|
|
|
+ tabs = item.statusKey as string[]
|
|
|
+ } else {
|
|
|
+ tabs.push(item.statusKey as string)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return tabs
|
|
|
+})
|
|
|
+const columnList = computed(() => {
|
|
|
+ const columns: any = [
|
|
|
+ {
|
|
|
+ title: 'Key',
|
|
|
+ field: 'key',
|
|
|
+ width: 300,
|
|
|
+ slots: {
|
|
|
+ default: 'key'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ currnentTab.value.forEach((statusKey) => {
|
|
|
+ let column = {
|
|
|
+ title: '',
|
|
|
+ field: '',
|
|
|
+ minWidth: 300,
|
|
|
+ slots: {
|
|
|
+ header: 'table_header',
|
|
|
+ default: 'cell'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ switch (statusKey) {
|
|
|
+ case 'englishStatus':
|
|
|
+ column.title = 'English'
|
|
|
+ column.field = 'english'
|
|
|
+ break
|
|
|
+ case 'simplifiedChineseStatus':
|
|
|
+ column.title = 'Chinese (Simplified)'
|
|
|
+ column.field = 'simplifiedChinese'
|
|
|
+ break
|
|
|
+ case 'traditionalChineseStatus':
|
|
|
+ column.title = 'Chinese (Traditional)'
|
|
|
+ column.field = 'traditionalChinese'
|
|
|
+ break
|
|
|
+ case 'frenchStatus':
|
|
|
+ column.title = 'Français'
|
|
|
+ column.field = 'french'
|
|
|
+ break
|
|
|
+ case 'spanishStatus':
|
|
|
+ column.title = 'Español'
|
|
|
+ column.field = 'spanish'
|
|
|
+ break
|
|
|
+ case 'portugueseStatus':
|
|
|
+ column.title = 'Português'
|
|
|
+ column.field = 'portuguese'
|
|
|
+ break
|
|
|
+ }
|
|
|
+ columns.push(column)
|
|
|
+ })
|
|
|
+ return columns
|
|
|
+})
|
|
|
+
|
|
|
+const tabChange = (newTabList) => {
|
|
|
+ tabList.value = cloneDeep(newTabList)
|
|
|
+ getMultilingualConfig()
|
|
|
+ nextTick(() => {
|
|
|
+ tableData.value.columns = columnList.value
|
|
|
+ })
|
|
|
+}
|
|
|
+const initColumns = () => {
|
|
|
+ tableData.value.columns = columnList.value
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ initColumns()
|
|
|
+})
|
|
|
+
|
|
|
+const selectedPage = ref('all')
|
|
|
+const pageList = ref<{ label: string; value: string; unverifiedNumber?: number }[]>([])
|
|
|
+
|
|
|
+// 将首字母大写
|
|
|
+const capitalizeFirstLetter = (str: string) => {
|
|
|
+ if (!str) return str
|
|
|
+ return str.charAt(0).toUpperCase() + str.slice(1)
|
|
|
+}
|
|
|
+const getMultilingualPageInfo = async () => {
|
|
|
+ try {
|
|
|
+ const res = await $api.getMultilingualPageInfo()
|
|
|
+ if (res.code === 200) {
|
|
|
+ pageList.value = res.data.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: capitalizeFirstLetter(item.page_key),
|
|
|
+ value: item.page_key,
|
|
|
+ unverifiedNumber: item.unverified_count
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getMultilingualPageInfo()
|
|
|
+})
|
|
|
const getCurrentPageUnverifiedNumber = () => {
|
|
|
- return pageList.find((item) => item.value === selectedPage.value)?.unverifiedNumber || 0
|
|
|
+ return pageList.value.find((item) => item.value === selectedPage.value)?.unverifiedNumber || 0
|
|
|
}
|
|
|
const searchKey = ref('')
|
|
|
|
|
|
-const containerHeight = useCalculatingHeight(document.documentElement, 456, [])
|
|
|
+const containerHeight = useCalculatingHeight(document.documentElement, 276, [])
|
|
|
|
|
|
type RowItem = {
|
|
|
key: string
|
|
|
@@ -43,43 +182,39 @@ const tableData = ref<VxeGridProps<RowItem>>({
|
|
|
border: true,
|
|
|
round: true,
|
|
|
columns: [
|
|
|
- {
|
|
|
- title: 'Key',
|
|
|
- field: 'key',
|
|
|
- width: 300,
|
|
|
- slots: {
|
|
|
- default: 'key'
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: 'English',
|
|
|
- field: 'english',
|
|
|
- minWidth: 300,
|
|
|
- slots: {
|
|
|
- header: 'table_header',
|
|
|
- default: 'languageVerification'
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: 'Chinese',
|
|
|
- field: 'simplifiedChinese',
|
|
|
- minWidth: 300,
|
|
|
- slots: {
|
|
|
- header: 'table_header',
|
|
|
- default: 'languageVerification'
|
|
|
- }
|
|
|
- }
|
|
|
+ // {
|
|
|
+ // title: 'Key',
|
|
|
+ // field: 'key',
|
|
|
+ // width: 300,
|
|
|
+ // slots: {
|
|
|
+ // default: 'key'
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // title: 'English',
|
|
|
+ // field: 'english',
|
|
|
+ // minWidth: 300,
|
|
|
+ // slots: {
|
|
|
+ // header: 'table_header',
|
|
|
+ // default: 'cell'
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // title: 'Chinese',
|
|
|
+ // field: 'simplifiedChinese',
|
|
|
+ // minWidth: 300,
|
|
|
+ // slots: {
|
|
|
+ // header: 'table_header',
|
|
|
+ // default: 'cell'
|
|
|
+ // }
|
|
|
+ // }
|
|
|
],
|
|
|
cellConfig: {
|
|
|
- height: 68
|
|
|
+ // minHeight: 68
|
|
|
},
|
|
|
scrollY: { enabled: true, oSize: 20, gt: 30 },
|
|
|
- emptyText: ' ',
|
|
|
- showHeaderOverflow: true,
|
|
|
- showOverflow: true
|
|
|
+ emptyText: ' '
|
|
|
})
|
|
|
-const tableLoadingTableData = ref(false)
|
|
|
-const tableLoadingColumn = ref(false)
|
|
|
|
|
|
const originalTableData = ref([
|
|
|
{
|
|
|
@@ -96,35 +231,20 @@ const originalTableData = ref([
|
|
|
spanishStatus: 0, // 0: 未审核, 1: 已审核, 2: 已修改
|
|
|
portuguese: 'Nome de usuário', // 葡萄牙语
|
|
|
portugueseStatus: 0 // 0: 未审核, 1: 已审核, 2: 已修改
|
|
|
- },
|
|
|
- {
|
|
|
- key: 'password',
|
|
|
- traditionalChinese: '密碼', // 繁体中文
|
|
|
- traditionalChineseStatus: 1, // 0: 未审核, 1: 已审核, 2: 已修改
|
|
|
- simplifiedChinese: '密码', // 简体中文
|
|
|
- simplifiedChineseStatus: 0, // 0: 未审核, 1: 已审核, 2: 已修改
|
|
|
- english: 'Password', // 英文
|
|
|
- englishStatus: 1, // 0: 未审核, 1: 已审核, 2: 已修改
|
|
|
- french: 'Mot de passe', // 法语
|
|
|
- frenchStatus: 0, // 0: 未审核, 1: 已审核, 2: 已修改
|
|
|
- spanish: 'Contraseña', // 西班牙语
|
|
|
- spanishStatus: 0, // 0: 未审核, 1: 已审核, 2: 已修改
|
|
|
- portuguese: 'Senha', // 葡萄牙语
|
|
|
- portugueseStatus: 0 // 0: 未审核, 1: 已审核, 2: 已修改
|
|
|
}
|
|
|
])
|
|
|
+const variableTableData = ref([])
|
|
|
|
|
|
const showTableData = computed(() => {
|
|
|
- let arr = originalTableData.value.filter((item) => {
|
|
|
+ let arr = variableTableData.value.filter((item) => {
|
|
|
return item.key.includes(searchKey.value)
|
|
|
})
|
|
|
- const unverifiedFilter = Object.entries(headerSwitchMap.value).find((item) => item[1] === true)
|
|
|
- if (unverifiedFilter) {
|
|
|
+ // 筛选未审核的字段
|
|
|
+ if (unverifiedSwitch.value) {
|
|
|
arr = arr.filter((item) => {
|
|
|
- return item[unverifiedFilter[0]] === 0
|
|
|
+ return currnentTab.value.some((status) => item[status as keyof typeof item] === 0)
|
|
|
})
|
|
|
}
|
|
|
- console.log(unverifiedFilter, 'unverifiedFilter')
|
|
|
return arr
|
|
|
})
|
|
|
|
|
|
@@ -158,22 +278,37 @@ const unverifiedNumberMap = computed(() => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
-const headerSwitchMap = ref<Record<string, boolean>>({
|
|
|
- traditionalChineseStatus: false,
|
|
|
- simplifiedChineseStatus: false,
|
|
|
- englishStatus: false,
|
|
|
- frenchStatus: false,
|
|
|
- spanishStatus: false,
|
|
|
- portugueseStatus: false
|
|
|
-})
|
|
|
+const tableLoading = ref(false)
|
|
|
|
|
|
-const handleSwitchChange = (field: EditableField) => {
|
|
|
- Object.entries(headerSwitchMap.value).forEach((item) => {
|
|
|
- if (item[0] !== field) {
|
|
|
- headerSwitchMap.value[item[0]] = false
|
|
|
+const getMultilingualConfig = async () => {
|
|
|
+ tableLoading.value = true
|
|
|
+ try {
|
|
|
+ const { code, data: responseData } = await $api.getMultilingualConfig({
|
|
|
+ pagekey: selectedPage.value,
|
|
|
+ langKey: currnentTab.value.map((status) => status.replace('Status', '')).join(',')
|
|
|
+ })
|
|
|
+ if (code === 200) {
|
|
|
+ originalTableData.value = cloneDeep(responseData.data)
|
|
|
+ variableTableData.value = cloneDeep(responseData.data)
|
|
|
+ pageList.value = responseData.pageDate.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: capitalizeFirstLetter(item.page_key),
|
|
|
+ value: item.page_key,
|
|
|
+ unverifiedNumber: item.unverified_count
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
- })
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ } finally {
|
|
|
+ tableLoading.value = false
|
|
|
+ }
|
|
|
}
|
|
|
+onMounted(() => {
|
|
|
+ getMultilingualConfig()
|
|
|
+})
|
|
|
+
|
|
|
+const unverifiedSwitch = ref(false)
|
|
|
|
|
|
const currentEditor = ref<{ rowIndex: number | null; field: EditableField | null }>({
|
|
|
rowIndex: null,
|
|
|
@@ -186,6 +321,7 @@ const handleEdit = (rowIndex: number, field: EditableField, value: string) => {
|
|
|
}
|
|
|
const handleComfirmEdit = (rowIndex: number, field: EditableField) => {
|
|
|
showTableData.value[rowIndex][field] = currentEditorValue.value
|
|
|
+ showTableData.value[rowIndex][field + 'Status'] = 1
|
|
|
currentEditor.value = { rowIndex: null, field: null }
|
|
|
currentEditorValue.value = ''
|
|
|
}
|
|
|
@@ -193,6 +329,57 @@ const handleCancelEdit = () => {
|
|
|
currentEditor.value = { rowIndex: null, field: null }
|
|
|
currentEditorValue.value = ''
|
|
|
}
|
|
|
+
|
|
|
+// 值对应语言映射
|
|
|
+const multilingualConfigMapping = {
|
|
|
+ englishStatus: 'english',
|
|
|
+ simplifiedChinese: 'simplifiedChinese',
|
|
|
+ simplifiedChineseStatus: 'simplifiedChinese',
|
|
|
+ traditionalChineseStatus: 'traditionalChinese',
|
|
|
+ frenchStatus: 'french',
|
|
|
+ spanishStatus: 'spanish',
|
|
|
+ portugueseStatus: 'portuguese'
|
|
|
+}
|
|
|
+
|
|
|
+const getChangedConfig = () => {
|
|
|
+ let changedConfigList: any = []
|
|
|
+
|
|
|
+ variableTableData.value.forEach((item, itemIndex) => {
|
|
|
+ currnentTab.value.forEach((statusKey) => {
|
|
|
+ if (item[statusKey] !== originalTableData.value[itemIndex][statusKey]) {
|
|
|
+ changedConfigList.push({
|
|
|
+ page: item.key_page,
|
|
|
+ lang: multilingualConfigMapping[statusKey],
|
|
|
+ trans_key: item.key,
|
|
|
+ status: 1, // 1代表已审核
|
|
|
+ trans_value: item[multilingualConfigMapping[statusKey]]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ return {
|
|
|
+ multilingual_param: changedConfigList
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const saveMultilingualConfig = async () => {
|
|
|
+ try {
|
|
|
+ const changedConfig = getChangedConfig()
|
|
|
+ console.log('changedConfig', changedConfig)
|
|
|
+ if (changedConfig.multilingual_param.length === 0) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const res = await $api.saveMultilingualConfig(changedConfig)
|
|
|
+ if (res.code === 200) {
|
|
|
+ getMultilingualConfig()
|
|
|
+ } else {
|
|
|
+ ElMessage.error('Save failed')
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ ElMessage.error('Save failed')
|
|
|
+ }
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
@@ -201,17 +388,19 @@ const handleCancelEdit = () => {
|
|
|
<span>Multilingual Config</span>
|
|
|
</div>
|
|
|
<div class="page-filter">
|
|
|
+ <div class="language-tab">
|
|
|
+ <FilterTabs :tabList="tabList" @tabChange="tabChange" />
|
|
|
+ </div>
|
|
|
<div class="top-content">
|
|
|
- <span class="font_family icon-icon_page_b" style="font-size: 24px"></span>
|
|
|
- <span style="margin: 0 8px; font-size: 18px; font-weight: 700">Select Page</span>
|
|
|
<el-select
|
|
|
v-model="selectedPage"
|
|
|
placeholder="Select Page"
|
|
|
- style="width: 400px; height: 48px"
|
|
|
+ @change="getMultilingualConfig()"
|
|
|
+ style="width: 240px; height: 32px"
|
|
|
>
|
|
|
<template #label="{ label }">
|
|
|
<div style="display: flex; align-items: center">
|
|
|
- <span style="font-size: 18px">{{ label }}</span>
|
|
|
+ <span style="font-size: 14px">{{ label }}</span>
|
|
|
<div class="page-select-unverified-tag">
|
|
|
<span> {{ getCurrentPageUnverifiedNumber() }} Unverified</span>
|
|
|
</div>
|
|
|
@@ -226,30 +415,33 @@ const handleCancelEdit = () => {
|
|
|
<div style="display: flex; align-items: center">
|
|
|
<span>{{ item.label }}</span>
|
|
|
<div class="page-item-unverified-tag" style="margin-left: 20px">
|
|
|
- <span style="font-size: 10px">
|
|
|
- {{ getCurrentPageUnverifiedNumber() }} Unverified</span
|
|
|
- >
|
|
|
+ <span style="font-size: 10px"> {{ item.unverifiedNumber || 0 }} Unverified</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
+ <div class="unverified-switch">
|
|
|
+ <el-switch
|
|
|
+ v-model="unverifiedSwitch"
|
|
|
+ active-text="Unverified only"
|
|
|
+ inactive-text=""
|
|
|
+ size="small"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <el-input placeholder="Search key..." v-model="searchKey" style="width: 400px">
|
|
|
+ <template #prefix>
|
|
|
+ <span class="font_family icon-icon_search_b"></span>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ <el-button type="primary" @click="saveMultilingualConfig">Save</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="label">Filter</div>
|
|
|
- <el-input
|
|
|
- placeholder="Search key..."
|
|
|
- v-model="searchKey"
|
|
|
- style="margin-left: 24px; width: 400px"
|
|
|
- >
|
|
|
- <template #prefix>
|
|
|
- <span class="font_family icon-icon_search_b"></span>
|
|
|
- </template>
|
|
|
- </el-input>
|
|
|
- <el-divider style="width: calc(100% - 48px); margin: 8px auto" />
|
|
|
+
|
|
|
+ <el-divider style="margin: 8px auto" />
|
|
|
<div class="config-table">
|
|
|
<vxe-grid
|
|
|
ref="tableRef"
|
|
|
- v-vloading="tableLoadingTableData || tableLoadingColumn"
|
|
|
+ v-vloading="tableLoading"
|
|
|
:height="containerHeight"
|
|
|
:data="showTableData"
|
|
|
:style="{ border: 'none' }"
|
|
|
@@ -261,27 +453,19 @@ const handleCancelEdit = () => {
|
|
|
<span class="unverified-number">{{
|
|
|
unverifiedNumberMap[column.field as keyof typeof unverifiedNumberMap]
|
|
|
}}</span>
|
|
|
- <el-switch
|
|
|
- v-model="headerSwitchMap[(column.field + 'Status') as keyof typeof headerSwitchMap]"
|
|
|
- active-text="Unverified only"
|
|
|
- inactive-text=""
|
|
|
- @change="handleSwitchChange((column.field + 'Status') as EditableField)"
|
|
|
- />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<template #key="{ row }">
|
|
|
+ <div>{{ row.orginEnglish }}</div>
|
|
|
<span>{{ row.key }}</span>
|
|
|
</template>
|
|
|
- <template #languageVerification="{ row, column, rowIndex }">
|
|
|
- <div
|
|
|
- class="show-content"
|
|
|
+ <template #cell="{ row, column, rowIndex }">
|
|
|
+ <template
|
|
|
v-if="currentEditor.rowIndex !== rowIndex || currentEditor.field !== column.field"
|
|
|
>
|
|
|
- <span>{{ row[column.field as EditableField] }}</span>
|
|
|
- <span
|
|
|
- class="font_family icon-icon_edit_b edit-icon"
|
|
|
- style="display: none"
|
|
|
+ <div
|
|
|
+ class="show-content"
|
|
|
@click="
|
|
|
handleEdit(
|
|
|
rowIndex,
|
|
|
@@ -289,31 +473,42 @@ const handleCancelEdit = () => {
|
|
|
row[column.field as EditableField]
|
|
|
)
|
|
|
"
|
|
|
- ></span>
|
|
|
- </div>
|
|
|
+ >
|
|
|
+ <span>{{ row[column.field as EditableField] }}</span>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="unverified-tag"
|
|
|
+ v-if="row[(column.field as EditableField) + 'Status'] === 0"
|
|
|
+ >
|
|
|
+ <span class="font_family icon-icon_delay_b" style="font-size: 14px"></span>
|
|
|
+ <span style="display: inline-block; margin-top: 2px">Unverified</span>
|
|
|
+ </div>
|
|
|
+ <div class="verified-tag" v-if="row[(column.field as EditableField) + 'Status'] === 1">
|
|
|
+ <span class="font_family icon-icon_active" style="font-size: 9px"></span>
|
|
|
+ <span style="display: inline-block; margin-top: 1px">Verified</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
<div class="editor-input" v-else>
|
|
|
- <el-input v-model="currentEditorValue" style="height: 28px; margin-bottom: 3px">
|
|
|
- <template #suffix>
|
|
|
- <span
|
|
|
- class="font_family icon-icon_reject_b"
|
|
|
- style="margin-top: 1px; margin-right: 10px; font-size: 16px"
|
|
|
- @click="handleCancelEdit"
|
|
|
- ></span>
|
|
|
- <span
|
|
|
- class="font_family icon-icon_confirm_b"
|
|
|
- style="margin-top: 1px; font-size: 18px; color: #ed6d00; cursor: pointer"
|
|
|
- @click="handleComfirmEdit(rowIndex, column.field as EditableField)"
|
|
|
- ></span>
|
|
|
- </template>
|
|
|
- </el-input>
|
|
|
- </div>
|
|
|
- <div class="unverified-tag" v-if="row[(column.field as EditableField) + 'Status'] === 0">
|
|
|
- <span class="font_family icon-icon_delay_b" style="font-size: 14px"></span>
|
|
|
- <span style="display: inline-block; margin-top: 1px">Unverified</span>
|
|
|
- </div>
|
|
|
- <div class="verified-tag" v-if="row[(column.field as EditableField) + 'Status'] === 1">
|
|
|
- <span class="font_family icon-icon_active" style="font-size: 9px"></span>
|
|
|
- <span style="display: inline-block; margin-top: 1px">Verified</span>
|
|
|
+ <el-input
|
|
|
+ v-model="currentEditorValue"
|
|
|
+ type="textarea"
|
|
|
+ :autosize="{ minRows: 1, maxRows: 8 }"
|
|
|
+ style="margin-bottom: 3px"
|
|
|
+ />
|
|
|
+ <div class="operate-btn">
|
|
|
+ <el-button @click="handleCancelEdit">
|
|
|
+ <span class="font_family icon-icon_reject_b"></span>
|
|
|
+ <span>Cancel</span>
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ class="el-button--main"
|
|
|
+ @click="handleComfirmEdit(rowIndex, column.field as EditableField)"
|
|
|
+ >
|
|
|
+ <span class="font_family icon-icon_confirm_b"></span>
|
|
|
+ <span>Verify</span>
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
</vxe-grid>
|
|
|
@@ -327,25 +522,25 @@ const handleCancelEdit = () => {
|
|
|
padding-bottom: 40px;
|
|
|
background-color: var(--color-mode);
|
|
|
.page-filter {
|
|
|
- margin: 16px 24px 24px;
|
|
|
+ margin: 16px 24px 8px;
|
|
|
border-radius: 12px;
|
|
|
.top-content {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- height: 80px;
|
|
|
- padding: 28px 16px;
|
|
|
- background-color: var(--color-shipment-status-header-bg);
|
|
|
+ margin-top: 16px;
|
|
|
:deep(.el-select__wrapper) {
|
|
|
- height: 48px;
|
|
|
+ height: 32px;
|
|
|
+ }
|
|
|
+ .unverified-switch {
|
|
|
+ height: 34px;
|
|
|
+ margin: 0 8px;
|
|
|
+ padding: 4px 16px;
|
|
|
+ border-radius: 6px;
|
|
|
+ border: 1px solid var(--input-border);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- .label {
|
|
|
- margin-left: 24px;
|
|
|
- margin-bottom: 12px;
|
|
|
- font-size: 18px;
|
|
|
- font-weight: 700;
|
|
|
- }
|
|
|
+
|
|
|
.page-select-unverified-tag {
|
|
|
display: inline-flex;
|
|
|
height: 20px;
|
|
|
@@ -360,6 +555,19 @@ const handleCancelEdit = () => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+.page-item-unverified-tag {
|
|
|
+ display: inline-flex;
|
|
|
+ height: 20px;
|
|
|
+ margin-left: 8px;
|
|
|
+ padding: 5px 7px;
|
|
|
+ line-height: 11px;
|
|
|
+ border-radius: 3px;
|
|
|
+ background-color: var(--color-multilingual-page-select-item-tag-bg);
|
|
|
+ span {
|
|
|
+ color: var(--color-steps-current-icon-color);
|
|
|
+ font-size: 10px;
|
|
|
+ }
|
|
|
+}
|
|
|
.header {
|
|
|
position: sticky;
|
|
|
top: 0;
|
|
|
@@ -394,6 +602,7 @@ const handleCancelEdit = () => {
|
|
|
.unverified-tag,
|
|
|
.verified-tag {
|
|
|
display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
height: 16px;
|
|
|
padding: 2px 4px;
|
|
|
font-size: 10px;
|
|
|
@@ -423,17 +632,44 @@ const handleCancelEdit = () => {
|
|
|
:deep(.el-switch__label--right) {
|
|
|
margin-left: 4px;
|
|
|
}
|
|
|
+
|
|
|
+ :deep(.vxe-cell) {
|
|
|
+ white-space: normal !important; /* 强制不换行改为自动换行 */
|
|
|
+ word-break: break-word; /* 长单词自动换行 */
|
|
|
+ line-height: normal; /* 行高恢复正常 */
|
|
|
+ overflow: visible; /* 允许溢出可见 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 2. 让行高自动适应内容 */
|
|
|
+ :deep(.vxe-cell) {
|
|
|
+ height: auto !important; /* 关键:强制高度为 auto */
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.show-content {
|
|
|
- &:hover {
|
|
|
- .edit-icon {
|
|
|
- display: block !important;
|
|
|
- float: right;
|
|
|
- color: #ed6d00;
|
|
|
- font-size: 18px;
|
|
|
- cursor: pointer;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.editor-input {
|
|
|
+ position: relative;
|
|
|
+ .operate-btn {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 11px;
|
|
|
+ right: 10px;
|
|
|
+ .el-button {
|
|
|
+ height: 24px;
|
|
|
+ padding: 8px 4px;
|
|
|
+ .font_family {
|
|
|
+ margin-right: 1px;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ span {
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ :deep(.el-textarea__inner) {
|
|
|
+ padding-bottom: 28px;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|