大屏页面与接口开发v1

dev-0829
ccongli 1 year ago
parent b3a84d0eda
commit 99882f1e5c

@ -9,5 +9,7 @@ namespace VOL.Data.IServices
{
public partial interface IData_ConfigService
{
// 获取设备配置列表
List<Data_Config> getConfigList();
}
}

@ -9,5 +9,7 @@ namespace VOL.Data.IServices
{
public partial interface IData_MachineService
{
// 查询设备列表数据
Dictionary<int, Data_Machine> GetMachineData();
}
}

@ -20,15 +20,13 @@ namespace VOL.Data.IServices.modbus
Dictionary<string, Dictionary<string, object>> readGSKData(IModbusService modbus);
// 写设备运行数据
bool saveDeviceData(Data_Machine machine, out string message);
// 保存设备数据
bool saveMachineData(Data_Machine machine, out string message);
// 写设备生产数据
// 保存生产数据
bool saveProduceData(Data_Produce produce, out string message);
// 写设备性能数据
bool saveEfficiencyData();
}
}

@ -1,13 +1,19 @@
/*
*Data_Produce
*/
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
using VOL.Core.Utilities;
using System.Linq.Expressions;
namespace VOL.Data.IServices
{
public partial interface IData_ProduceService
{
// 根据查询对象获取最新的一条记录
Data_Produce getLastProduceData(Func<Data_Produce, bool> query);
// 最近一周生产加工数
List<Data_Produce> produceDataGroupByWeekDays();
}
}

@ -37,5 +37,12 @@ namespace VOL.Data.Services
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
public List<Data_Config> getConfigList() {
var list = _repository.DbContext.Set<Data_Config>().Select(x => new Data_Config(){
id = x.id, name = x.name, type = x.type, device_ip = x.device_ip, com_ip = x.com_ip
}).OrderBy(x=> x.id).ToList();
return list;
}
}
}

@ -22,6 +22,8 @@ namespace VOL.Data.Services
}
public static IData_MachineService Instance
{
get { return AutofacContainerModule.GetService<IData_MachineService>(); } }
get { return AutofacContainerModule.GetService<IData_MachineService>(); }
}
}
}

@ -17,6 +17,14 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.Data.IRepositories;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using SkiaSharp;
using StackExchange.Redis;
using System.Text.RegularExpressions;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace VOL.Data.Services
{
@ -37,5 +45,57 @@ namespace VOL.Data.Services
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
public Dictionary<int, Data_Machine> GetMachineData()
{
var db = _repository.DbContext.Set<Data_Machine>();
var machineList = new Dictionary<int, Data_Machine>();
List<Data_Config> configList = Data_ConfigService.Instance.getConfigList();
IQueryable<Data_Machine> query = db.Where(x => x.com_status == 5);
foreach ( Data_Config config in configList )
{
// 机床数据,各自取最新一条
Data_Machine? data_Machine = query.Where(x => x.config_id == config.id).
OrderByDescending(d => d.CreateDate).FirstOrDefault();
if ( data_Machine != null )
{
data_Machine.com_ip = config.com_ip;
data_Machine.name = config.name;
data_Machine.totalQuantity = data_Machine.quantity_total;
data_Machine.totalRuntime = data_Machine.run_time_total;
// 生产数据, 各自取最新一条
Func<Data_Produce, bool> where = p => p.config_id == config.id && p.com_status == 5;
Data_Produce data_Produce = Data_ProduceService.Instance.getLastProduceData(where);
if (data_Produce != null)
{
data_Machine.currentTurnout = data_Produce.turnout_all;
data_Machine.OEE = data_Produce.oee;
}
machineList.Add(config.id, data_Machine);
}
}
return machineList;
}
public void testQuery() {
//List<Data_Machine> data_Machines = _repository.DbContext.Set<Data_Machine>().ToList();
//var list = db.Where(x => x.com_status == 5).GroupBy(e => e.config_id).Select(g => new {
// ConfigId = g.Key,
// Data_Machine = g.OrderByDescending(d => d.CreateDate).ToList()
//}).OrderBy(g => g.ConfigId).ToList();
// 1. 查设备ID分组
//var result1 = db.GroupBy(e => e.config_id).Select(g => new
//{
// ConfigId = g.Key
//}).OrderBy(g => g.ConfigId).ToList();
//List<int> configIds = result1.Select(c => c.ConfigId).ToList();
// 2. 查找设备名称并赋值
//var result2 = db.Where(p => configIds.Contains(p.config_id) && p.com_status == 5).OrderByDescending(o => o.CreateDate).ToList();
//Console.Write(JsonConvert.SerializeObject(result2));
//Console.Write(string.Join(",", data_Machines));
//var list = db.GroupBy(e => e.config_id).Count();
}
}
}

@ -54,12 +54,13 @@ namespace VOL.Data.Services.modbus
{ "cut_rate", modbus.readData(1, 1225, "single")}, // 切削倍率
{ "main_rate", modbus.readData(1, 1231, "single")}, // 主轴倍率
{ "run_program_no", modbus.readData(1, 6689, "string", 26)}, // 加工程序号 length = 52
{ "run_time_total", modbus.readData(1, 6435, "int16")}, // 累计运行时长 分钟
};
// 组装Map返回
Dictionary<string, Dictionary<string, object>> map = new();
map.Add("produce", map1);
map.Add("device", map2);
map.Add("machine", map2);
return map;
}
@ -105,13 +106,13 @@ namespace VOL.Data.Services.modbus
// 组装Map返回
Dictionary<string, Dictionary<string, object>> map = new();
map.Add("produce", map1);
map.Add("device", map2);
map.Add("machine", map2);
return map;
}
// 机床数据
public bool saveDeviceData(Data_Machine machine, out string message) {
// 保存机床数据
public bool saveMachineData(Data_Machine machine, out string message) {
SaveModel model = new SaveModel();
Dictionary<string, object> mapData = new()
{
@ -142,7 +143,7 @@ namespace VOL.Data.Services.modbus
// 生产数据
// 保存生产数据
public bool saveProduceData(Data_Produce produce, out string message)
{
SaveModel model = new SaveModel();
@ -174,13 +175,5 @@ namespace VOL.Data.Services.modbus
message = "ok";
return true;
}
// 写设备性能数据
public bool saveEfficiencyData()
{
throw new NotImplementedException();
}
}
}

@ -24,4 +24,6 @@ namespace VOL.Data.Services
{
get { return AutofacContainerModule.GetService<IData_ProduceService>(); } }
}
}

