数据库结构及数据sql源码

-- 创建数据库
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>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值