yxq 2 months ago
parent
commit
8b7dd88692
15 changed files with 410 additions and 257 deletions
  1. +10
    -0
      SafeCampus.API/SafeCampus.Application/SafeCampus.Application.xml
  2. +35
    -4
      SafeCampus.API/SafeCampus.Application/Services/Business/CameraInfoService/CameraInfoService.cs
  3. +10
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/Warn/Dto/WarnInfoList.cs
  4. +1
    -1
      SafeCampus.API/SafeCampus.Application/Services/Business/Warn/Service/WarnInfoService.cs
  5. +1
    -1
      SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/ClassRoomCallApi.cs
  6. +49
    -5
      SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Violation/VioPortraitSummary.cs
  7. +5
    -0
      SafeCampus.API/SafeCampus.Web.Core/Startup.cs
  8. +1
    -1
      SafeCampus.API/SafeCampus.Web.Entry/Properties/PublishProfiles/FolderProfile.pubxml.user
  9. +1
    -0
      SafeCampus.API/SafeCampus.Web.Entry/appsettings.json
  10. +34
    -107
      SafeCampus.WEB/src/views/violation/portrait/detail.vue
  11. +73
    -15
      monitorMobile/components/tki-tree/tki-tree.vue
  12. +2
    -0
      monitorMobile/pages.json
  13. +88
    -70
      monitorMobile/pages/earlyWarning/detail.vue
  14. +27
    -35
      monitorMobile/pages/earlyWarning/index.vue
  15. +73
    -18
      monitorMobile/pages/monitor/index.vue

+ 10
- 0
SafeCampus.API/SafeCampus.Application/SafeCampus.Application.xml View File

@@ -1888,6 +1888,16 @@
班级名称 班级名称
</summary> </summary>
</member> </member>
<member name="P:SafeCampus.Application.Services.Business.Warn.Dto.WarnInfoList.MajorName">
<summary>
专业名称
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.Warn.Dto.WarnInfoList.DepName">
<summary>
院系名称
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.Warn.Dto.WarnInfoList.Gender"> <member name="P:SafeCampus.Application.Services.Business.Warn.Dto.WarnInfoList.Gender">
<summary> <summary>
性别 性别


+ 35
- 4
SafeCampus.API/SafeCampus.Application/Services/Business/CameraInfoService/CameraInfoService.cs View File

@@ -3,6 +3,8 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using SafeCampus.Application.Manager.DeepelephManager; using SafeCampus.Application.Manager.DeepelephManager;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;


namespace SafeCampus.Application.Services.Business.CameraInfoService; namespace SafeCampus.Application.Services.Business.CameraInfoService;


@@ -50,13 +52,27 @@ public class CameraInfoService:DbRepository<CameraInfo>, ICameraInfoService
old_model.ResWidth = (int)item["resWidth"]; old_model.ResWidth = (int)item["resWidth"];
old_model.SensorName = item["sensorName"].ToString(); old_model.SensorName = item["sensorName"].ToString();
old_model.SnapshotUrl = item["snapshotUrl"].ToString(); old_model.SnapshotUrl = item["snapshotUrl"].ToString();
await UpdateAsync(old_model);
var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:CameraImg"], old_model.SensorId + ".jpg");
var steam = await old_model.SnapshotUrl.GetAsByteArrayAsync();
using (MemoryStream ms = new MemoryStream(steam))
{
using (Bitmap bmp = new Bitmap(ms))
{
using (Graphics g = Graphics.FromImage(bmp))
{
}
bmp.Save(signImg, ImageFormat.Jpeg);
}
}
old_model.SnapshotUrl = $"/Files/{App.Configuration["AppInfo:CameraImg"]}/{old_model.SensorId}.jpg";
await UpdateAsync(old_model);
} }
else else
{ {
await InsertAsync(new CameraInfo
var cameraModel = new CameraInfo
{ {
DeviceStatus = item["deviceStatus"].ToString()== "online",
DeviceStatus = item["deviceStatus"].ToString() == "online",
DirectUrlIp = item["directUrlIp"].ToString(), DirectUrlIp = item["directUrlIp"].ToString(),
FieldId = item["fieldId"].ToString(), FieldId = item["fieldId"].ToString(),
FieldName = item["fieldName"].ToString(), FieldName = item["fieldName"].ToString(),
@@ -67,7 +83,22 @@ public class CameraInfoService:DbRepository<CameraInfo>, ICameraInfoService
SensorName = item["sensorName"].ToString(), SensorName = item["sensorName"].ToString(),
SnapshotUrl = item["snapshotUrl"].ToString(), SnapshotUrl = item["snapshotUrl"].ToString(),


});
};
var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:CameraImg"], cameraModel.SensorId + ".jpg");
var steam = await cameraModel.SnapshotUrl.GetAsByteArrayAsync();
using (MemoryStream ms = new MemoryStream(steam))
{
using (Bitmap bmp = new Bitmap(ms))
{
using (Graphics g = Graphics.FromImage(bmp))
{

}
bmp.Save(signImg, ImageFormat.Jpeg);
}
}
cameraModel.SnapshotUrl = $"/Files/{App.Configuration["AppInfo:CameraImg"]}/{cameraModel.SensorId}.jpg";
await InsertAsync(cameraModel);
} }
} }
return true; return true;


+ 10
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/Warn/Dto/WarnInfoList.cs View File

@@ -53,6 +53,14 @@ public class WarnInfoList
/// </summary> /// </summary>
public string PersonSetName { get; set; } public string PersonSetName { get; set; }
/// <summary> /// <summary>
/// 专业名称
/// </summary>
public long MajorName { get; set; }
/// <summary>
/// 院系名称
/// </summary>
public long DepName { get; set; }
/// <summary>
/// 性别 /// 性别
/// </summary> /// </summary>
public string Gender { get; set; } public string Gender { get; set; }
@@ -78,6 +86,8 @@ public class WarnInfoListMapper : IRegister
.Map(dest => dest.CameraName, src => src.CameraInfoItem.SensorName) .Map(dest => dest.CameraName, src => src.CameraInfoItem.SensorName)
.Map(x=>x.PersonName,x=>x.PersonInfoItem.Name) .Map(x=>x.PersonName,x=>x.PersonInfoItem.Name)
.Map(x=>x.PersonSetName,x=>x.PersonSetInfoItem.PersonSetName) .Map(x=>x.PersonSetName,x=>x.PersonSetInfoItem.PersonSetName)
.Map(x=>x.MajorName,x=>x.PersonSetInfoItem.MajorInfoItem.Name)
.Map(x=>x.DepName,x=>x.PersonSetInfoItem.MajorInfoItem.DepartmentInfoItem.Name)
.Map(dest => dest.CameraGroup, src => src.CameraInfoItem.CameraGroupItem.Name); .Map(dest => dest.CameraGroup, src => src.CameraInfoItem.CameraGroupItem.Name);
} }
} }