@ -17,6 +17,8 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.Data.IRepositories;
using VOL.Core.DBManager;
using SkiaSharp;
namespace VOL.Data.Services
{
@ -37,5 +39,35 @@ namespace VOL.Data.Services
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
}
public Data_Produce getLastProduceData(Func<Data_Produce, bool> query) {
//_repository.DbContext.Set<Data_Produce>().FirstOrDefault(query);
Data_Produce? data_Produce = _repository.DbContext.Set<Data_Produce>().Where(query)
.OrderByDescending(x => x.CreateDate).FirstOrDefault();
return data_Produce;
}
public List<Data_Produce> produceDataGroupByWeekDays() {
var db = _repository.DbContext.Set<Data_Produce>();
List<Data_Produce> data_Produces = new();
data_Produces =
db.FromSqlRaw(
"SELECT c.datelist as date, COALESCE(MAX(turnout_all), 0) AS currentTurnout, d.* FROM Data_Calendar c" +
"LEFT JOIN Data_Produce d ON c.datelist = DATE(d.CreateDate) and d.com_status = 5 " +
"WHERE c.datelist BETWEEN CURDATE() - INTERVAL 6 DAY AND CURDATE()" +
"GROUP BY c.datelist").ToList();
//var result = (from c in db.Set<Data_Calendar>()
// join d in db.Set<Data_Produce>()
// on c.datelist equals DATE(d.CreateDate) && d.com_status = 5 into joinResult
// from d in joinResult.DefaultIfEmpty());
//select new
//{
// Column1 = t1.Column1,
// Column2 = t2.Column2
//};
return data_Produces;
}
}
}

@ -13,6 +13,9 @@ namespace VOL.Entity.DomainModels
public string msg { get; set; }
public int total { get; set; }
public List<T> rows { get; set; }
/// <summary>
/// 统计求和数据
/// </summary>
public object summary { get; set; }
/// <summary>
/// 可以在返回前,再返回一些额外的数据,比如返回其他表的信息,前台找到查询后的方法取出来

@ -17,5 +17,21 @@ namespace VOL.Entity.DomainModels
public partial class Data_Config
{
//此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常
/// <summary>
///通讯状态
/// </summary>
[Display(Name = "通讯状态")]
[Column(TypeName = "short")]
[Editable(true), NotMapped]
public short? com_status { get; set; }
/// <summary>
///运行状态
/// </summary>
[Display(Name = "运行状态")]
[Column(TypeName = "short")]
[Editable(true), NotMapped]
public short? state { get; set; }
}
}

@ -17,5 +17,56 @@ namespace VOL.Entity.DomainModels
public partial class Data_Machine
{
//此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常
[Display(Name = "设备名称")]
[MaxLength(255)]
[Column(TypeName = "nvarchar(255)")]
[Editable(true), NotMapped]
public string name { get; set; }
/// <summary>
///通讯IP
/// </summary>
[Display(Name = "通讯IP")]
[MaxLength(60)]
[Column(TypeName = "nvarchar(60)")]
[Editable(true), NotMapped]
public string com_ip { get; set; }
/// <summary>
///累计运行时长
/// </summary>
[Display(Name = "当班产量")]
[Column(TypeName = "int")]
[Editable(true), NotMapped]
public int? currentTurnout { get; set; }
/// <summary>
///累计加工数
/// </summary>
[Display(Name = "累计加工数")]
[Column(TypeName = "bigint")]
[Editable(true), NotMapped]
public long? totalQuantity { get; set; }
/// <summary>
///累计运行时长
/// </summary>
[Display(Name = "累计运行时长")]
[Column(TypeName = "bigint")]
[Editable(true), NotMapped]
public long? totalRuntime { get; set; }
/// <summary>
///设备综合效率
/// </summary>
[Display(Name = "设备综合效率")]
[DisplayFormat(DataFormatString = "10,2")]
[Column(TypeName = "decimal")]
[Editable(true), NotMapped]
public decimal? OEE { get; set; }
}
}

@ -17,5 +17,12 @@ namespace VOL.Entity.DomainModels
public partial class Data_Produce
{
//此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常
/// <summary>
/// 日期
/// </summary>
[Display(Name = "日期")]
[Column(TypeName = "date")]
[Editable(true), NotMapped]
public DateOnly? datelist { get; set; }
}
}

@ -0,0 +1,68 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using System;
using VOL.Core.Filters;
using VOL.Data.IServices.modbus;
using VOL.Data.Services.modbus;
using Microsoft.Extensions.DependencyInjection;
using VOL.WebApi.Utils;
using VOL.Entity.DomainModels;
using System.Collections.Generic;
using Confluent.Kafka;
using VOL.Data.IServices;
namespace VOL.WebApi.Controllers.Data
{
/// <summary>
/// 数据采集API类
/// </summary>
[Route("api/Data_Screen")]
[JWTAuthorize, ApiController, AllowAnonymous]
public class DataApiController : Controller
{
private IData_ConfigService _configService;
private IData_MachineService _machineService;
private IData_ProduceService _produceService;
private readonly IHttpContextAccessor _httpContextAccessor;
[ActivatorUtilitiesConstructor]
public DataApiController(
IData_ConfigService configService,
IData_MachineService machineService,
IData_ProduceService produceService,
IHttpContextAccessor httpContextAccessor
)
{
_configService = configService;
_machineService = machineService;
_produceService = produceService;
_httpContextAccessor = httpContextAccessor;
}
// 获取设备配置数据
[HttpPost, Route("GetDeviceConfig")]
public IActionResult getDeviceConfig([FromBody] PageDataOptions loadData)
{
return Json(_configService.GetPageData(loadData));
}
// 获取机床数据
[HttpPost, Route("GetMachineData")]
public IActionResult getMachineData()
{
return Json(_machineService.GetMachineData());
}
// 获取生产数据
[HttpPost, Route("GetProduceData")]
public IActionResult getProduceData()
{
return Json(_produceService.produceDataGroupByWeekDays());
}
}
}

