-- 创建数据库
CREATE SCHEMA `sims` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建表
CREATE TABLE `role` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '角色编号',
`name` varchar(45)
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '角色名称',PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='角色表';
-- 新增数据
INSERT INTO `role` (`name`) VALUES ('admin');
INSERT INTO `role` (`name`) VALUES ('salesperson');
SELECT `id`, `name` FROM `role`;
-- 创建用户表,每一个用户对应角色表的一个角色
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '用户编号',
`name` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '姓名',
`gender` int NOT NULL COMMENT '性别(0:女,1:男)',
`phone` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '电话',
`password` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码',
`roleid` int NOT NULL COMMENT '角色编号', PRIMARY KEY (`id`), UNIQUE KEY `phone_UNIQUE` (`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
-- 新增用户表数据
INSERT INTO `user` (`name`, `gender`, `phone`, `password`,`roleid` ) VALUES ('赵总监', '1', '12345678901', '123456', '1');
INSERT INTO `user` (`name`, `gender`, `phone`, `password`,`roleid` ) VALUES ('钱经理', '0', '23456789012', '234567', '2');
-- SELECT `id`, `roleid`, `phone`, `password`, `name`, `gender` FROM `user`;
--
-- -- 修改数据
-- UPDATE `user` SET `name` = '小赵' WHERE `id` = 1;
-- SELECT `id`, `roleid`, `phone`, `password`, `name`, `gender` FROM `user`;
--
-- -- 删除数据/删除钱经理
-- DELETE FROM `user` WHERE `id` = 2;
-- SELECT `id`, `roleid`, `phone`, `password`, `name`, `gender` FROM `user`;
--
-- -- 查询数量
-- SELECT COUNT(*) FROM `user`
-- SELECT COUNT(*) FROM `role` -- 结果表示有多少个角色
-- 联表查询,as用于改列名,from指定表名,left join表示左连接后面跟的表名和重命名,on表示根据指定列进行联接
-- SELECT u.`id` AS uid, u.`phone`, u.`password`, u.`name` AS uname, u.`gender`, r.`id` AS rid, r.`name` AS rname FROM `user` u LEFT JOIN `role` r ON u.`roleid`= r.`id`
-- 给user表添加数据
INSERT INTO `user` (`roleid`, `phone`, `password`, `name`, `gender`) VALUES ('2', '34567890123', '123456', '孙经理', '0');
INSERT INTO `user` (`roleid`, `phone`, `password`, `name`, `gender`) VALUES ('2', '45678901234', '123456', '周经理', '1');
INSERT INTO `user` (`roleid`, `phone`, `password`, `name`, `gender`) VALUES ('2', '56789012345', '123456', '吴经理', '0');
INSERT INTO `user` (`roleid`, `phone`, `password`, `name`, `gender`) VALUES ('2', '67890123456', '123456', '郑经理', '1');
INSERT INTO `user` (`roleid`, `phone`, `password`, `name`, `gender`) VALUES ('2', '78901234567', '123456', '王经理', '0');
SELECT `id`, `roleid`, `phone`, `password`, `name`, `gender` FROM `user`;
-- 分页查询
-- SELECT u.`id` AS uid, u.`phone`, u.`password`, u.`name` AS uname,u.`gender`, r.`id` AS rid, r.`name` AS rname FROM `user` u LEFT JOIN `role` r ON u.`roleid` = r.`id` LIMIT 0, 2
-- 创建销售线索表
CREATE TABLE `sims`.`lead` (
`id` INT NOT NULL AUTO_INCREMENT,
`source` VARCHAR(255) NULL,-- 线索来源
`information` VARCHAR(255) NULL,-- 客户信息
`contact` VARCHAR(255) NULL,-- 联系方式
`description` VARCHAR(255) NULL,-- 需求描述
PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '北京百货', '010-12345678', '衬衫');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '广州百货', '020-12345678', '羊毛衫');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '上海百货', '021-12345678', '袜子');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '重庆百货', '023-12345678', '裤子');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '南京百货', '025-12345678', '高跟鞋');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '武汉百货', '027-12345678', '衬衫');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '成都百货', '028-12345678', '羊毛衫');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '西安百货', '029-12345678', '袜子');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '杭州百货', '0571-12345678', '裤子');
INSERT INTO `lead` (`source`, `information`, `contact`, `description`) VALUES ('百度营销', '深圳百货', '0755-12345678', '高跟鞋');
-- 创建销售机会表
CREATE TABLE `sims`.`opportunity` (
`id` INT NOT NULL AUTO_INCREMENT,
`source` VARCHAR(255) NULL,-- 机会来源
`information` VARCHAR(255) NULL,-- 客户信息
`contact` VARCHAR(255) NULL,-- 联系方式
`description` VARCHAR(255) NULL,-- 需求描述
`stage` VARCHAR(255) NULL,-- 进展状况
PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '赵先生', '010-12345678', '衬衫', '初步接触');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '钱女士', '020-12345678', '羊毛衫', '需求分析');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '孙先生', '021-12345678', '袜子', '提案');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '李女士', '023-12345678', '裤子', '谈判');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '周先生', '025-12345678', '高跟鞋', '成交');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '吴女士', '027-12345678', '衬衫', '初步接触');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '郑先生', '028-12345678', '羊毛衫', '需求分析');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '王女士', '029-12345678', '袜子', '提案');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '冯先生', '0571-12345678', '裤子', '谈判');
INSERT INTO `opportunity` (`source`, `information`, `contact`, `description`, `stage`) VALUES ('百度营销', '陈女士', '0755-12345678', '高跟鞋', '成交');
-- 创建客户表
CREATE TABLE `sims`.`customer` (
`id` INT NOT NULL AUTO_INCREMENT,
`information` VARCHAR(255) NULL,-- 客户信息
`name` VARCHAR(255) NULL,-- 联系人
`contact` VARCHAR(255) NULL,-- 联系方式
`description` VARCHAR(255) NULL,-- 互动记录描述
`evaluate` VARCHAR(255) NULL,-- 客户价值评估
PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('北京百货', '赵先生', '010-12345678', '成交1笔生意', '较大');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('广州百货', '钱女士', '020-12345678', '成交2笔生意', '较小');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('上海百货', '孙先生', '021-12345678', '成交3笔生意', '较大');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('重庆百货', '李女士', '023-12345678', '成交4笔生意', '较小');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('南京百货', '周先生', '025-12345678', '成交5笔生意', '较大');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('武汉百货', '吴女士', '027-12345678', '成交6笔生意', '较小');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('成都百货', '郑先生', '028-12345678', '成交7笔生意', '较大');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('西安百货', '王女士', '029-12345678', '成交8笔生意', '较小');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('杭州百货', '冯先生', '0571-12345678', '成交9笔生意', '较大');
INSERT INTO `customer` (`information`, `name`, `contact`, `description`, `evaluate`) VALUES ('深圳百货', '陈女士', '0755-12345678', '成交10笔生意', '较小');
-- 创建销售订单表
CREATE TABLE `sims`.`order` (
`id` INT NOT NULL AUTO_INCREMENT,
`information` VARCHAR(255) NULL,-- 客户信息
`detail` VARCHAR(255) NULL,-- 产品明细
`contact` VARCHAR(255) NULL,-- 发货信息
`status` VARCHAR(255) NULL,-- 付款状态
PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('北京百货', '1000件衬衫', '北京百货_赵先生_010-12345678', '已付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('广州百货', '1000件羊毛衫', '广州百货_钱女士_020-12345678', '未付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('上海百货', '1000件袜子', '上海百货_孙先生_021-12345678', '已付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('重庆百货', '1000件裤子', '重庆百货_李女士_023-12345678', '未付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('南京百货', '1000件高跟鞋', '南京百货_周先生_025-12345678', '已付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('武汉百货', '1000件衬衫', '武汉百货_吴女士_027-12345678', '未付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('成都百货', '1000件羊毛衫', '成都百货_郑先生_028-12345678', '已付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('西安百货', '1000件袜子', '西安百货_王女士_029-12345678', '未付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('杭州百货', '1000件裤子', '杭州百货_冯先生_0571-12345678', '已付');
INSERT INTO `order` (`information`, `detail`, `contact`, `status`) VALUES ('深圳百货', '1000件高跟鞋', '深圳百货_陈女士_0755-12345678', '未付');
spring boot mysql相关配置
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/sims?serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=aaaa
大屏界面代码绝
<script setup lang="ts">
import { ref, reactive, getCurrentInstance, onMounted } from 'vue';
import * as echarts from 'echarts';
import china from '../assets/china.json';
let dataList = ref([]);
// 初始化图表的方法
const initEChartsMethod = () => {
// 在容器echart1中生成图表
let chart1 = echarts.init(document.getElementById('echart1'));
chart1.setOption(
{
series: [
{
name: 'Access From',
type: 'pie',
radius: ['20%', '50%'], // 只设置一个外半径为圆饼,同时设置内半径和外半径后为圆环
data: [
{ value: 1048, name: '衬衫' },
{ value: 735, name: '羊毛衫' },
{ value: 580, name: '袜子' },
{ value: 484, name: '裤子' },
{ value: 300, name: '高跟鞋' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}
);
// 在容器echart2中生成图表
let chart2 = echarts.init(document.getElementById('echart2'));
chart2.setOption(
{
// 网格配置 grid可以控制线形图 柱状图 图表大小
grid: {
left: '3%',
right: '4%',
top: '9%',
bottom: '3%',
// 是否显示刻度标签 如果是true 就显示 否则反之
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap:false,
data: ['衬衫', '羊毛衫', '袜子', '裤子', '高跟鞋']
},
yAxis: {
type: 'value'
},
series: [
{
data: [150, 230, 224, 218, 135],
type: 'line'
}
]
}
);
// 在容器echart3中生成图表
let chart3 = echarts.init(document.getElementById('echart3'));
chart3.setOption(
{
// 网格配置 grid可以控制线形图 柱状图 图表大小
grid: {
left: '3%',
right: '9%',
top: '9%',
bottom: '3%',
// 是否显示刻度标签 如果是true 就显示 否则反之
containLabel: true
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: ['第一季度', '第二季度', '第三季度', '第四季度']
},
series: [
{
data: [1200, 2000, 1500, 800],
type: 'bar'
}
]
}
);
// 在容器echart4中生成图表
let chart4 = echarts.init(document.getElementById('echart4'));
chart4.setOption(
{
// 网格配置 grid可以控制线形图 柱状图 图表大小
grid: {
left: '3%',
right: '4%',
top: '9%',
bottom: '3%',
// 是否显示刻度标签 如果是true 就显示 否则反之
containLabel: true
},
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value'
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar'
}
]
}
);
// 在容器echart5中生成图表
let chart5 = echarts.init(document.getElementById('echart5'));
chart5.setOption(
{
tooltip: {
trigger:'item' // 鼠标悬浮时显示提示信息
},
legend: {
data: ['销量'] // series里面有了 name值则 legend里面的data可以删掉
},
visualMap:{
min:0, // 最小值
max:1000, // 最大值
// left:'left', // 位置
// top:'bottom', // 位置
text:['高','低'], // 文本
calculable:true // 是否显示拖拽用的手柄
},
series: [
{
name: '销量',
type: 'map',
map:'china',
zoom:1.2,
lable:{
show:true // 显示地图区域名称
},
data: [
{name:'北京市',value:999},
{name:'天津市',value:200},
{name:'河北省',value:500},
{name:'山西省',value:520},
{name:'内蒙古自治区',value:120},
{name:'辽宁省',value:210},
{name:'吉林省',value:620},
{name:'黑龙江省',value:20},
{name:'上海市',value:300},
{name:'江苏省',value:700},
{name:'浙江省',value:320},
{name:'安徽省',value:420},
{name:'福建省',value:90},
{name:'江西省',value:110},
{name:'山东省',value:920},
{name:'河南省',value:800},
{name:'湖北省',value:720},
{name:'湖南省',value:810},
{name:'广东省',value:900},
{name:'广西壮族自治区',value:90},
{name:'海南省',value:200},
{name:'重庆市',value:20},
{name:'四川省',value:240},
{name:'贵州省',value:190},
{name:'云南省',value:360},
{name:'西藏自治区',value:90},
{name:'陕西省',value:210},
{name:'甘肃省',value:190},
{name:'青海省',value:90},
{name:'宁夏回族自治区',value:120},
{name:'新疆维吾尔自治区',value:130},
{name:'台湾省',value:270},
{name:'香港特别行政区',value:180},
{name:'澳门特别行政区',value:180},
]
}
]
}
);
// 窗口大小发生变动时调整图表的大小
window.addEventListener('resize', function() {
// console.log('resize_begin');
chart1.resize();
chart2.resize();
chart3.resize();
chart4.resize();
chart5.resize();
});
};
onMounted(() => { // 需要在组件完成初始渲染并创建DOM节点后运行的代码
echarts.registerMap('china',china as any);
initEChartsMethod();
});
let annualSalesVolume = ref(4091436);
let annualSalesTarget = ref(9000000);
let targetCompletionRate = ref(0);
let showAnnualSalesTarget = ref('');
let showTargetCompletionRate = ref('');
const simulateMQTTMethod = setInterval(() => {
// console.log('simulateMQTTMethod_begin');
annualSalesVolume.value=annualSalesVolume.value+1000;
// console.log('simulateMQTTMethod_annualSalesVolume.value:',annualSalesVolume.value);
showAnnualSalesTarget.value=annualSalesVolume.value.toLocaleString();
// console.log('simulateMQTTMethod_showAnnualSalesTarget.value:',showAnnualSalesTarget.value);
targetCompletionRate.value = annualSalesVolume.value * 100 / annualSalesTarget.value;
showTargetCompletionRate.value = targetCompletionRate.value.toFixed(2)+'%';
// console.log('simulateMQTTMethod_end');
},1000);
// clearInterval(simulateMQTTMethod);
</script>
<template>
<div class="largeScreen">
<div class="lshead">
<span>数据中心</span>
</div>
<div class="lsbody">
<div class="column1">
<div class="panel1">
<div class="pltitle">
销售概况:
</div>
<div class="plcontent">
<table>
<tr>
<td>销售地区</td>
<td>销售省份</td>
</tr>
<tr>
<td>5</td>
<td>31</td>
</tr>
<tr>
<td>订单总数</td>
<td>在售产品数</td>
</tr>
<tr>
<td>1,082</td>
<td>8</td>
</tr>
</table>
</div>
</div>
<div class="panel2">
<div class="pltitle">
销售对比:
</div>
<div class="plcontent" id="echart1"></div>
</div>
<div class="panel3">
<div class="pltitle">
销售对比:
</div>
<div class="plcontent" id="echart2"></div>
</div>
</div>
<div class="column2">
<div class="panel1">
<div class="pltitle">
信息展示:
</div>
<div class="plcontent">
<table>
<tr>
<td>年度销售量</td>
<td>年度销售目标</td>
<td>目标完成率</td>
</tr>
<tr>
<td>{{showAnnualSalesTarget}}</td>
<td>{{ annualSalesTarget.toLocaleString() }}</td>
<td>{{showTargetCompletionRate}}</td>
</tr>
</table>
</div>
</div>
<div class="panel2">
<div class="pltitle">
信息展示:
</div>
<div class="plcontent" id="echart5"></div>
</div>
</div>
<div class="column3">
<div class="panel1">
<div class="pltitle">
销售数据:
</div>
<div class="plcontent">
<table>
<tr>
<td>名次</td>
<td>省份</td>
<td>数量</td>
</tr>
<tr>
<td>1</td>
<td>北京市</td>
<td>999</td>
</tr>
<tr>
<td>2</td>
<td>山东省</td>
<td>920</td>
</tr>
<tr>
<td>3</td>
<td>广东省</td>
<td>900</td>
</tr>
</table>
</div>
</div>
<div class="panel2">
<div class="pltitle">
销售数据:
</div>
<div class="plcontent" id="echart3"></div>
</div>
<div class="panel3">
<div class="pltitle">
销售数据:
</div>
<div class="plcontent" id="echart4"></div>
</div>
</div>
</div>
</div>
</template>
角色管理界面前端代码
<script setup lang="ts">
import { ref, reactive, getCurrentInstance, onMounted } from 'vue';
const currentPage = ref(1); // 当前页码
const pageSize = ref(2); // 每页显示几条数据
const dataCount = ref(0); // 符合条件的数据数量
const arrTableData = ref([] as any); // 显示在表格里的数据数组
const { proxy } = getCurrentInstance() as any;
const obtainDataMethodForList = async () => { // 向后端获取列表数据列表
try {
// =========>第1处需要修改的地方:调用后端查询列表数据方法的路径<=========
let { data: { code, msg, dataCount: dc, list } } = await proxy.$axios.post("role/list", 'strCurrentPageNo=' + currentPage.value + '&strPageSize=' + pageSize.value);
if (code == 1 && msg == "SUCCESS") {
arrTableData.value.splice(0, arrTableData.value.length);
dataCount.value = dc;
for (let i = 0; i < list.length; i++) {
arrTableData.value.push(list[i]); // 将从后端获取到的列表数据列表放入显示在表格里的数据数组
}
} else {
proxy.$message.warning(`读取列表数据失败。`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
console.log("error:", error);
}
}
onMounted(() => { // 需要在组件完成初始渲染并创建DOM节点后运行的代码
obtainDataMethodForList(); // 向后端获取数据列表
});
const handleSizeChange = (val: number) => {
console.log(`${val} items per page`);
pageSize.value = val;
obtainDataMethodForList();
};
const handleCurrentChange = (val: number) => {
console.log(`current page: ${val}`);
currentPage.value = val;
obtainDataMethodForList();
};
// 定义需要新增或修改的对象
// =========>第2处需要修改的地方:将此对象的属性改成与后端对应实体类的属性一样<=========
const entityObject = reactive({
id: 0,
name: '',
});
const drawer = ref(false); // 抽屉是否显示
const elDrawerTitle = ref('新增'); // 抽屉的标题
const direction = ref('rtl'); // 抽屉的打开方向:rtl(left to right);ltr(right to left);ttb(top to bottom);btt(bottom to top)
const handleInsert = (op: string) => { // 将抽屉的标题改为新增并清空对象中的数据
if (op == 'insert') {
elDrawerTitle.value = '新增';
drawer.value = true;
// =========>第3处需要修改的地方:新增前清空对象的各个属性值<=========
entityObject.id = 0;
entityObject.name = '';
}
}
const isValidUsername = ref(true); // 是否有效的数据(数据库中还不存在此数据)
const checkDataExistMethodForName = async () => { // 向后端验证此数据是否已经存在。若业务中没有需要避免重复值的属性则可将checkDataExistMethodForName方法全部删除。
try {
// =========>第4处需要修改的地方:调用后端验证Role新增的名称是否已经存在的方法的路径,以及需要验证的属性名。若业务中没有需要避免重复值的属性则可将checkDataExistMethodForName方法全部删除。<=========
let { data: { code, msg } } = await proxy.$axios.post("role/checkName", 'name=' + entityObject.name);
if (code == 1 && msg == "SUCCESS") {
isValidUsername.value = false;
proxy.$message.info(`此数据已经存在!`);
}
if (code == 1 && msg == "INVALID") {
isValidUsername.value = true;
proxy.$message.info(`此数据目前可用!`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
}
};
const handleCancel = (formName: string) => { // 点击取消按钮后调用的方法
proxy.$refs[formName].resetFields();
drawer.value = false;
};
const addEntity = async () => { // 调用后端新增的方法
try {
// =========>第5处需要修改的地方:调用后端新增方法的路径<=========
let { data: { code, msg, idJustInserted } } = await proxy.$axios.post("role/add", entityObject);
if (code == 1 && msg == "SUCCESS") {
console.log('idJustInserted:', idJustInserted);
obtainDataMethodForList();
} else {
proxy.$message.error(`新增数据失败!`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
}
};
const doInsert = (formName: string) => { // 新增对象的方法
if (!isValidUsername.value) {
proxy.$message.warning(`此数据已存在,请修改数据后再进行操作!`);
return;
}
proxy.$refs[formName].validate((valid: any) => {
if (valid) {
console.log('valid submit!');
addEntity(); // 调用后端新增对象的方法
} else {
console.log('invalid submit!');
return false;
}
handleCancel(formName);
})
};
const handleEdit = (index: number, row: any) => { // 将抽屉的标题改为修改并将修改那行的数据赋给对象
console.log(index, row);
elDrawerTitle.value = '修改';
drawer.value = true;
// =========>第6处需要修改的地方:修改前将对象的各个属性设置为要修改的那条数据所对应的值<=========
entityObject.id = row.id;
entityObject.name = row.name;
};
const modifyEntity = async () => { // 调用后端修改对象的方法
try {
// =========>第7处需要修改的地方:调用后端修改方法的路径<=========
let { data: { code, msg } } = await proxy.$axios.post("role/modify", entityObject);
if (code == 1 && msg == "SUCCESS") {
obtainDataMethodForList();
} else {
proxy.$message.error(`修改数据失败!`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
}
}
const doEdit = (formName: string) => { // 修改实体的方法
proxy.$refs[formName].validate((valid: boolean) => {
if (valid) {
console.log('valid submit!');
modifyEntity(); // 调用后端修改实体的方法
} else {
console.log('invalid submit!');
return false;
}
handleCancel(formName);
})
};
const doOperation = (formName: string) => { // 点击提交按钮后调用的方法
if (elDrawerTitle.value == '新增') { // 如果标题为新增则调用新增方法
doInsert(formName);
} else if (elDrawerTitle.value == '修改') { // 如果标题为修改则调用修改方法
doEdit(formName);
}
}
const removeEntity = async (id: string) => { // 调用后端删除实体的方法
try {
// =========>第8处需要修改的地方:调用后端删除方法的路径<=========
let { data: { code, msg } } = await proxy.$axios.post("role/remove", 'id=' + id);
if (code == 1 && msg == "SUCCESS") {
obtainDataMethodForList();
} else {
proxy.$message.error(`删除数据失败!`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
console.log("error:", error);
}
}
const handleDelete = (index: number, row: any) => { // 在确认是否删除对话框中点是调用的方法
console.log(index, row);
removeEntity(row.id); // 调用后端删除的方法
};
const cancelEvent = () => { // 在确认是否删除对话框中点否调用的方法
console.log('cancel!')
}
</script>
<template>
<div class="user">
<el-table :data="arrTableData" style="width: 100%">
<!-- =========>第9处需要修改的地方:将显示列表表格的列改为展示对应实体的属性<========= -->
<el-table-column prop="id" label="角色编号" width="90"> </el-table-column>
<el-table-column prop="name" label="角色名称" width="90"></el-table-column>
<el-table-column align="right">
<template #header>
<el-button size="small" type="info" @click="handleInsert('insert')">新增</el-button>
</template>
<template #default="scope">
<el-button size="small" type='warning' @click="handleEdit(scope.$index, scope.row)">修改</el-button>
<el-popconfirm confirm-button-text="是" cancel-button-text="否" icon-color="red" title="你确定要删除吗?"
@confirm="handleDelete(scope.$index, scope.row)" @cancel="cancelEvent">
<template #reference>
<el-button size="small" type="danger">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-pagination v-model:currentPage="currentPage" :page-sizes="[1, 2, 9, 10]" :page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="dataCount" @size-change="handleSizeChange"
@current-change="handleCurrentChange">
</el-pagination>
<el-drawer v-model="drawer" :title="elDrawerTitle" :direction="direction">
<span>
<el-form ref="ruleForm1" :model="entityObject" label-width="120px" size="small">
<!-- =========>第10处需要修改的地方:将抽屉里的表单项改为对应实体的属性(主键属性不需要修改)<========= -->
<el-form-item label="角色名称" prop="name" :rules="[
{ required: true, message: 'name is required', trigger: 'blur' },
{ min: 1, max: 45, message: 'Length should be 1 to 45', trigger: 'blur' },
]">
<el-input v-model="entityObject.name" placeholder="角色名称"></el-input>
</el-form-item>
<el-form-item size="large">
<el-button type="primary" @click="doOperation('ruleForm1')">提交</el-button>
<el-button @click="handleCancel('ruleForm1')">取消</el-button>
</el-form-item>
</el-form>
</span>
</el-drawer>
</div>
</template>
<style scoped></style>
用户管理界面前端代码
<script setup lang="ts">
import { ref, reactive, getCurrentInstance, onMounted } from 'vue';
const currentPage = ref(1); // 当前页码
const pageSize = ref(2); // 每页显示几条数据
const dataCount = ref(0); // 符合条件的数据数量
const arrTableData = ref([] as any); // 显示在表格里的数据数组
const { proxy } = getCurrentInstance() as any;
const obtainDataMethodForUserList = async () => { // 向后端获取用户数据列表
try {
let { data: { code, msg, dataCount: dc, list } } = await proxy.$axios.post("user/list", 'strCurrentPageNo=' + currentPage.value + '&strPageSize=' + pageSize.value);
if (code == 1 && msg == "SUCCESS") {
arrTableData.value.splice(0, arrTableData.value.length);
dataCount.value = dc;
for (let i = 0; i < list.length; i++) {
arrTableData.value.push(list[i]); // 将从后端获取到的用户数据列表放入显示在表格里的数据数组
}
} else {
proxy.$message.warning(`读取用户列表数据失败。`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
console.log("error:", error);
}
}
const refArrRole = ref([] as any);
const obtainDataMethodForRoleList = async () => { // 向后端获取角色数据列表
try {
let { data: { code, msg, dataCount: dc, list } } = await proxy.$axios.post("role/list", 'strCurrentPageNo=1&strPageSize=0');
if (code == 1 && msg == "SUCCESS") {
refArrRole.value.splice(0, refArrRole.value.length);
dataCount.value = dc;
for (let i = 0; i < list.length; i++) {
refArrRole.value.push(list[i]); // 将从后端获取到的角色数据列表放入角色数组
}
} else {
proxy.$message.warning(`读取角色列表数据失败。`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
}
}
onMounted(() => { // 需要在组件完成初始渲染并创建DOM节点后运行的代码
obtainDataMethodForUserList(); // 向后端获取用户数据列表
obtainDataMethodForRoleList();// 向后端获取角色数据列表
});
const handleSizeChange = (val:number) => {
console.log(`${val} items per page`);
pageSize.value = val;
obtainDataMethodForUserList();
};
const handleCurrentChange = (val:number) => {
console.log(`current page: ${val}`);
currentPage.value = val;
obtainDataMethodForUserList();
};
// 定义需要新增或修改的对象
const entityObject = reactive({
id: 0,
name: '',
gender: '',
phone: '',
password: '',
role: { id: '', name: '' }
});
const drawer = ref(false); // 抽屉是否显示
const elDrawerTitle = ref('新增'); // 抽屉的标题
const direction = ref('rtl'); // 抽屉的打开方向:rtl(left to right);ltr(right to left);ttb(top to bottom);btt(bottom to top)
const handleInsert = (op:string) => { // 将抽屉的标题改为新增并清空对象中的数据
if (op == 'insert') {
elDrawerTitle.value = '新增';
entityObject.id = 0;
entityObject.name = '';
entityObject.gender = '1';
entityObject.phone = '';
entityObject.password = '';
entityObject.role.id = '';
drawer.value = true;
}
}
const isValidUsername = ref(true); // 是否有效的用户名(数据库中还不存在此用户名)
const checkMethodForUsername = async () => { // 向后端验证此用户名是否已经存在
try {
let { data: { code, msg } } = await proxy.$axios.post("user/checkUsername", 'username=' + entityObject.phone);
if (code == 1 && msg == "SUCCESS") {
isValidUsername.value = false;
proxy.$message.info(`此账号已经存在!`);
}
if (code == 1 && msg == "INVALID") {
isValidUsername.value = true;
proxy.$message.info(`此账号目前可用!`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
}
};
const handleCancel = (formName:string) => { // 点击取消按钮后调用的方法
proxy.$refs[formName].resetFields();
drawer.value = false;
};
const addDoctor = async () => { // 调用后端新增用户的方法
try {
let { data: { code, msg, idJustInserted } } = await proxy.$axios.post("user/add", entityObject);
if (code == 1 && msg == "SUCCESS") {
console.log('idJustInserted:', idJustInserted);
obtainDataMethodForUserList();
} else {
proxy.$message.error(`新增用户数据失败!`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
}
};
const doInsert = (formName:string) => { // 新增用户的方法
if (!isValidUsername.value) {
proxy.$message.warning(`此账号已存在,请修改账号后再进行操作!`);
return;
}
proxy.$refs[formName].validate((valid:any) => {
if (valid) {
console.log('valid submit!');
addDoctor(); // 调用后端新增用户的方法
} else {
console.log('invalid submit!');
return false;
}
handleCancel(formName);
})
};
const handleEdit = (index:number, row:any) => { // 将抽屉的标题改为修改并将修改那行的数据赋给对象
console.log(index, row);
elDrawerTitle.value = '修改';
entityObject.id = row.id;
entityObject.name = row.name;
entityObject.gender = row.gender+""; // 需要将数字转换为字符串后单选按钮才能识别
entityObject.phone = row.phone;
entityObject.password = row.password;
entityObject.role.id = row.role.id;
drawer.value = true;
};
const modifyDoctor = async () => { // 调用后端修改用户的方法
try {
let { data: { code, msg } } = await proxy.$axios.post("user/modify", entityObject);
if (code == 1 && msg == "SUCCESS") {
obtainDataMethodForUserList();
} else {
proxy.$message.error(`修改用户数据失败!`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
}
}
const doEdit = (formName:string) => { // 修改用户的方法
proxy.$refs[formName].validate((valid:boolean) => {
if (valid) {
console.log('valid submit!');
modifyDoctor(); // 调用后端修改用户的方法
} else {
console.log('invalid submit!');
return false;
}
handleCancel(formName);
})
};
const doOperation = (formName:string) => { // 点击提交按钮后调用的方法
if (elDrawerTitle.value == '新增') { // 如果标题为新增则调用新增方法
doInsert(formName);
} else if (elDrawerTitle.value == '修改') { // 如果标题为修改则调用修改方法
doEdit(formName);
}
}
const removeDoctor = async (id:string) => { // 调用后端删除用户的方法
try {
let { data: { code, msg } } = await proxy.$axios.post("user/remove", 'id=' + id);
if (code == 1 && msg == "SUCCESS") {
obtainDataMethodForUserList();
} else {
proxy.$message.error(`删除用户数据失败!`);
}
} catch (error) {
proxy.$message.warning(`系统繁忙。请稍后。`);
console.log("error:", error);
}
}
const handleDelete = (index:number, row:any) => { // 在确认是否删除对话框中点是调用的方法
console.log(index, row);
removeDoctor(row.id); // 调用后端删除用户的方法
};
const cancelEvent = () => { // 在确认是否删除对话框中点否调用的方法
console.log('cancel!')
}
</script>
<template>
<div class="user">
<el-table :data="arrTableData" style="width: 100%">
<el-table-column prop="id" label="用户编号" width="90"> </el-table-column>
<el-table-column prop="name" label="用户姓名" width="90"></el-table-column>
<el-table-column prop="gender" label="性别" width="90">
<template #default="scope">{{ scope.row.gender==1?'男':scope.row.gender==0?'女':'未知' }}</template>
</el-table-column>
<el-table-column prop="phone" label="登录账号" width="90"> </el-table-column>
<el-table-column prop="password" label="登录密码" width="90"> </el-table-column>
<el-table-column prop="role.id" label="角色编号" width="90"></el-table-column>
<el-table-column prop="role.name" label="角色名称" width="180"></el-table-column>
<el-table-column align="right">
<template #header>
<el-button size="small" type="info" @click="handleInsert('insert')">新增</el-button>
</template>
<template #default="scope">
<el-button size="small" type='warning' @click="handleEdit(scope.$index, scope.row)">修改</el-button>
<el-popconfirm confirm-button-text="是" cancel-button-text="否" icon-color="red" title="你确定要删除吗?"
@confirm="handleDelete(scope.$index, scope.row)" @cancel="cancelEvent">
<template #reference>
<el-button size="small" type="danger">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-pagination v-model:currentPage="currentPage" :page-sizes="[1, 2, 9, 10]" :page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="dataCount" @size-change="handleSizeChange"
@current-change="handleCurrentChange">
</el-pagination>
<el-drawer v-model="drawer" :title="elDrawerTitle" :direction="direction">
<span>
<el-form ref="ruleForm1" :model="entityObject" label-width="120px" size="small">
<el-form-item label="用户姓名" prop="name" :rules="[
{ required: true, message: 'name is required', trigger: 'blur' },
{ min: 1, max: 45, message: 'Length should be 1 to 45', trigger: 'blur' },
]">
<el-input v-model="entityObject.name" placeholder="用户姓名"></el-input>
</el-form-item>
<el-form-item label="性别" prop="gender" :rules="[
{ required: true, message: 'gender is required', trigger: 'blur' },
]">
<el-radio-group v-model="entityObject.gender">
<el-radio value="1">男</el-radio>
<el-radio value="0">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="账号" prop="phone" :rules="[
{ required: true, message: 'phone is required', trigger: 'blur' },
{ min: 1, max: 45, message: 'Length should be 1 to 45', trigger: 'blur' },
]">
<el-input v-model="entityObject.phone" placeholder="账号" @blur='checkMethodForUsername()'></el-input>
</el-form-item>
<el-form-item label="密码" prop="password" :rules="[
{ required: true, message: 'password is required', trigger: 'blur' },
{ min: 1, max: 45, message: 'Length should be 1 to 45', trigger: 'blur' },
]">
<el-input v-model="entityObject.password" placeholder="密码" show-password></el-input>
</el-form-item>
<el-form-item label="角色" prop="role.id" :rules="[
{ required: true, message: 'Please select', trigger: 'change' },
]">
<el-select v-model="entityObject.role.id" placeholder="请选择">
<el-option v-for="(item, index) in refArrRole" :key="item.id" :label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item size="large">
<el-button type="primary" @click="doOperation('ruleForm1')">提交</el-button>
<el-button @click="handleCancel('ruleForm1')">取消</el-button>
</el-form-item>
</el-form>
</span>
</el-drawer>
</div>
</template>
<style scoped></style>