+ 1
- 1
SafeCampus.API/SafeCampus.Application/Services/Business/Warn/Service/WarnInfoService.cs View File

@@ -98,7 +98,7 @@ public class WarnInfoService:DbRepository<WarnInfo>, IWarnInfoService,ITransient
var query = Context.Queryable<WarnInfo>() var query = Context.Queryable<WarnInfo>()
.Includes(x=>x.CameraInfoItem) .Includes(x=>x.CameraInfoItem)
.Includes(x=>x.PersonInfoItem) .Includes(x=>x.PersonInfoItem)
.Includes(x=>x.PersonSetInfoItem)
.Includes(x=>x.PersonSetInfoItem,x1=>x1.MajorInfoItem,x2=>x2.DepartmentInfoItem)
.WhereIF(search.WarnHand.HasValue, x => x.WarnHand == search.WarnHand) .WhereIF(search.WarnHand.HasValue, x => x.WarnHand == search.WarnHand)
.WhereIF(!string.IsNullOrEmpty(search.AlarmType),x => x.AlarmType == search.AlarmType) .WhereIF(!string.IsNullOrEmpty(search.AlarmType),x => x.AlarmType == search.AlarmType)
.WhereIF(!string.IsNullOrEmpty(search.CameraId), x => x.CameraId == search.CameraId) .WhereIF(!string.IsNullOrEmpty(search.CameraId), x => x.CameraId == search.CameraId)


+ 1
- 1
SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/ClassRoomCallApi.cs View File

@@ -176,7 +176,7 @@ public class ClassRoomCallApi : IDynamicApiController
Rects = "", Rects = "",
Extend = "", Extend = "",
CreateTime = DateTime.Now, CreateTime = DateTime.Now,
TrackId = ""
TrackId = "SDDM"+ item.PersonId
}; };
await _classRoomCallService.Add(model); await _classRoomCallService.Add(model);
} }


+ 49
- 5
SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Violation/VioPortraitSummary.cs View File

@@ -99,7 +99,7 @@ public class VioPortraitSummary
var random = new Random(); var random = new Random();
var label = new List<string> { "正常出勤", "缺勤", "迟到" }; var label = new List<string> { "正常出勤", "缺勤", "迟到" };
var value = label.Select(item => random.Next(2, 20)).ToList(); var value = label.Select(item => random.Next(2, 20)).ToList();
return await Task.FromResult(new { label, value });
return await Task.FromResult(new { label, value,msg= $"{(value[0] / value.Sum()) *100}%出勤率,在班级中属于中等水平" });
} }
} }
/// <summary> /// <summary>
@@ -108,7 +108,49 @@ public class VioPortraitSummary
/// <returns></returns> /// <returns></returns>
public async Task<dynamic> OutsideSchool(SummarySeach seach) public async Task<dynamic> OutsideSchool(SummarySeach seach)
{ {
return await StudentSummary(seach, ApplicationConst.XXDM);
var camera = await _cameraInfoService.GetPageList(new CameraSearch { GroupId = ApplicationConst.XXDM, PageSize = 1000, PageNum = 1 });
var cameraIds = camera.List.Select(x => x.SensorId).ToList();
DateTime endWeek = DateTime.Now;
// 获取本周的第一天(假设一周从周一开始)
DateTime startOfWeek = endWeek.AddDays(-(int)endWeek.DayOfWeek + (int)DayOfWeek.Monday);
switch (seach.SearchType)
{
case SearchType.ThisWeek:
var list = await _warnInfoService.GetListNoPage(new WarnInfoSearch
{
AlarmType = AlarmType.visual_fence.GetDisplay(),
CameraIds = cameraIds,
PersonId = seach.PersonId,
StartTick = startOfWeek,
EndTick = endWeek
});
return await Task.FromResult(new{data= list.Select(x => new { x.Tick, x.PersonName, x.PersonSetName, x.SnapshotUrl }).ToList(), msg= $"有{list.Count}次出校访问经历,在班级中属于优秀水平" });
case SearchType.LastWeek:
DateTime startOfLastWeek = startOfWeek.AddDays(-7);
DateTime endOfLastWeek = startOfLastWeek.AddDays(6).Date.AddDays(1).AddTicks(-1); // 上周的最后一刻
var list1 = await _warnInfoService.GetListNoPage(new WarnInfoSearch
{
AlarmType = AlarmType.visual_fence.GetDisplay(),
CameraIds = cameraIds,
PersonId = seach.PersonId,
StartTick = startOfLastWeek,
EndTick = endOfLastWeek
});
return await Task.FromResult(new { data = list1.Select(x => new { x.Tick, x.PersonName, x.PersonSetName, x.SnapshotUrl }).ToList(), msg = $"有{list1.Count}次出校访问经历,在班级中属于优秀水平" });
case SearchType.ThisMonth:
DateTime startOfMonth = new DateTime(endWeek.Year, endWeek.Month, 1);
var list2 = await _warnInfoService.GetListNoPage(new WarnInfoSearch
{
AlarmType = AlarmType.visual_fence.GetDisplay(),
CameraIds = cameraIds,
PersonId = seach.PersonId,
StartTick = startOfMonth,
EndTick = endWeek
});
return await Task.FromResult(new { data = list2.Select(x => new { x.Tick, x.PersonName, x.PersonSetName, x.SnapshotUrl }).ToList(), msg = $"有{list2.Count}次出校访问经历,在班级中属于优秀水平" });
default:
return null;
}
} }
/// <summary> /// <summary>
/// 学生--图书馆 /// 学生--图书馆
@@ -116,7 +158,8 @@ public class VioPortraitSummary
/// <returns></returns> /// <returns></returns>
public async Task<dynamic> Library(SummarySeach seach) public async Task<dynamic> Library(SummarySeach seach)
{ {
return await StudentSummary(seach, ApplicationConst.TSG);
var data= await StudentSummary(seach, ApplicationConst.TSG);
return new { data.label, data.value, msg = $"每周平均使用图书馆6次,与班级其他学生相较为频繁" };
} }
/// <summary> /// <summary>
/// 学生--食堂 /// 学生--食堂
@@ -124,7 +167,8 @@ public class VioPortraitSummary
/// <returns></returns> /// <returns></returns>
public async Task<dynamic> Canteen(SummarySeach seach) public async Task<dynamic> Canteen(SummarySeach seach)
{ {
return await StudentSummary(seach, ApplicationConst.ST);
var data= await StudentSummary(seach, ApplicationConst.ST);
return new { data.label, data.value, msg = $"与全校学生消费情况相比较为节俭" };
} }
/// <summary> /// <summary>
/// 学生画像统计 /// 学生画像统计
@@ -196,7 +240,7 @@ public class VioPortraitSummary
value.Add(list2.Count(x => x.Tick.Year == i.Year && x.Tick.Month == i.Month && x.Tick.Day == i.Day)); value.Add(list2.Count(x => x.Tick.Year == i.Year && x.Tick.Month == i.Month && x.Tick.Day == i.Day));
i = i.AddDays(1); i = i.AddDays(1);
} }
return new { label, value };
return new { label, value};
default: default:
return null; return null;
} }