@ -8,6 +8,8 @@ using VOL.Data.Services.modbus;
using Microsoft.Extensions.DependencyInjection;
using VOL.WebApi.Utils;
using VOL.Entity.DomainModels;
using System.Collections.Generic;
using Confluent.Kafka;
namespace VOL.WebApi.Controllers.Data
{
@ -42,34 +44,94 @@ namespace VOL.WebApi.Controllers.Data
/// <returns>IActionResult</returns>
[ApiTask]
[HttpGet, HttpPost, Route("gatherSiemens")]
public IActionResult Collection()
public IActionResult gatherSiemens()
{
try
{
_service = new ModbusTcpService("127.0.0.1", 502);
Console.WriteLine("master modbus tcp connected...");
_service = new ModbusTcpService("192.168.1.99", 502);
Console.WriteLine("siemens modbus tcp connected...");
}
catch (Exception)
{
Console.WriteLine("master modbus tcp connect failed");
return Content("master modbus connect failed!");
Console.WriteLine("siemens modbus tcp connect failed");
return Content("siemens modbus tcp connect failed!");
}
if (!_service.isConnected)
{
Console.WriteLine("master modbus disconnect!");
return Content("master modbus disconnect!");
Console.WriteLine("siemens modbus tcp disconnect!");
return Content("siemens modbus tcp disconnect!");
}
string message = "";
try {
Dictionary<string, Dictionary<string, object>> dataMap = _dataService.readSiemensData(_service);
message = saveSourceData(dataMap);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
return Content("read data error!");
message = "read data error: " + ex.Message;
} finally {
_service.disConnent();
}
return Content("ok!");
return Content(message);
}
/// <summary>
/// 采集广数设备
/// </summary>
/// <returns>IActionResult</returns>
[ApiTask]
[HttpGet, HttpPost, Route("gatherGSK")]
public IActionResult gatherGSK()
{
try
{
_service = new ModbusTcpService("192.168.1.100", 502);
Console.WriteLine("siemens modbus tcp connected...");
}
catch (Exception)
{
Console.WriteLine("siemens modbus tcp connect failed");
return Content("siemens modbus tcp connect failed!");
}
if (!_service.isConnected)
{
Console.WriteLine("siemens modbus tcp disconnect!");
return Content("siemens modbus tcp disconnect!");
}
string message = "";
try
{
Dictionary<string, Dictionary<string, object>> dataMap = _dataService.readGSKData(_service);
message = saveSourceData(dataMap);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
message = "read data error: " + ex.Message;
}
finally
{
_service.disConnent();
}
return Content(message);
}
private string saveSourceData(Dictionary<string, Dictionary<string, object>> dataMap) {
// 获取当前系统时间, 保证插入时间一致
DateTime now = DateTime.Now;
Dictionary<string, object> machineData = dataMap["machine"];
Data_Machine data_Machine = CommonUtil.ConvertToObject<Data_Machine>(machineData);
data_Machine.CreateDate = now;
bool result1 = _dataService.saveMachineData(data_Machine, out string message1);
Dictionary<string, object> produceData = dataMap["produce"];
Data_Produce data_Produce = CommonUtil.ConvertToObject<Data_Produce>(produceData);
data_Produce.CreateDate = now;
bool result2 = _dataService.saveProduceData(data_Produce, out string message2);
return (result1 && result2) ? "OK" : "save machine: " + message1 + "; save produce" + message2 + ";";
}
}
}

@ -15,7 +15,7 @@
"ali-oss": "^6.17.1",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"echarts": "^5.0.2",
"echarts": "^5.3.0",
"element-plus": "^2.2.14",
"less": "^4.1.1",
"vue": "^3.2.37",

@ -12,7 +12,7 @@ import { ElLoading as Loading, ElMessage as Message } from 'element-plus';
let loadingInstance;
let loadingStatus = false;
if (process.env.NODE_ENV == 'development') {
axios.defaults.baseURL = 'http://127.0.0.1:9991/';
axios.defaults.baseURL = 'http://192.168.0.187:9991/';
}
else if (process.env.NODE_ENV == 'debug') {
axios.defaults.baseURL = 'http://127.0.0.1:9991/';
@ -205,6 +205,7 @@ function createXHR () {
}
function redirect (responseText, message) {
console.log(typeof responseText);
try {
let responseData = typeof responseText == 'string' ? JSON.parse(responseText) : responseText;
if ((responseData.hasOwnProperty('code') && responseData.code == 401)

@ -0,0 +1,175 @@
<template>
<div class="bar" ref="vbar"></div>
</template>
<script>
var echarts = require("echarts");
let $chartBar;
export default {
name: "Bar",
props: {
option: {
type: Object,
required: false,
default: () => {
return null;
}
}
},
data() {
return {
defaultOption: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
toolbox: {
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
// saveAsImage: { show: true, name: "" }
}
},
legend: {
top: 0,
data: ['广数980DI-1', '西门子828D-1'],
itemGap: 20, //
textStyle: {
fontSize: 14,
color: '#fff'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '2%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { //
lineStyle: {
color: '#fff',
}
},
axisTick: { // 线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '广数980DI-1',
alignTicks: true,
min: 0,
axisLabel: {
formatter: '{value} 件'
},
axisLine: { //
show: false, // 线
lineStyle: {
color: '#fff',
},
onZero: true
},
splitLine: { // 线
show: true,
lineStyle: {
// 使
color: ['#fff','#ff9f7f'],
width: 1
}
}
},
{
type: 'value',
name: '西门子828D-1',
min: 0,
// interval: 50,
alignTicks: true,
axisLabel: {
formatter: '{value} 件'
},
axisLine: { //
lineStyle: {
color: '#fff',
}
},
}
],
series: [
{
name: '广数980DI-1',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' 件';
}
},
data: [
100, 99, 91, 107, 121, 137, 101
]
},
{
name: '西门子828D-1',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' 件';
}
},
data: [
120, 117, 99, 100, 111, 127, 101
]
}
]
}
}
},
created() {
console.log("bar loaded...");
this.defaultOption = this.option || this.defaultOption;
},
mounted() {
this.initGauge(this.defaultOption);
},
methods: {
initGauge(option) {
console.log(option);
this.$nextTick(() => {
$chartBar = echarts.init(this.$refs.vbar);
$chartBar.setOption(option);
});
}
},
destroyed() {
$chartBar = null;
},
};
</script>
<style lang="less" scoped>
.bar {
width: 100%;
height: 100%;
// padding: 20px;
}
</style>

