CN-59 feat:国际化 列表页面开发

CN-60 feat:国际化 新增修改页面开发
This commit is contained in:
晶晶 张
2021-07-21 09:23:02 +08:00
parent 5998b73d00
commit 866af9c071
3 changed files with 386 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
<template>
<div v-click-outside="{object: editObject, func: esc}" class="right-box right-box-user">
<div class="right-box__header">
<div class="header__title">{{editObject.id ? $t('config.user.editUser') : $t('config.user.createUser')}}</div>
<div class="header__operation">
<span v-cancel="{object: editObject, func: esc}"><i class="cn-icon cn-icon-close"></i></span>
</div>
</div>
<div class="right-box__container">
<div class="container__form">
<el-form ref="i18nForm" :model="editObject" :rules="editObject.id ? rules2 : rules" label-position="top" label-width="120px">
<!--name-->
<el-form-item :label="$t('config.I18n.name')" prop="name">
<el-input id="account-input-name" v-model="editObject.name" :disabled="editObject.username==='admin' && editObject.id === 1"
maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
</el-form-item>
<!--code-->
<el-form-item :label="$t('config.I18n.code')" prop="code">
<el-input id="account-input-username" v-model="editObject.code" :disabled="editObject.code==='admin' && editObject.id === 1"
maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
</el-form-item>
<!--lang-->
<el-form-item :label="$t('config.I18n.lang')" prop="lang">
<el-input id="account-input-password" v-model="editObject.lang" maxlength="64" placeholder=""
show-word-limit size="small" @blur="pinBlur" autocomplete="new-password"></el-input>
</el-form-item>
<!--value-->
<el-form-item :label="$t('config.I18n.value')" label-width="200px" prop="pinChange">
<el-input id="account-input-pinChange" v-model="editObject.value" maxlength="64" placeholder=""
show-word-limit size="small"></el-input>
</el-form-item>
<!--enable-->
<!-- <el-form-item :label="$t('config.user.enable')">
<el-switch
id="account-input-status"
v-model="editObject.status"
:active-color="theme.themeColor"
:disabled="(editObject.username === loginName) || (editObject.username==='admin' && editObject.id==1)"
:active-value="1"
:inactive-value="0">
</el-switch>
</el-form-item>-->
</el-form>
</div>
</div>
<div class="right-box__footer">
<button id="asset-edit-cancel" v-cancel="{object: editObject, func: esc}" class="footer__btn footer__btn--light">
<span>{{$t('overall.cancel')}}</span>
</button>
<button id="asset-edit-save" :class="{'footer__btn--disabled': blockOperation.save}" :disabled="blockOperation.save" class="footer__btn" @click="save">
<span>{{$t('overall.save')}}</span>
</button>
</div>
</div>
</template>
<script>
import rightBoxMixin from '@/mixins/rightBox'
import { get, post, put } from '@/utils/http'
export default {
name: 'I18nBox',
mixins: [rightBoxMixin],
data () {
const validatePin = (rule, value, callback) => { // 确认密码的二次校验
if (value === '' && this.editObject.pin) {
callback(new Error(this.$t('config.user.inputConfirmPin')))
} else if (value !== this.editObject.pin) {
callback(new Error(this.$t('config.user.confirmPinErr')))
} else {
callback()
}
}
return {
url: 'sys/i18n',
loginName: localStorage.getItem('cn-username'),
rules: { // 表单校验规则
name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
username: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
pin: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
]
},
rules2: { // 表单校验规则
username: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
pinChange: [
{ validator: validatePin, trigger: 'blur' }
]
},
roleData: []
}
},
setup () {
},
mounted () {
this.getRoleData()
},
methods: {
isCurrentUser (username) {
return localStorage.getItem('cn-username') === username
},
/* 密码失去焦点 检验确认密码 */
pinBlur () {
if (this.editObject.pin && this.editObject.pinChange) {
this.$refs.i18nForm.validateField('pinChange')
}
},
save () {
if (this.blockOperation.save) { return }
this.blockOperation.save = true
this.$refs.i18nForm.validate((valid) => {
if (valid) {
if (this.editObject.id) {
put(this.url, this.editObject).then(res => {
this.blockOperation.save = false
if (res.code === 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.esc(true)
} else {
this.$message.error(res.msg)
}
})
} else {
post(this.url, this.editObject).then(res => {
this.blockOperation.save = false
if (res.code === 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.esc(true)
} else {
this.$message.error(res.msg)
}
})
}
} else {
this.blockOperation.save = false
return false
}
})
},
getRoleData () {
get('sys/i18n?pageSize=-1').then(response => {
if (response.code === 200) {
this.roleData = response.data.list
}
})
}
}
}
</script>