+ 5
- 0
SafeCampus.API/SafeCampus.Web.Core/Startup.cs View File

@@ -128,6 +128,11 @@ public class Startup : AppStartup
{ {
Directory.CreateDirectory(attendanceImg); Directory.CreateDirectory(attendanceImg);
} }
var cameraImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", "cameraImg");
if (!Directory.Exists(cameraImg))
{
Directory.CreateDirectory(cameraImg);
}
app.UseFileServer(new FileServerOptions() app.UseFileServer(new FileServerOptions()
{ {
FileProvider = new PhysicalFileProvider(path), FileProvider = new PhysicalFileProvider(path),


+ 1
- 1
SafeCampus.API/SafeCampus.Web.Entry/Properties/PublishProfiles/FolderProfile.pubxml.user View File

@@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<_PublishTargetUrl>F:\Project\QJKJ\SafeCampus\SafeCampus.API\SafeCampus.Web.Entry\bin\Release\net6.0\publish\</_PublishTargetUrl> <_PublishTargetUrl>F:\Project\QJKJ\SafeCampus\SafeCampus.API\SafeCampus.Web.Entry\bin\Release\net6.0\publish\</_PublishTargetUrl>
<History>True|2024-08-27T07:31:21.7026102Z;True|2024-08-20T11:12:26.7141701+08:00;True|2024-08-19T17:23:34.5703879+08:00;True|2024-08-19T15:55:28.3484786+08:00;True|2024-08-19T15:45:49.5623372+08:00;True|2024-08-19T14:56:17.7733738+08:00;True|2024-08-19T14:52:03.2782392+08:00;True|2024-08-19T14:10:57.7043528+08:00;True|2024-08-19T13:38:29.9236695+08:00;False|2024-08-19T13:29:18.8873264+08:00;True|2024-08-19T12:31:57.9280692+08:00;True|2024-08-19T11:50:36.7241244+08:00;True|2024-08-19T10:24:05.0018377+08:00;True|2024-08-19T10:23:30.0445364+08:00;True|2024-08-19T10:12:33.8316906+08:00;True|2024-08-19T10:10:48.0967630+08:00;True|2024-08-16T12:17:51.5743944+08:00;True|2024-08-16T11:36:15.1880346+08:00;True|2024-08-12T11:27:42.2864171+08:00;True|2024-08-09T14:54:42.9062124+08:00;True|2024-08-09T11:49:01.0339449+08:00;True|2024-08-09T11:43:21.9947939+08:00;True|2024-08-09T10:43:25.7641675+08:00;True|2024-08-08T15:23:17.0510180+08:00;True|2024-08-08T15:20:50.3450876+08:00;True|2024-08-08T11:06:43.0783261+08:00;True|2024-08-07T17:24:03.0780935+08:00;True|2024-08-07T17:20:50.6266614+08:00;True|2024-08-07T17:18:15.6367265+08:00;True|2024-08-06T17:31:40.3452266+08:00;True|2024-07-31T16:54:03.1890463+08:00;True|2024-07-30T17:11:33.2514194+08:00;True|2024-07-30T17:08:14.5888060+08:00;True|2024-07-30T09:56:08.6349163+08:00;True|2024-07-30T09:50:02.2368269+08:00;True|2024-07-29T16:20:12.3202393+08:00;True|2024-07-29T16:16:29.9634841+08:00;True|2024-07-29T16:09:51.7696392+08:00;True|2024-07-29T16:06:49.4145658+08:00;True|2024-07-29T15:58:50.6654249+08:00;True|2024-07-29T11:32:11.6206514+08:00;True|2024-07-29T11:26:26.1574563+08:00;True|2024-07-29T11:04:41.1896705+08:00;True|2024-07-29T10:38:38.4560275+08:00;True|2024-07-29T10:33:38.5288332+08:00;False|2024-07-29T10:33:21.0642261+08:00;False|2024-07-29T10:33:00.1005216+08:00;True|2024-07-29T09:54:59.2794860+08:00;True|2024-07-29T09:08:54.4899269+08:00;True|2024-07-26T18:02:13.5407348+08:00;True|2024-07-26T17:46:06.7922851+08:00;True|2024-07-26T15:50:48.6986834+08:00;True|2024-07-26T15:11:17.1696147+08:00;True|2024-07-26T13:58:49.6884964+08:00;True|2024-07-25T17:31:33.0050952+08:00;True|2024-07-25T17:09:12.7084910+08:00;True|2024-07-25T17:02:01.2617736+08:00;True|2024-07-25T16:59:51.6271873+08:00;True|2024-07-25T16:58:05.5249148+08:00;True|2024-07-25T14:14:10.2008367+08:00;False|2024-07-25T14:13:54.0300465+08:00;True|2024-07-25T14:08:57.0244482+08:00;True|2024-07-25T13:41:48.8201522+08:00;True|2024-07-25T10:41:30.7277553+08:00;True|2024-07-25T10:16:05.9105335+08:00;True|2024-07-24T15:31:54.7914854+08:00;True|2024-07-24T09:54:17.6182454+08:00;True|2024-07-23T17:01:18.1510211+08:00;True|2024-07-23T16:41:53.3366577+08:00;True|2024-07-23T16:07:25.4129335+08:00;True|2024-07-23T15:50:42.2437488+08:00;True|2024-07-23T15:19:00.1900116+08:00;True|2024-07-23T14:59:22.8551233+08:00;True|2024-07-23T14:19:55.1193373+08:00;True|2024-07-19T18:04:32.2703039+08:00;True|2024-07-19T15:56:25.4103701+08:00;True|2024-07-19T15:09:00.9662436+08:00;True|2024-07-19T15:05:35.7255851+08:00;True|2024-07-19T13:14:42.9559521+08:00;False|2024-07-19T11:37:52.4020673+08:00;True|2024-07-19T11:10:22.8661346+08:00;True|2024-07-19T11:00:00.8819251+08:00;True|2024-07-19T10:45:46.8271770+08:00;True|2024-07-19T10:45:03.8183458+08:00;True|2024-07-18T18:04:42.1000382+08:00;True|2024-07-18T18:01:51.3964409+08:00;True|2024-07-18T17:57:50.3509206+08:00;True|2024-07-18T16:32:46.2184830+08:00;True|2024-07-18T16:00:11.1381449+08:00;True|2024-07-18T15:11:52.6472758+08:00;True|2024-07-18T11:54:49.4848006+08:00;True|2024-07-18T09:25:58.7204846+08:00;True|2024-07-17T17:29:28.6175272+08:00;True|2024-07-17T17:10:54.5184246+08:00;True|2024-07-17T16:57:59.8174060+08:00;True|2024-07-17T16:18:13.8137834+08:00;True|2024-07-17T15:59:16.2360757+08:00;True|2024-07-17T15:31:41.9159909+08:00;True|2024-07-17T14:41:14.6127340+08:00;True|2024-07-17T14:28:53.4455461+08:00;</History>
<History>True|2024-09-04T08:01:07.1761640Z;True|2024-09-04T15:47:33.3094448+08:00;True|2024-09-04T13:33:22.9396193+08:00;True|2024-08-30T13:27:03.2003529+08:00;True|2024-08-27T15:31:21.7026102+08:00;True|2024-08-20T11:12:26.7141701+08:00;True|2024-08-19T17:23:34.5703879+08:00;True|2024-08-19T15:55:28.3484786+08:00;True|2024-08-19T15:45:49.5623372+08:00;True|2024-08-19T14:56:17.7733738+08:00;True|2024-08-19T14:52:03.2782392+08:00;True|2024-08-19T14:10:57.7043528+08:00;True|2024-08-19T13:38:29.9236695+08:00;False|2024-08-19T13:29:18.8873264+08:00;True|2024-08-19T12:31:57.9280692+08:00;True|2024-08-19T11:50:36.7241244+08:00;True|2024-08-19T10:24:05.0018377+08:00;True|2024-08-19T10:23:30.0445364+08:00;True|2024-08-19T10:12:33.8316906+08:00;True|2024-08-19T10:10:48.0967630+08:00;True|2024-08-16T12:17:51.5743944+08:00;True|2024-08-16T11:36:15.1880346+08:00;True|2024-08-12T11:27:42.2864171+08:00;True|2024-08-09T14:54:42.9062124+08:00;True|2024-08-09T11:49:01.0339449+08:00;True|2024-08-09T11:43:21.9947939+08:00;True|2024-08-09T10:43:25.7641675+08:00;True|2024-08-08T15:23:17.0510180+08:00;True|2024-08-08T15:20:50.3450876+08:00;True|2024-08-08T11:06:43.0783261+08:00;True|2024-08-07T17:24:03.0780935+08:00;True|2024-08-07T17:20:50.6266614+08:00;True|2024-08-07T17:18:15.6367265+08:00;True|2024-08-06T17:31:40.3452266+08:00;True|2024-07-31T16:54:03.1890463+08:00;True|2024-07-30T17:11:33.2514194+08:00;True|2024-07-30T17:08:14.5888060+08:00;True|2024-07-30T09:56:08.6349163+08:00;True|2024-07-30T09:50:02.2368269+08:00;True|2024-07-29T16:20:12.3202393+08:00;True|2024-07-29T16:16:29.9634841+08:00;True|2024-07-29T16:09:51.7696392+08:00;True|2024-07-29T16:06:49.4145658+08:00;True|2024-07-29T15:58:50.6654249+08:00;True|2024-07-29T11:32:11.6206514+08:00;True|2024-07-29T11:26:26.1574563+08:00;True|2024-07-29T11:04:41.1896705+08:00;True|2024-07-29T10:38:38.4560275+08:00;True|2024-07-29T10:33:38.5288332+08:00;False|2024-07-29T10:33:21.0642261+08:00;False|2024-07-29T10:33:00.1005216+08:00;True|2024-07-29T09:54:59.2794860+08:00;True|2024-07-29T09:08:54.4899269+08:00;True|2024-07-26T18:02:13.5407348+08:00;True|2024-07-26T17:46:06.7922851+08:00;True|2024-07-26T15:50:48.6986834+08:00;True|2024-07-26T15:11:17.1696147+08:00;True|2024-07-26T13:58:49.6884964+08:00;True|2024-07-25T17:31:33.0050952+08:00;True|2024-07-25T17:09:12.7084910+08:00;True|2024-07-25T17:02:01.2617736+08:00;True|2024-07-25T16:59:51.6271873+08:00;True|2024-07-25T16:58:05.5249148+08:00;True|2024-07-25T14:14:10.2008367+08:00;False|2024-07-25T14:13:54.0300465+08:00;True|2024-07-25T14:08:57.0244482+08:00;True|2024-07-25T13:41:48.8201522+08:00;True|2024-07-25T10:41:30.7277553+08:00;True|2024-07-25T10:16:05.9105335+08:00;True|2024-07-24T15:31:54.7914854+08:00;True|2024-07-24T09:54:17.6182454+08:00;True|2024-07-23T17:01:18.1510211+08:00;True|2024-07-23T16:41:53.3366577+08:00;True|2024-07-23T16:07:25.4129335+08:00;True|2024-07-23T15:50:42.2437488+08:00;True|2024-07-23T15:19:00.1900116+08:00;True|2024-07-23T14:59:22.8551233+08:00;True|2024-07-23T14:19:55.1193373+08:00;True|2024-07-19T18:04:32.2703039+08:00;True|2024-07-19T15:56:25.4103701+08:00;True|2024-07-19T15:09:00.9662436+08:00;True|2024-07-19T15:05:35.7255851+08:00;True|2024-07-19T13:14:42.9559521+08:00;False|2024-07-19T11:37:52.4020673+08:00;True|2024-07-19T11:10:22.8661346+08:00;True|2024-07-19T11:00:00.8819251+08:00;True|2024-07-19T10:45:46.8271770+08:00;True|2024-07-19T10:45:03.8183458+08:00;True|2024-07-18T18:04:42.1000382+08:00;True|2024-07-18T18:01:51.3964409+08:00;True|2024-07-18T17:57:50.3509206+08:00;True|2024-07-18T16:32:46.2184830+08:00;True|2024-07-18T16:00:11.1381449+08:00;True|2024-07-18T15:11:52.6472758+08:00;True|2024-07-18T11:54:49.4848006+08:00;True|2024-07-18T09:25:58.7204846+08:00;True|2024-07-17T17:29:28.6175272+08:00;True|2024-07-17T17:10:54.5184246+08:00;True|2024-07-17T16:57:59.8174060+08:00;True|2024-07-17T16:18:13.8137834+08:00;</History>
<LastFailureDetails /> <LastFailureDetails />
</PropertyGroup> </PropertyGroup>
</Project> </Project>

+ 1
- 0
SafeCampus.API/SafeCampus.Web.Entry/appsettings.json View File

@@ -49,6 +49,7 @@
"PersonImg": "personImg", "PersonImg": "personImg",
"AttendanceImg": "attendanceImg", "AttendanceImg": "attendanceImg",
"RoomCallImg": "roomCallImg", "RoomCallImg": "roomCallImg",
"CameraImg": "cameraImg",
"Python": "D:\\Program Files\\py39\\python.exe" "Python": "D:\\Program Files\\py39\\python.exe"
}, },
//腾讯云短信配置 //腾讯云短信配置


+ 34
- 107
SafeCampus.WEB/src/views/violation/portrait/detail.vue
File diff suppressed because it is too large
View File


+ 73
- 15
monitorMobile/components/tki-tree/tki-tree.vue View File

@@ -3,18 +3,24 @@
<view class="tki-tree-mask" :class="{'show':showTree}" @tap="_cancel"></view> <view class="tki-tree-mask" :class="{'show':showTree}" @tap="_cancel"></view>
<view class="tki-tree-cnt" :class="{'show':showTree}"> <view class="tki-tree-cnt" :class="{'show':showTree}">
<view class="tki-tree-bar"> <view class="tki-tree-bar">
<view class="tki-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">取消</view>
<view class="tki-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">取消
</view>
<view class="tki-tree-bar-title" :style="{'color':titleColor}">{{title}}</view> <view class="tki-tree-bar-title" :style="{'color':titleColor}">{{title}}</view>
<view class="tki-tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c" @tap="_confirm">确定</view>
<view class="tki-tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c"
@tap="_confirm">确定</view>
</view> </view>

<view class="tki-tree-view"> <view class="tki-tree-view">
<scroll-view class="tki-tree-view-sc" :scroll-y="true"> <scroll-view class="tki-tree-view-sc" :scroll-y="true">
<view style="">
<u-search height="90rpx" :inputStyle="{fontSize:'30rpx'}"
v-model="searchText" placeholder="请输入" shape="square" :showAction="false"></u-search>
</view>
<block v-for="(item, index) in treeList" :key="index"> <block v-for="(item, index) in treeList" :key="index">
<view class="tki-tree-item" :style="[{
<view v-if="(item[rangeKey].includes(searchText))" class="tki-tree-item" :style="[{
paddingLeft: item.rank*15 + 'px', paddingLeft: item.rank*15 + 'px',
zIndex: item.rank*-1 +50 zIndex: item.rank*-1 +50
}]"
:class="{
}]" :class="{
border: border === true, border: border === true,
show: item.show, show: item.show,
last: item.lastRank, last: item.lastRank,
@@ -22,14 +28,21 @@
open: item.open, open: item.open,
}"> }">
<view class="tki-tree-label" @tap.stop="_treeItemTap(item, index)"> <view class="tki-tree-label" @tap.stop="_treeItemTap(item, index)">
<image class="tki-tree-icon" :src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon"></image>
<image class="tki-tree-icon"
:src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon">
</image>
{{item.name}} {{item.name}}
</view> </view>
<view class="tki-tree-check" @tap.stop="_treeItemSelect(item, index)" v-if="selectParent?true:item.lastRank">
<view class="tki-tree-check-yes" v-if="item.checked" :class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
<view class="tki-tree-check-yes-b" :style="{'background-color':confirmColor}"><u-icon name="checkbox-mark" color="#ffffff" size="16"></u-icon></view>
<view class="tki-tree-check" @tap.stop="_treeItemSelect(item, index)"
v-if="selectParent?true:item.lastRank">
<view class="tki-tree-check-yes" v-if="item.checked" :class="{'radio':!multiple}"
:style="{'border-color':confirmColor}">
<view class="tki-tree-check-yes-b" :style="{'background-color':confirmColor}">
<u-icon name="checkbox-mark" color="#ffffff" size="16"></u-icon>
</view>
</view> </view>
<view class="tki-tree-check-no" v-else :class="{'radio':!multiple}" :style="{'border-color':confirmColor}"></view>
<view class="tki-tree-check-no" v-else :class="{'radio':!multiple}"
:style="{'border-color':confirmColor}"></view>
</view> </view>
</view> </view>
</block> </block>
@@ -74,6 +87,10 @@
type: Boolean, type: Boolean,
default: false default: false
}, },
showChild: {//是否显示子级
type: Boolean,
default: false
},
confirmColor: { // 确定按钮颜色 confirmColor: { // 确定按钮颜色
type: String, type: String,
default: '' // #2388FF default: '' // #2388FF
@@ -108,10 +125,12 @@
showTree: false, showTree: false,
treeList: [], treeList: [],
selectIndex: -1, selectIndex: -1,
searchText: ''
} }
}, },
computed: {}, computed: {},
methods: { methods: {
_show() { _show() {
this.showTree = true this.showTree = true
}, },
@@ -149,9 +168,9 @@
parentId, // 父级id数组 parentId, // 父级id数组
parents, // 父级id数组 parents, // 父级id数组
rank, // 层级 rank, // 层级
showChild: false, //子级是否显示
showChild: this.showChild, //子级是否显示
open: false, //是否打开 open: false, //是否打开
show: rank === 0, // 自身是否显示
show: this.showChild, // 自身是否显示
hideArr: [], hideArr: [],
orChecked: item.checked ? item.checked : false, orChecked: item.checked ? item.checked : false,
checked: item.checked ? item.checked : false, checked: item.checked ? item.checked : false,
@@ -268,13 +287,39 @@
this.treeList[i].checked = v.orChecked this.treeList[i].checked = v.orChecked
}) })
}, },
_initTree(range = this.range){
_initTree(range = this.range) {
this.treeList = []; this.treeList = [];
this._renderTreeList(range); this._renderTreeList(range);
this.$nextTick(() => { this.$nextTick(() => {
this._defaultSelect(range) this._defaultSelect(range)
}) })
}
},
// searChange(value, data) {
// // this.treeList = this.filterTree(value, data)
// },
// filterTree(val, tree, newArr = []) {
// if (!(tree.length && val)) { // 如果搜索关键字为空直接返回源数据
// return tree
// }
// for (let item of tree) {
// if (item.name.indexOf(val) > -1) { // 匹配到关键字的逻辑
// newArr.push(item) // 如果匹配到就在数值中添加记录
// continue // 匹配到了就退出循环了此时如果有子集也会一并带着
// }
// if (item.children && item.children.length) { // 如果父级节点没有匹配到就看看是否有子集,然后做递归
// let subArr = this.filterTree(val, item.children) // 缓存递归后的子集数组
// if (subArr && subArr.length) { // 如果子集数据有匹配到的节点
// let node = {
// ...item,
// children: subArr
// } // 关键逻辑,缓存父节点同时将递归后的子节点作为新值
// newArr.push(node) // 添加进数组
// }
// }
// }
// return newArr
// },
}, },
watch: { watch: {
range(list) { range(list) {
@@ -290,6 +335,19 @@
this._reTreeList(); this._reTreeList();
} }
}, },
// searchText: {
// handler(newValue, oldValue) {
// console.log(111)
// console.log(this.treeList,11)
// console.log(this.range,11)
// // let arr = JSON.parse(JSON.stringify(this.treeList))
// this.filterTrees = this.filterTree(newValue, this.range)
// console.log(this.range,22)
// console.log(this.treeList,22)
// },
// deep: true