@ -0,0 +1,140 @@
<template>
<div class="gauge" ref="vgauge"></div>
</template>
<script>
var echarts = require("echarts");
let $chartGauge;
export default {
name: "Gauge",
props: {
option: {
type: Object,
required: false,
default: () => {
return null;
}
}
},
data() {
return {
defaultOption: {
series: [{
radius: '130%',
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 1,
splitNumber: 10,
center: ["50%", "80%"], //
axisLine: {
lineStyle: {
width: 3,
color: [
[0.2, '#FF6E76'],
[0.4, '#FF9F7F'],
[0.6, '#FDDD60'],
[0.8, '#58D9F9'],
[1.0, '#7CFFB2']
]
}
},
pointer: {
icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
length: '12%',
width: 20,
offsetCenter: [0, '-60%'],
itemStyle: {
color: 'auto'
}
},
axisTick: {
length: 12,
lineStyle: {
color: 'auto',
width: 2
}
},
splitLine: {
length: 20,
lineStyle: {
color: 'auto',
width: 5
}
},
axisLabel: {
color: '#fff',
fontSize: 20,
// distance: -60,
rotate: 'tangential',
formatter: function (value) {
switch(value) {
case 0.20:
return "差";
case 0.50:
return "中";
case 0.80:
return "良";
default:
return '';
}
}
},
title: {
offsetCenter: [0, '-20%'],
fontSize: 20,
color: '#fff'
},
detail: {
fontSize: 30,
offsetCenter: [0, '0%'],
valueAnimation: true,
formatter: function (value) {
return Math.round(value * 100) + '%';
},
color: 'auto'
},
data: [
{
value: 0.70,
name: '利用率'
}
]
}]
}
}
},
created() {
console.log("gauge loaded...");
this.defaultOption = (this.option || this.defaultOption);
},
mounted() {
this.initGauge(this.defaultOption);
},
methods: {
initGauge(option) {
console.log(option);
this.$nextTick(() => {
$chartGauge = echarts.init(this.$refs.vgauge);
$chartGauge.setOption(option);
});
}
},
destroyed() {
$chartGauge = null;
},
};
</script>
<style lang="less" scoped>
.gauge {
width: 100%;
height: 100%;
// padding: 20px;
}
</style>

@ -0,0 +1,172 @@
<template>
<div class="line" ref="vline"></div>
</template>
<script>
var echarts = require("echarts");
let $chartLine;
export default {
name: "Line",
props: {
option: {
type: Object,
required: false,
default: () => {
return null;
}
}
},
data() {
return {
defaultOption: {
title: {
text: '产量折线图',
textStyle: {
fontSize: 20,
color: "#fff"
},
left: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['工单1', '工单2', '工单3'],
itemGap: 20, //
textStyle: {
fontSize: 14,
color: '#fff'
}
},
toolbox: {
feature: {
// , my
mySwitch: {
show: true,
title: '更多',
icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
onclick: function () {
alert('暂未实现!')
}
},
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] }
}
},
grid: {
left: '3%',
right: '4%',
bottom: '2%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false, //
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { //
lineStyle: {
color: '#fff',
}
},
axisTick: { // 线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '产量',
position: 'left',
alignTicks: true,
axisLine: {
show: true,
lineStyle: {
color: '#fff',
},
},
axisLabel: {
formatter: '{value} 次'
}
}
],
series: [
{
name: '工单1',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '工单2',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '工单3',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [150, 232, 201, 154, 190, 330, 410]
},
]
}
}
},
created() {
console.log("line loaded...");
this.defaultOption = this.option || this.defaultOption;
},
mounted() {
this.initLine(this.defaultOption);
},
methods: {
initLine(option) {
console.log(option);
this.$nextTick(() => {
$chartLine = echarts.init(this.$refs.vline);
$chartLine.setOption(option);
});
}
},
destroyed() {
$chartLine = null;
},
};
</script>
<style lang="less" scoped>
.line {
width: 100%;
height: 100%;
// padding: 20px;
}
</style>

@ -0,0 +1,71 @@
<template>
<div class="number">
<dv-digital-flop :config="config" />
</div>
</template>
<script>
var echarts = require("echarts");
let $chartBar;
export default {
name: "Number",
props: {
number: {
type: Number,
required: false,
default: 10000
},
unity: {
type: String,
required: false,
default: ''
},
toFixed: {
type: Number,
required: false,
default: 0
},
toFormat: {
type: Boolean,
required: false,
default: true
}
},
data() {
return {
config: {
number: [this.number],
content: '{nt} ',
toFixed: this.toFixed
}
}
},
created() {
this.config.content += this.unity;
if (this.toFormat) {
this.config.formatter = this.formatter;
}
},
methods: {
//
formatter(number) {
const numbers = number.toString().split('').reverse();
const segs = [];
while (numbers.length) segs.push(numbers.splice(0, 3).join(''));
return segs.join(',').split('').reverse().join('');
}
}
};
</script>
<style lang="less" scoped>
.number {
width: 100%;
height: 100%;
// padding: 20px;
}
</style>

