feat:增加i8n国际化插件;增加语言切换功能;国际化示例页面:登录、用户管理

This commit is contained in:
高新宇 2021-09-18 15:33:33 +08:00
parent 12ab8b03d9
commit 88f1f8bd5b
11 changed files with 388 additions and 95 deletions

View File

@ -55,6 +55,7 @@
"vue": "2.6.12", "vue": "2.6.12",
"vue-count-to": "1.0.13", "vue-count-to": "1.0.13",
"vue-cropper": "0.5.5", "vue-cropper": "0.5.5",
"vue-i18n": "^8.25.0",
"vue-meta": "^2.4.0", "vue-meta": "^2.4.0",
"vue-router": "3.4.9", "vue-router": "3.4.9",
"vuedraggable": "2.24.3", "vuedraggable": "2.24.3",

View File

@ -0,0 +1,53 @@
<template>
<el-dropdown
trigger="click"
@command="handleSetLanguage"
>
<div>
<svg-icon
class-name="size-icon"
icon-class="language"
/>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="item of languageOptions"
:key="item.value"
:disabled="lang===item.value"
:command="item.value"
>
{{
item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
data() {
return {
languageOptions: [
{ label: '中文', value: 'zh' },
{ label: 'English', value: 'en' }
]
}
},
computed: {
lang() {
return this.$store.getters.lang
}
},
methods: {
handleSetLanguage(lang) {
this.$store.dispatch('app/setLang', lang)
this.$i18n.locale = lang
const msg = lang == 'zh' ? '语言切换成功' : 'Switch Language Success'
this.$message({
message: msg,
type: 'success'
})
}
}
}
</script>

40
ruoyi-ui/src/i18n/i18n.js Normal file
View File

@ -0,0 +1,40 @@
import Vue from 'vue'
import Cookies from 'js-cookie'
import VueI18n from 'vue-i18n'
import locale from 'element-ui/lib/locale';
import zh from './langs/zh'
import en from './langs/en'
import enLocale from 'element-ui/lib/locale/lang/en'
import zhLocale from 'element-ui/lib/locale/lang/zh-CN'
Vue.use(VueI18n)
const messages = {
en: Object.assign(en, enLocale),
zh: Object.assign(zh, zhLocale)
}
export function getLanguage() {
const chooseLanguage = Cookies.get('lang')
if (chooseLanguage) return chooseLanguage
const language = (navigator.language || navigator.browserLanguage).toLowerCase()
const locales = Object.keys(messages)
for (const locale of locales) {
if (language.indexOf(locale) > -1) {
return locale
}
}
return 'en'
}
const i18n = new VueI18n({
locale: getLanguage(),
messages
})
locale.i18n((key, value) => i18n.t(key, value)) //为了实现element插件的多语言切换
export default i18n

View File

@ -0,0 +1,50 @@
const bt = {
search: 'Search',
reset: 'Reset',
create: 'Create',
edit: 'Edit',
delete: 'Delete',
import: 'Import',
export: 'Export',
more: 'More',
resetPassWord: 'ResetPassWord',
assigningRoles: 'AssigningRoles',
register: 'Register'
}
const hint = {
inputDeptName: 'Please enter the department name',
inputUserName: 'Please enter the user name',
inputPhonenumber: 'Please enter the phone number',
selectUserStatus: 'UserStatus',
startDate: 'StartDate',
endDate: 'EndDate',
operate: 'Operate',
inputPassword: 'Please enter the password',
inputCode: 'Please enter the verification code'
}
const system = {
user: {
managementSystem: 'RuoYi Management System',
userId: 'UserId',
userName: 'UserName',
passWord: 'PassWord',
checkCode: 'CheckCode',
rememberMe: 'Remember Me',
login: 'Login',
loggingIn: 'Logging in',
phonenumber: 'Phonenumber',
status: 'Status',
createDate: 'CreateDate',
nickName: 'NickName',
deptName: 'DeptName',
createTime: 'CreateTime'
}
}
module.exports = {
bt,
hint,
system,
}

View File

@ -0,0 +1,50 @@
const bt = {
search: '搜索',
reset: '重置',
create: '新增',
edit: '修改',
delete: '删除',
import: '导入',
export: '导出',
more: '更多',
resetPassWord: '重置密码',
assigningRoles: '分配角色',
register: '注册'
}
const hint = {
inputDeptName: '请输入部门名称',
inputUserName: '请输入用户名',
inputPhonenumber: '请输入手机号码',
selectUserStatus: '用户状态',
startDate: '开始日期',
endDate: '结束日期',
operate: '操作',
inputPassword: '请输入密码',
inputCode: '请输入验证码'
}
const system = {
user: {
managementSystem: '若依后台管理系统',
userId: '用户编号',
userName: '用户名',
passWord: '密码',
checkCode: '验证码',
rememberMe: '记住我',
login: '登 录',
loggingIn: '登 录 中...',
phonenumber: '手机号码',
status: '状态',
createDate: '创建日期',
nickName: '用户昵称',
deptName: '部门',
createTime: '创建时间'
}
}
module.exports = {
bt,
hint,
system,
}

View File

@ -22,7 +22,10 @@
<el-tooltip content="布局大小" effect="dark" placement="bottom"> <el-tooltip content="布局大小" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" /> <size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip> </el-tooltip>
<language-select
id="language"
class="right-menu-item hover-effect"
/>
</template> </template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click"> <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
@ -56,6 +59,7 @@ import SizeSelect from '@/components/SizeSelect'
import Search from '@/components/HeaderSearch' import Search from '@/components/HeaderSearch'
import RuoYiGit from '@/components/RuoYi/Git' import RuoYiGit from '@/components/RuoYi/Git'
import RuoYiDoc from '@/components/RuoYi/Doc' import RuoYiDoc from '@/components/RuoYi/Doc'
import LanguageSelect from '@/components/LanguageSelect'
export default { export default {
components: { components: {
@ -66,7 +70,8 @@ export default {
SizeSelect, SizeSelect,
Search, Search,
RuoYiGit, RuoYiGit,
RuoYiDoc RuoYiDoc,
LanguageSelect
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([

View File

@ -1,7 +1,7 @@
import Vue from 'vue' import Vue from 'vue'
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
import i18n from './i18n/i18n'
import Element from 'element-ui' import Element from 'element-ui'
import './assets/styles/element-variables.scss' import './assets/styles/element-variables.scss'
@ -87,5 +87,6 @@ new Vue({
el: '#app', el: '#app',
router, router,
store, store,
i18n,
render: h => h(App) render: h => h(App)
}) })

View File

@ -1,6 +1,7 @@
const getters = { const getters = {
sidebar: state => state.app.sidebar, sidebar: state => state.app.sidebar,
size: state => state.app.size, size: state => state.app.size,
lang: state => state.app.lang,
device: state => state.app.device, device: state => state.app.device,
visitedViews: state => state.tagsView.visitedViews, visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews, cachedViews: state => state.tagsView.cachedViews,

View File

@ -6,7 +6,8 @@ const state = {
withoutAnimation: false withoutAnimation: false
}, },
device: 'desktop', device: 'desktop',
size: Cookies.get('size') || 'medium' size: Cookies.get('size') || 'medium',
lang: Cookies.get('lang') || 'zh'
} }
const mutations = { const mutations = {
@ -30,6 +31,10 @@ const mutations = {
SET_SIZE: (state, size) => { SET_SIZE: (state, size) => {
state.size = size state.size = size
Cookies.set('size', size) Cookies.set('size', size)
},
SET_LANG: (state, lang) => {
state.lang = lang
Cookies.set('lang', lang)
} }
} }
@ -45,6 +50,11 @@ const actions = {
}, },
setSize({ commit }, size) { setSize({ commit }, size) {
commit('SET_SIZE', size) commit('SET_SIZE', size)
},
setLang({
commit
}, lang) {
commit('SET_LANG', lang)
} }
} }

View File

@ -1,10 +1,32 @@
<template> <template>
<div class="login"> <div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> <el-form
<h3 class="title">若依后台管理系统</h3> ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
>
<div class="head">
<h3 class="title">{{$t('system.user.managementSystem')}}
</h3>
<language-select
id="language"
class="right-menu-item hover-effect"
style="height: 20px;"
/>
</div>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号"> <el-input
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> v-model="loginForm.username"
type="text"
auto-complete="off"
:placeholder="$t('system.user.userName')"
>
<svg-icon
slot="prefix"
icon-class="user"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
@ -12,27 +34,46 @@
v-model="loginForm.password" v-model="loginForm.password"
type="password" type="password"
auto-complete="off" auto-complete="off"
placeholder="密码" :placeholder="$t('system.user.passWord')"
@keyup.enter.native="handleLogin" @keyup.enter.native="handleLogin"
show-password
> >
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> <svg-icon
slot="prefix"
icon-class="password"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="captchaOnOff"> <el-form-item
prop="code"
v-if="captchaOnOff"
>
<el-input <el-input
v-model="loginForm.code" v-model="loginForm.code"
auto-complete="off" auto-complete="off"
placeholder="验证码" :placeholder="$t('system.user.checkCode')"
style="width: 63%" style="width: 63%"
@keyup.enter.native="handleLogin" @keyup.enter.native="handleLogin"
> >
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> <svg-icon
slot="prefix"
icon-class="validCode"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
<div class="login-code"> <div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/> <img
:src="codeUrl"
@click="getCode"
class="login-code-img"
/>
</div> </div>
</el-form-item> </el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> <el-checkbox
v-model="loginForm.rememberMe"
style="margin:0px 0px 25px 0px;"
>{{$t('system.user.rememberMe')}}</el-checkbox>
<el-form-item style="width:100%;"> <el-form-item style="width:100%;">
<el-button <el-button
:loading="loading" :loading="loading"
@ -41,11 +82,17 @@
style="width:100%;" style="width:100%;"
@click.native.prevent="handleLogin" @click.native.prevent="handleLogin"
> >
<span v-if="!loading"> </span> <span v-if="!loading">{{$t('system.user.login')}}</span>
<span v-else> 中...</span> <span v-else>{{$t('system.user.loggingIn')}}</span>
</el-button> </el-button>
<div style="float: right;" v-if="register"> <div
<router-link class="link-type" :to="'/register'">立即注册</router-link> style="float: right;"
v-if="register"
>
<router-link
class="link-type"
:to="'/register'"
>{{$t('bt.register')}}</router-link>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -57,31 +104,24 @@
</template> </template>
<script> <script>
import { getCodeImg } from "@/api/login"; import { getCodeImg } from '@/api/login'
import Cookies from "js-cookie"; import Cookies from 'js-cookie'
import { encrypt, decrypt } from '@/utils/jsencrypt' import { encrypt, decrypt } from '@/utils/jsencrypt'
import LanguageSelect from '@/components/LanguageSelect'
export default { export default {
name: "Login", name: 'Login',
components: { LanguageSelect },
data() { data() {
return { return {
codeUrl: "", codeUrl: '',
cookiePassword: "", cookiePassword: '',
loginForm: { loginForm: {
username: "admin", username: 'admin',
password: "admin123", password: 'admin123',
rememberMe: false, rememberMe: false,
code: "", code: '',
uuid: "" uuid: ''
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" }
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" }
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
}, },
loading: false, loading: false,
// //
@ -89,66 +129,104 @@ export default {
// //
register: false, register: false,
redirect: undefined redirect: undefined
}; }
}, },
watch: { watch: {
$route: { $route: {
handler: function(route) { handler: function(route) {
this.redirect = route.query && route.query.redirect; this.redirect = route.query && route.query.redirect
}, },
immediate: true immediate: true
} }
}, },
computed: {
loginRules() {
const that = this
const rules = {
username: [
{
required: true,
trigger: 'blur',
message: that.$t('hint.inputUserName')
}
],
password: [
{
required: true,
trigger: 'blur',
message: that.$t('hint.inputPassword')
}
],
code: [
{
required: true,
trigger: 'change',
message: that.$t('hint.inputCode')
}
]
}
return rules
}
},
created() { created() {
this.getCode(); this.getCode()
this.getCookie(); this.getCookie()
}, },
methods: { methods: {
getCode() { getCode() {
getCodeImg().then(res => { getCodeImg().then(res => {
this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff; this.captchaOnOff =
res.captchaOnOff === undefined ? true : res.captchaOnOff
if (this.captchaOnOff) { if (this.captchaOnOff) {
this.codeUrl = "data:image/gif;base64," + res.img; this.codeUrl = 'data:image/gif;base64,' + res.img
this.loginForm.uuid = res.uuid; this.loginForm.uuid = res.uuid
} }
}); })
}, },
getCookie() { getCookie() {
const username = Cookies.get("username"); const username = Cookies.get('username')
const password = Cookies.get("password"); const password = Cookies.get('password')
const rememberMe = Cookies.get('rememberMe') const rememberMe = Cookies.get('rememberMe')
this.loginForm = { this.loginForm = {
username: username === undefined ? this.loginForm.username : username, username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password), password:
password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
}; }
}, },
handleLogin() { handleLogin() {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate(valid => {
if (valid) { if (valid) {
this.loading = true; this.loading = true
if (this.loginForm.rememberMe) { if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 }); Cookies.set('username', this.loginForm.username, { expires: 30 })
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); Cookies.set('password', encrypt(this.loginForm.password), {
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); expires: 30
})
Cookies.set('rememberMe', this.loginForm.rememberMe, {
expires: 30
})
} else { } else {
Cookies.remove("username"); Cookies.remove('username')
Cookies.remove("password"); Cookies.remove('password')
Cookies.remove('rememberMe'); Cookies.remove('rememberMe')
} }
this.$store.dispatch("Login", this.loginForm).then(() => { this.$store
this.$router.push({ path: this.redirect || "/" }).catch(()=>{}); .dispatch('Login', this.loginForm)
}).catch(() => { .then(() => {
this.loading = false; this.$router.push({ path: this.redirect || '/' }).catch(() => {})
})
.catch(() => {
this.loading = false
if (this.captchaOnOff) { if (this.captchaOnOff) {
this.getCode(); this.getCode()
} }
}); })
}
})
} }
});
} }
} }
};
</script> </script>
<style rel="stylesheet/scss" lang="scss"> <style rel="stylesheet/scss" lang="scss">
@ -160,6 +238,10 @@ export default {
background-image: url("../assets/images/login-background.jpg"); background-image: url("../assets/images/login-background.jpg");
background-size: cover; background-size: cover;
} }
.head {
display: flex;
}
.title { .title {
margin: 0px auto 30px auto; margin: 0px auto 30px auto;
text-align: center; text-align: center;

View File

@ -6,7 +6,7 @@
<div class="head-container"> <div class="head-container">
<el-input <el-input
v-model="deptName" v-model="deptName"
placeholder="请输入部门名称" :placeholder="$t('hint.inputDeptName')"
clearable clearable
size="small" size="small"
prefix-icon="el-icon-search" prefix-icon="el-icon-search"
@ -28,17 +28,17 @@
<!--用户数据--> <!--用户数据-->
<el-col :span="20" :xs="24"> <el-col :span="20" :xs="24">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="用户名称" prop="userName"> <el-form-item :label="$t('system.user.userName')" prop="userName" label-width='100px'>
<el-input <el-input
v-model="queryParams.userName" v-model="queryParams.userName"
placeholder="请输入用户名称" :placeholder="$t('hint.inputUserName')"
clearable clearable
size="small" size="small"
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="手机号码" prop="phonenumber"> <el-form-item :label="$t('system.user.phonenumber')" prop="phonenumber" label-width='100px'>
<el-input <el-input
v-model="queryParams.phonenumber" v-model="queryParams.phonenumber"
placeholder="请输入手机号码" placeholder="请输入手机号码"
@ -48,10 +48,10 @@
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item :label="$t('system.user.status')" prop="status">
<el-select <el-select
v-model="queryParams.status" v-model="queryParams.status"
placeholder="用户状态" :placeholder="$t('hint.selectUserStatus')"
clearable clearable
size="small" size="small"
style="width: 240px" style="width: 240px"
@ -64,7 +64,7 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="创建时间"> <el-form-item :label="$t('system.user.createDate')" label-width='100px'>
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
size="small" size="small"
@ -72,13 +72,13 @@
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" type="daterange"
range-separator="-" range-separator="-"
start-placeholder="开始日期" :start-placeholder="$t('hint.startDate')"
end-placeholder="结束日期" :end-placeholder="$t('hint.endDate')"
></el-date-picker> ></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{$t('bt.search')}}</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{$t('bt.reset')}}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -91,7 +91,7 @@
size="mini" size="mini"
@click="handleAdd" @click="handleAdd"
v-hasPermi="['system:user:add']" v-hasPermi="['system:user:add']"
>新增</el-button> >{{$t('bt.create')}}</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -102,7 +102,7 @@
:disabled="single" :disabled="single"
@click="handleUpdate" @click="handleUpdate"
v-hasPermi="['system:user:edit']" v-hasPermi="['system:user:edit']"
>修改</el-button> >{{$t('bt.edit')}}</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -113,7 +113,7 @@
:disabled="multiple" :disabled="multiple"
@click="handleDelete" @click="handleDelete"
v-hasPermi="['system:user:remove']" v-hasPermi="['system:user:remove']"
>删除</el-button> >{{$t('bt.delete')}}</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -123,7 +123,7 @@
size="mini" size="mini"
@click="handleImport" @click="handleImport"
v-hasPermi="['system:user:import']" v-hasPermi="['system:user:import']"
>导入</el-button> >{{$t('bt.import')}}</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -134,19 +134,19 @@
:loading="exportLoading" :loading="exportLoading"
@click="handleExport" @click="handleExport"
v-hasPermi="['system:user:export']" v-hasPermi="['system:user:export']"
>导出</el-button> >{{$t('bt.export')}}</el-button>
</el-col> </el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row> </el-row>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" /> <el-table-column type="selection" width="50" align="center" />
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns[0].visible" /> <el-table-column :label="$t('system.user.userId')" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
<el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" /> <el-table-column :label="$t('system.user.userName')" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" /> <el-table-column :label="$t('system.user.nickName')" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
<el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" /> <el-table-column :label="$t('system.user.deptName')" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" /> <el-table-column :label="$t('system.user.phonenumber')" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
<el-table-column label="状态" align="center" key="status" v-if="columns[5].visible"> <el-table-column :label="$t('system.user.status')" align="center" key="status" v-if="columns[5].visible">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch <el-switch
v-model="scope.row.status" v-model="scope.row.status"
@ -156,13 +156,13 @@
></el-switch> ></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160"> <el-table-column :label="$t('system.user.createTime')" align="center" prop="createTime" v-if="columns[6].visible" width="160">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span> <span>{{ parseTime(scope.row.createTime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="操作" :label="$t('hint.operate')"
align="center" align="center"
width="160" width="160"
class-name="small-padding fixed-width" class-name="small-padding fixed-width"
@ -174,23 +174,23 @@
icon="el-icon-edit" icon="el-icon-edit"
@click="handleUpdate(scope.row)" @click="handleUpdate(scope.row)"
v-hasPermi="['system:user:edit']" v-hasPermi="['system:user:edit']"
>修改</el-button> >{{$t('bt.edit')}}</el-button>
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-delete" icon="el-icon-delete"
@click="handleDelete(scope.row)" @click="handleDelete(scope.row)"
v-hasPermi="['system:user:remove']" v-hasPermi="['system:user:remove']"
>删除</el-button> >{{$t('bt.delete')}}</el-button>
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']"> <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
<span class="el-dropdown-link"> <span class="el-dropdown-link">
<i class="el-icon-d-arrow-right el-icon--right"></i>更多 <i class="el-icon-d-arrow-right el-icon--right"></i>{{$t('bt.more')}}
</span> </span>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item command="handleResetPwd" icon="el-icon-key" <el-dropdown-item command="handleResetPwd" icon="el-icon-key"
v-hasPermi="['system:user:resetPwd']">重置密码</el-dropdown-item> v-hasPermi="['system:user:resetPwd']">{{$t('bt.resetPassWord')}}</el-dropdown-item>
<el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check" <el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check"
v-hasPermi="['system:user:edit']">分配角色</el-dropdown-item> v-hasPermi="['system:user:edit']">{{$t('bt.assigningRoles')}}</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</template> </template>