// }
}, },
mounted() { mounted() {
this._initTree(); this._initTree();
@@ -299,4 +357,4 @@


<style scoped> <style scoped>
@import "./style.css"; @import "./style.css";
</style>
</style>

+ 2
- 0
monitorMobile/pages.json View File

@@ -41,6 +41,7 @@
{ {
"path": "pages/earlyWarning/index", "path": "pages/earlyWarning/index",
"style": { "style": {
"enablePullDownRefresh": true,
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
@@ -102,6 +103,7 @@
{ {
"path": "pages/monitor/index", "path": "pages/monitor/index",
"style": { "style": {
"enablePullDownRefresh": true,
"navigationBarTitleText": "监控管理" "navigationBarTitleText": "监控管理"
} }
}, },


+ 88
- 70
monitorMobile/pages/earlyWarning/detail.vue View File

@@ -1,83 +1,92 @@
<template> <template>
<view class="warningDetail"> <view class="warningDetail">
<view class="title cli">
{{detailData.alarmTypeDesc ? detailData.alarmTypeDesc + '-' + detailData.tick : ''}}
</view>
<image style="width: 100%;height:422rpx;" :src="detailData.snapshotUrl" mode="aspectFit"></image>
<view class="cli">
<view class="labelBox">
所属学校:
</view>
<view class="valueBox">
演示学校
</view>
</view>
<view class="cli">
<view class="labelBox">
班级:
</view>
<view class="valueBox">
--
</view>
</view>
<view class="cli">
<view class="labelBox">
姓名:
</view>
<view class="valueBox">
{{ detailData.personName || "--" }}
</view>
</view>
<view class="cli">
<view class="labelBox">
预警摄像头:
<!-- <view style="height: 100vh;background: #fff;" v-if="showLoading">
<u-loading-page :loading="true" bg-color="#e8e8e8" color="#ffffff"></u-loading-page>
</view> -->
<u-loading-page :loading="showLoading" bg-color="#e8e8e8" color="#ffffff"></u-loading-page>
<!-- <u-loading-icon v-if="showLoading" text="加载中" textSize="18"></u-loading-icon> -->
<view class="">
<view class="title cli">
{{detailData.alarmTypeDesc ? detailData.alarmTypeDesc + '-' + detailData.tick : ''}}
</view> </view>
<view class="valueBox">
{{ detailData.cameraName || "--" }}
</view>
</view>
<view class="cli">
<view class="labelBox">
预警类型:
<image style="width: 100%;height:422rpx;" :src="detailData.snapshotUrl" mode="aspectFit"></image>
<view class="cli">
<view class="labelBox">
所属学校:
</view>
<view class="valueBox">
演示学校
</view>
</view> </view>
<view class="valueBox">
{{ detailData.alarmTypeDesc || "--" }}
<view class="cli">
<view class="labelBox">
班级:
</view>
<view class="valueBox">
--
</view>
</view> </view>
</view>
<view class="cli">
<view class="labelBox">
预警时间:
<view class="cli">
<view class="labelBox">
姓名:
</view>
<view class="valueBox">
{{ detailData.personName || "--" }}
</view>
</view> </view>
<view class="valueBox">
{{ detailData.tick || "--" }}
<view class="cli">
<view class="labelBox">
预警摄像头:
</view>
<view class="valueBox">
{{ detailData.cameraName || "--" }}
</view>
</view> </view>
</view>
<view class="cli">
<view class="labelBox">
复核视频:
<view class="cli">
<view class="labelBox">
预警类型:
</view>
<view class="valueBox">
{{ detailData.alarmTypeDesc || "--" }}
</view>
</view> </view>
<view class="valueBox">
<text v-if="detailData.videoUrl" style="color: #2388FF;" @click="seeVideo(detailData.videoUrl)">查看视频</text>
<text v-else>--</text>
<view class="cli">
<view class="labelBox">
预警时间:
</view>
<view class="valueBox">
{{ detailData.tick || "--" }}
</view>
</view> </view>
</view>
<view class="cli2">
<view class="labelBox">
备注信息:
<view class="cli">
<view class="labelBox">
复核视频:
</view>
<view class="valueBox">
<text v-if="detailData.videoUrl" style="color: #2388FF;"
@click="seeVideo(detailData.videoUrl)">查看视频</text>
<text v-else>--</text>
</view>
</view> </view>
<view class="valueBox">
{{ detailData.extend || '--' }}
<view class="cli2">
<view class="labelBox">
备注信息:
</view>
<view class="valueBox">
{{ detailData.extend || '--' }}
</view>
</view> </view>
</view>


<view class="cli2">
<view class="labelBox">
处理意见:
</view>
<view class="valueBox">
{{ detailData.remark || '--' }}
<view class="cli2">
<view class="labelBox">
处理意见:
</view>
<view class="valueBox">
{{ detailData.remark || '--' }}
</view>
</view> </view>
</view> </view>

<u-popup :show="showVideo" :closeable="true" @close="close" @open="open" mode="center"> <u-popup :show="showVideo" :closeable="true" @close="close" @open="open" mode="center">
<!-- <view class=""> <!-- <view class="">
视频 视频
@@ -126,6 +135,7 @@
playbackRate: 1, playbackRate: 1,
currentTime: 0, currentTime: 0,
duration: 0, duration: 0,
showLoading: false,
} }
}, },
computed: { computed: {
@@ -143,17 +153,25 @@
}, },
onLoad(options) { onLoad(options) {
console.log(options) console.log(options)
if(options.id) {
if (options.id) {
this.id = options.id; this.id = options.id;
} }
this.getInfo(); this.getInfo();
}, },
methods: { methods: {
getInfo() { getInfo() {
detail({ id: this.id }).then(res=>{
if(res.code == 200) {
this.showLoading = true;
detail({
id: this.id
}).then(res => {
if (res.code == 200) {
this.detailData = res.data; this.detailData = res.data;
} }
this.showLoading = false;
}).catch(err => {

this.showLoading = false;

}) })
}, },
seeVideo(url) { seeVideo(url) {
@@ -294,7 +312,7 @@
.valueBox { .valueBox {
color: #333333; color: #333333;
font-weight: 700; font-weight: 700;
} }
} }




+ 27
- 35
monitorMobile/pages/earlyWarning/index.vue View File

@@ -10,7 +10,7 @@
<image src="@/static/image/earlyWarning/logo.png" mode="heightFix"></image> <image src="@/static/image/earlyWarning/logo.png" mode="heightFix"></image>
</view> </view>
</view> </view>
<view class="contentBox" @touchmove.stop @touch.stop>
<view class="contentBox">
<view class="warningInfo"> <view class="warningInfo">
<view class="searchBox"> <view class="searchBox">
<view class="searchLine" @click="openSearch"> <view class="searchLine" @click="openSearch">
@@ -172,9 +172,9 @@
<!-- </scroll-view> --> <!-- </scroll-view> -->
<!-- </u-pull-refresh> --> <!-- </u-pull-refresh> -->
</view> </view>
<selectSearch ref="selectSearchBox" :cellVisible="false" v-model="searchForm.alarmType"
:options="warnOption" :title.sync="searchForm.$alarmType" placeholder="预警类型"
search-placeholder="预警类型" />
<selectSearch ref="selectSearchBox" :cellVisible="false"
v-model="searchForm.alarmType" :options="warnOption" :title.sync="searchForm.$alarmType"
placeholder="预警类型" search-placeholder="预警类型" />
<selectRadio ref="selectRadioBox" :cellVisible="false" v-model="searchForm.warnHand" <selectRadio ref="selectRadioBox" :cellVisible="false" v-model="searchForm.warnHand"
:options="handOption" :title.sync="searchForm.$warnHand" placeholder="处理状态" /> :options="handOption" :title.sync="searchForm.$warnHand" placeholder="处理状态" />
</view> </view>
@@ -196,7 +196,7 @@
}, },
data() { data() {
return { return {
searchValue: '',
searchValue: '全部',
isShowSearch: false, isShowSearch: false,
isTriggered: true, isTriggered: true,
searchForm: { searchForm: {
@@ -210,7 +210,12 @@
pageNum: 1, pageNum: 1,
pageSize: 10 pageSize: 10
}, },
warnOption: [],
warnOption: [
{
label: '全部',
value: ''
}
],
handOption: [{ handOption: [{
label: '已处理', label: '已处理',
value: 1 value: 1
@@ -239,36 +244,22 @@
}, },
}, },
onLoad() { onLoad() {
console.log(this.searchForm.$alarmType)
// 获取预警类型 // 获取预警类型
this.getWarnTypeList() this.getWarnTypeList()
// 隐藏导航栏 // 隐藏导航栏
this.loadmore() this.loadmore()
}, },
onPullDownRefresh() {
uni.stopPullDownRefresh()
this.status = 'loadmore'
this.searchForm.pageNum = 1;
this.warnList = []
this.loadmore()
},
methods: { methods: {

onRefresh() {
// this.refreshing = true;
console.log('下拉刷新')
},
// 执行刷新操作
doRefresh() {
console.log('正在刷新...');
// 这里执行刷新数据的逻辑
this.searchForm.pageNum = 1;
this.warnList = [];
this.loadmore()
setTimeout(() => {
// 刷新数据完成后,调用restore或abort方法结束刷新状态
this.restore();
}, 2000);
},
// 刷新结束,恢复scroll-view
restore() {
console.log('刷新结束');
},
// 刷新结束,取消scroll-view的刷新状态
abort() {
console.log('取消刷新');
selectChange(e) {
console.log(e, 2323)
}, },
// 预览图片 // 预览图片
previewImage(url, index) { previewImage(url, index) {
@@ -317,16 +308,17 @@
} = res; } = res;


if (code == 200) { if (code == 200) {
this.warnOption = data.map(item => {
let arr = data.map(item => {
return { return {
label: item.name, label: item.name,
value: item.code value: item.code
}; };
}) })
this.warnOption.unshift({
label: '全部',
value: ''
})
this.warnOption = [...this.warnOption,...arr]
// this.warnOption.unshift({
// label: '全部',
// value: ''
// })
} }
}); });




+ 73
- 18
monitorMobile/pages/monitor/index.vue View File

@@ -1,10 +1,24 @@
<template> <template>
<view @touchmove.stop@touch.stop class="inspectionCenter">
<view class="inspectionCenter">
<view v-show="showVideo" class="poupBox"> <view v-show="showVideo" class="poupBox">
<view class="videoHeader">

</view>
<view class="contentBox"> <view class="contentBox">
<view id="url-player-test"></view>
<view class="closeBox">
<view class="">
</view>
<view class="closes" @click="closeDialog">
<u-icon name="close-circle-fill" color="#ccc" size="24"></u-icon>
</view>
</view>
<view class="botbox">
<view id="url-player-test"></view>
</view>
</view> </view>
<view class="bottom-content" @click="closeDialog">
<view class="bottom-content">


</view> </view>
</view> </view>
@@ -125,8 +139,8 @@


</view> </view>
</u-modal> --> </u-modal> -->
<tki-tree ref="tkitree" :selectParent="selectParent" :multiple="multiple" :range="treelist" :foldAll="flod"
rangeKey="name" @confirm="treeConfirm" @cancel="treeCancel"></tki-tree>
<tki-tree ref="tkitree" title="摄像头分组" :showChild="showChild" :selectParent="selectParent" :multiple="multiple"
:range="treelist" :foldAll="flod" rangeKey="name" @confirm="treeConfirm" @cancel="treeCancel"></tki-tree>
</view> </view>
</template> </template>


@@ -154,6 +168,7 @@
videoTitle: '', videoTitle: '',
isShowSearch: false, isShowSearch: false,
searchForm: { searchForm: {
groupName: '全部',
groupId: '', groupId: '',
pageNum: 1, pageNum: 1,
pageSize: 10 pageSize: 10
@@ -165,6 +180,7 @@
multiple: false, //是否多选 multiple: false, //是否多选
selectParent: true, //父级可选择 selectParent: true, //父级可选择
flod: false, //折叠 flod: false, //折叠
showChild: true,
player: null, player: null,
sensorId: '', sensorId: '',
videoUrl: '', videoUrl: '',
@@ -183,9 +199,23 @@
// 获取列表数据 // 获取列表数据
this.loadmore() this.loadmore()
}, },
methods: {
onUnload() {
if(this.showVideo) {
this.closeDialog()
}
},
onPullDownRefresh() {
uni.stopPullDownRefresh()
this.status = 'loadmore'
this.searchForm.pageNum = 1;
this.monitorList = []
this.loadmore()
},
methods: {

setVideo() { setVideo() {
let that = this;
this.loadWebPlayerSDK().then(() => { this.loadWebPlayerSDK().then(() => {
// 如果需要使用自定义组件,打开以下注释 // 如果需要使用自定义组件,打开以下注释
// this.loadComponent().then(() => { // this.loadComponent().then(() => {
@@ -198,12 +228,12 @@
rtsFallback: true, rtsFallback: true,
rtsFallbackType: 'HLS', rtsFallbackType: 'HLS',
}, function(player) { }, function(player) {
// player.mute()
player.mute()
}); });


this.player.one('canplay', function() { this.player.one('canplay', function() {
// console.log('canplay', this.player.tag); // console.log('canplay', this.player.tag);
this.player.tag.play();
that.player.tag.play();
}); });




@@ -294,21 +324,25 @@
this.showVideo = false; this.showVideo = false;
}, },
getGroupList() { getGroupList() {
groupList({}).then((res) => {
if (res.code == 200) {
this.treelist = [...[{id: "",name: "全部"}], ...res.data];
}
});
groupList({}).then((res) => {
if (res.code == 200) {
this.treelist = [...[{
id: "",
name: "全部",
checked: true
}], ...res.data];
}
});
}, },
// 获取视频地址 // 获取视频地址
startClick(id) { startClick(id) {
this.sensorId = id; this.sensorId = id;
this.showVideo = true; this.showVideo = true;
startUrl({ startUrl({
sensorId: id sensorId: id
}).then(res => { }).then(res => {
let { let {
code, code,
data data
@@ -386,18 +420,39 @@
width: 100%; width: 100%;
z-index: 100000000000000; z-index: 100000000000000;
// background: red; // background: red;
background: rgba(0, 0, 0, 0.2);
background: rgba(0, 0, 0, 0.5);

.videoHeader {
height: 255rpx;
}


.contentBox { .contentBox {
// z-index: 1000000; // z-index: 1000000;
width: 100%; width: 100%;
height: 500rpx;
height: 590rpx;
background: #000; background: #000;

// margin: 50rpx auto; // margin: 50rpx auto;
.closeBox {
text-align: right;
height: 80rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 25rpx;
background: #fff;
.closes {
// background: #ccc;
}
}
.botbox {
height:calc(100% - 80rpx);
}
} }


.bottom-content { .bottom-content {
height: calc(100% - 500rpx);
height: calc(100% - 590rpx -255rpx);
} }
} }
} }


Loading…
Cancel
Save