@ -188,6 +188,7 @@ let extension = {
//你可以指定param查询的参数处如果返回false则不会执行查询
// this.$message.success(this.table.cnName + ',查询前' });
// console.log("扩展的"this.detailOptions.cnName + '触发loadDetailTableBefore');
console.log(param);
return true;
},
searchAfter(result) { //查询ViewGird表数据后param查询参数,result回返查询的结果

@ -324,6 +324,24 @@ let base = {
return this.getTreeAllChildren(id, data).map((c) => {
return c.id;
});
},
//使用递归的方式实现数组、对象的深拷贝
deepClone(obj) {
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
var objClone = Array.isArray(obj) ? [] : {};
//进行深拷贝的不能为空,并且是对象或者是
if (obj && typeof obj === "object") {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = this.deepClone(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
};
export default base;

@ -1,128 +1,527 @@
// 折线图
let chartLeft1 = {
// color: ["#37a2da", "#32c5e9","#67e0e3"], // 图表折线默认配色
let MachineInfo = {
series: [{
radius: '130%',
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 1,
splitNumber: 10,
center: ["50%", "80%"], // 圆心坐标
axisLine: {
lineStyle: {
width: 3,
color: [
[0.2, '#FF6E76'],
[0.4, '#FF9F7F'],
[0.6, '#FDDD60'],
[0.8, '#58D9F9'],
[1.0, '#7CFFB2']
]
}
},
pointer: {
icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
length: '12%',
width: 20,
offsetCenter: [0, '-60%'],
itemStyle: {
color: 'auto'
}
},
axisTick: {
length: 12,
lineStyle: {
color: 'auto',
width: 2
}
},
splitLine: {
length: 20,
lineStyle: {
color: 'auto',
width: 5
}
},
axisLabel: {
color: '#fff',
fontSize: 20,
// distance: -60,
rotate: 'tangential',
formatter: function (value) {
switch (value) {
case 0.20:
return "差";
case 0.50:
return "中";
case 0.80:
return "良";
default:
return '';
}
}
},
title: {
offsetCenter: [0, '-20%'],
fontSize: 20,
color: '#fff'
},
detail: {
fontSize: 30,
offsetCenter: [0, '0%'],
valueAnimation: true,
formatter: function (value) {
return Math.round(value * 100) + '%';
},
color: 'auto'
},
data: [
{
value: 0.70,
name: ''
}
]
}]
};
let WorkData = {
turnout: {
title: {
text: '',
offset: [-300, -30], // 标题[左右 上下]偏移
style: {
fill: '#fff',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
textBaseline: 'bpttom'
}
},
legend:{ // 图例标签
data: ['', ''],
orient: 'horizontal', // 横向
left:"50%",
top: '10%',
text: '线',
textStyle: {
fontSize: 20,
color: "#fff"
},
left: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['1', '2', '3'],
itemGap: 20, // 标签间距
textStyle: {
fontFamily: 'Arial',
fontSize: 13,
fill: '#fff'
fontSize: 14,
color: '#fff'
}
},
toolbox: {
feature: {
// 自定义切换按钮,只能以 my 开头
mySwitch: {
show: true,
title: '',
icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
onclick: function () {
alert('')
}
},
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] }
}
},
xAxis: { // x轴
name: '',
data: ['1', '2', '3', '4', '5', '6', '7'],
nameTextStyle: { // 名称样式
fill: '#fff',
fontSize: 10
grid: {
left: '3%',
right: '4%',
bottom: '2%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false, // 坐标轴两边不留白
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { // 坐标轴
style: {
stroke: '#fff',
lineWidth: 2
lineStyle: {
color: '#fff',
}
},
axisTick: { // 坐标轴刻度线
style: {
stroke: '#fff',
lineWidth: 2
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '',
position: 'left',
alignTicks: true,
axisLine: {
show: true,
lineStyle: {
color: '#fff',
},
},
axisLabel: {
formatter: '{value} '
}
}
],
series: [
{
name: '1',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '2',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '3',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [150, 232, 201, 154, 190, 330, 410]
},
axisLabel: { // 坐标轴标签
style: {
fill: '#fff',
fontSize: 12,
rotate: 10 // 倾斜度
]
},
schedule: {
title: {
text: '线',
textStyle: {
fontSize: 20,
color: "#fff"
},
left: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['1', '2', '3'],
itemGap: 20, // 标签间距
textStyle: {
fontSize: 14,
color: '#fff'
}
},
yAxis: {
name: '',
data: 'value',
xAxis: [
{
type: 'category',
boundaryGap: false, // 坐标轴两边不留白
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { // 坐标轴
style: {
stroke: '#fff',
lineWidth: 2
lineStyle: {
color: '#fff',
}
},
axisTick: { // 坐标轴刻度线
style: {
stroke: '#fff',
lineWidth: 2
lineStyle: {
color: '#fff',
}
},
axisLabel: { // 坐标轴标签
show:true, // 显示
style: {
fill: '#fff',
fontSize: 12,
rotate: 10 // 倾斜度
}
}
],
yAxis: [
{
type: 'value',
name: '',
// position: 'right',
// min: 0,
// max: 100,
// interval: 20,
alignTicks: true,
axisLine: {
show: true,
lineStyle: {
color: '#fff',
},
},
axisLabel: {
formatter: '{value} %'
}
}
],
series: [
{
name: "图例一",
data: [1200, 2230, 1900, 2100, 3500, 4200, 3985],
name: '1',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [91, 92, 88, 94, 87, 85, 95]
},
{
name: '2',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [81, 92, 98, 93, 97, 95, 85]
},
{
name: '3',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [81, 97, 83, 91, 89, 95, 92]
},
]
},
yield: {
title: {
text: '线',
textStyle: {
fontSize: 20,
color: "#fff"
},
left: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['1', '2', '3'],
itemGap: 20, // 标签间距
textStyle: {
fontSize: 14,
color: '#fff'
}
},
xAxis: [
{
type: 'category',
boundaryGap: false, // 坐标轴两边不留白
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { // 坐标轴
lineStyle: {
color: '#fff',
}
},
axisTick: { // 坐标轴刻度线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '',
// offset: 80,
// position: 'right',
alignTicks: true,
axisLine: {
show: true,
formatter : '{value}',
style: {
fontSize: 16
lineStyle: {
color: '#fff',
},
},
axisLabel: {
formatter: '{value} %'
}
}
],
series: [
{
name: '1',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [81, 82, 88, 94, 89, 85, 85]
},
{
name: "图例二",
data: [2200, 1230, 1900, 2200, 2500, 3200, 2985],
name: '2',
type: 'line',
smooth: true,
label: {
show: true
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [81, 93, 83, 84, 87, 85, 95]
},
{
name: '3',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [91, 82, 88, 84, 87, 85, 94]
},
]
}
}
],
// tooltip:{ // dataV暂不支持此功能
// trigger:'item',
// show:true
// }
};
// 柱状图
let chartLeft2 = {
title: {
text: ''
let WeekProcess = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
toolbox: {
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
saveAsImage: { show: true, name: "近一周加工数" }
}
},
legend: {
top: 0,
data: ['广980DI-1', '西828D-1'],
itemGap: 20, // 标签间距
textStyle: {
fontSize: 14,
color: '#fff'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '2%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { // 坐标轴
lineStyle: {
color: '#fff',
}
},
axisTick: { // 坐标轴刻度线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '广980DI-1',
alignTicks: true,
min: 0,
axisLabel: {
formatter: '{value} '
},
axisLine: { // 坐标轴
show: false, // 不显示坐标轴轴线。
lineStyle: {
color: '#fff',
},
onZero: true
},
xAxis: {
name: '',
data: ['', '', '', '', '', '', '']
splitLine: { // 坐标轴分隔线
show: true,
lineStyle: {
// 使用深浅的间隔色
color: ['#fff','#ff9f7f'],
width: 1
}
}
},
yAxis: {
name: '',
data: 'value' // x或y坐标轴应至少有一个配置为'value'
{
type: 'value',
name: '西828D-1',
min: 0,
// interval: 50,
alignTicks: true,
axisLabel: {
formatter: '{value} '
},
axisLine: { // 坐标轴
lineStyle: {
color: '#fff',
}
},
}
],
series: [
{
data: [1200, 2230, 1900, 2100, 3500, 4200, 3985],
type: 'bar'
name: '广980DI-1',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' ';
}
},
data: [
100, 99, 91, 107, 121, 137, 101
]
};
},
{
name: '西828D-1',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' ';
}
},
data: [
120, 117, 99, 100, 111, 127, 101
]
}
]
}
export { chartLeft1, chartLeft2 }
export { MachineInfo, WorkData, WeekProcess }

@ -90,6 +90,25 @@
margin-bottom: 10px;
z-index: 10;
.title {
height: 50px;
text-align: center;
color: #fff;
line-height: 50px;
font-size: 24px;
}
.content {
height: 400px;
width: 100%;
.chart {
flex: 1;
height: 100%;
}
}
&::before {
border-left: 2px solid #02a6b5;
left: 0;
@ -113,18 +132,15 @@
}
}
// .title {
// color: #fff;
// font-size: 16px;
// text-align: center;
// }
.data-foot-line {
position: absolute;
bottom: 0;
width: 100%;
left: 0;
&::before, &::after {
&::before,
&::after {
position: absolute;
width: 10px;
height: 10px;
@ -144,183 +160,129 @@
}
}
}
.oee {
height: 250px;
display: flex;
flex-direction: row;
justify-content: center;
}
.machine {
height: 150px;
display: flex;
flex-direction: row;
justify-content: space-around;
.status-item {
flex: 1;
.tagbox {
width: 100%;
padding: 0 10px;
display: flex;
justify-content: space-around;
align-items: center;
color: #fff;
.taglist {
flex: 1;
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
.tag {
width: 50%;
display: flex;
align-items: center;
margin: 5px 0;
.text {
font-size: 16px;
}
}
}
.status {
flex: 1;
.item {
margin: 5px;
font-size: 18px;
display: flex;
align-items: center;
.name {
margin-left: 5px;
}
}
}
}
}
}
.switch {
position: absolute;
top: 20px;
right: 12px;
}
.output {
margin-top: 10px;
padding: 10px 0;
height: 400px;
}
.statbox {
height: 400px;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #fff;
padding: 10px;
.stat-item {
flex: 1;
width: 100%;
display: flex;
align-items: center;
.device {
font-size: 20px;
flex: 1;
display: flex;
align-items: center;
.name {
margin-left: 5px;
text-align: center;
}
}
.stat-info {
flex: 3;
display: flex;
flex-direction: row;
.digital {
flex: 1;
.head {
margin-top: 30px;
font-size: 20px;
text-align: center;
height: 20px;
line-height: 20px;
}
}
}
}
}
}
// .head h1 {
// margin: 0;
// color: #fff;
// text-align: center;
// /* font-size: .4rem; */
// /* line-height: .8rem; */
// line-height: 71px;
// }
// .data-container {
// /* margin: 5px 15px;
// height:100%; */
// margin: 0px 15px;
// position: absolute;
// left: 0;
// right: 0;
// top: 76px;
// bottom: 0;
// }
// .data-container > div {
// float: left;
// /* border: 1px solid white; */
// height: 100%;
// }
// .data-center {
// padding: 0 0.9rem;
// width: 40%;
// display: flex;
// flex-direction: column;
// // .center-top{
// // height: 210px;
// // background: red;
// // }
// .chart-center{
// flex: 1;
// }
// }
// .chart-center{
// width: 100%;
// display: flex;
// // background: white;
// }
// .data-left,
// .data-right {
// width: 30%;
// display: flex;
// flex-direction: column;
// }
// .data-left-item,
// .data-right-item,.center-top,.center-top-num,.chart-center {
// border: 1px solid rgba(25, 186, 139, 0.17);
// padding: 0 0.2rem 0.4rem 0.15rem;
// background: rgba(255, 255, 255, 0.04);
// background-size: 100% auto;
// position: relative;
// margin-bottom: 0.15rem;
// z-index: 10;
// }
// .data-foot-line {
// position: absolute;
// bottom: 0;
// width: 100%;
// left: 0;
// }
// .data-foot-line:before,
// .data-foot-line:after {
// position: absolute;
// width: 10px;
// height:10px;
// content: "";
// border-bottom: 2px solid #02a6b5;
// bottom: 0;
// }
// .boxall:before,
// .data-foot-line:before {
// border-left: 2px solid #02a6b5;
// left: 0;
// }
// .boxall:after,
// .data-foot-line:after {
// border-right: 2px solid #02a6b5;
// right: 0;
// }
// .boxall:before,
// .boxall:after {
// position: absolute;
// width: 10px;
// height: 10px;
// content: "";
// border-top: 2px solid #02a6b5;
// top: 0;
// }
// .data-left-item:before,
// .data-right-item:before,
// .center-top-num:before,
// .center-top:before{
// border-left: 2px solid #02a6b5;
// left: 0;
// position: absolute;
// width: 10px;
// height:10px;
// content: "";
// border-top: 2px solid #02a6b5;
// top: 0;
// }
// .data-left-item:after,
// .data-right-item:after,
// .center-top-num:after,
// .center-top:after {
// border-right: 2px solid #02a6b5;
// right: 0;
// position: absolute;
// width: 10px;
// height: 10px;
// content: "";
// border-top: 2px solid #02a6b5;
// top: 0;
// }
// .data-left,
// .data-right {
// /* display: flex; */
// }
// .data-left > .data-left-item,
// .data-right > .data-right-item {
// flex: 1;
// margin-bottom: 0.9rem;
// }
// .data-center .title,
// .data-left > .data-left-item .title,
// .data-right > .data-right-item .title {
// /* font-size: .2rem; */
// font-size: 1rem;
// padding: 7px 0;
// color: #fff;
// text-align: center;
// /* line-height: .5rem; */
// }
// .data-center .chart-center{
// width: 100%;
// }
// .center-top-num{
// height: 80px;
// padding-top: 7px;
// margin-bottom: 0.8rem;
// display: flex;
// .item{
// flex: 1;
// text-align: center;
// }
// .text{
// color: #fcf0d8;
// font-size: 14px;
// }
// .num{
// font-size: 34px;
// font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
// font-weight: bold;
// color: #67caca;
// }
// }
}

@ -16,29 +16,134 @@
<h3 class="datetime">{{ datetime }}</h3>
<dv-decoration-8 :reverse="true" />
</div>
<!-- <dv-decoration-10 style="width:100%;height:5px; transform: rotateY(180deg);" /> -->
</div>
<!-- 四方格样式 -->
<div class="data-container">
<dv-border-box-13>
<div class="data-left">
<div class="data-left-item">
<!-- <div class="title">商品销量分类</div> -->
<dv-charts :option="chartLeft1"></dv-charts>
<div class="title">设备综合利用率</div>
<div class="content">
<div class="oee">
<div class="chart" v-for="(machine, index) in machineList" :key="index">
<Gauge :option="machineOption(machine)"></Gauge>
</div>
</div>
<div class="machine">
<div class="status-item">
<div class="title">运行状态</div>
<div class="tagbox">
<div class="taglist">
<div class="tag" v-for="(item, index) in dicts.state" :key="index">
<el-icon :color="item.color" :size="30">
<TakeawayBox />
</el-icon>
<span class="text">{{ item.name }}</span>
</div>
</div>
<div class="status">
<div class="item" v-for="(machine, index) in machineList" :key="index">
<template v-for="item in dicts.state" :key="item.value">
<el-icon :color="item.color" :size="40" v-if="item.value == machine.state">
<TakeawayBox />
</el-icon>
</template>
<span class="name">{{ machine.name }}</span>
</div>
</div>
</div>
</div>
<div class="status-item">
<div class="title">通讯状态</div>
<div class="tagbox">
<div class="taglist">
<div class="tag" v-for="(item, index) in dicts.com_status" :key="index">
<el-icon :color="item.color" :size="30">
<Link />
</el-icon>
<span class="text">{{ item.name }}</span>
</div>
</div>
<div class="status">
<!-- <div class="item">
<el-icon color="#FF6E76" :size="40">
<Link />
</el-icon>
<span class="name">西门子828D-1</span>
</div> -->
<!-- <div class="item">
<el-icon color="#7CFFB2" :size="40">
<Link />
</el-icon>
<span class="name">广数980DI-1</span>
</div> -->
<div class="item" v-for="(machine, index) in machineList" :key="index">
<template v-for="item in dicts.com_status" :key="item.value">
<el-icon :color="item.color" :size="40" v-if="item.value == machine.com_status">
<Link />
</el-icon>
</template>
<span class="name">{{ machine.name }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="data-foot-line"></div>
</div>
<div class="data-left-item">
<dv-charts :option="chartLeft1"></dv-charts>
<div class="title">工单近一周走势图</div>
<div class="switch">
<el-select v-model="gdselect" @change="changeQuota">
<el-option label="产量" value="turnout" />
<el-option label="进度" value="schedule" />
<el-option label="良品率" value="yield" />
</el-select>
</div>
<div class="output">
<Line :option="workdata[gdoption]" ref="vline"></Line>
</div>
<div class="data-foot-line"></div>
</div>
</div>
<div class="data-right">
<div class="data-right-item">
<dv-charts :option="chartLeft1"></dv-charts>
<div class="title">统计数据</div>
<div class="statbox">
<div class="stat-item" v-for="(machine, index) in machineList" :key="index">
<div class="device">
<el-icon color="#8378ea" :size="40">
<TakeawayBox />
</el-icon>
<div class="name">
<div style="margin-bottom: 5px;">{{ machine.name }}</div>
<div>{{ machine.com_ip }}</div>
</div>
</div>
<div class="stat-info">
<div class="digital">
<div class="head">当班产量</div>
<Number :number="machine.currentTurnout" unity="件"></Number>
</div>
<div class="digital">
<div class="head">累计加工数</div>
<Number :number="machine.totalQuantity" unity="次" :toFixed="1" :toFormat="false"></Number>
</div>
<div class="digital">
<div class="head">累计运行时长</div>
<Number :number="machine.totalRuntime" unity="分"></Number>
</div>
</div>
</div>
</div>
<div class="data-foot-line"></div>
</div>
<div class="data-right-item">
<dv-charts :option="chartLeft1"></dv-charts>
<div class="title">最近一周加工数</div>
<div class="output">
<Bar :data="{}"></Bar>
</div>
<div class="data-foot-line"></div>
</div>
</div>
@ -49,23 +154,63 @@
</div>
</template>
<script>
import {
chartLeft1,
chartLeft2
} from "./chart-options";
import myMixin from '@/mixin';
import Gauge from "@/components/echarts/Gauge.vue";
import Bar from "@/components/echarts/Bar.vue";
import Line from "@/components/echarts/Line.vue";
import Number from "@/components/echarts/Number.vue";
import { MachineInfo, WorkData, WeekProcess } from "./chart-options";
import "./index.less";
import { changeDefaultConfig } from '@jiaminghi/charts'
export default {
components: {
Bar,
Gauge,
Line,
Number
},
mixins: [myMixin],
data() {
return {
loading: true,
datetime: '',
chartLeft1: {},
chartLeft2: {}
dicts: {
state: [
{ color: "#FDDD60", name: "待机", value: 0 },
{ color: "#FF6E76", name: "故障", value: 1 },
{ color: "#7CFFB2", name: "运行", value: 2 },
{ color: "#58D9F9", name: "暂停", value: 3 }
],
com_status: [
{ color: "#FF6E76", name: "通讯断开", value: 15 },
{ color: "#7CFFB2", name: "通讯正常", value: 5 },
]
},
machineList: [
{
id: 1,
name: "西门子828D-1",
com_ip: "192.168.1.99",
com_status: 5,
state: 3,
oee: 0.88,
currentTurnout: 1009,
totalQuantity: 19876.5,
totalRuntime: 10086
},
{
id: 2,
name: "GSK980DI-1",
com_ip: "192.168.1.100",
com_status: 5,
state: 2,
oee: 0.92,
currentTurnout: 1009,
totalQuantity: 19876.5,
totalRuntime: 10086
}
],
machineinfo: MachineInfo,
workdata: WorkData,
weekprocess: WeekProcess,
gdselect: "turnout",
}
},
created() {
@ -74,29 +219,98 @@ export default {
setInterval(() => {
this.datetime = this.base.getDate(true);
});
},
mounted() {
// changeDefaultConfig('color', ['#67e0e3']); //
this.chartLeft1 = chartLeft1;
this.chartLeft2 = chartLeft2;
this.getDeviceConfig();
},
methods: {
onLoading() {
setTimeout(() => {
this.loading = false; // todo
this.loading = false;
}, 1000);
},
//
changeQuota(value) {
let option = this.workdata[value];
this.$refs.vline.initLine(option);
},
//
machineOption(machine) {
let machineOption = this.base.deepClone(this.machineinfo); // copy
let oeeObj = {
name: machine.name,
value: machine.oee
}
machineOption.series[0].data[0] = oeeObj;
return machineOption;
},
getDeviceConfig() { //
// let wheres = [
// {
// name: "name",
// value: "西",
// displayType: "like"
// }
// ];
let wheres = []; //
let params = {
sort: "CreateDate",
order: "desc",
page: 1,
rows: 999,
wheres: JSON.stringify(wheres)
};
console.log(JSON.stringify(params));
// this.http.post("/api/Data_Screen/GetDeviceConfig", params, true)
// .then(result => {
// console.log(result);
// });
},
destroyed() {
// $chartLeft1 = null;
// $chartLeft2 = null;
// $chartLeft3 = null;
// $chartCenter = null;
// $chartRight1 = null;
// $chartGauge1 = null;
// $chartGauge2 = null;
getMachineData() { //
let params = {
sort: "CreateDate",
order: "desc",
page: 1,
rows: 7,
Wheres: []
};
this.http.post("/api/Data_Screen/GetMachineData", params, true)
.then(result => {
console.log(result);
}).catch(reject => {
console.log(reject);
});
},
getProduceData() { //
let params = {
sort: "CreateDate",
order: "desc",
page: 1,
rows: 7,
Wheres: []
};
this.http.post("/api/Data_Screen/GetProduceData", params, true)
.then(result => {
console.log(result);
}).catch(reject => {
console.log(reject);
});
},
//
getDictData() {
let dicNos = ["machine_state", "produce_com_status"];
this.http.post('/api/Sys_Dictionary/GetVueDictionary', dicNos).then((res) => {
console.log(res);
});
},
},
computed: {
// params(){
// // Proxy
// return JSON.parse(JSON.stringify(this.pagination));
// }
}
}
</script>
<style lang="less" scoped>
// vue3 dv-loading

@ -3844,13 +3844,13 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
echarts@^5.0.2:
version "5.0.2"
resolved "https://registry.nlark.com/echarts/download/echarts-5.0.2.tgz"
integrity sha1-FybRelfPBdYs0FZ7QyXhIBpWuvY=
echarts@^5.3.0:
version "5.4.3"
resolved "https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz#f5522ef24419164903eedcfd2b506c6fc91fb20c"
integrity sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==
dependencies:
tslib "2.0.3"
zrender "5.0.4"
tslib "2.3.0"
zrender "5.4.4"
ee-first@1.1.1, ee-first@~1.1.1:
version "1.1.1"
@ -8937,10 +8937,10 @@ ts-pnp@^1.1.6:
resolved "https://registry.npm.taobao.org/ts-pnp/download/ts-pnp-1.2.0.tgz"
integrity sha1-pQCtCEsHmPHDBxrzkeZZEshrypI=
tslib@2.0.3:
version "2.0.3"
resolved "https://registry.nlark.com/tslib/download/tslib-2.0.3.tgz"
integrity sha1-jgdBrEX8DCJuWKF7/D5kubxsphw=
tslib@2.3.0, tslib@^2.1.0:
version "2.3.0"
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
tslib@^1.10.0, tslib@^1.9.0:
version "1.14.1"
@ -8952,11 +8952,6 @@ tslib@^2.0.1:
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
tslib@^2.1.0:
version "2.3.0"
resolved "https://registry.nlark.com/tslib/download/tslib-2.3.0.tgz"
integrity sha1-gDuM2rPhK6WBpMpByIObuw2ssJ4=
tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.npm.taobao.org/tty-browserify/download/tty-browserify-0.0.0.tgz"
@ -9843,9 +9838,9 @@ yorkie@^2.0.0:
normalize-path "^1.0.0"
strip-indent "^2.0.0"
zrender@5.0.4:
version "5.0.4"
resolved "https://registry.nlark.com/zrender/download/zrender-5.0.4.tgz"
integrity sha1-icNVr5CLn2SjAbOPdRt5UfLIqVo=
zrender@5.4.4:
version "5.4.4"
resolved "https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz#8854f1d95ecc82cf8912f5a11f86657cb8c9e261"
integrity sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==
dependencies:
tslib "2.0.3"
tslib "2.3.0"

Loading…
Cancel
Save