1 \src\components\Users\AddUser.vue
<template>
<!--
elmentUI 子页面的渲染显示注意事项说明:
子页面的渲染显示必须的使用“<el-dialog></el-dialog>标签及其所包含的子标签,否则子页面将不会被渲染显示出来。”
-->
<el-dialog width="30%">
<template #header>
<div class="my-header">
<h1 style="margin: 0px; padding: 0px; ">
<el-icon style="margin-right:5px; font-size: 25px; color:#337ecc; vertical-align: middle">
<CirclePlusFilled />
</el-icon>
添加用户
</h1>
</div>
</template>
<el-form label-width="100px" class="demo-ruleForm" label-position="left" status-icon :model="formAdd"
:rules="ruleAdd" ref="refRule">
<el-form-item label="账户:" prop="name">
<el-input v-model="formAdd.name" />
</el-form-item>
<el-form-item label="电子邮箱:" prop="email">
<el-input v-model="formAdd.email" />
</el-form-item>
<el-form-item label="手机号:" prop="phone">
<el-input v-model="formAdd.phone" />
</el-form-item>
<el-form-item label="角色:" prop="roleIdList">
<el-checkbox-group v-model="formAdd.roleIdList">
<el-checkbox v-for="item in formAdd.roleList" :key="item.id" :label="item.id">
{{item.name}}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<!-- <el-form-item label="系统帐户:" prop="isSystemAccount">
<el-select v-model="formAdd.isSystemAccount" style="width: 100%;">
<el-option label="系统帐户" :value="true" />
<el-option label="其它" :value="false" />
</el-select>
</el-form-item> -->
<el-form-item label="激活:" prop="isActive">
<el-select v-model="formAdd.isActive" style="width: 100%;">
<el-option label="激活" :value="true" />
<el-option label="禁用" :value="false" />
</el-select>
</el-form-item>
<el-form-item label="可用:" prop="deleted">
<el-select v-model="formAdd.deleted" style="width: 100%;">
<el-option label="已被删除" :value="true" />
<el-option label="可用" :value="false" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="this.formAdd.centerDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="onSubmit">提 交</el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import {
getCustomerByEmail,
getCustomerByPhone,
getRoleIndex,
createCustomer,
} from '../../common/http.api.js';
export default {
/*name和propParent属性用于在子页面成功提交后,控制对父页面的自动刷新*/
name: 'AddUser',
props: {
propParent: {},
},
data() {
//验证1个指定的电子邮箱已经是否被注册。
const validateEmailUnique = async (rule, value, callback) => {
if (value) {
let data = await this.isEmailUnique(value);
//console.log(data);
if (data.status == 200 && data.response) {
callback(new Error("该电子邮箱已经被注册!"));
} else {
callback();
}
}
};
//验证1个指定的手机号已经是否被注册。
const validatePhoneUnique = async (rule, value, callback) => {
if (value) {
let data = await this.isPhoneUnique(value);
if (data.status == 200 && data.response) {
callback(new Error("该手机号已经被注册!"));
} else {
callback();
}
}
};
return {
formAdd: {
name: '',
email: '',
phone: '',
roleIdList: [],
roleList: [],
deleted: false,
isActive: true,
//该实例用于指示,当前页面角色编辑子页面是否在父窗口中显示出来。
centerDialogVisible: false,
},
//用户添加表单输入验证初始化。
ruleAdd: {
name: [{
required: true,
message: '请输入账号名!',
trigger: 'blur',
},
{
min: 2,
max: 16,
message: '账号名的长度应在2到16个字符之间!',
trigger: 'blur'
},
],
email: [{
required: true,
message: '请输入电子邮箱!',
trigger: 'blur',
},
{
pattern: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/,
message: "电子邮箱格式错误!"
},
{
validator: validateEmailUnique,
trigger: "blur",
},
],
phone: [{
required: true,
message: "请输入手机号!",
trigger: 'blur',
},
{
pattern: 11 && /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/,
message: "手机号格式错误!"
},
{
validator: validatePhoneUnique,
trigger: "blur",
},
],
roleIdList: [{
required: true,
message: "必须选择1指定的角色!",
trigger: 'blur',
},
],
},
};
},
//监视父窗口传递的参数实例,来监视弹出对话框的不显示。
watch: {
async propParent(val) {
//console.log(val);
/*this.formAdd = val用于在子页面成功提交后,控制对子页面的自动关闭和父页面的自动刷新*/
this.formAdd = val;
this.formAdd.isActive = true;
this.formAdd.deleted = false;
let param = {
isActive: this.formAdd.isActive,
};
let res = await getRoleIndex(param);
this.formAdd.roleList = res.data.response;
//获取默认被选中的角色
this.formAdd.roleIdList=[];
this.formAdd.roleIdList.push(this.formAdd.roleList.find(route => route.name == "Register").id);
//console.log(this.formAdd.roleIdList.push(this.formAdd.roleList.find(route => route.name == "Register").id));
},
},
methods: {
//通过1个指定电子邮箱获取1个指定的用户实例,验证电子邮箱的唯一性。
async isEmailUnique(email) {
let emailParam = {
email: email,
};
let res = await getCustomerByEmail(emailParam);
return res.data;
},
//过1个指定手机号获取1个指定的用户实例,验证手机号的唯一性。
async isPhoneUnique(phone) {
let phoneParam = {
phone: phone,
};
let res = await getCustomerByPhone(phoneParam);
return res.data;
},
//添加提交事件
async onSubmit() {
this.$refs.refRule.validate(async (valid) => {
if (valid) {
let para = {
name: this.formAdd.name,
email: this.formAdd.email,
phone: this.formAdd.phone,
roleIdList: this.formAdd.roleIdList,
isSystemAccount: this.formAdd.isSystemAccount,
isActive: this.formAdd.isActive,
deleted: this.formAdd.deleted,
};
console.log(para);
let res = await createCustomer(JSON.stringify(para));
console.log(res.data);
if (res.status == 200) {
this.$message.success("成功添加");
//"runParent":自定义事件名,= @runParent(父控件),
this.$emit("runParent");
this.formAdd.centerDialogVisible = false;
} else {
this.$message.error(res.msg);
this.formAdd.centerDialogVisible = true;
}
} else {
this.$message.error('输入不能通过验证 !');
this.formAdd.centerDialogVisible = true;
return false;
}
});
},
},
async mounted() {
},
};
</script>
<style scoped lang="scss">
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
</style>
2 \src\components\Users\ EditUser.vue
<template>
<!--
elmentUI 子页面的渲染显示注意事项说明:
子页面的渲染显示必须的使用“<el-dialog></el-dialog>标签及其所包含的子标签,否则子页面将不会被渲染显示出来。”
-->
<el-dialog width="30%">
<template #header>
<div class="my-header">
<h1 style="margin: 0px; padding: 0px; ">
<el-icon style="margin-right:5px; font-size: 25px; color:#337ecc; vertical-align: middle">
<Edit />
</el-icon>
编辑用户
</h1>
</div>
</template>
<el-form :model="formUser" label-width="100px" class="demo-ruleForm" label-position="left" status-icon
:rules="ruleEdit" ref="refRule">
<!--
elmentUI Upload组件注意事项说明:
v-model:file-list:文件上传--需要或已经被上传的文件。
:action:必须被实例化的属性,文件上传--上传文件所需要调用的指定的后端控制器行为方法。
name:如果指定的后端控制器行为方法中使用IFormFile参数实例,则该属性是必须被实例化的属性,且属性实例化值与IFormFile参数名必须相同。
:limit="1"://同1次上传操作中,最大能够上传多文件的个数值。
:headers(注意):很多网上的示例把headers属性实例化为“mutipart/form-data,在此我重申一下,没有必要。elementUI已经封装加工过了,
同时如果设定headers属性实例,还会造成异常:"Failed to read the request form. Missing content-type boundary"
或异常:"body length limit 16384 exceeded"。
:before-upload:文件上传前验证文件是否符合所规则的上传规则。
-->
<el-upload v-model:file-list="fileList" class="upload-demo" list-type="picture" :action="actionRequestUrl"
name="formFile" :before-upload="beforeUpload" :on-change="onUploadChange" :data="paramData">
<el-button type="primary">点击上传</el-button>
</el-upload>
<el-form-item label="编号:">
<el-input v-model="formUser.id" disabled />
</el-form-item>
<el-form-item label="名称:" prop="name">
<el-input v-model="formUser.name" />
</el-form-item>
<el-form-item label="邮箱:" prop="email">
<el-input v-model="formUser.email" />
</el-form-item>
<el-form-item label="手机号:" prop="phone">
<el-input v-model="formUser.phone" />
</el-form-item>
<el-form-item label="角色:" prop="roleIdList">
<el-checkbox-group v-model="formUser.roleIdList">
<el-checkbox v-for="item in formUser.roleList" :key="item.id" :label="item.id">
{{item.name}}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<!-- 注意:必须使用 :value="true",不能使用 value=true,否则会出现:
“ [Vue warn]: Invalid prop: type check failed for prop "modelValue". Expected String | Number | Object, got Boolean with value true. ”
警告信息 -->
<!-- <el-form-item label="系统帐户:" prop="isSystemAccount">
<el-select v-model="formUser.isSystemAccount" style="width: 100%;">
<el-option label="系统帐户" :value="true" />
<el-option label="其它" :value="false" />
</el-select>
</el-form-item> -->
<el-form-item label="激活:" prop="isActive">
<el-select v-model="formUser.isActive" style="width: 100%;">
<el-option label="激活" :value="true" />
<el-option label="禁用" :value="false" />
</el-select>
</el-form-item>
<el-form-item label="可用:" prop="deleted">
<el-select v-model="formUser.deleted" style="width: 100%;">
<el-option label="已被删除" :value="true" />
<el-option label="可用" :value="false" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel">取 消</el-button>
<el-button type="primary" @click="submitEdit">提 交</el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import {
getCustomerByEmail,
getCustomerByPhone,
getRoleIndex,
editCustomer,
} from '../../common/http.api.js';
export default {
name: 'EditUser',
props: {
propParent: {},
},
data() {
//验证1个指定的电子邮箱已经是否被注册。
const validateEmailUnique = async (rule, value, callback) => {
if (value) {
let data = await this.isEmailUnique(value);
//console.log(data);
if (data.status == 200 && data.response) {
callback(new Error("该电子邮箱已经被注册!"));
} else {
callback();
}
}
};
//验证1个指定的手机号已经是否被注册。
const validatePhoneUnique = async (rule, value, callback) => {
if (value) {
let data = await this.isPhoneUnique(value);
if (data.status == 200 && data.response) {
callback(new Error("该手机号已经被注册!"));
} else {
callback();
}
}
};
return {
//用户编辑表单实例初始化。
formUser: {
id: 0,
name: '',
email: '',
phone: '',
avatar: '',
roleIdList: [],
roleList: [],
isSystemAccount: false,
isActive: true,
deleted: false,
//该实例用于指示,当前页面角色编辑子页面是否在父窗口中显示出来。
centerDialogVisible: false,
},
//文件上传--需要或已经被上传的文件。
fileList: [{
name: '',
url: '',
}],
//文件上传--上传文件所需要调用的指定的后端控制器行为方法。
actionRequestUrl: '',
//文件上传--允许被上传文件的类型规则
fileType: ["bmp", "gif", "jpeg", "jpg", "jpe", "jfif", "pjpeg", "webp", "png", "svg", "tiff", "tif"],
//文件上传--允许被上传文件的最大大小值规则,单位:MB
fileSize: 10,
paramData: {
customerId: 0,
},
//用户添加表单输入验证初始化。
ruleEdit: {
name: [{
required: true,
message: '请输入账号名!',
trigger: 'blur',
},
{
min: 2,
max: 16,
message: '账号名的长度应在2到16个字符之间!',
trigger: 'blur'
},
],
email: [{
required: true,
message: '请输入电子邮箱!',
trigger: 'blur',
},
{
pattern: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/,
message: "电子邮箱格式错误!"
},
{
validator: validateEmailUnique,
trigger: "blur",
},
],
phone: [{
required: true,
message: "请输入手机号!",
trigger: 'blur',
},
{
pattern: 11 && /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/,
message: "手机号格式错误!"
},
{
validator: validatePhoneUnique,
trigger: "blur",
},
],
roleIdList: [{
required: true,
message: "必须选择1指定的角色!",
trigger: 'blur',
}, ],
},
};
},
//监视父窗口传递的参数实例,使当前子页面中的表单始终显示父窗口最新传递的参数实例。
watch: {
async propParent(val) {
//console.log(val);
/*this.formUser = val用于在子页面成功提交后,控制对子页面的自动关闭和父页面的自动刷新*/
this.formUser = val;
this.fileList[0].name = "";
this.fileList[0].url = this.formUser.avatar;
//获取所有角色。
let param = {
isActive: this.formUser.isActive,
};
let res = await getRoleIndex(param);
this.formUser.roleList = res.data.response;
//获取默认被选中的角色。
this.formUser.roleIdList = [];
this.formUser.roleIdList = val.roleCollection.map((item) => item.id);
},
},
methods: {
//上传文件之前,验证指定上传文件是否符合上传规则。
beforeUpload(file) {
if (file.type != "" || file.type != null || file.type != undefined) {
//清空已上传的文件列表
//this.$refs.upload.clearFiles();
//截取文件的后缀,判断文件类型
let fileExt = file.name.replace(/.+\./, "").toLowerCase();
//计算指定上传文件大小是否大于10MB。
let isMaxFileSize = file.size / 1024 / 1024 <= 10;
//如果大于i大于10MB
if (!isMaxFileSize) {
this.$message.error("上传文件大小不能超过 10MB!");
return false;
}
//如果文件类型不在允许上传的范围内
if (this.fileType.includes(fileExt)) {
return true;
} else {
this.$message.error("上传文件格式不正确!");
return false;
}
}
},
//头像图片文件发生变更时,实现头像图片文件的上传操作。
//注意:该方法必须包含“file”参数。
async onUploadChange(file, fileList) {
/* console.log("需要或已经被上传的文件列表:", fileList);
console.log("1个指定的需要被上传的文件:", file);
console.log("1个指定的需要被上传文件的大小:", file.size);
console.log("1个指定的需要被上传文件的文件名:", file.name);
console.log("1个指定的需要被上传文件的完整信息(作为传递参数的实例值):", file.raw);
console.log("1个指定的需要被上传文件的URL:", file.url);
console.log("上传操作后所返回的成功/失败的数据信息:", file.response);
console.log("1个指定用户的长整型编号值:", this.formUser.id); */
this.paramData.customerId = this.formUser.id;
this.actionRequestUrl = "";
//this.actionRequestUrl = "https://localhost:7239/Customer/PostAvatarStream?customerId=" + this.formUser.id;
this.actionRequestUrl = " https://localhost:7239/Customer/PostAvatarStream";
//需要或已经被上传的文件列表中只渲染显示最新的1个上传文件。
this.fileList = fileList.slice(-1);
//console.log("渲染显示的文件列表:", this.fileList);
},
//通过1个指定电子邮箱获取1个指定的用户实例,验证电子邮箱的唯一性。
async isEmailUnique(email) {
let emailParam = {
email: email,
customerId: this.formUser.id,
};
let res = await getCustomerByEmail(emailParam);
return res.data;
},
//过1个指定手机号获取1个指定的用户实例,验证手机号的唯一性。
async isPhoneUnique(phone) {
let phoneParam = {
phone: phone,
customerId: this.formUser.id,
};
let res = await getCustomerByPhone(phoneParam);
return res.data;
},
//编辑提交事件
async submitEdit() {
this.$refs.refRule.validate(async (valid) => {
if (valid) {
let para = {
id: this.formUser.id,
name: this.formUser.name,
email: this.formUser.email,
phone: this.formUser.phone,
roleIdList: this.formUser.roleIdList,
isSystemAccount: this.formUser.isSystemAccount,
isActive: this.formUser.isActive,
deleted: this.formUser.deleted,
};
let res = await editCustomer(JSON.stringify(para));
//console.log(res.data);
if (res.status == 200) {
this.$message.success("成功修改");
//"runParent":自定义事件名,= @runParent(父控件),
this.$emit("runParent");
this.formUser.centerDialogVisible = false;
} else {
this.$message.error(res.msg);
this.formUser.centerDialogVisible = true;
}
} else {
this.$message.error('输入不能通过验证 !');
this.formUser.centerDialogVisible = true;
return false;
}
});
},
async onCancel() {
//"runParent":自定义事件名,= @runParent(父控件),
this.$emit("runParent");
this.formUser.centerDialogVisible = false;
},
},
async mounted() {
}, };
</script>
<style scoped lang="scss">
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
</style>
3 \src\views\Users\UserView.vue
<template>
<div class="wrap">
<!--注意:1、“回到顶部”组件及其回滚内容都必须包含到同1个div容器中。-->
<!-- 2、div容器中必须有1个唯1性的样式类(例如:wrap)的定义,以便“回到顶部”组件进行回滚时进行定位。 -->
<!-- 3、“回到顶部”组件 必须在所有的回滚内容之上。 -->
<el-backtop :bottom="100" target=".wrap" style="background-color: #666;">
<el-icon style="color: #99ffff; font-size: 40px; margin-top: -2px;">
<CaretTop />
</el-icon>
</el-backtop>
<el-form :model="queryForm" :rules="queryRule" ref="refRule" label-width="120px" label-position="left">
<el-row :gutter="20">
<el-col :span="18">
<el-form-item label="账户:">
<el-input v-model="queryForm.name" type="text" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="激活:">
<el-select v-model="queryForm.isActive">
<el-option label="不限" value="" />
<el-option label="激活" value=true />
<el-option label="禁用" value=false />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="18">
<el-form-item label="电子邮箱:">
<el-input v-model="queryForm.email" type="text" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="系统账户:">
<el-select v-model="queryForm.isSystemAccount">
<el-option label="不限" value="" />
<el-option label="系统账户" value=true />
<el-option label="其它" value=false />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="18">
<el-form-item label="手机:">
<el-input v-model="queryForm.phone" type="text" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="可用:">
<el-select v-model="queryForm.deleted">
<el-option label="不限" value="" />
<el-option label="已被删除" value=true />
<el-option label="可用" value=false />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="开始日期:" prop="createdDateTimeFrom">
<el-date-picker style="width: 100%" v-model="queryForm.createdDateTimeFrom" type="date"
format="YYYY-MM-DD" value-format="YYYY-MM-DD" :append-to-body="false">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结束日期:" prop="createdDateTimeTo">
<el-date-picker style="width: 100%" v-model="queryForm.createdDateTimeTo" type="date"
format="YYYY-MM-DD" value-format="YYYY-MM-DD" :append-to-body="false"> </el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-button type="primary" @click="onSubmit">
<el-icon style="margin-right:5px; font-size: 16px;">
<Search />
</el-icon>
查 询
</el-button>
<el-button @click="onResert">
<el-icon style="margin-right:5px; font-size: 16px;">
<RefreshRight />
</el-icon>
重 置
</el-button>
</el-col>
</el-row>
</el-form>
<el-row type="flex" justify="end" style="margin:5px 0px;">
<el-col :span="8">
<div class="lightgreen-box">
<el-button style="background-color: #79bbff; color: #FFFFFF; margin-right:10px" @click="addUser()">
<el-icon style="margin-right:5px; font-size: 22px;">
<CirclePlusFilled />
</el-icon>
添 加
</el-button>
<el-button type="danger" @click="deleteSelected()">
<el-icon style="margin-right:5px; font-size: 22px;">
<Delete />
</el-icon>
删除所选
</el-button>
</div>
</el-col>
</el-row>
<!-- 指定页面渲染显示,handleTableSort:排序;selectionChange:所选择的复选框控件,为删除所选操作提供数据支撑;-->
<el-table :data="currentPageList" style="width: 100%" :default-sort="{
'prop': JSON.parse(this.pagination.OrderByModel).OrderByFiled,
'order':JSON.parse(this.pagination.OrderByModel).OrderByType}" @sort-change="handleTableSort" ref="refTable"
@selection-change="selectionChange">
<el-table-column type="selection" width="50px" />
<el-table-column property="id" label="编号" width="80px" sortable />
<el-table-column property="name" label="帐号" sortable>
<template #default="scope">
<el-avatar shape="square" :size="80" style="vertical-align: middle; margin-right: 3px; float: left;"
:src="scope.row.avatar" :fit="fitCover">
</el-avatar>
<div class="userinfo-inner">
<span style="width: 100%; height: 20px; line-height: 20px;">
{{scope.row.name}}
</span>
<br />
<span
style=" width: 100%; height: 10px; line-height: 10px; font-size: 60%; color: #999999; font-weight: 400;">
{{scope.row.email}}
</span>
<br />
<span
style=" width: 100%; height: 10px; line-height: 10px; font-size: 60%; color: #999999; font-weight: 400;">
{{scope.row.phone}}
</span>
</div>
</template>
</el-table-column>
<el-table-column label="角色" align="center" width="100px">
<template #default="scope">
<el-tag v-for="tag in scope.row.roleCollection" :key="tag.id" effect="plain"
style="margin-bottom: 3px;">
{{ tag.name }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" align="center" width="85px">
<template #default="scope">
<!-- <el-tag effect="plain" v-show="scope.row.isSystemAccount">系统帐户</el-tag>
<el-tag type="success" v-show="!scope.row.isSystemAccount">其它</el-tag> -->
<el-tag effect="plain" v-show="scope.row.isSystemAccount">系统帐户</el-tag>
<el-tag type="success" effect="plain" v-show="!scope.row.isSystemAccount"
style="letter-spacing:7px; text-indent:10px">其它</el-tag>
<el-tag type="success" effect="plain" style="letter-spacing:7px; text-indent:10px; margin: 3px 0px;"
v-show="scope.row.isActive">激活</el-tag>
<el-tag type="danger" effect="plain" style="letter-spacing:7px; text-indent:10px; margin: 3px 0px;"
v-show="!scope.row.isActive">禁用</el-tag>
<el-tag type="success" effect="plain" v-show="!scope.row.deleted"
style="letter-spacing:7px; text-indent:10px">可用</el-tag>
<el-tag type="danger" effect="plain" v-show="scope.row.deleted">已被删除</el-tag>
</template>
</el-table-column>
<el-table-column prop="createdDateTime" label="注册时间" :formatter="dateTimeformat" width="155" sortable />
<el-table-column prop="updatedDateTime" label="最后更新时间" :formatter="dateTimeformat" width="155" sortable />
<el-table-column align="center" width="85px">
<template #default="scope">
<el-button type="primary" size="small" style="" :disabled="scope.row.email=='admin@yourStore.com'"
@click="onResertPassword(scope.row)">
密码重置
</el-button>
<el-button type="primary" size="small"
style="letter-spacing:7px; text-indent:10px; margin: 7px 0px;"
:disabled="scope.row.email=='admin@yourStore.com'" @click="editUser(scope.row)">
编辑
</el-button>
<el-button type="danger" size="small" style="letter-spacing:7px; text-indent:10px; margin:0px;"
:disabled="scope.row.email=='admin@yourStore.com'" @click="deleteSingle(scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- “->”:设定 “el-pagination”分页组件靠右显示。 -->
<el-pagination v-model:current-page="this.pagination.pageIndex" v-model:page-size="this.pagination.pageSize"
:page-sizes="[3, 10, 15, 20, 50, 100]" :total="this.pagination.totalCount" prev-text="上一页" next-text="下一页"
background layout="->, total, sizes, prev, pager, next" @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
<!-- 注意: @runParent,不能与"editDialogClose"同名,否则会出现:
“ [Vue warn]:emitted event "editDialogClose" but it is neither declared in the emits option nor as an "onEditDialogClose" prop. ”
警告信息 -->
<EditUser v-model="this.formEidt.centerDialogVisible" :propParent="this.formEidt" @runParent="editDialogClose">
</EditUser>
<AddUser v-model="this.formAdd.centerDialogVisible" :propParent="this.formAdd" @runParent="addDialogClose">
</AddUser>
</div>
</template>
<script>
import moment from 'moment';
import {
postCustomerIndex,
resertPassword,
deleteCustomer,
deleteSelectedCustomer,
} from '../../common/http.api.js';
import EditUser from '@/components/Users/EditUser.vue';
import AddUser from '@/components/Users/AddUser.vue'
export default {
components: {
EditUser,
AddUser,
},
data() {
//验证查询表单中的开始日期必须小于等于当前时间。
const validateDateTimeFrom = (rule, value, callback) => {
if (value != null || value != '') {
if (this.moment(value) > Date.now())
callback(new Error("开始日期必须小于等于当前时间!"));
}
callback();
};
//验证查询表单中的开始日期必须小大于等于开始日期;且小于等于当前时间。
const validateDateTimeTo = (rule, value, callback) => {
if (this.queryForm.createdDateTimeFrom != '') {
if (value == null || value == '') {
callback(new Error("请输入结束日期!"));
} else if (this.moment(value) > Date.now()) {
callback(new Error("结束日期必须小于等于当前时间!"));
} else if (this.moment(value) < this.moment(this.queryForm.createdDateTimeFrom)) {
callback(new Error("结束日期必须大于等于开始日期!"));
}
}
callback();
};
return {
//获取日期格式化类的1个指定实例。
moment: moment,
//查询表单实例初始化。
queryForm: {
name: '',
email: '',
phone: '',
isSystemAccount: '',
isActive: '',
deleted: '',
createdDateTimeFrom: '',
createdDateTimeTo: '',
},
queryRule: {
createdDateTimeFrom: [{
validator: validateDateTimeFrom,
trigger: "blur"
}],
createdDateTimeTo: [{
validator: validateDateTimeTo,
trigger: "blur"
}]
},
//分页表实例初始化。
pagination: {
pageIndex: 1, //初始化当前页,即第1页。
pageSize: 15, //初始化每页最多所包含的项数值,即每页最多所包含15项。
totalCount: 0, //初始化数据源的总计项数值,由于还没有加载数据源所以该值为:0。
//初始化排序字段及其方式。
OrderByModel: JSON.stringify({
OrderByFiled: 'createdDateTime',
OrderByType: 'descending',
}),
QueryCondition: ""
},
//初始化当前页的渲染数据集列表实例。
currentPageList: [],
//初始化图片的填充方式:按照长宽比填充整个图片(https://www.w3school.com.cn/css/css3_object-fit.asp)。
fitCover: "cover",
//当前页面中被选择选复选框中的值。
selectIdArray: [],
//编辑子页参数实例。
formEidt: {
id: 0,
name: '',
email: '',
phone: '',
avatar: '',
isSystemAccount: false,
isActive: true,
deleted: false,
//该实例用于指示,当前页面角色编辑子页面是否在父窗口中显示出来。
centerDialogVisible: false,
},
//添加子页参数实例,由于添加子页,不需要获取监视父窗口传递的参数实例,所以可以只有“centerDialogVisible”。
formAdd: {
//该实例用于指示,当前页面角色编辑子页面是否在父窗口中显示出来。
centerDialogVisible: false,
},
};
},
methods: {
//格式化日期显示。
dateTimeformat: function(row, column) {
let data = row[column.property];
if (data == null) {
return null;
}
return moment(data).format('YYYY-MM-DD HH:mm:ss');
},
//获取当前页面渲染显示所需的数据源。
async currentPageInit() {
let res = await postCustomerIndex(this.pagination);
//console.log(res.data.response.data);
this.currentPageList = res.data.response.data;
this.pagination.totalCount = res.data.response.totalCount;
},
//表单查询事件
async onSubmit() {
this.$refs.refRule.validate(async (valid) => {
if (valid) {
var where = {};
if (this.queryForm.name != '') {
where.name = this.queryForm.name;
}
if (this.queryForm.email != '') {
where.email = this.queryForm.email;
}
if (this.queryForm.phone != '') {
where.phone = this.queryForm.phone;
}
if (this.queryForm.isSystemAccount != '') {
where.isSystemAccount = this.queryForm.isSystemAccount;
}
if (this.queryForm.isActive != '') {
where.isActive = this.queryForm.isActive;
}
if (this.queryForm.deleted != '') {
where.deleted = this.queryForm.deleted;
}
if (this.queryForm.createdDateTimeFrom != '') {
where.createdDateTimeFrom = this.moment(this.queryForm.createdDateTimeFrom)
.format('YYYY-MM-DD HH:mm:ss');
}
if (this.queryForm.createdDateTimeTo != '') {
where.createdDateTimeTo = this.moment(this.queryForm.createdDateTimeTo).add(
1, 'days').format('YYYY-MM-DD HH:mm:ss');
}
//console.log(where);
this.pagination.QueryCondition = JSON.stringify(where);
//console.log(this.pagination.QueryCondition);
await this.currentPageInit();
} else {
this.$message.error('输入不能通过验证 !');
return false;
}
});
},
//重置页面样式及其数据。
async onResert() {
//重置查询表单。
this.queryForm = {
name: '',
email: '',
phone: '',
isSystemAccount: '',
isActive: '',
deleted: '',
createdDateTimeFrom: '',
createdDateTimeTo: '',
};
//重置排序字段试及其排序方式。
this.pagination = {
pageIndex: 1,
pageSize: 15,
totalCount: 0,
OrderByModel: JSON.stringify({
OrderByFiled: 'createdDateTime',
OrderByType: 'descending',
}),
QueryCondition: ""
};
await this.$refs.refTable.sort(JSON.parse(this.pagination.OrderByModel).OrderByFiled,
JSON.parse(this.pagination.OrderByModel).OrderByType);
await this.currentPageInit();
},
// 单击排序三角图标时所触发的事件。
async handleTableSort({
column
}) {
//防止排序方式的值为:null。
if (column.property == null && column.order == null) {
column.property = 'createdDateTime',
column.order = "descending";
} else if (column.property != null && column.order == null) {
column.order = "ascending";
}
this.pagination.OrderByModel = JSON.stringify({
OrderByFiled: column.property,
OrderByType: column.order,
});
await this.currentPageInit();
},
//该事件在改变每页最多所包含的项数值后,把数据源加载到当前页面中,并重新对当前页进行渲染显示。
async handleSizeChange(size) {
this.pagination.pagesize = size;
//console.log(this.pagesize); //每页最多所包含的项数值。
await this.currentPageInit();
},
//该事件在改变当前页的索引值后,把数据源加载到当前页面中,并重新对当前页进行渲染显示。
async handleCurrentChange(currentPage) {
this.pagination.PageIndex = currentPage;
//console.log(this.PageIndex); //当前页的索引值。
await this.currentPageInit();
},
//对1个指定用户的密码进行重置。
async onResertPassword(row) {
let res = await resertPassword({
customerId: row.id
});
console.log(res.data);
if (res.status == 200) {
this.$message.success("成功密码重置");
} else {
this.$message.error(res.msg);
}
},
//从用户表中删除单行指定数据后,并重新渲染显示当前页面。
async deleteSingle(row) {
await this.$confirm(`确认删除记录:${row.id}!`, '提示', {
type: 'warning'
})
.then(async () => { // 确定操作
let para = {
customerId: row.id,
};
let res = await deleteCustomer(para);
console.log(res.data);
})
.catch(() => { // 取消操作
this.$message({
type: 'info',
message: '已取消退出'
});
});
await this.currentPageInit();
},
//获取将要被删除的编号值集,编号之间用“,”隔开。
async selectionChange(selectIdArray) {
this.selectIdArray = selectIdArray;
//console.log("选中的值", selectIdArray.map((item) => item.id));
//console.log("this.selectIdArray选中的值", this.selectIdArray);
},
//从用户表中删除多行指定数据后,并重新渲染显示当前页面。
async deleteSelected() {
let idArray = this.selectIdArray.map((item) => item.id);
// 根据后台想要的参数格式选择
//console.log(idArray.join(",")); //1,2,3,4
//console.log(idArray); //[1,2,3,4]
if (idArray.length <= 0) {
this.$message.error("请选择要删除的一行数据!");
return;
}
await this.$confirm(`确认删除记录:${idArray}!`, '提示', {
type: 'warning'
})
.then(async () => { // 确定操作
// 根据后台想要的参数格式选择
//console.log(this.selectIdArray.join(",")); //1,2,3,4
//console.log(this.selectIdArray); //[1,2,3,4]
await deleteSelectedCustomer({
selectIdArray: idArray.join(",")
});
})
.catch(() => { // 取消操作
this.$message({
type: 'info',
message: '已取消退出'
});
});
await this.currentPageInit();
},
//编辑单击事件,为子编辑页面的渲染显示提供数据支撑。
async editUser(row) {
this.formEidt = Object.assign({}, row);
this.formEidt.centerDialogVisible = true;
},
//子编辑页面提交成功时,自动刷新当前页。
async editDialogClose() {
await this.currentPageInit();
},
//添加单击事件,为子添加页面的渲染显示提供数据支撑。
async addUser() {
this.formAdd = Object.assign({}, {});
this.formAdd.centerDialogVisible = true;
},
//子添加页面提交成功时,自动刷新当前页。
async addDialogClose() {
await this.onResert();
},
},
async mounted() {
await this.currentPageInit();
},
};
</script>
<style scoped lang="scss">
.wrap {
height: 100%;
overflow-x: hidden;
}
//表单“label”字体样式
:deep(.el-form-item__label) {
font-weight: 400;
}
// 修改表头样式。
:deep(.el-table__header thead th) {
background-color: #000000;
color: #ffd04b;
font-weight: 400;
text-align: center;
}
//修改复选框控件样式。
:deep(.el-checkbox) {
display: flex;
align-items: center;
width: 25px;
height: 25px;
//修改选中框的大小
.el-checkbox__inner {
width: 20px;
height: 20px;
border: #409EFF solid 2px;
//修改选中框中的对勾的大小和位置
&::after {
// 对号
border: 4px solid #FFFFFF;
// 不覆盖下面的 会 导致对号变形
box-sizing: content-box;
content: "";
border-left: 0;
border-top: 0;
height: 15px;
position: absolute;
top: -3px;
}
}
//修改点击文字颜色不变
.el-checkbox__input.is-checked+.el-checkbox__label {
color: #333333;
}
.el-checkbox__label {
line-height: 25px;
//padding-left: 8px;
}
}
//表格隔行变换颜色。
:deep(.el-table__body tbody tr:nth-child(odd)) {
background-color: #FFFFFF;
}
:deep(.el-table__body tbody tr:nth-child(even) td) {
background-color: #CCFFFF;
}
.userinfo-inner {
cursor: pointer;
float: left;
}
//标签控件字体样式。
.el-tag {
font-weight: 400;
padding: 5px 5px;
}
//按钮控件字体样式。
.el-button {
font-weight: 400;
padding: 5px 5px;
}
//“el-pagination”分页组件样式。
.el-pagination {
margin-top: 10px;
//font-size: 25px;
//"上一页"样式。
:deep(.btn-prev) {
background-color: transparent;
height: 40px;
margin-right: 20px;
}
//"下一页"样式。
:deep(.btn-next) {
background-color: transparent;
height: 40px;
margin-left: 20px;
}
//分页索引样式。
:deep(.number) {
background-color: transparent;
min-width: 40px;
height: 40px;
margin-right: 15px;
}
}
//“el-pagination”分页组件中下拉框控件字体样式。
:deep(.el-input__wrapper) {
//font-size: 25px;
}
.lightgreen-box {
//background-color: lightgreen;
//height: 24px;
float: right;
}
</style>
对以上功能更为具体实现和注释见:230412_016shopvue(用户增、修、删的前端实现)。