View File

@@ -0,0 +1,144 @@
<template>
<el-table
id="i18nTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitles"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:sortable="item.sortable"
:width="`${item.width}`"
>
<template #header>
<span class="data-column__span">{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template #default="scope" :column="item">
<template v-if="item.prop === 'roles'">
<template v-if="scope.row[item.prop]">
{{scope.row[item.prop].map(t=>t.name).join(',')}}
</template>
<template v-else>
<span>-</span>
</template>
</template>
<template v-else-if="item.prop === 'status'">
<el-switch
v-if="scope.row.id"
v-model="scope.row.status"
:active-color="theme.themeColor"
active-value="1"
:disabled="(scope.row.username === loginName) || (scope.row.username==='admin' && scope.row.id==1) "
inactive-value="0"
@change="()=>{statusChange(scope.row)}">
</el-switch>
</template>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<template #header>
<div class="table-operation-title">{{$t('overall.option')}}</div>
</template>
<template #default="scope">
<div class="table-operation-items">
<button class="table-operation-item" @click="tableOperation(['edit', scope.row])"><i class="cn-icon cn-icon-edit"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<i class="cn-icon cn-icon-more-arrow-down"></i>
</div>
<template #dropdown>
<el-dropdown-menu >
<el-dropdown-item v-has="'user_delete'" :command="['delete', scope.row]" :disabled="scope.row.id === 1"><i class="cn-icon cn-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/mixins/table'
import { put } from '@/utils/http'
export default {
name: 'I18nTable',
mixins: [table],
data () {
return {
loginName: localStorage.getItem('cn-username'),
tableTitle: [ // 原始table列
{
label: 'ID',
prop: 'id',
show: true,
width: 80,
sortable: 'custom'
},
{
label: this.$t('config.i18n.name'),
prop: 'name',
show: true,
sortable: 'custom'
},
{
label: this.$t('config.i18n.code'),
prop: 'code',
show: true,
sortable: 'custom'
},
{
label: this.$t('config.i18n.lang'),
prop: 'lang',
show: true,
sortable: 'custom'
}, {
label: this.$t('config.i18n.value'),
prop: 'value',
show: true,
width: 150
}
]
}
},
methods: {
statusChange (i18n) {
if (i18n.roles) {
i18n.roleIds = i18n.roles.map(t => t.id)
}
put('sys/i18n', i18n).then(response => {
if (response.code === 200) {
this.rightBox.show = false
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
} else {
this.$message.error(response.msg)
}
this.$emit('reload')
})
}
}
}
</script>

View File

@@ -0,0 +1,87 @@
<template>
<div>
<cn-data-list
ref="dataList"
:tableId="tableId"
v-model:custom-table-title="tools.customTableTitle"
:api="url"
:from="fromRoute.user"
:layout="['columnCustomize','elementSet']"
>
<template #top-tool-right>
<button
id="account-add"
v-has="'user_add'"
class="top-tool-btn margin-r-10"
type="button"
@click="add"
>
<i class="cn-icon-add cn-icon"/>
</button>
</template>
<template #default>
<i18n-table
ref="dataTable"
v-loading="tools.loading"
:api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight"
:table-data="tableData"
@delete="del"
@edit="edit"
@orderBy="tableDataSort"
@reload="getTableData"
@selectionChange="selectionChange"
@showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"
/>
</template>
<template #pagination>
<pagination ref="pagination" :page-obj="pageObj" :table-id="tableId" @pageNo='pageNo' @pageSize='pageSize'></pagination>
</template>
</cn-data-list>
<el-drawer
v-model="rightBox.show"
direction="rtl"
:with-header="false"
:size="700"
destroy-on-close>
<i18n-box
:object="object"
@close="closeRightBox"
/>
</el-drawer>
</div>
</template>
<script>
import cnDataList from '@/components/table/CnDataList'
import dataListMixin from '@/mixins/dataList'
import i18nTable from '@/components/table/settings/I18nTable'
import i18nBox from '@/components/rightBox/settings/I18nBox'
import { put } from '@/utils/http'
export default {
name: 'I18n',
mixins: [dataListMixin],
components: {
cnDataList,
i18nTable,
i18nBox
},
data () {
return {
url: 'sys/i18n',
blankObject: { // 空白对象
id: '',
name: '',
code: '',
lang: '',
value: ''
},
tableId: 'i18nTable'
}
},
methods: {
}
}
</script>