初始化
This commit is contained in:
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/SupplierManager/obj
|
||||||
|
/SupplierManager/bin
|
||||||
|
/ViewModels/obj
|
||||||
|
/ViewModels/bin
|
||||||
|
/.vs
|
||||||
|
/SupplierManager/.vs
|
||||||
|
/aas_pc_web/.vscode
|
||||||
|
/aas_pc_web/obj
|
||||||
|
/SupplierManager/SupplierManager.csproj.user
|
||||||
|
/SupplierManager/.config
|
||||||
|
/SupplierManager/Properties/PublishProfiles
|
||||||
|
/SupplierManager/wwwroot/Uploads
|
||||||
|
/ConsoleAppTest/obj
|
||||||
|
/ConsoleAppTest/bin
|
||||||
10
ConsoleAppTest/ConsoleAppTest.csproj
Normal file
10
ConsoleAppTest/ConsoleAppTest.csproj
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
55
ConsoleAppTest/Program.cs
Normal file
55
ConsoleAppTest/Program.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
namespace ConsoleAppTest
|
||||||
|
{
|
||||||
|
public struct AFS
|
||||||
|
{
|
||||||
|
public int x;
|
||||||
|
public int y;
|
||||||
|
public string Name;
|
||||||
|
}
|
||||||
|
internal class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
List<Com> l = new List<Com>()
|
||||||
|
{
|
||||||
|
new Com(){id=1,Name="boolive"},
|
||||||
|
new Com(){id=2,Name="boolive"}
|
||||||
|
};
|
||||||
|
List<Com> l1 = new List<Com>()
|
||||||
|
{
|
||||||
|
new Com(){id=1,Name="boolive"},
|
||||||
|
new Com(){id=3,Name="boolive"}
|
||||||
|
};
|
||||||
|
var DDD= l1.Except(l).ToList();
|
||||||
|
var DDD1= l.Except(l1).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<Product> lll = new List<Product>()
|
||||||
|
{
|
||||||
|
new Product{id=1,ComId=1},
|
||||||
|
new Product{id=2,ComId=2},
|
||||||
|
new Product{id=3,ComId=3},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var str = l.Where(s => s.Name.StartsWith("JavaScript")).DefaultIfEmpty().First();
|
||||||
|
Console.WriteLine("str=" + str.Name); //输出空白
|
||||||
|
//使用string str1 = ListInt.Where(s => s.StartsWith("JavaScript")).First(); 如去掉DefaultEmpty就会报异常
|
||||||
|
Console.WriteLine("Hello, World!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Com
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
public class Product
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public int ComId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
45
SupplierManager.sln
Normal file
45
SupplierManager.sln
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.12.35527.113
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SupplierManager", "SupplierManager\SupplierManager.csproj", "{C0E9114F-9A75-4C9C-A620-835AB7320445}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ViewModels", "ViewModels\ViewModels.csproj", "{CCF28C8C-C597-40BF-B3FD-C1275C1DFD83}"
|
||||||
|
EndProject
|
||||||
|
Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "aas_pc_web", "aas_pc_web\aas_pc_web.esproj", "{ADB8BA1A-A076-739A-24E7-A4D2CD5A9514}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppTest", "ConsoleAppTest\ConsoleAppTest.csproj", "{50107F1E-6C76-43FB-B944-700330011DD7}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{C0E9114F-9A75-4C9C-A620-835AB7320445}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C0E9114F-9A75-4C9C-A620-835AB7320445}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C0E9114F-9A75-4C9C-A620-835AB7320445}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C0E9114F-9A75-4C9C-A620-835AB7320445}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{CCF28C8C-C597-40BF-B3FD-C1275C1DFD83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{CCF28C8C-C597-40BF-B3FD-C1275C1DFD83}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{CCF28C8C-C597-40BF-B3FD-C1275C1DFD83}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{CCF28C8C-C597-40BF-B3FD-C1275C1DFD83}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{ADB8BA1A-A076-739A-24E7-A4D2CD5A9514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{ADB8BA1A-A076-739A-24E7-A4D2CD5A9514}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{ADB8BA1A-A076-739A-24E7-A4D2CD5A9514}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||||
|
{ADB8BA1A-A076-739A-24E7-A4D2CD5A9514}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{ADB8BA1A-A076-739A-24E7-A4D2CD5A9514}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{ADB8BA1A-A076-739A-24E7-A4D2CD5A9514}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
|
{50107F1E-6C76-43FB-B944-700330011DD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{50107F1E-6C76-43FB-B944-700330011DD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{50107F1E-6C76-43FB-B944-700330011DD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{50107F1E-6C76-43FB-B944-700330011DD7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {6F6BE90E-782F-4AD7-9E68-D65B522CFEDA}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
13
SupplierManager/Common/MyMemoryCache.cs
Normal file
13
SupplierManager/Common/MyMemoryCache.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
|
||||||
|
namespace WebAPIServer.Common
|
||||||
|
{
|
||||||
|
public class MyMemoryCache
|
||||||
|
{
|
||||||
|
public MemoryCache Cache { get; } = new MemoryCache(
|
||||||
|
new MemoryCacheOptions
|
||||||
|
{
|
||||||
|
SizeLimit = 1024
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
30
SupplierManager/Common/StaticData.cs
Normal file
30
SupplierManager/Common/StaticData.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using IronPython.Hosting;
|
||||||
|
using Microsoft.Scripting.Hosting;
|
||||||
|
using SupplierManager.Extensions;
|
||||||
|
|
||||||
|
namespace SupplierManager.Common
|
||||||
|
{
|
||||||
|
public class StaticData
|
||||||
|
{
|
||||||
|
public readonly static object obj = new object();
|
||||||
|
public static ScriptEngine eng = Python.CreateEngine();
|
||||||
|
public static ScriptScope scope1 = eng.CreateScope();
|
||||||
|
public static ScriptScope scope2 = eng.CreateScope();
|
||||||
|
public static ScriptScope scope3 = eng.CreateScope();
|
||||||
|
|
||||||
|
public static void GetWebAPIMethod()
|
||||||
|
{
|
||||||
|
eng.Runtime.LoadAssembly(Assembly.GetExecutingAssembly());
|
||||||
|
eng.ExecuteFile("script\\webapi.py", scope1);
|
||||||
|
}
|
||||||
|
public static void GetWebAPIMethod1()
|
||||||
|
{
|
||||||
|
eng.ExecuteFile("script\\a.py", scope1);
|
||||||
|
}
|
||||||
|
public static void GetWebAPIMethod2()
|
||||||
|
{
|
||||||
|
eng.ExecuteFile("script\\b.py", scope1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
SupplierManager/Controllers/AasCustomerInfoesController.cs
Normal file
120
SupplierManager/Controllers/AasCustomerInfoesController.cs
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class AasCustomerInfoesController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly AgentApprovalSystemContext _context;
|
||||||
|
|
||||||
|
public AasCustomerInfoesController(AgentApprovalSystemContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/AasCustomerInfoes
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<ReturnInfo> GetAasCustomerInfos([FromBody] QueryAll_Or_Single S)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnInfo.isok = true;
|
||||||
|
if (S.IsAll)
|
||||||
|
{
|
||||||
|
returnInfo.response = await _context.AasCustomerInfos.ToListAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var aasCustomerInfo = await _context.AasCustomerInfos.FindAsync(S.ID);
|
||||||
|
|
||||||
|
returnInfo.response = aasCustomerInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// PUT: api/AasCustomerInfoes/5
|
||||||
|
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||||
|
[HttpPut("{id}")]
|
||||||
|
public async Task<ReturnInfo> PutAasCustomerInfo([FromBody] AasCustomerInfo aasCustomerInfo)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_context.Entry(aasCustomerInfo).State = EntityState.Modified;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/AasCustomerInfoes
|
||||||
|
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ReturnInfo> AddAasCustomerInfo([FromBody] AasCustomerInfo aasCustomerInfo)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_context.AasCustomerInfos.Add(aasCustomerInfo);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
public async Task<ReturnInfo> DeleteAasCustomerInfo([FromBody] Dictionary<string, long> stu)
|
||||||
|
{
|
||||||
|
ReturnInfo re = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
long id = stu["id"];
|
||||||
|
re.isok = true;
|
||||||
|
var aasCustomerInfo = await _context.AasCustomerInfos.FindAsync(id);
|
||||||
|
|
||||||
|
if (aasCustomerInfo != null)
|
||||||
|
{
|
||||||
|
_context.AasCustomerInfos.Remove(aasCustomerInfo);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
re.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
re.isok = false;
|
||||||
|
}
|
||||||
|
return re;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
451
SupplierManager/Controllers/AasProjectInfoesController.cs
Normal file
451
SupplierManager/Controllers/AasProjectInfoesController.cs
Normal file
@@ -0,0 +1,451 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.CodeAnalysis.Elfie.Model.Tree;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SupplierManager.Common;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class AasProjectInfoesController : ControllerBase
|
||||||
|
{
|
||||||
|
|
||||||
|
// GET: api/AasProjectInfoes
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> GetAasProjectInfos([FromBody] QueryAll_Or_Single_ProjectInfo S)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
if (S.IsAll)
|
||||||
|
{
|
||||||
|
returnInfo.isok = true;
|
||||||
|
var U = q.AasProjectInfos.Where(A => A.CompanyId == S.ComId).ToList();
|
||||||
|
|
||||||
|
var A = new List<ShengPiDDD>();
|
||||||
|
foreach (AasProjectInfo item in U)
|
||||||
|
{
|
||||||
|
ShengPiDDD s = new ShengPiDDD();
|
||||||
|
s.Id = item.Id;
|
||||||
|
s.Shengfen = item.Shengfen;
|
||||||
|
s.Quyu = item.Quyu;
|
||||||
|
s.AddressDetail = item.AddressDetail;
|
||||||
|
s.HangyeClass = item.HangyeClass;
|
||||||
|
s.ProjectCode = item.ProjectCode;
|
||||||
|
s.ProjectName = item.ProjectName;
|
||||||
|
s.CompanyId = item.CompanyId;
|
||||||
|
s.RoomTotalCount = item.RoomTotalCount;
|
||||||
|
s.RoomTypeCount = item.RoomTypeCount;
|
||||||
|
s.Blueprint = item.Blueprint;
|
||||||
|
s.Createtime = item.Createtime;
|
||||||
|
s.Updatetime = item.Updatetime;
|
||||||
|
s.ShengpiStatus = item.ShengpiStatus;
|
||||||
|
s.Uid = item.Uid;
|
||||||
|
s.Customization = item.Customization;
|
||||||
|
|
||||||
|
var U1 = q.AasProjectShenpis.Where(A => A.ProjectCode == item.ProjectCode).ToList();
|
||||||
|
s.sp = U1;
|
||||||
|
A.Add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
//var query = from t1 in q.AasProjectInfos
|
||||||
|
// join t2 in q.AasProjectShenpis on t1.ProjectCode equals t2.ProjectCode into tt1
|
||||||
|
// from t3 in tt1.DefaultIfEmpty()
|
||||||
|
// where t1.CompanyId == S.ComId
|
||||||
|
// select new
|
||||||
|
// {
|
||||||
|
// t1.Id,
|
||||||
|
// t1.Shengfen,
|
||||||
|
// t1.Quyu,
|
||||||
|
// t1.AddressDetail,
|
||||||
|
// t1.HangyeClass,
|
||||||
|
// t1.ProjectName,
|
||||||
|
// t1.ProjectCode,
|
||||||
|
// t1.CompanyId,
|
||||||
|
// t1.RoomTotalCount,
|
||||||
|
// t1.RoomTypeCount,
|
||||||
|
// t3.RejectReason,
|
||||||
|
// t3.ShenpiNumber,
|
||||||
|
// sp_Createtime= t3.Createtime
|
||||||
|
// };
|
||||||
|
|
||||||
|
//var result = query.ToList();
|
||||||
|
//var D = Q.ToList<ShengPiDDD>();
|
||||||
|
//var D = Q.ToList();
|
||||||
|
returnInfo.response = A;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//returnInfo.isok = true;
|
||||||
|
//var a = q.AasUsers.SingleOrDefault(A => A.Id == S.ID);
|
||||||
|
//if (a != null)
|
||||||
|
//{
|
||||||
|
// returnInfo.response = a;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> GetAasProjectInfos_Page([FromBody] QueryAll_Or_Single_ProjectInfo_Page S)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DateTime dt_s = DateTime.Now;
|
||||||
|
|
||||||
|
DateTime dt_e = DateTime.Now;
|
||||||
|
|
||||||
|
using var q = new AgentApprovalSystemContext();
|
||||||
|
|
||||||
|
|
||||||
|
List<AasProjectInfo> U = new List<AasProjectInfo>();
|
||||||
|
if (!string.IsNullOrEmpty(S.UpdateTime_Start) && !string.IsNullOrEmpty(S.UpdateTime_End) && S.ComId != 0)
|
||||||
|
{
|
||||||
|
DateTime.TryParse(S.UpdateTime_Start, out dt_s);
|
||||||
|
DateTime.TryParse(S.UpdateTime_End, out dt_e);
|
||||||
|
long dt_s_l = Tools.ToUnixTimestampBySeconds(dt_s);
|
||||||
|
long dt_e_l = Tools.ToUnixTimestampBySeconds(dt_e);
|
||||||
|
U = await q.AasProjectInfos.Where(A => A.CompanyId == S.ComId && A.UpdatetimeUnix > dt_s_l && A.UpdatetimeUnix <= dt_e_l).ToListAsync();
|
||||||
|
}
|
||||||
|
else if (string.IsNullOrEmpty(S.UpdateTime_Start) && string.IsNullOrEmpty(S.UpdateTime_End) && S.ComId != 0)
|
||||||
|
{
|
||||||
|
U = await q.AasProjectInfos.Where(A => A.CompanyId == S.ComId).ToListAsync();
|
||||||
|
}
|
||||||
|
else if (!string.IsNullOrEmpty(S.UpdateTime_Start) && !string.IsNullOrEmpty(S.UpdateTime_End) && S.ComId == 0)
|
||||||
|
{
|
||||||
|
DateTime.TryParse(S.UpdateTime_Start, out dt_s);
|
||||||
|
DateTime.TryParse(S.UpdateTime_End, out dt_e);
|
||||||
|
long dt_s_l = Tools.ToUnixTimestampBySeconds(dt_s);
|
||||||
|
long dt_e_l = Tools.ToUnixTimestampBySeconds(dt_e);
|
||||||
|
U = await q.AasProjectInfos.Where(A => A.UpdatetimeUnix > dt_s_l && A.UpdatetimeUnix <= dt_e_l).ToListAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
var A = new List<ShengPiDDD>();
|
||||||
|
foreach (AasProjectInfo item in U)
|
||||||
|
{
|
||||||
|
ShengPiDDD s = new ShengPiDDD();
|
||||||
|
s.Id = item.Id;
|
||||||
|
s.Shengfen = item.Shengfen;
|
||||||
|
s.Quyu = item.Quyu;
|
||||||
|
s.AddressDetail = item.AddressDetail;
|
||||||
|
s.HangyeClass = item.HangyeClass;
|
||||||
|
s.ProjectCode = item.ProjectCode;
|
||||||
|
s.ProjectName = item.ProjectName;
|
||||||
|
s.CompanyId = item.CompanyId;
|
||||||
|
s.RoomTotalCount = item.RoomTotalCount;
|
||||||
|
s.RoomTypeCount = item.RoomTypeCount;
|
||||||
|
s.Blueprint = item.Blueprint;
|
||||||
|
s.Createtime = item.Createtime;
|
||||||
|
s.Updatetime = item.Updatetime;
|
||||||
|
s.ShengpiStatus = item.ShengpiStatus;
|
||||||
|
s.Uid = item.Uid;
|
||||||
|
s.Customization = item.Customization;
|
||||||
|
|
||||||
|
var U1 = await q.AasProjectShenpis.Where(A => A.ProjectCode == item.ProjectCode).ToListAsync();
|
||||||
|
s.sp = U1;
|
||||||
|
A.Add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
returnInfo.isok = true;
|
||||||
|
returnInfo.response = A;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ShengPiDDD : AasProjectInfo
|
||||||
|
{
|
||||||
|
public List<AasProjectShenpi> sp { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PInfo
|
||||||
|
{
|
||||||
|
public long id { get; set; }
|
||||||
|
public string projectName { get; set; }
|
||||||
|
public int projectCode { get; set; }
|
||||||
|
public string shengfen { get; set; }
|
||||||
|
public string quyu { get; set; }
|
||||||
|
public string? addressDetail { get; set; }
|
||||||
|
public string? hangyeClass { get; set; }
|
||||||
|
public int roomTypeCount { get; set; }
|
||||||
|
public int roomTotalCount { get; set; }
|
||||||
|
public string? blueprint { get; set; }
|
||||||
|
public string? customization { get; set; }
|
||||||
|
}
|
||||||
|
// PUT: api/AasProjectInfoes/5
|
||||||
|
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> EditProjectInfo([FromBody] PInfo record)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var _context = new AgentApprovalSystemContext();
|
||||||
|
var aasProjectInfo = _context.AasProjectInfos.SingleOrDefault(A => A.Id == record.id);
|
||||||
|
if (aasProjectInfo != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
DateTime dt = DateTime.Now;
|
||||||
|
aasProjectInfo.Updatetime = dt;
|
||||||
|
aasProjectInfo.UpdatetimeUnix = Tools.ToUnixTimestampBySeconds(dt);
|
||||||
|
aasProjectInfo.Shengfen = record.shengfen;
|
||||||
|
aasProjectInfo.ProjectName = record.projectName;
|
||||||
|
aasProjectInfo.Quyu = record.quyu;
|
||||||
|
aasProjectInfo.AddressDetail = record.addressDetail;
|
||||||
|
aasProjectInfo.RoomTotalCount = record.roomTotalCount;
|
||||||
|
aasProjectInfo.RoomTypeCount = record.roomTypeCount;
|
||||||
|
aasProjectInfo.HangyeClass = record.hangyeClass;
|
||||||
|
aasProjectInfo.Blueprint = record.blueprint;
|
||||||
|
aasProjectInfo.Customization = record.customization;
|
||||||
|
|
||||||
|
_context.Entry(aasProjectInfo).State = EntityState.Modified;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = "你修改了一个不存在的数据,这是不允许的";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/AasProjectInfoes
|
||||||
|
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> AddAasProjectInfo(AasProjectInfo aasProjectInfo)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lock (StaticData.obj)
|
||||||
|
{
|
||||||
|
using (var _context = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
using var tran = _context.Database.BeginTransaction();
|
||||||
|
var QQQ = _context.Autokeygeneraters.SingleOrDefault();
|
||||||
|
if (QQQ != null)
|
||||||
|
{
|
||||||
|
long? n = QQQ.ProjectInfoCode + 1;
|
||||||
|
QQQ.ProjectInfoCode = n;
|
||||||
|
_context.Autokeygeneraters.Update(QQQ);
|
||||||
|
aasProjectInfo.ProjectCode = n.ToString();
|
||||||
|
}
|
||||||
|
long ll = Tools.ToUnixTimestampBySeconds(DateTime.Now);
|
||||||
|
aasProjectInfo.Createtime = DateTime.Now;
|
||||||
|
aasProjectInfo.Updatetime = DateTime.Now;
|
||||||
|
aasProjectInfo.ShengpiStatus = "1";
|
||||||
|
aasProjectInfo.CreatetimeUnix = ll;
|
||||||
|
aasProjectInfo.UpdatetimeUnix = ll;
|
||||||
|
_context.AasProjectInfos.Add(aasProjectInfo);
|
||||||
|
_context.SaveChanges();
|
||||||
|
|
||||||
|
tran.Commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/AasProjectInfoes/5
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> DeleteAasProjectInfo(long id)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
r.isok = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
using var _context = new AgentApprovalSystemContext();
|
||||||
|
|
||||||
|
var aasProjectInfo = await _context.AasProjectInfos.FindAsync(id);
|
||||||
|
if (aasProjectInfo == null)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = "要删除的数据不存在";
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.AasProjectInfos.Remove(aasProjectInfo);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> StatusChange_AasProjectInfo([FromBody] A a)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
r.isok = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
using var _context = new AgentApprovalSystemContext();
|
||||||
|
|
||||||
|
|
||||||
|
var aasProjectInfo = await _context.AasProjectInfos.FindAsync(a.id);
|
||||||
|
if (aasProjectInfo == null)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = "要修改的数据不存在";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (a.Status.Equals("3"))
|
||||||
|
{
|
||||||
|
var aasProjectInfo0 = await _context.AasProjectInfos.Where(X => X.ShengpiStatus.Equals("3") && X.ProjectName.Equals(aasProjectInfo.ProjectName)).ToListAsync();
|
||||||
|
if (aasProjectInfo0.Count > 0)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = "已有同名项目,请重试";
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aasProjectInfo.ShengpiStatus = a.Status;
|
||||||
|
aasProjectInfo.Updatetime = DateTime.Now;
|
||||||
|
_context.AasProjectInfos.Update(aasProjectInfo);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> Get_ProjectCode_Generate()
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
r.isok = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var _context = new AgentApprovalSystemContext();
|
||||||
|
var a = await _context.Autokeygeneraters.FirstOrDefaultAsync();
|
||||||
|
if (a == null)
|
||||||
|
{
|
||||||
|
Autokeygenerater d1 = new Autokeygenerater();
|
||||||
|
d1.ProjectInfoCode = 1000;
|
||||||
|
_context.Autokeygeneraters.Add(d1);
|
||||||
|
r.isok = true;
|
||||||
|
r.response = a.ProjectInfoCode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a.ProjectInfoCode = a.ProjectInfoCode + 1;
|
||||||
|
_context.Autokeygeneraters.Update(a);
|
||||||
|
r.isok = true;
|
||||||
|
r.response = a.ProjectInfoCode;
|
||||||
|
|
||||||
|
}
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> Get_ProjectByStatusCode()
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
r.isok = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var _context = new AgentApprovalSystemContext();
|
||||||
|
var LLL = await _context.AasProjectInfos.Where(A => A.ShengpiStatus.Equals("3")).ToListAsync();
|
||||||
|
r.response = LLL;
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public class A
|
||||||
|
{
|
||||||
|
public long id { get; set; }
|
||||||
|
public string? Status { get; set; }
|
||||||
|
//public string? Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
129
SupplierManager/Controllers/AasProjectReportReadiesController.cs
Normal file
129
SupplierManager/Controllers/AasProjectReportReadiesController.cs
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class AasProjectReportReadiesController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly AgentApprovalSystemContext _context;
|
||||||
|
|
||||||
|
public AasProjectReportReadiesController(AgentApprovalSystemContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/AasProjectReportReadies
|
||||||
|
[HttpPost()]
|
||||||
|
public async Task<ReturnInfo> GetAasProjectReportReadies([FromBody] QueryAll_Or_Single_ProjectInfo S)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (S.IsAll)
|
||||||
|
{
|
||||||
|
|
||||||
|
returnInfo.isok = true;
|
||||||
|
returnInfo.response = await _context.AasProjectReportReadies.ToListAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnInfo.isok = true;
|
||||||
|
var a = await _context.AasProjectReportReadies.FindAsync(S.ID);
|
||||||
|
if (a != null)
|
||||||
|
{
|
||||||
|
returnInfo.response = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// PUT: api/AasProjectReportReadies/5
|
||||||
|
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||||
|
[HttpPost()]
|
||||||
|
public async Task<ReturnInfo> EditAasProjectReportReady(AasProjectReportReady aasProjectReportReady)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
_context.Entry(aasProjectReportReady).State = EntityState.Modified;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/AasProjectReportReadies
|
||||||
|
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ReturnInfo> AddAasProjectReportReady(AasProjectReportReady aasProjectReportReady)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
_context.AasProjectReportReadies.Add(aasProjectReportReady);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/AasProjectReportReadies/5
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
public async Task<ReturnInfo> DeleteAasProjectReportReady(long id)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var aasProjectReportReady = await _context.AasProjectReportReadies.FindAsync(id);
|
||||||
|
if (aasProjectReportReady == null)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = "找不到要删除的数据";
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.AasProjectReportReadies.Remove(aasProjectReportReady);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
139
SupplierManager/Controllers/AasProjectShenpisController.cs
Normal file
139
SupplierManager/Controllers/AasProjectShenpisController.cs
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class AasProjectShenpisController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly AgentApprovalSystemContext _context;
|
||||||
|
|
||||||
|
public AasProjectShenpisController(AgentApprovalSystemContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/AasProjectShenpis
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> GetAasProjectShenpis([FromBody] QueryAll_Or_Single_ProjectInfo S)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (S.IsAll)
|
||||||
|
{
|
||||||
|
r.response = await _context.AasProjectShenpis.ToListAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
var aasProjectShenpi = await _context.AasProjectShenpis.FindAsync(S.ID);
|
||||||
|
r.isok = true;
|
||||||
|
r.response = aasProjectShenpi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> EditAasProjectShenpi([FromBody] AasProjectShenpi aasProjectShenpi)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
aasProjectShenpi.Updatetime = DateTime.Now;
|
||||||
|
_context.Entry(aasProjectShenpi).State = EntityState.Modified;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> AddAasProjectShenpi(AasProjectShenpi aasProjectShenpi)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
r.isok = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var Q = _context.AasProjectShenpis.Where(x => x.ProjectCode.Equals(aasProjectShenpi.ProjectCode));
|
||||||
|
if (Q.Count() > 0)
|
||||||
|
{
|
||||||
|
var Q1 = Q.OrderByDescending(A => A.ShenpiNumber).FirstOrDefault();
|
||||||
|
aasProjectShenpi.ShenpiNumber = Q1?.ShenpiNumber + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aasProjectShenpi.ShenpiNumber = 0;
|
||||||
|
}
|
||||||
|
aasProjectShenpi.Updatetime = DateTime.Now;
|
||||||
|
_context.AasProjectShenpis.Add(aasProjectShenpi);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/AasProjectShenpis/5
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> DeleteAasProjectShenpi(long id)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
var aasProjectShenpi = await _context.AasProjectShenpis.FindAsync(id);
|
||||||
|
if (aasProjectShenpi == null)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = "找不到相应的数据";
|
||||||
|
}
|
||||||
|
_context.AasProjectShenpis.Remove(aasProjectShenpi);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool AasProjectShenpiExists(long id)
|
||||||
|
{
|
||||||
|
return _context.AasProjectShenpis.Any(e => e.Id == id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
235
SupplierManager/Controllers/CompanyController.cs
Normal file
235
SupplierManager/Controllers/CompanyController.cs
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class CompanyController : ControllerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 删除用户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="LLL"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo DelCom([FromBody] Dictionary<string, int> LLL)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int idd = LLL["Id"];
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
var FFF = q.AasCompanyInfos.FirstOrDefault(A => A.Id == idd);
|
||||||
|
if (FFF != null)
|
||||||
|
{
|
||||||
|
q.AasCompanyInfos.Remove(FFF);
|
||||||
|
q.SaveChanges();
|
||||||
|
returnInfo.isok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改用户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="LLL"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo EditCom([FromBody] Com LLL)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
var lll = q.AasCompanyInfos.SingleOrDefault(A => A.Id == LLL.Id);
|
||||||
|
if (lll != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
lll.NameCn = LLL.NameCn;
|
||||||
|
lll.NameEn = LLL.NameEn;
|
||||||
|
lll.Identity = LLL.Identity;
|
||||||
|
lll.Industry = LLL.Industry;
|
||||||
|
lll.Code = LLL.Code;
|
||||||
|
lll.LicenseCode = LLL.LicenseCode;
|
||||||
|
lll.Region = LLL.Region;
|
||||||
|
lll.Logoaddress= LLL.Logoaddress;
|
||||||
|
lll.Updatetime = DateTime.Now;
|
||||||
|
|
||||||
|
q.AasCompanyInfos.Update(lll);
|
||||||
|
q.SaveChanges();
|
||||||
|
returnInfo.isok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取用户信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="S"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo GetComInfo([FromBody] QueryAll_Or_Single S)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
if (S.IsAll)
|
||||||
|
{
|
||||||
|
returnInfo.isok = true;
|
||||||
|
returnInfo.response = q.AasCompanyInfos.Select(F => new AasCompanyInfo
|
||||||
|
{
|
||||||
|
Id = F.Id,
|
||||||
|
Code = F.Code,
|
||||||
|
NameCn = F.NameCn,
|
||||||
|
NameEn = F.NameEn,
|
||||||
|
Identity = F.Identity,
|
||||||
|
LicenseCode = F.LicenseCode,
|
||||||
|
Industry = F.Industry,
|
||||||
|
Region = F.Region,
|
||||||
|
Logoaddress = F.Logoaddress
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnInfo.isok = true;
|
||||||
|
var a = q.AasCompanyInfos.SingleOrDefault(A => A.Id == S.ID);
|
||||||
|
if (a != null)
|
||||||
|
{
|
||||||
|
AasCompanyInfo u = new AasCompanyInfo();
|
||||||
|
u.Id = a.Id;
|
||||||
|
u.Code = a.Code;
|
||||||
|
u.NameCn = a.NameCn;
|
||||||
|
u.NameEn = a.NameEn;
|
||||||
|
u.Updatetime = a.Updatetime;
|
||||||
|
u.Createtime = a.Createtime;
|
||||||
|
u.Industry = a.Industry;
|
||||||
|
u.LicenseCode = a.LicenseCode;
|
||||||
|
u.Region = a.Region;
|
||||||
|
returnInfo.response = u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增用户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="LLL"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo AddCom([FromBody] Com LLL)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
AasCompanyInfo a = new AasCompanyInfo();
|
||||||
|
a.NameCn = LLL.NameCn;
|
||||||
|
a.NameEn = LLL.NameEn;
|
||||||
|
a.Identity = LLL.Identity;
|
||||||
|
a.Industry = LLL.Industry;
|
||||||
|
a.Region = LLL.Region;
|
||||||
|
a.Logoaddress = LLL.Logoaddress;
|
||||||
|
a.Createtime = DateTime.Now;
|
||||||
|
a.Updatetime = DateTime.Now;
|
||||||
|
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
var Q = q.AasCompanyInfos.Where(A => A.NameCn.Equals(LLL.NameCn));
|
||||||
|
if (Q.Count() > 0)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = "此公司已经存在";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using var T = q.Database.BeginTransaction();
|
||||||
|
Autokeygenerater? QQQ = q.Autokeygeneraters.SingleOrDefault();
|
||||||
|
QQQ.CompanyCode = QQQ.CompanyCode + 1;
|
||||||
|
|
||||||
|
a.Code = QQQ.CompanyCode.ToString();
|
||||||
|
q.Autokeygeneraters.Update(QQQ);
|
||||||
|
q.AasCompanyInfos.Add(a);
|
||||||
|
returnInfo.isok = true;
|
||||||
|
q.SaveChanges();
|
||||||
|
T.Commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class Com
|
||||||
|
{
|
||||||
|
|
||||||
|
public int Id { get; set; } = -1;
|
||||||
|
public string? Code { get; set; }
|
||||||
|
|
||||||
|
public string? NameCn { get; set; }
|
||||||
|
|
||||||
|
public string? NameEn { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属行业
|
||||||
|
/// </summary>
|
||||||
|
public string? Industry { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 身份
|
||||||
|
/// </summary>
|
||||||
|
public string? Identity { get; set; }
|
||||||
|
|
||||||
|
public string? Region { get; set; }
|
||||||
|
public string? Logoaddress { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业执照
|
||||||
|
/// </summary>
|
||||||
|
public string? LicenseCode { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
134
SupplierManager/Controllers/ConfigPYController.cs
Normal file
134
SupplierManager/Controllers/ConfigPYController.cs
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Scripting.Utils;
|
||||||
|
using SupplierManager.Common;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class ConfigPYController : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> GetConfigString()
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] str = await System.IO.File.ReadAllLinesAsync("script\\webapi.py");
|
||||||
|
|
||||||
|
List<VK> ll = new List<VK>();
|
||||||
|
foreach (var item in str)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(item))
|
||||||
|
{
|
||||||
|
string[] a = item.Split('=');
|
||||||
|
VK v = new VK();
|
||||||
|
v.VarName = a[0];
|
||||||
|
v.VarValue = a[1];
|
||||||
|
ll.Add(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.isok = true;
|
||||||
|
r.response = ll;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo RefreshConfig()
|
||||||
|
{
|
||||||
|
ReturnInfo info = new ReturnInfo();
|
||||||
|
info.isok = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StaticData.GetWebAPIMethod();
|
||||||
|
info.message = "Sucess";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
info.isok = false;
|
||||||
|
info.message = ex.Message;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VK
|
||||||
|
{
|
||||||
|
public string VarName { get; set; }
|
||||||
|
public string VarValue { get; set; }
|
||||||
|
}
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> SaveOrAddConfigString([FromBody] VK data)
|
||||||
|
{
|
||||||
|
ReturnInfo info = new ReturnInfo();
|
||||||
|
info.isok = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sss = System.IO.File.ReadAllLines("script\\webapi.py", Encoding.UTF8).ToList<string>();
|
||||||
|
for (int i = 0; i < sss.Count; i++)
|
||||||
|
{
|
||||||
|
string item = sss[i];
|
||||||
|
string[] txtdata = item.Split('=');
|
||||||
|
if (txtdata[0].Equals(data.VarName))
|
||||||
|
{
|
||||||
|
txtdata[1] = data.VarValue;
|
||||||
|
sss[i] = txtdata[0] + "=" + txtdata[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool exists = sss.Any(A => A.StartsWith(data.VarName));
|
||||||
|
|
||||||
|
if (exists == false)
|
||||||
|
{
|
||||||
|
sss.AddRange<string>(new string[] { data.VarName + "=" + data.VarValue });
|
||||||
|
}
|
||||||
|
|
||||||
|
await System.IO.File.WriteAllLinesAsync("script\\webapi.py", sss, Encoding.UTF8);
|
||||||
|
StaticData.GetWebAPIMethod();
|
||||||
|
info.message = "Sucess";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
info.isok = false;
|
||||||
|
info.message = ex.Message;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo GetSingleValue([FromBody] Dictionary<string, string> dic)
|
||||||
|
{
|
||||||
|
ReturnInfo info = new ReturnInfo();
|
||||||
|
info.isok = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string VarValue = dic["VarName"];
|
||||||
|
if (!string.IsNullOrEmpty(VarValue))
|
||||||
|
{
|
||||||
|
var QQQ = StaticData.scope1.GetVariable(VarValue);
|
||||||
|
string str = System.Text.Json.JsonSerializer.Serialize(QQQ);
|
||||||
|
info.response = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
info.isok = false;
|
||||||
|
info.message = ex.Message;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
134
SupplierManager/Controllers/FileUploadController.cs
Normal file
134
SupplierManager/Controllers/FileUploadController.cs
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class FileUploadController : ControllerBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public static string[] FolderG = new string[] {"face" };
|
||||||
|
|
||||||
|
[Authorize()]
|
||||||
|
[HttpPost()]
|
||||||
|
public async Task<IActionResult> UploadFile([FromForm] UploadFileModel model)
|
||||||
|
{
|
||||||
|
if (model.File == null || model.File.Length == 0)
|
||||||
|
{
|
||||||
|
return BadRequest("没有上传任何文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 获取文件名和扩展名
|
||||||
|
string originalFileName = Path.GetFileNameWithoutExtension(model.File.FileName);
|
||||||
|
string fileExtension = Path.GetExtension(model.File.FileName); // 包含扩展名前的点(如.jpg)
|
||||||
|
|
||||||
|
// 生成8位GUID(取完整GUID的前8位字符)
|
||||||
|
string guidPart = Guid.NewGuid().ToString("N")[..16];
|
||||||
|
|
||||||
|
// 组合新文件名:原文件名_8位GUID.扩展名
|
||||||
|
string newFileName = $"{originalFileName}_{guidPart}{fileExtension}";
|
||||||
|
|
||||||
|
var filePath = Path.Combine(Directory.GetCurrentDirectory(),
|
||||||
|
$"wwwroot/Uploads/{model.Folder}",
|
||||||
|
newFileName);
|
||||||
|
|
||||||
|
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||||
|
{
|
||||||
|
await model.File.CopyToAsync(stream);
|
||||||
|
}
|
||||||
|
return Ok(new { FileName = newFileName });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new { Message = ex.Message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record DF
|
||||||
|
{
|
||||||
|
public string? FileName { get; set; }
|
||||||
|
}
|
||||||
|
// 示例:通过文件名获取图片
|
||||||
|
[Authorize()]
|
||||||
|
[HttpPost()]
|
||||||
|
public IActionResult DownloadFile([FromBody]DF imageName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 拼接图片物理路径(假设图片存放在项目的 wwwroot/images 目录下)
|
||||||
|
var imagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/", imageName.FileName);
|
||||||
|
|
||||||
|
// 检查文件是否存在
|
||||||
|
if (!System.IO.File.Exists(imagePath))
|
||||||
|
{
|
||||||
|
return NotFound("Image not found");
|
||||||
|
}
|
||||||
|
if (imageName.FileName.Contains(".."))
|
||||||
|
{
|
||||||
|
return BadRequest("Invalid file name");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 读取文件流并返回
|
||||||
|
var imageStream = System.IO.File.OpenRead(imagePath);
|
||||||
|
|
||||||
|
// 根据扩展名自动设置 Content-Type(MIME类型)
|
||||||
|
var mimeType = GetMimeType(imageName.FileName);
|
||||||
|
|
||||||
|
return File(imageStream, mimeType);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, $"Internal server error: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize()]
|
||||||
|
[HttpPost()]
|
||||||
|
public IActionResult GetFileNameList()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 拼接图片物理路径(假设图片存放在项目的 wwwroot/images 目录下)
|
||||||
|
var filePath = Path.Combine(Directory.GetCurrentDirectory(),
|
||||||
|
$"wwwroot/Download/customization","");
|
||||||
|
|
||||||
|
string[] files= System.IO.Directory.GetFiles(filePath);
|
||||||
|
var myfiles= files.Select(A=>Path.GetFileName(A));
|
||||||
|
return Ok(new { FileNameList = myfiles });
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, $"Internal server error: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 MIME 类型映射
|
||||||
|
private string GetMimeType(string fileName)
|
||||||
|
{
|
||||||
|
var extension = Path.GetExtension(fileName).ToLowerInvariant();
|
||||||
|
return
|
||||||
|
extension switch
|
||||||
|
{
|
||||||
|
".jpg" => "image/jpeg",
|
||||||
|
".jpeg" => "image/jpeg",
|
||||||
|
".png" => "image/png",
|
||||||
|
".gif" => "image/gif",
|
||||||
|
".xls" =>"application/vnd.ms-excel",
|
||||||
|
".xlsx"=>"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
|
_ => "application/octet-stream" // 默认类型
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class UploadFileModel
|
||||||
|
{
|
||||||
|
public IFormFile File { get; set; }
|
||||||
|
public string Folder { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
247
SupplierManager/Controllers/LoginController.cs
Normal file
247
SupplierManager/Controllers/LoginController.cs
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.IdentityModel.Logging;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Text;
|
||||||
|
using ViewModels;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using ViewModels.RequestData;
|
||||||
|
using ViewModels.ResponseData;
|
||||||
|
using System.Net;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using RestSharp;
|
||||||
|
using NLog;
|
||||||
|
using SupplierManager.Extensions;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
using ViewModels.Common;
|
||||||
|
using static IronPython.Modules._ast;
|
||||||
|
|
||||||
|
namespace WebAPIServer.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class LoginController : ControllerBase
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
|
public IConfiguration? configuration { get; set; }
|
||||||
|
public LoginController(IConfiguration _configuration)
|
||||||
|
{
|
||||||
|
configuration = _configuration;
|
||||||
|
}
|
||||||
|
[Authorize()]
|
||||||
|
[HttpPost()]
|
||||||
|
public ReturnInfo TokenXuQi()
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
r.isok = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var claims = HttpContext.AuthenticateAsync().Result?.Principal?.Claims;
|
||||||
|
if (claims != null && claims.Any())
|
||||||
|
{
|
||||||
|
var Name = claims.SingleOrDefault(A => A.Type == ClaimTypes.Name)?.Value;
|
||||||
|
var UUU = claims.SingleOrDefault(A => A.Type == ClaimTypes.Role)?.Value;
|
||||||
|
var TTT = claims.SingleOrDefault(A => A.Type == ClaimTypes.NameIdentifier)?.Value;
|
||||||
|
|
||||||
|
AasUser? HH = new AasUser();
|
||||||
|
int a = 0;
|
||||||
|
int.TryParse(TTT, out a);
|
||||||
|
HH.Id = a;
|
||||||
|
bool bl = false;
|
||||||
|
bool.TryParse(UUU, out bl);
|
||||||
|
HH.Username = Name;
|
||||||
|
string TokenStr = GetToken(HH);
|
||||||
|
r.isok = true;
|
||||||
|
r.response = TokenStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 登录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="username">用户名</param>
|
||||||
|
/// <param name="password">密码</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public ReturnInfo Login([FromBody] LoginData data)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo res = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string password = data.password;
|
||||||
|
string username = data.username;
|
||||||
|
AasUser? entity = null;
|
||||||
|
string TokenString = "";
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
entity = q.AasUsers.SingleOrDefault(A => A.Username.Equals(username)&&A.Isdelete==false);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
bool vvv = Tools.VerifyHashedPassword(entity.Password, password);
|
||||||
|
if (vvv == false)
|
||||||
|
{
|
||||||
|
res.isok = false;
|
||||||
|
res.message = "密码错误";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TokenString = GetToken(entity);
|
||||||
|
res.isok = true;
|
||||||
|
|
||||||
|
|
||||||
|
ResLoginData r = new ResLoginData();
|
||||||
|
r.AccessToken = TokenString;
|
||||||
|
r.Id = entity.Id;
|
||||||
|
r.Username = entity.Username;
|
||||||
|
r.Realname = entity.Realname;
|
||||||
|
r.Position = entity.Position;
|
||||||
|
r.ComId = entity.ComId;
|
||||||
|
r.RoleId = entity.RoleId;
|
||||||
|
r.Avatar = entity.Avatar;
|
||||||
|
|
||||||
|
res.response = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res.isok = false;
|
||||||
|
res.message = "用户不存在";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
res.message = ex.Message;
|
||||||
|
res.isok = false;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// wy登录验证
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="username">用户名</param>
|
||||||
|
/// <param name="password">密码</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public ReturnInfo WeLogin([FromBody] LoginData data)
|
||||||
|
{
|
||||||
|
|
||||||
|
ReturnInfo res = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string password = data.password;
|
||||||
|
string username = data.username;
|
||||||
|
AasUser? entity = null;
|
||||||
|
string TokenString = "";
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
entity = q.AasUsers.SingleOrDefault(A => A.Username.Equals(username)&&A.Isdelete==false);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
bool vvv = Tools.VerifyHashedPassword(entity.Password, password);
|
||||||
|
if (vvv == false)
|
||||||
|
{
|
||||||
|
res.isok = false;
|
||||||
|
res.message = "密码错误";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TokenString = GetToken(entity);
|
||||||
|
res.isok = true;
|
||||||
|
|
||||||
|
JWTData r = new()
|
||||||
|
{
|
||||||
|
AccessToken = TokenString,
|
||||||
|
iss = "BLW-" + Guid.NewGuid().ToString(),
|
||||||
|
exp = Tools.ToUnixTimestampBySeconds(DateTime.Now.AddHours(12)),
|
||||||
|
iat = Tools.ToUnixTimestampBySeconds(DateTime.Now).ToString(),
|
||||||
|
jti = "AAS-" + Guid.NewGuid().ToString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
res.response = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res.isok = false;
|
||||||
|
res.message = "用户不存在";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
res.message = ex.Message;
|
||||||
|
res.isok = false;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetToken(AasUser? entity)
|
||||||
|
{
|
||||||
|
string TokenString;
|
||||||
|
var claims = new Claim[]
|
||||||
|
{
|
||||||
|
new Claim(ClaimTypes.NameIdentifier, entity.Id.ToString()),
|
||||||
|
new Claim(ClaimTypes.MobilePhone, entity.Mobile.ToString()),
|
||||||
|
new Claim(ClaimTypes.Name, entity.Username)
|
||||||
|
};
|
||||||
|
|
||||||
|
var secretByte = Encoding.UTF8.GetBytes(configuration["JwT:SecretKey"]);
|
||||||
|
var signingKey = new SymmetricSecurityKey(secretByte);
|
||||||
|
var a = SecurityAlgorithms.HmacSha256;
|
||||||
|
|
||||||
|
var signingCredentials = new SigningCredentials(signingKey, a);
|
||||||
|
|
||||||
|
var token = new JwtSecurityToken(
|
||||||
|
issuer: configuration["JwT:Issuer"],
|
||||||
|
audience: configuration["JwT:Audience"],//接收
|
||||||
|
claims: claims,//存放的用户信息
|
||||||
|
notBefore: DateTime.UtcNow,//发布时间
|
||||||
|
expires: DateTime.UtcNow.AddHours(12),
|
||||||
|
signingCredentials: signingCredentials
|
||||||
|
//有效期设置为1天signingCredentials //数字名
|
||||||
|
);
|
||||||
|
TokenString = new JwtSecurityTokenHandler().WriteToken(token);
|
||||||
|
return TokenString;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public string Helloooo()
|
||||||
|
{
|
||||||
|
return "hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class TblUtsManageUser
|
||||||
|
{
|
||||||
|
public object Id { get; internal set; }
|
||||||
|
public bool IsAdmin { get; internal set; }
|
||||||
|
public string? UserName { get; internal set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
20
SupplierManager/Controllers/PanelSelectionController.cs
Normal file
20
SupplierManager/Controllers/PanelSelectionController.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class PanelSelectionController : ControllerBase
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
381
SupplierManager/Controllers/UsersController.cs
Normal file
381
SupplierManager/Controllers/UsersController.cs
Normal file
@@ -0,0 +1,381 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
using ViewModels;
|
||||||
|
using ViewModels.Common;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class UsersController : ControllerBase
|
||||||
|
{
|
||||||
|
public class duser
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 删除用户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="LLL"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo DelUser([FromBody] duser LLL)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new();
|
||||||
|
if(LLL.Id == 2 || LLL.Id == 1)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = "超级管理员不可删除!";
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
var FFF = q.AasUsers.FirstOrDefault(A => A.Id == LLL.Id);
|
||||||
|
if (FFF != null)
|
||||||
|
{
|
||||||
|
FFF.Isdelete = true;
|
||||||
|
q.AasUsers.Update(FFF);
|
||||||
|
q.SaveChanges();
|
||||||
|
returnInfo.isok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改用户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="LLL"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo EditUser([FromBody] ReturnUser LLL)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
var lll = q.AasUsers.SingleOrDefault(A => A.Id == LLL.Id);
|
||||||
|
if (lll != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
string username = LLL.Username;
|
||||||
|
int? companyId = LLL.ComId;
|
||||||
|
string mobile = LLL.Mobile;
|
||||||
|
string weiXin = LLL.Weixin;
|
||||||
|
string email = LLL.Email;
|
||||||
|
|
||||||
|
lll.Realname = LLL.Realname;
|
||||||
|
lll.RoleId = LLL.RoleId;
|
||||||
|
lll.Position = LLL.Position;
|
||||||
|
if (!string.IsNullOrWhiteSpace(LLL.Avatar))
|
||||||
|
{
|
||||||
|
lll.Avatar = "Uploads/face/" + LLL.Avatar;
|
||||||
|
}
|
||||||
|
lll.Username = username;
|
||||||
|
lll.ComId = companyId;
|
||||||
|
lll.Mobile = mobile;
|
||||||
|
lll.Weixin = weiXin;
|
||||||
|
lll.Email = email;
|
||||||
|
lll.UpdateTime = DateTime.Now;
|
||||||
|
|
||||||
|
string PPP = LLL.Password.Trim();
|
||||||
|
if (!string.IsNullOrWhiteSpace(PPP))
|
||||||
|
{
|
||||||
|
lll.Password = Tools.HashPassword(PPP);
|
||||||
|
lll.PswEncryption = Tools.EncryptString(PPP);
|
||||||
|
}
|
||||||
|
|
||||||
|
q.AasUsers.Update(lll);
|
||||||
|
q.SaveChanges();
|
||||||
|
returnInfo.isok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置密码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="LLL"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo ModifyPassWord([FromBody] PWD_Reset LLL)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
var QQQ = q.AasUsers.SingleOrDefault(A => A.Id == LLL.Id);
|
||||||
|
if (QQQ != null)
|
||||||
|
{
|
||||||
|
QQQ.Password = Tools.HashPassword(LLL.PlaintextPwd);
|
||||||
|
QQQ.PswEncryption = Tools.EncryptString(LLL.PlaintextPwd);
|
||||||
|
q.AasUsers.Update(QQQ);
|
||||||
|
q.SaveChanges();
|
||||||
|
returnInfo.isok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 新增密码为123456
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="LLL"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo ResetPassWord([FromBody] PWD_Reset LLL)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
var Q = q.AasUsers.SingleOrDefault(A => A.Id == LLL.Id);
|
||||||
|
if (Q != null)
|
||||||
|
{
|
||||||
|
Q.Password = Tools.HashPassword("123456");
|
||||||
|
Q.PswEncryption = Tools.EncryptString("123456");
|
||||||
|
q.AasUsers.Update(Q);
|
||||||
|
q.SaveChanges();
|
||||||
|
returnInfo.isok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取用户信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="S"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public ReturnInfo GetUserInfo([FromBody] QueryAll_Or_Single S)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
if (S.IsAll)
|
||||||
|
{
|
||||||
|
returnInfo.isok = true;
|
||||||
|
returnInfo.response = q.AasUsers.Where(A=>!A.Isdelete).Select(F => new ReturnUser
|
||||||
|
{
|
||||||
|
Id = F.Id,
|
||||||
|
Username = F.Username,
|
||||||
|
Realname = F.Realname,
|
||||||
|
RoleId = F.RoleId,
|
||||||
|
Email = F.Email,
|
||||||
|
Weixin = F.Weixin,
|
||||||
|
Position = F.Position,
|
||||||
|
Avatar = F.Avatar,
|
||||||
|
ComId = F.ComId,
|
||||||
|
Mobile = F.Mobile,
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnInfo.isok = true;
|
||||||
|
var a = q.AasUsers.SingleOrDefault(A => A.Id == S.ID);
|
||||||
|
if (a != null)
|
||||||
|
{
|
||||||
|
ReturnUser u = new ReturnUser();
|
||||||
|
u.Id = a.Id;
|
||||||
|
u.Username = a.Username;
|
||||||
|
u.Realname = a.Realname;
|
||||||
|
u.RoleId = a.RoleId;
|
||||||
|
u.ComId = a.ComId;
|
||||||
|
u.Mobile = a.Mobile;
|
||||||
|
u.Weixin = a.Weixin;
|
||||||
|
u.Position = a.Position;
|
||||||
|
u.Avatar = a.Avatar;
|
||||||
|
u.Email = a.Email;
|
||||||
|
returnInfo.response = u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增用户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="LLL"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost()]
|
||||||
|
//[Authorize()]
|
||||||
|
public ReturnInfo AddUser([FromBody] ReturnUser LLL)
|
||||||
|
{
|
||||||
|
ReturnInfo returnInfo = new ReturnInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
string username = LLL.Username;
|
||||||
|
int? companyId = LLL.ComId;
|
||||||
|
string mobile = LLL.Mobile;
|
||||||
|
string weiXin = LLL.Weixin;
|
||||||
|
string email = LLL.Email;
|
||||||
|
|
||||||
|
AasUser lll = new AasUser();
|
||||||
|
lll.Username = username;
|
||||||
|
lll.Realname = LLL.Realname;
|
||||||
|
lll.ComId = LLL.ComId;
|
||||||
|
lll.RoleId = LLL.RoleId;
|
||||||
|
lll.Position = LLL.Position;
|
||||||
|
lll.Weixin = LLL.Weixin;
|
||||||
|
lll.Email = email;
|
||||||
|
lll.Mobile = mobile;
|
||||||
|
if (!string.IsNullOrWhiteSpace(LLL.Avatar))
|
||||||
|
{
|
||||||
|
lll.Avatar = "Uploads/face/" + LLL.Avatar;
|
||||||
|
}
|
||||||
|
lll.Isdelete = false;
|
||||||
|
|
||||||
|
lll.CreationTime = DateTime.Now;
|
||||||
|
lll.UpdateTime = DateTime.Now;
|
||||||
|
|
||||||
|
using (var q = new AgentApprovalSystemContext())
|
||||||
|
{
|
||||||
|
var Q = q.AasUsers.Where(A => A.Username.Equals(username));
|
||||||
|
if (Q.Count() > 0)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = "此用户名已经存在";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//lll.Password = Tools.HashPassword("123456");
|
||||||
|
//lll.PswEncryption = Tools.EncryptString("123456");
|
||||||
|
|
||||||
|
lll.Password = Tools.HashPassword(LLL.Password.Trim());
|
||||||
|
lll.PswEncryption = Tools.EncryptString(LLL.Password.Trim());
|
||||||
|
q.AasUsers.Add(lll);
|
||||||
|
returnInfo.isok = true;
|
||||||
|
}
|
||||||
|
q.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
returnInfo.isok = false;
|
||||||
|
returnInfo.message = ex.Message;
|
||||||
|
}
|
||||||
|
return returnInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 返回用户信息
|
||||||
|
/// </summary>
|
||||||
|
public class ReturnUser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名(登录名)
|
||||||
|
/// </summary>
|
||||||
|
public string? Username { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 真实姓名
|
||||||
|
/// </summary>
|
||||||
|
public string? Realname { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属公司ID
|
||||||
|
/// </summary>
|
||||||
|
public int? ComId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 角色ID
|
||||||
|
/// </summary>
|
||||||
|
public int? RoleId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位
|
||||||
|
/// </summary>
|
||||||
|
public string? Position { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码
|
||||||
|
/// </summary>
|
||||||
|
public string Password { get; set; } = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码加密处理
|
||||||
|
/// </summary>
|
||||||
|
public string PswEncryption { get; set; } = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信号
|
||||||
|
/// </summary>
|
||||||
|
public string? Weixin { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 邮箱
|
||||||
|
/// </summary>
|
||||||
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 电话号码
|
||||||
|
/// </summary>
|
||||||
|
public string? Mobile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 账户头像
|
||||||
|
/// </summary>
|
||||||
|
public string? Avatar { get; set; }
|
||||||
|
}
|
||||||
|
public class PWD_Reset
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string PlaintextPwd { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
41
SupplierManager/Controllers/WeatherForecastController.cs
Normal file
41
SupplierManager/Controllers/WeatherForecastController.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class WeatherForecastController : ControllerBase
|
||||||
|
{
|
||||||
|
private static readonly string[] Summaries = new[]
|
||||||
|
{
|
||||||
|
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly ILogger<WeatherForecastController> _logger;
|
||||||
|
|
||||||
|
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IEnumerable<WeatherForecast> Get()
|
||||||
|
{
|
||||||
|
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||||
|
{
|
||||||
|
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||||
|
TemperatureC = Random.Shared.Next(-20, 55),
|
||||||
|
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AAA()
|
||||||
|
{
|
||||||
|
//using var q = new AgentApprovalSystemContext();
|
||||||
|
//q.AasCompanyInfos.ToLinqToDB().LeftJoin(A=>A.Id==A.Id);
|
||||||
|
return "hello";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
143
SupplierManager/Controllers/WyUsersController.cs
Normal file
143
SupplierManager/Controllers/WyUsersController.cs
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
|
namespace SupplierManager.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class WyUsersController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly AgentApprovalSystemContext _context;
|
||||||
|
|
||||||
|
public WyUsersController(AgentApprovalSystemContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/WyUsers
|
||||||
|
[HttpPost()]
|
||||||
|
public async Task<ReturnInfo> GetUserInfo([FromBody] QueryAll_Or_Single S)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
r.isok = true;
|
||||||
|
r.response= await _context.WyUsers.ToListAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message=ex.Message;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost()]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> EditWyUser(WyUser wyUser)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!WyUserExists(wyUser.Id))
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = "此用户不存在";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_context.Entry(wyUser).State = EntityState.Modified;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
string Introduced = JsonSerializer.Serialize(wyUser);
|
||||||
|
string ReturnValue = JsonSerializer.Serialize(r);
|
||||||
|
await LogRecord(Introduced, ReturnValue);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetIP()
|
||||||
|
{
|
||||||
|
string? ip = string.Empty;
|
||||||
|
string? NNN = HttpContext?.Request?.HttpContext?.Connection?.RemoteIpAddress?.ToString();
|
||||||
|
if (string.IsNullOrEmpty(NNN))
|
||||||
|
{
|
||||||
|
ip = HttpContext?.Request.Headers["HTTP_X_FORWARDED_FOR"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ip = NNN;
|
||||||
|
}
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize()]
|
||||||
|
public async Task<ReturnInfo> AddWyUser(List<WyUser> wyUser)
|
||||||
|
{
|
||||||
|
ReturnInfo r = new ReturnInfo();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_context.WyUsers.AddRange(wyUser);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
r.isok = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
r.isok = false;
|
||||||
|
r.message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
string Introduced = JsonSerializer.Serialize(wyUser);
|
||||||
|
string ReturnValue = JsonSerializer.Serialize(r);
|
||||||
|
await LogRecord(Introduced, ReturnValue);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LogRecord(string Introduced, string ReturnValue)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
WyLog wx = new WyLog();
|
||||||
|
wx.Ip = GetIP();
|
||||||
|
wx.Operation = "Edit";
|
||||||
|
wx.Introduced = Introduced;
|
||||||
|
wx.ReturnValue = ReturnValue;
|
||||||
|
wx.CreationTime = Tools.ToUnixTimestampBySeconds(DateTime.Now);
|
||||||
|
_context.WyLogs.Add(wx);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool WyUserExists(long id)
|
||||||
|
{
|
||||||
|
return _context.WyUsers.Any(e => e.Id == id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
346
SupplierManager/Extensions/StringExtensions.cs
Normal file
346
SupplierManager/Extensions/StringExtensions.cs
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SupplierManager.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 字符串扩展函数工具类
|
||||||
|
/// </summary>
|
||||||
|
public static class StringExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 将\r\n替换成BR
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string ToSafeBR(this string str)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(str))
|
||||||
|
{
|
||||||
|
return str.Replace("\r\n", "<br>").Replace("\r", "<br>").Replace("\n", "<br>");
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 得到父部门的ID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetDepartmentFatherID(this string str)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(str) && str.Length > 2)
|
||||||
|
{
|
||||||
|
str = str.Substring(0, str.Length - 3);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 截取字符串,超过部分用...代替
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
/// <param name="len"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string Substr(this string source, int len)
|
||||||
|
{
|
||||||
|
return source.Substr(len, "...");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 截取字符串,超过部分用自定义代替
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
/// <param name="len"></param>
|
||||||
|
/// <param name="att"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string Substr(this string source, int len, string att)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(source))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
att = (att ?? string.Empty);
|
||||||
|
Regex regex = new Regex("[\\u4e00-\\u9fa5]");
|
||||||
|
Regex regex2 = new Regex("^[A-Za-z0-9]+$");
|
||||||
|
if (regex.IsMatch(source))
|
||||||
|
{
|
||||||
|
if (source.Length <= len)
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
return source.Substring(0, len) + att;
|
||||||
|
}
|
||||||
|
else if (regex2.IsMatch(source))
|
||||||
|
{
|
||||||
|
if (source.Length <= len * 2)
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
return source.Substring(0, len * 2) + att;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (source.Length <= len)
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
return source.Substring(0, len) + att;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string InputStr(this string source)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(source))
|
||||||
|
{
|
||||||
|
Regex regex = new Regex("[\\u4e00-\\u9fa5]");
|
||||||
|
Regex regex2 = new Regex("^[A-Za-z0-9]+$");
|
||||||
|
if (regex.IsMatch(source))
|
||||||
|
{
|
||||||
|
if (source.Length < 3)
|
||||||
|
{
|
||||||
|
return string.Format("{0}**", source[0]);
|
||||||
|
}
|
||||||
|
if (source.Length == 3)
|
||||||
|
{
|
||||||
|
return string.Format("{0}*{1}", source[0], source[source.Length - 1]);
|
||||||
|
}
|
||||||
|
if (source.Length > 3)
|
||||||
|
{
|
||||||
|
return string.Format("{0}**{1}", source[0], source[source.Length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!regex2.IsMatch(source))
|
||||||
|
{
|
||||||
|
return string.Format("{0}**", source.Substring(0, 2));
|
||||||
|
}
|
||||||
|
if (source.Length < 6)
|
||||||
|
{
|
||||||
|
return string.Format("{0}**", source.Substring(0, 2));
|
||||||
|
}
|
||||||
|
return string.Format("{0}****{1}", source.Substring(0, 2), source.Substring(source.Length - 3, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除掉所有的Html代码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="strHtml"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string RemoveHtml(this string strHtml)
|
||||||
|
{
|
||||||
|
Regex regex = new Regex("<.+?>", RegexOptions.IgnoreCase);
|
||||||
|
strHtml = regex.Replace(strHtml, "");
|
||||||
|
strHtml = strHtml.Replace(" ", "");
|
||||||
|
return strHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成0-9随机数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="VcodeNum">生成长度</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string RndNum(int VcodeNum)
|
||||||
|
{
|
||||||
|
StringBuilder stringBuilder = new StringBuilder(VcodeNum);
|
||||||
|
Random random = new Random();
|
||||||
|
for (int i = 1; i < VcodeNum + 1; i++)
|
||||||
|
{
|
||||||
|
int num = random.Next(9);
|
||||||
|
stringBuilder.AppendFormat("{0}", num);
|
||||||
|
}
|
||||||
|
return stringBuilder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回星号的加密
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="items"></param>
|
||||||
|
/// <param name="mask"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string MaskStar(Dictionary<string, string> items, bool mask)
|
||||||
|
{
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
if (mask)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, string> keyValuePair in items)
|
||||||
|
{
|
||||||
|
stringBuilder.Append(string.Concat(new string[]
|
||||||
|
{
|
||||||
|
"$('#",
|
||||||
|
keyValuePair.Key,
|
||||||
|
"').attr('name', '",
|
||||||
|
keyValuePair.Key,
|
||||||
|
"mask');"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
stringBuilder.Append("$('.maskstar').attr('disabled', true);");
|
||||||
|
stringBuilder.Append("$('.maskstar').val('***');");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, string> keyValuePair2 in items)
|
||||||
|
{
|
||||||
|
stringBuilder.Append(string.Concat(new string[]
|
||||||
|
{
|
||||||
|
"$('#",
|
||||||
|
keyValuePair2.Key,
|
||||||
|
"').attr('name', '",
|
||||||
|
keyValuePair2.Key,
|
||||||
|
"');"
|
||||||
|
}));
|
||||||
|
stringBuilder.Append(string.Concat(new string[]
|
||||||
|
{
|
||||||
|
"$('#",
|
||||||
|
keyValuePair2.Key,
|
||||||
|
"').val('",
|
||||||
|
keyValuePair2.Value,
|
||||||
|
"');"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
stringBuilder.Append("$('.maskstar').attr('disabled', false);");
|
||||||
|
}
|
||||||
|
return stringBuilder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 给自动填充使用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str1"></param>
|
||||||
|
/// <param name="str2"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string ToAutoComplate(this string str1, string str2)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(str1) && !string.IsNullOrEmpty(str2))
|
||||||
|
{
|
||||||
|
return str1 + "," + str2;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回红色字体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string ToRedColor(this int value)
|
||||||
|
{
|
||||||
|
if (value != 0)
|
||||||
|
{
|
||||||
|
return "<font color='red'>" + value.ToString() + "</font>";
|
||||||
|
}
|
||||||
|
return value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回安全的字符串类型如果为NULL则返回空
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string ToSafeString(this object value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将中文转换成Unicode编码,主要用在URL传递中文
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GB2Unicode(this string str)
|
||||||
|
{
|
||||||
|
string text = "";
|
||||||
|
Encoding encoding = Encoding.GetEncoding("GB2312");
|
||||||
|
Encoding unicode = Encoding.Unicode;
|
||||||
|
byte[] bytes = encoding.GetBytes(str);
|
||||||
|
for (int i = 0; i < bytes.Length; i++)
|
||||||
|
{
|
||||||
|
string str2 = "%" + bytes[i].ToString("x");
|
||||||
|
text += str2;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将字符串转换成为大写的MD5
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string ToMD5(this string str)
|
||||||
|
{
|
||||||
|
MD5CryptoServiceProvider md5CryptoServiceProvider = new MD5CryptoServiceProvider();
|
||||||
|
byte[] array = md5CryptoServiceProvider.ComputeHash(Encoding.Default.GetBytes(str));
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
foreach (byte b in array)
|
||||||
|
{
|
||||||
|
stringBuilder.Append(b.ToString("x2"));
|
||||||
|
}
|
||||||
|
return stringBuilder.ToString().ToUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 字节码长度转可读字符串 00000000 bytes 0.0GB
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="KSize"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string ByteSizeToString(this long KSize)
|
||||||
|
{
|
||||||
|
if (KSize > 0L)
|
||||||
|
{
|
||||||
|
string[] array = new string[]
|
||||||
|
{
|
||||||
|
"B",
|
||||||
|
"KB",
|
||||||
|
"MB",
|
||||||
|
"GB",
|
||||||
|
"TB"
|
||||||
|
};
|
||||||
|
double num = 0.0;
|
||||||
|
int num2 = array.Length - 1;
|
||||||
|
while (num2 >= 0 && (num = Math.Round((double)KSize / Math.Pow(1024.0, (double)num2), 2)) < 1.0)
|
||||||
|
{
|
||||||
|
num2--;
|
||||||
|
}
|
||||||
|
return string.Format("{0}{1}", num, array[num2]);
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将字符串转换成为大写的MD5
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static string GetMD5Code(this string str)
|
||||||
|
{
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
using (MD5CryptoServiceProvider md5CryptoServiceProvider = new MD5CryptoServiceProvider())
|
||||||
|
{
|
||||||
|
byte[] array = md5CryptoServiceProvider.ComputeHash(Encoding.Default.GetBytes(str));
|
||||||
|
foreach (byte b in array)
|
||||||
|
{
|
||||||
|
stringBuilder.Append(b.ToString("x2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stringBuilder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
33
SupplierManager/Extensions/TimeExtensions.cs
Normal file
33
SupplierManager/Extensions/TimeExtensions.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SupplierManager.Extensions
|
||||||
|
{
|
||||||
|
public static class TimeExtensions
|
||||||
|
{
|
||||||
|
public static DateTime? ToDateTime(this string timeStamp)
|
||||||
|
{
|
||||||
|
long ticks = 0L;
|
||||||
|
if (long.TryParse(timeStamp, out ticks))
|
||||||
|
{
|
||||||
|
DateTime dateTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
|
||||||
|
TimeSpan value = new TimeSpan(ticks);
|
||||||
|
return new DateTime?(dateTime.Add(value));
|
||||||
|
}
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
if (DateTime.TryParse(timeStamp, out now))
|
||||||
|
{
|
||||||
|
return new DateTime?(now);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static string fff()
|
||||||
|
{
|
||||||
|
return "hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
50
SupplierManager/Models/AasCompanyInfo.cs
Normal file
50
SupplierManager/Models/AasCompanyInfo.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasCompanyInfo
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 公司代码
|
||||||
|
/// </summary>
|
||||||
|
public string? Code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 中文名
|
||||||
|
/// </summary>
|
||||||
|
public string? NameCn { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 英文名
|
||||||
|
/// </summary>
|
||||||
|
public string? NameEn { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属行业
|
||||||
|
/// </summary>
|
||||||
|
public string? Industry { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 身份
|
||||||
|
/// </summary>
|
||||||
|
public string? Identity { get; set; }
|
||||||
|
|
||||||
|
public string? Region { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业执照
|
||||||
|
/// </summary>
|
||||||
|
public string? LicenseCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// logo地址
|
||||||
|
/// </summary>
|
||||||
|
public string? Logoaddress { get; set; }
|
||||||
|
|
||||||
|
public DateTime? Createtime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? Updatetime { get; set; }
|
||||||
|
}
|
||||||
21
SupplierManager/Models/AasCustomerInfo.cs
Normal file
21
SupplierManager/Models/AasCustomerInfo.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasCustomerInfo
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
public string? Realname { get; set; }
|
||||||
|
|
||||||
|
public string? ComName { get; set; }
|
||||||
|
|
||||||
|
public string? Job { get; set; }
|
||||||
|
|
||||||
|
public string? Mobile { get; set; }
|
||||||
|
|
||||||
|
public string? Weixin { get; set; }
|
||||||
|
|
||||||
|
public string? Mark { get; set; }
|
||||||
|
}
|
||||||
85
SupplierManager/Models/AasProjectInfo.cs
Normal file
85
SupplierManager/Models/AasProjectInfo.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasProjectInfo
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属省份
|
||||||
|
/// </summary>
|
||||||
|
public string? Shengfen { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属区域
|
||||||
|
/// </summary>
|
||||||
|
public string? Quyu { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 详细地址
|
||||||
|
/// </summary>
|
||||||
|
public string? AddressDetail { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 行业类型
|
||||||
|
/// </summary>
|
||||||
|
public string? HangyeClass { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目名称
|
||||||
|
/// </summary>
|
||||||
|
public string? ProjectName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目编码
|
||||||
|
/// </summary>
|
||||||
|
public string? ProjectCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 公司ID
|
||||||
|
/// </summary>
|
||||||
|
public int? CompanyId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 房型数量
|
||||||
|
/// </summary>
|
||||||
|
public int? RoomTypeCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 房间总数
|
||||||
|
/// </summary>
|
||||||
|
public int? RoomTotalCount { get; set; }
|
||||||
|
|
||||||
|
public DateTime? Createtime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? Updatetime { get; set; }
|
||||||
|
|
||||||
|
public long? UpdatetimeUnix { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unix时间
|
||||||
|
/// </summary>
|
||||||
|
public long? CreatetimeUnix { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 审批状态
|
||||||
|
/// </summary>
|
||||||
|
public string? ShengpiStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 申请人
|
||||||
|
/// </summary>
|
||||||
|
public int? Uid { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计图
|
||||||
|
/// </summary>
|
||||||
|
public string? Blueprint { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 套餐名称
|
||||||
|
/// </summary>
|
||||||
|
public string? Customization { get; set; }
|
||||||
|
}
|
||||||
19
SupplierManager/Models/AasProjectReportReady.cs
Normal file
19
SupplierManager/Models/AasProjectReportReady.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasProjectReportReady
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
public string? ProjectCode { get; set; }
|
||||||
|
|
||||||
|
public string? CustomerContactsH { get; set; }
|
||||||
|
|
||||||
|
public DateTime? Createtime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? Updatetime { get; set; }
|
||||||
|
|
||||||
|
public long? Unixtime { get; set; }
|
||||||
|
}
|
||||||
33
SupplierManager/Models/AasProjectShenpi.cs
Normal file
33
SupplierManager/Models/AasProjectShenpi.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasProjectShenpi
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目代码
|
||||||
|
/// </summary>
|
||||||
|
public string? ProjectCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 审批建议
|
||||||
|
/// </summary>
|
||||||
|
public string? ShenpiSuggest { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 驳回理由
|
||||||
|
/// </summary>
|
||||||
|
public string? RejectReason { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 审批序号
|
||||||
|
/// </summary>
|
||||||
|
public int? ShenpiNumber { get; set; }
|
||||||
|
|
||||||
|
public DateTime? Createtime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? Updatetime { get; set; }
|
||||||
|
}
|
||||||
82
SupplierManager/Models/AasUser.cs
Normal file
82
SupplierManager/Models/AasUser.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasUser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名(登录名)
|
||||||
|
/// </summary>
|
||||||
|
public string? Username { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 真实姓名
|
||||||
|
/// </summary>
|
||||||
|
public string? Realname { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属公司ID
|
||||||
|
/// </summary>
|
||||||
|
public int? ComId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 角色ID
|
||||||
|
/// </summary>
|
||||||
|
public int? RoleId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位
|
||||||
|
/// </summary>
|
||||||
|
public string? Position { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码
|
||||||
|
/// </summary>
|
||||||
|
public string Password { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码加密处理
|
||||||
|
/// </summary>
|
||||||
|
public string PswEncryption { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信号
|
||||||
|
/// </summary>
|
||||||
|
public string? Weixin { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 邮箱
|
||||||
|
/// </summary>
|
||||||
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 电话号码
|
||||||
|
/// </summary>
|
||||||
|
public string? Mobile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 账户头像
|
||||||
|
/// </summary>
|
||||||
|
public string? Avatar { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否删除
|
||||||
|
/// </summary>
|
||||||
|
public bool Isdelete { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? CreationTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? UpdateTime { get; set; }
|
||||||
|
}
|
||||||
13
SupplierManager/Models/AasUserPermission.cs
Normal file
13
SupplierManager/Models/AasUserPermission.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasUserPermission
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string? ProxyClass { get; set; }
|
||||||
|
|
||||||
|
public string? ProxyRegion { get; set; }
|
||||||
|
}
|
||||||
47
SupplierManager/Models/AasUsersLoginLog.cs
Normal file
47
SupplierManager/Models/AasUsersLoginLog.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasUsersLoginLog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名字
|
||||||
|
/// </summary>
|
||||||
|
public string? Username { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ip地址
|
||||||
|
/// </summary>
|
||||||
|
public string? Ip { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 浏览器版本
|
||||||
|
/// </summary>
|
||||||
|
public string? Browser { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 操作类型
|
||||||
|
/// </summary>
|
||||||
|
public string? Operation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备型号
|
||||||
|
/// </summary>
|
||||||
|
public string? Device { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 地理位置
|
||||||
|
/// </summary>
|
||||||
|
public string? Location { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? CreationTime { get; set; }
|
||||||
|
}
|
||||||
57
SupplierManager/Models/AasUsersOperateLog.cs
Normal file
57
SupplierManager/Models/AasUsersOperateLog.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AasUsersOperateLog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名字
|
||||||
|
/// </summary>
|
||||||
|
public string? Username { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日志类型ID
|
||||||
|
/// </summary>
|
||||||
|
public int? TypeId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行操作
|
||||||
|
/// </summary>
|
||||||
|
public string? Operate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ip地址
|
||||||
|
/// </summary>
|
||||||
|
public string? Ip { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 浏览器版本
|
||||||
|
/// </summary>
|
||||||
|
public string? Browser { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 操作类型
|
||||||
|
/// </summary>
|
||||||
|
public string? Operation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备型号
|
||||||
|
/// </summary>
|
||||||
|
public string? Device { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 地理位置
|
||||||
|
/// </summary>
|
||||||
|
public string? Location { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? CreationTime { get; set; }
|
||||||
|
}
|
||||||
550
SupplierManager/Models/AgentApprovalSystemContext.cs
Normal file
550
SupplierManager/Models/AgentApprovalSystemContext.cs
Normal file
@@ -0,0 +1,550 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Pomelo.EntityFrameworkCore.MySql.Scaffolding.Internal;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class AgentApprovalSystemContext : DbContext
|
||||||
|
{
|
||||||
|
public AgentApprovalSystemContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public AgentApprovalSystemContext(DbContextOptions<AgentApprovalSystemContext> options)
|
||||||
|
: base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual DbSet<AasCompanyInfo> AasCompanyInfos { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<AasCustomerInfo> AasCustomerInfos { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<AasProjectInfo> AasProjectInfos { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<AasProjectReportReady> AasProjectReportReadies { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<AasProjectShenpi> AasProjectShenpis { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<AasUser> AasUsers { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<AasUserPermission> AasUserPermissions { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<AasUsersOperateLog> AasUsersOperateLogs { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Autokeygenerater> Autokeygeneraters { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<WyLog> WyLogs { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<WyUser> WyUsers { get; set; }
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
|
||||||
|
=> optionsBuilder.UseMySql("server=blv-cloud-db.mysql.rds.aliyuncs.com;database=agent_approval_system;uid=blv_rcu;pwd=fnadiaJDIJ7546;charset=utf8;port=3307", Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.28-mysql"));
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder
|
||||||
|
.UseCollation("utf8mb4_bin")
|
||||||
|
.HasCharSet("utf8mb4");
|
||||||
|
|
||||||
|
modelBuilder.Entity<AasCompanyInfo>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("aas_company_info");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Code)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("公司代码")
|
||||||
|
.HasColumnName("code");
|
||||||
|
entity.Property(e => e.Createtime)
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("createtime");
|
||||||
|
entity.Property(e => e.Identity)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("身份")
|
||||||
|
.HasColumnName("identity");
|
||||||
|
entity.Property(e => e.Industry)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("所属行业")
|
||||||
|
.HasColumnName("industry");
|
||||||
|
entity.Property(e => e.LicenseCode)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("营业执照")
|
||||||
|
.HasColumnName("licenseCode");
|
||||||
|
entity.Property(e => e.Logoaddress)
|
||||||
|
.HasComment("logo地址")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("logoaddress");
|
||||||
|
entity.Property(e => e.NameCn)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("中文名")
|
||||||
|
.HasColumnName("nameCn");
|
||||||
|
entity.Property(e => e.NameEn)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("英文名")
|
||||||
|
.HasColumnName("nameEn");
|
||||||
|
entity.Property(e => e.Region)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("region");
|
||||||
|
entity.Property(e => e.Updatetime)
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("updatetime");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<AasCustomerInfo>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("aas_customer_info");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id)
|
||||||
|
.ValueGeneratedNever()
|
||||||
|
.HasColumnName("id");
|
||||||
|
entity.Property(e => e.ComName)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("com_name");
|
||||||
|
entity.Property(e => e.Job)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("job");
|
||||||
|
entity.Property(e => e.Mark)
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("mark");
|
||||||
|
entity.Property(e => e.Mobile)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("mobile");
|
||||||
|
entity.Property(e => e.Realname)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("realname");
|
||||||
|
entity.Property(e => e.Weixin)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("weixin");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<AasProjectInfo>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("aas_project_info");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.UpdatetimeUnix, "Unixupdatetime");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.CompanyId, "comid");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.AddressDetail)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("详细地址")
|
||||||
|
.HasColumnName("address_detail");
|
||||||
|
entity.Property(e => e.Blueprint)
|
||||||
|
.HasComment("设计图")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("blueprint");
|
||||||
|
entity.Property(e => e.CompanyId)
|
||||||
|
.HasComment("公司ID")
|
||||||
|
.HasColumnName("company_id");
|
||||||
|
entity.Property(e => e.Createtime)
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("createtime");
|
||||||
|
entity.Property(e => e.CreatetimeUnix)
|
||||||
|
.HasComment("Unix时间")
|
||||||
|
.HasColumnName("createtime_unix");
|
||||||
|
entity.Property(e => e.Customization)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("套餐名称")
|
||||||
|
.HasColumnName("customization");
|
||||||
|
entity.Property(e => e.HangyeClass)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("行业类型")
|
||||||
|
.HasColumnName("hangye_class");
|
||||||
|
entity.Property(e => e.ProjectCode)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("项目编码")
|
||||||
|
.HasColumnName("project_code");
|
||||||
|
entity.Property(e => e.ProjectName)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("项目名称")
|
||||||
|
.HasColumnName("project_name");
|
||||||
|
entity.Property(e => e.Quyu)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("所属区域")
|
||||||
|
.HasColumnName("quyu");
|
||||||
|
entity.Property(e => e.RoomTotalCount)
|
||||||
|
.HasComment("房间总数")
|
||||||
|
.HasColumnName("room_total_count");
|
||||||
|
entity.Property(e => e.RoomTypeCount)
|
||||||
|
.HasComment("房型数量")
|
||||||
|
.HasColumnName("room_type_count");
|
||||||
|
entity.Property(e => e.Shengfen)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("所属省份")
|
||||||
|
.HasColumnName("shengfen");
|
||||||
|
entity.Property(e => e.ShengpiStatus)
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasComment("审批状态")
|
||||||
|
.HasColumnName("shengpi_status");
|
||||||
|
entity.Property(e => e.Uid)
|
||||||
|
.HasComment("申请人")
|
||||||
|
.HasColumnName("uid");
|
||||||
|
entity.Property(e => e.Updatetime)
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("updatetime");
|
||||||
|
entity.Property(e => e.UpdatetimeUnix).HasColumnName("updatetime_unix");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<AasProjectReportReady>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("aas_project_report_ready");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Createtime)
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("createtime");
|
||||||
|
entity.Property(e => e.CustomerContactsH)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("customer_contacts_h");
|
||||||
|
entity.Property(e => e.ProjectCode)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("project_code");
|
||||||
|
entity.Property(e => e.Unixtime).HasColumnName("unixtime");
|
||||||
|
entity.Property(e => e.Updatetime)
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("updatetime");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<AasProjectShenpi>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("aas_project_shenpi");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Createtime)
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("createtime");
|
||||||
|
entity.Property(e => e.ProjectCode)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("项目代码")
|
||||||
|
.HasColumnName("project_code");
|
||||||
|
entity.Property(e => e.RejectReason)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("驳回理由")
|
||||||
|
.HasColumnName("reject_reason");
|
||||||
|
entity.Property(e => e.ShenpiNumber)
|
||||||
|
.HasComment("审批序号")
|
||||||
|
.HasColumnName("shenpi_number");
|
||||||
|
entity.Property(e => e.ShenpiSuggest)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("审批建议")
|
||||||
|
.HasColumnName("shenpi_suggest");
|
||||||
|
entity.Property(e => e.Updatetime)
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("updatetime");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<AasUser>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("aas_users");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id)
|
||||||
|
.HasComment("主键")
|
||||||
|
.HasColumnName("id");
|
||||||
|
entity.Property(e => e.Avatar)
|
||||||
|
.HasComment("账户头像")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("avatar");
|
||||||
|
entity.Property(e => e.ComId)
|
||||||
|
.HasComment("所属公司ID")
|
||||||
|
.HasColumnName("com_id");
|
||||||
|
entity.Property(e => e.CreationTime)
|
||||||
|
.HasComment("创建时间")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("creation_time");
|
||||||
|
entity.Property(e => e.Email)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("邮箱")
|
||||||
|
.HasColumnName("email");
|
||||||
|
entity.Property(e => e.Isdelete)
|
||||||
|
.HasComment("是否删除")
|
||||||
|
.HasColumnName("isdelete");
|
||||||
|
entity.Property(e => e.Mobile)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("电话号码")
|
||||||
|
.HasColumnName("mobile");
|
||||||
|
entity.Property(e => e.Password)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("密码")
|
||||||
|
.HasColumnName("password");
|
||||||
|
entity.Property(e => e.Position)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("职位")
|
||||||
|
.HasColumnName("position");
|
||||||
|
entity.Property(e => e.PswEncryption)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("密码加密处理")
|
||||||
|
.HasColumnName("psw_encryption");
|
||||||
|
entity.Property(e => e.Realname)
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasComment("真实姓名")
|
||||||
|
.HasColumnName("realname");
|
||||||
|
entity.Property(e => e.RoleId)
|
||||||
|
.HasComment("角色ID")
|
||||||
|
.HasColumnName("role_id");
|
||||||
|
entity.Property(e => e.UpdateTime)
|
||||||
|
.HasComment("更新时间")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("update_time");
|
||||||
|
entity.Property(e => e.Username)
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasComment("用户名(登录名)")
|
||||||
|
.HasColumnName("username");
|
||||||
|
entity.Property(e => e.Weixin)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("微信号")
|
||||||
|
.HasColumnName("weixin");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<AasUserPermission>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("aas_user_permission");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.ProxyClass)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("proxy_class");
|
||||||
|
entity.Property(e => e.ProxyRegion)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("proxy_region");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<AasUsersOperateLog>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("aas_users_operate_log");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id)
|
||||||
|
.HasComment("主键")
|
||||||
|
.HasColumnName("id");
|
||||||
|
entity.Property(e => e.Browser)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("浏览器版本")
|
||||||
|
.HasColumnName("browser")
|
||||||
|
.UseCollation("utf8_general_ci")
|
||||||
|
.HasCharSet("utf8");
|
||||||
|
entity.Property(e => e.CreationTime)
|
||||||
|
.HasComment("创建时间")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("creation_time");
|
||||||
|
entity.Property(e => e.Device)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("设备型号")
|
||||||
|
.HasColumnName("device")
|
||||||
|
.UseCollation("utf8_general_ci")
|
||||||
|
.HasCharSet("utf8");
|
||||||
|
entity.Property(e => e.Ip)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("ip地址")
|
||||||
|
.HasColumnName("ip")
|
||||||
|
.UseCollation("utf8_general_ci")
|
||||||
|
.HasCharSet("utf8");
|
||||||
|
entity.Property(e => e.Location)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("地理位置")
|
||||||
|
.HasColumnName("location")
|
||||||
|
.UseCollation("utf8_general_ci")
|
||||||
|
.HasCharSet("utf8");
|
||||||
|
entity.Property(e => e.Operate)
|
||||||
|
.HasComment("执行操作")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("operate");
|
||||||
|
entity.Property(e => e.Operation)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("操作类型")
|
||||||
|
.HasColumnName("operation")
|
||||||
|
.UseCollation("utf8_general_ci")
|
||||||
|
.HasCharSet("utf8");
|
||||||
|
entity.Property(e => e.TypeId)
|
||||||
|
.HasComment("日志类型ID")
|
||||||
|
.HasColumnName("type_id");
|
||||||
|
entity.Property(e => e.Username)
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasComment("用户名字")
|
||||||
|
.HasColumnName("username")
|
||||||
|
.UseCollation("utf8_general_ci")
|
||||||
|
.HasCharSet("utf8");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Autokeygenerater>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("autokeygenerater");
|
||||||
|
|
||||||
|
entity.Property(e => e.CompanyCode).HasColumnName("Company_code");
|
||||||
|
entity.Property(e => e.ProjectInfoCode).HasColumnName("ProjectInfo_code");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<WyLog>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity.ToTable("wy_logs");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id)
|
||||||
|
.HasComment("主键")
|
||||||
|
.HasColumnName("id");
|
||||||
|
entity.Property(e => e.CreationTime)
|
||||||
|
.HasComment("创建时间")
|
||||||
|
.HasColumnName("creation_time");
|
||||||
|
entity.Property(e => e.Introduced)
|
||||||
|
.HasComment("传入参数")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("introduced");
|
||||||
|
entity.Property(e => e.Ip)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("ip地址")
|
||||||
|
.HasColumnName("ip")
|
||||||
|
.UseCollation("utf8_general_ci")
|
||||||
|
.HasCharSet("utf8");
|
||||||
|
entity.Property(e => e.Operation)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("操作类型")
|
||||||
|
.HasColumnName("operation")
|
||||||
|
.UseCollation("utf8_general_ci")
|
||||||
|
.HasCharSet("utf8");
|
||||||
|
entity.Property(e => e.ReturnValue)
|
||||||
|
.HasComment("返回值")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("return_value");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<WyUser>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||||
|
|
||||||
|
entity
|
||||||
|
.ToTable("wy_users", tb => tb.HasComment("用户信息表"))
|
||||||
|
.UseCollation("utf8mb4_general_ci");
|
||||||
|
|
||||||
|
entity.HasIndex(e => e.Username, "idx_account");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id)
|
||||||
|
.HasComment("主键")
|
||||||
|
.HasColumnName("id");
|
||||||
|
entity.Property(e => e.Avatar)
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasComment("头像")
|
||||||
|
.HasColumnName("avatar");
|
||||||
|
entity.Property(e => e.Birthday)
|
||||||
|
.HasComment("生日")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("birthday");
|
||||||
|
entity.Property(e => e.Code)
|
||||||
|
.HasMaxLength(12)
|
||||||
|
.HasComment("用户编号")
|
||||||
|
.HasColumnName("code");
|
||||||
|
entity.Property(e => e.ComId)
|
||||||
|
.HasComment("所属公司ID")
|
||||||
|
.HasColumnName("com_id");
|
||||||
|
entity.Property(e => e.CreateDept)
|
||||||
|
.HasComment("创建部门")
|
||||||
|
.HasColumnName("create_dept");
|
||||||
|
entity.Property(e => e.CreateUser)
|
||||||
|
.HasComment("创建人")
|
||||||
|
.HasColumnName("create_user");
|
||||||
|
entity.Property(e => e.CreationTime)
|
||||||
|
.HasDefaultValueSql("CURRENT_TIMESTAMP")
|
||||||
|
.HasComment("创建时间")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("creation_time");
|
||||||
|
entity.Property(e => e.DeptId)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasComment("部门id")
|
||||||
|
.HasColumnName("dept_id");
|
||||||
|
entity.Property(e => e.Email)
|
||||||
|
.HasMaxLength(45)
|
||||||
|
.HasComment("邮箱")
|
||||||
|
.HasColumnName("email");
|
||||||
|
entity.Property(e => e.Isdelete)
|
||||||
|
.HasDefaultValueSql("'0'")
|
||||||
|
.HasComment("是否已删除")
|
||||||
|
.HasColumnName("isdelete");
|
||||||
|
entity.Property(e => e.Mobile)
|
||||||
|
.HasMaxLength(45)
|
||||||
|
.HasComment("手机")
|
||||||
|
.HasColumnName("mobile");
|
||||||
|
entity.Property(e => e.Name)
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasComment("昵称")
|
||||||
|
.HasColumnName("name");
|
||||||
|
entity.Property(e => e.Password)
|
||||||
|
.HasMaxLength(45)
|
||||||
|
.HasComment("密码")
|
||||||
|
.HasColumnName("password");
|
||||||
|
entity.Property(e => e.Position)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("职位")
|
||||||
|
.HasColumnName("position")
|
||||||
|
.UseCollation("utf8mb4_bin");
|
||||||
|
entity.Property(e => e.PostId)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasComment("岗位id")
|
||||||
|
.HasColumnName("post_id");
|
||||||
|
entity.Property(e => e.Realname)
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasComment("真名")
|
||||||
|
.HasColumnName("realname");
|
||||||
|
entity.Property(e => e.RoleId)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasComment("角色id")
|
||||||
|
.HasColumnName("role_id");
|
||||||
|
entity.Property(e => e.RoleIdAas)
|
||||||
|
.HasComment("角色ID")
|
||||||
|
.HasColumnName("role_id_aas");
|
||||||
|
entity.Property(e => e.Sex)
|
||||||
|
.HasComment("性别")
|
||||||
|
.HasColumnName("sex");
|
||||||
|
entity.Property(e => e.Status)
|
||||||
|
.HasComment("状态")
|
||||||
|
.HasColumnName("status");
|
||||||
|
entity.Property(e => e.TenantId)
|
||||||
|
.HasMaxLength(12)
|
||||||
|
.HasDefaultValueSql("'000000'")
|
||||||
|
.HasComment("租户ID")
|
||||||
|
.HasColumnName("tenant_id");
|
||||||
|
entity.Property(e => e.UpdateTime)
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasDefaultValueSql("CURRENT_TIMESTAMP")
|
||||||
|
.HasComment("修改时间")
|
||||||
|
.HasColumnType("datetime")
|
||||||
|
.HasColumnName("update_time");
|
||||||
|
entity.Property(e => e.UpdateUser)
|
||||||
|
.HasComment("修改人")
|
||||||
|
.HasColumnName("update_user");
|
||||||
|
entity.Property(e => e.UserType)
|
||||||
|
.HasComment("用户平台")
|
||||||
|
.HasColumnName("user_type");
|
||||||
|
entity.Property(e => e.Username)
|
||||||
|
.HasMaxLength(45)
|
||||||
|
.HasComment("账号")
|
||||||
|
.HasColumnName("username");
|
||||||
|
entity.Property(e => e.Weixin)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasComment("微信")
|
||||||
|
.HasColumnName("weixin");
|
||||||
|
});
|
||||||
|
|
||||||
|
OnModelCreatingPartial(modelBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||||
|
}
|
||||||
13
SupplierManager/Models/Autokeygenerater.cs
Normal file
13
SupplierManager/Models/Autokeygenerater.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class Autokeygenerater
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public long? ProjectInfoCode { get; set; }
|
||||||
|
|
||||||
|
public int? CompanyCode { get; set; }
|
||||||
|
}
|
||||||
37
SupplierManager/Models/WyLog.cs
Normal file
37
SupplierManager/Models/WyLog.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
public partial class WyLog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 传入参数
|
||||||
|
/// </summary>
|
||||||
|
public string? Introduced { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回值
|
||||||
|
/// </summary>
|
||||||
|
public string? ReturnValue { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ip地址
|
||||||
|
/// </summary>
|
||||||
|
public string? Ip { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 操作类型
|
||||||
|
/// </summary>
|
||||||
|
public string? Operation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public long? CreationTime { get; set; }
|
||||||
|
}
|
||||||
145
SupplierManager/Models/WyUser.cs
Normal file
145
SupplierManager/Models/WyUser.cs
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SupplierManager.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户信息表
|
||||||
|
/// </summary>
|
||||||
|
public partial class WyUser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键
|
||||||
|
/// </summary>
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户ID
|
||||||
|
/// </summary>
|
||||||
|
public string? TenantId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户编号
|
||||||
|
/// </summary>
|
||||||
|
public string? Code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户平台
|
||||||
|
/// </summary>
|
||||||
|
public int? UserType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 账号
|
||||||
|
/// </summary>
|
||||||
|
public string? Username { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 密码
|
||||||
|
/// </summary>
|
||||||
|
public string? Password { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 昵称
|
||||||
|
/// </summary>
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 真名
|
||||||
|
/// </summary>
|
||||||
|
public string? Realname { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 头像
|
||||||
|
/// </summary>
|
||||||
|
public string? Avatar { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 邮箱
|
||||||
|
/// </summary>
|
||||||
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 手机
|
||||||
|
/// </summary>
|
||||||
|
public string? Mobile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生日
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? Birthday { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 性别
|
||||||
|
/// </summary>
|
||||||
|
public int? Sex { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 角色id
|
||||||
|
/// </summary>
|
||||||
|
public string? RoleId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部门id
|
||||||
|
/// </summary>
|
||||||
|
public string? DeptId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 岗位id
|
||||||
|
/// </summary>
|
||||||
|
public string? PostId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建人
|
||||||
|
/// </summary>
|
||||||
|
public long? CreateUser { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建部门
|
||||||
|
/// </summary>
|
||||||
|
public long? CreateDept { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? CreationTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改人
|
||||||
|
/// </summary>
|
||||||
|
public long? UpdateUser { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? UpdateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 状态
|
||||||
|
/// </summary>
|
||||||
|
public int? Status { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否已删除
|
||||||
|
/// </summary>
|
||||||
|
public int? Isdelete { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所属公司ID
|
||||||
|
/// </summary>
|
||||||
|
public int? ComId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 角色ID
|
||||||
|
/// </summary>
|
||||||
|
public int? RoleIdAas { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职位
|
||||||
|
/// </summary>
|
||||||
|
public string? Position { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 微信
|
||||||
|
/// </summary>
|
||||||
|
public string? Weixin { get; set; }
|
||||||
|
}
|
||||||
108
SupplierManager/Program.cs
Normal file
108
SupplierManager/Program.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using System.Text;
|
||||||
|
using System.Threading.RateLimiting;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.AspNetCore.RateLimiting;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using SupplierManager.Common;
|
||||||
|
using SupplierManager.Models;
|
||||||
|
|
||||||
|
namespace SupplierManager
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddScoped<AgentApprovalSystemContext>();
|
||||||
|
|
||||||
|
builder.Services.AddCors(options =>
|
||||||
|
{
|
||||||
|
options.AddPolicy(name: "Vue3",
|
||||||
|
policy =>
|
||||||
|
{
|
||||||
|
//policy.WithOrigins("http://localhost:5180",
|
||||||
|
// "http://localhost:8809/",
|
||||||
|
// "http://www.contoso.com",
|
||||||
|
// "http://new.uts-data.com:6688/", "http://new.uts-data.com")
|
||||||
|
policy
|
||||||
|
.AllowAnyOrigin()
|
||||||
|
.AllowAnyHeader()
|
||||||
|
.AllowAnyMethod();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//builder.Services.AddRateLimiter(options =>
|
||||||
|
//{
|
||||||
|
// options.AddTokenBucketLimiter(policyName: "token_bucket", tokenBucketOptions =>
|
||||||
|
// {
|
||||||
|
// tokenBucketOptions.TokenLimit = 100;//Ͱ<><CDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵĶ<C5B5><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻᱻ<C6BB><E1B1BB><EFBFBD><EFBFBD>
|
||||||
|
// tokenBucketOptions.ReplenishmentPeriod = TimeSpan.FromSeconds(10);//<2F><><EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
// tokenBucketOptions.TokensPerPeriod = 100;//ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
// tokenBucketOptions.QueueLimit = 90;//<2F><>Ͱ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>꣨token=0<><30>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>
|
||||||
|
// tokenBucketOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
|
||||||
|
// tokenBucketOptions.AutoReplenishment = true;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3>Ƿ<EFBFBD><C7B7>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD><C6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊfalse<73><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD> TokenBucketRateLimiter.TryReplenish<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
// });
|
||||||
|
//});
|
||||||
|
builder.Services.AddAuthorization();
|
||||||
|
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||||
|
.AddJwtBearer(option =>
|
||||||
|
{
|
||||||
|
string DefaultKey = "B,EZipeApY3cNj3~4RP0UMR=H>9x8.1!E85wmZ]]py2d$Y?5";
|
||||||
|
var sec = Encoding.UTF8.GetBytes(builder.Configuration["JWT:SecretKey"] ?? DefaultKey);
|
||||||
|
|
||||||
|
option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
|
||||||
|
{
|
||||||
|
ValidateIssuer = true,
|
||||||
|
ValidateAudience = true,
|
||||||
|
ValidateLifetime = true,
|
||||||
|
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
ValidIssuer = builder.Configuration["JwT:Issuer"],
|
||||||
|
ValidAudience = builder.Configuration["JwT:Audience"],
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(sec)
|
||||||
|
};
|
||||||
|
|
||||||
|
option.Events = new JwtBearerEvents
|
||||||
|
{
|
||||||
|
OnMessageReceived = context =>
|
||||||
|
{
|
||||||
|
var token = context.Request.Headers["token"].FirstOrDefault();
|
||||||
|
if (string.IsNullOrEmpty(token))
|
||||||
|
{
|
||||||
|
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>ҵ<EFBFBD> token ͷ<><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Authorization ͷ<><CDB7>
|
||||||
|
token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
|
||||||
|
}
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD> token<65><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> HttpContext <20><>
|
||||||
|
if (!string.IsNullOrEmpty(token))
|
||||||
|
{
|
||||||
|
context.Token = token;
|
||||||
|
}
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
|
||||||
|
app.UseCors("Vue3");
|
||||||
|
app.UseAuthentication(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD>м<EFBFBD><D0BC><EFBFBD>
|
||||||
|
app.UseAuthorization(); // ʹ<><CAB9><EFBFBD><EFBFBD>Ȩ<EFBFBD>м<EFBFBD><D0BC><EFBFBD>
|
||||||
|
|
||||||
|
app.UseStaticFiles();
|
||||||
|
app.MapControllers();
|
||||||
|
//app.UseRateLimiter(new Microsoft.AspNetCore.RateLimiting.RateLimiterOptions()
|
||||||
|
//{
|
||||||
|
// RejectionStatusCode = 500
|
||||||
|
//});
|
||||||
|
|
||||||
|
StaticData.GetWebAPIMethod();
|
||||||
|
app.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
SupplierManager/Properties/launchSettings.json
Normal file
31
SupplierManager/Properties/launchSettings.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:46256",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "weatherforecast",
|
||||||
|
"applicationUrl": "http://localhost:5077",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "weatherforecast",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
56
SupplierManager/SupplierManager.csproj
Normal file
56
SupplierManager/SupplierManager.csproj
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Uploads\**" />
|
||||||
|
<Content Remove="Uploads\**" />
|
||||||
|
<EmbeddedResource Remove="Uploads\**" />
|
||||||
|
<None Remove="Uploads\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="IronPython" Version="3.4.2" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.15" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.15" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.15">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.15">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.7" />
|
||||||
|
<PackageReference Include="NLog" Version="5.4.0" />
|
||||||
|
<PackageReference Include="NLog.Schema" Version="5.4.0" />
|
||||||
|
<PackageReference Include="NLog.Web.AspNetCore" Version="5.4.0" />
|
||||||
|
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.3" />
|
||||||
|
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ViewModels\ViewModels.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Models\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="script\a.py">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="script\b.py">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="script\webapi.py">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
6
SupplierManager/SupplierManager.http
Normal file
6
SupplierManager/SupplierManager.http
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@SupplierManager_HostAddress = http://localhost:5076
|
||||||
|
|
||||||
|
GET {{SupplierManager_HostAddress}}/weatherforecast/
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
||||||
13
SupplierManager/WeatherForecast.cs
Normal file
13
SupplierManager/WeatherForecast.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
namespace SupplierManager
|
||||||
|
{
|
||||||
|
public class WeatherForecast
|
||||||
|
{
|
||||||
|
public DateOnly Date { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureC { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||||
|
|
||||||
|
public string? Summary { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
8
SupplierManager/appsettings.Development.json
Normal file
8
SupplierManager/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
SupplierManager/appsettings.json
Normal file
14
SupplierManager/appsettings.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"JwT": {
|
||||||
|
"SecretKey": "1%猜U36eraIYI?3s9dI}46an不Nn>P]3)$9:dCnS5=ajAu%8B5]15hF到20T20QBD]Mt9}2z76jO#Glg&0yDy7k-2zVdt&Z5ur>=l)QF2^1&Dq04m76U2P9wvlWf",
|
||||||
|
"Issuer": "宝来威供应商系统",
|
||||||
|
"Audience": "W*u93xxp*08DnW@%6}5Tjh6bE?;hW"
|
||||||
|
},
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
35
SupplierManager/nlog.config
Normal file
35
SupplierManager/nlog.config
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
|
<!-- enable asp.net core layout renderers -->
|
||||||
|
<targets>
|
||||||
|
<!--项目日志保存文件路径说明fileName="${basedir}/保存目录,以年月日的格式创建/${shortdate}/${记录器名称}-${单级记录}-${shortdate}.txt"-->
|
||||||
|
<target name="info_file" xsi:type="File"
|
||||||
|
fileName="${basedir}/Logs/${shortdate}/info_${shortdate}.txt"
|
||||||
|
layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${exception:format=ToString} ${newline} ${stacktrace} ${newline}"
|
||||||
|
archiveFileName="${basedir}/archives/info_${shortdate}-{#####}.txt"
|
||||||
|
archiveAboveSize="102400"
|
||||||
|
archiveNumbering="Sequence"
|
||||||
|
concurrentWrites="true"
|
||||||
|
keepFileOpen="false" />
|
||||||
|
<target name="error_file" xsi:type="File"
|
||||||
|
fileName="${basedir}/Logs/${shortdate}/error_${shortdate}.txt"
|
||||||
|
layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${exception:format=ToString} ${newline} ${stacktrace} ${newline}"
|
||||||
|
archiveFileName="${basedir}/archives/error_${shortdate}-{#####}.txt"
|
||||||
|
archiveAboveSize="102400"
|
||||||
|
archiveNumbering="Sequence"
|
||||||
|
concurrentWrites="true"
|
||||||
|
keepFileOpen="false" />
|
||||||
|
</targets>
|
||||||
|
|
||||||
|
<!--规则配置,final - 最终规则匹配后不处理任何规则-->
|
||||||
|
<!--规则配置,final - 最终规则匹配后不处理任何规则-->
|
||||||
|
<!--定义使用哪个target输出-->
|
||||||
|
<rules>
|
||||||
|
<!-- 优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL -->
|
||||||
|
<!-- 将所有日志输出到文件 -->
|
||||||
|
<logger name="*" minlevel="FATAL" maxlevel="FATAL" writeTo="info_file" />
|
||||||
|
<logger name="*" minlevel="ERROR" maxlevel="ERROR" writeTo="error_file" />
|
||||||
|
</rules>
|
||||||
|
</nlog>
|
||||||
3
SupplierManager/script/a.py
Normal file
3
SupplierManager/script/a.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
a="ffff"
|
||||||
|
b="ddddd"
|
||||||
|
c="fffff"
|
||||||
1
SupplierManager/script/b.py
Normal file
1
SupplierManager/script/b.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
9
SupplierManager/script/webapi.py
Normal file
9
SupplierManager/script/webapi.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
区域={"其他":["其他地区"],"华南大区":["广东省","福建省","台湾省","湖南省"],"东北大区":["黑龙江省","吉林省","辽宁省"]}
|
||||||
|
省份地区=["其他地区","北京市","天津市","河北省","山西省","内蒙古自治区","辽宁省","吉林省","黑龙江省","上海市","江苏省","浙江省","安徽省","福建省","江西省","山东省","河南省","湖北省","湖南省","广东省","广西壮族自治区","海南省","重庆市","四川省","贵州省","云南省","西藏自治区","陕西省","甘肃省","青海省","宁夏回族自治区","新疆维吾尔自治区","台湾省","香港特别行政区","澳门特别行政区","海外"]
|
||||||
|
用户类型=["其他","公司业务员","省级代理负责人","区域代理负责人","酒店业主"]
|
||||||
|
公司身份=["其他","公司业务","代理","酒店方"]
|
||||||
|
行业分类=["其他行业","连锁酒店","独立品牌酒店","短租公寓","民宿","养老机构","电竞酒店","棋牌室"]
|
||||||
|
驳回理由=["其他原因","信息填写不完整"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
SupplierManager/wwwroot/Download/customization/弱电-无界开关方案.xlsx
Normal file
BIN
SupplierManager/wwwroot/Download/customization/弱电-无界开关方案.xlsx
Normal file
Binary file not shown.
BIN
SupplierManager/wwwroot/Download/customization/弱电-智多方7寸屏.xlsx
Normal file
BIN
SupplierManager/wwwroot/Download/customization/弱电-智多方7寸屏.xlsx
Normal file
Binary file not shown.
BIN
SupplierManager/wwwroot/Download/customization/弱电-水悦派可视方案.xlsx
Normal file
BIN
SupplierManager/wwwroot/Download/customization/弱电-水悦派可视方案.xlsx
Normal file
Binary file not shown.
BIN
SupplierManager/wwwroot/Download/customization/弱电-轻触大板开关.xlsx
Normal file
BIN
SupplierManager/wwwroot/Download/customization/弱电-轻触大板开关.xlsx
Normal file
Binary file not shown.
BIN
SupplierManager/wwwroot/Download/customization/强电-D8T大板直连.xlsx
Normal file
BIN
SupplierManager/wwwroot/Download/customization/强电-D8T大板直连.xlsx
Normal file
Binary file not shown.
BIN
SupplierManager/wwwroot/Download/customization/强电-T1水立方.xlsx
Normal file
BIN
SupplierManager/wwwroot/Download/customization/强电-T1水立方.xlsx
Normal file
Binary file not shown.
BIN
SupplierManager/wwwroot/Download/customization/强电-T3水星阁直连.xlsx
Normal file
BIN
SupplierManager/wwwroot/Download/customization/强电-T3水星阁直连.xlsx
Normal file
Binary file not shown.
18
ViewModels/Common/CacheKey.cs
Normal file
18
ViewModels/Common/CacheKey.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ViewModels.Common
|
||||||
|
{
|
||||||
|
public class CacheKey
|
||||||
|
{
|
||||||
|
public static string RoomIP_Port_Prefix = "Log_IP_Port";
|
||||||
|
|
||||||
|
public static string Key = "monitor_host";
|
||||||
|
|
||||||
|
public static string MonitorLogPrefix = "AllLogKey";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
211
ViewModels/Common/Crypto.cs
Normal file
211
ViewModels/Common/Crypto.cs
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
||||||
|
|
||||||
|
namespace CryptoHelper;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides helper methods for hashing/salting and verifying passwords.
|
||||||
|
/// </summary>
|
||||||
|
public static class Crypto
|
||||||
|
{
|
||||||
|
/* =======================
|
||||||
|
* HASHED PASSWORD FORMATS
|
||||||
|
* =======================
|
||||||
|
*
|
||||||
|
* Version 3:
|
||||||
|
* PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 600.000 iterations.
|
||||||
|
* Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
|
||||||
|
* (All UInt32s are stored big-endian.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
private const int PBKDF2IterCount = 600_000;
|
||||||
|
private const int PBKDF2SubkeyLength = 256 / 8; // 256 bits
|
||||||
|
private const int SaltSize = 128 / 8; // 128 bits
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a hashed representation of the specified <paramref name="password"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="password">The password to generate a hash value for.</param>
|
||||||
|
/// <returns>The hash value for <paramref name="password" /> as a base-64-encoded string.</returns>
|
||||||
|
/// <exception cref="System.ArgumentNullException"><paramref name="password" /> is null.</exception>
|
||||||
|
public static string HashPassword(string password)
|
||||||
|
{
|
||||||
|
if (password == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(password));
|
||||||
|
}
|
||||||
|
|
||||||
|
return HashPasswordInternal(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified RFC 2898 hash and password are a cryptographic match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hashedPassword">The previously-computed RFC 2898 hash value as a base-64-encoded string.</param>
|
||||||
|
/// <param name="password">The plaintext password to cryptographically compare with hashedPassword.</param>
|
||||||
|
/// <returns>true if the hash value is a cryptographic match for the password; otherwise, false.</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// <paramref name="hashedPassword" /> must be of the format of HashPassword (salt + Hash(salt+input).
|
||||||
|
/// </remarks>
|
||||||
|
/// <exception cref="System.ArgumentNullException">
|
||||||
|
/// <paramref name="hashedPassword" /> or <paramref name="password" /> is null.
|
||||||
|
/// </exception>
|
||||||
|
public static bool VerifyHashedPassword(string hashedPassword, string password)
|
||||||
|
{
|
||||||
|
if (hashedPassword == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(hashedPassword));
|
||||||
|
}
|
||||||
|
if (password == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(password));
|
||||||
|
}
|
||||||
|
|
||||||
|
return VerifyHashedPasswordInternal(hashedPassword, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
|
||||||
|
|
||||||
|
private static string HashPasswordInternal(string password)
|
||||||
|
{
|
||||||
|
var bytes = HashPasswordInternal(password, KeyDerivationPrf.HMACSHA256, PBKDF2IterCount, SaltSize, PBKDF2SubkeyLength);
|
||||||
|
return Convert.ToBase64String(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] HashPasswordInternal(
|
||||||
|
string password,
|
||||||
|
KeyDerivationPrf prf,
|
||||||
|
int iterCount,
|
||||||
|
int saltSize,
|
||||||
|
int numBytesRequested)
|
||||||
|
{
|
||||||
|
// Produce a version 3 (see comment above) text hash.
|
||||||
|
var salt = new byte[saltSize];
|
||||||
|
_rng.GetBytes(salt);
|
||||||
|
var subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested);
|
||||||
|
|
||||||
|
var outputBytes = new byte[13 + salt.Length + subkey.Length];
|
||||||
|
|
||||||
|
// Write format marker.
|
||||||
|
outputBytes[0] = 0x01;
|
||||||
|
|
||||||
|
// Write hashing algorithm version.
|
||||||
|
WriteNetworkByteOrder(outputBytes, 1, (uint)prf);
|
||||||
|
|
||||||
|
// Write iteration count of the algorithm.
|
||||||
|
WriteNetworkByteOrder(outputBytes, 5, (uint)iterCount);
|
||||||
|
|
||||||
|
// Write size of the salt.
|
||||||
|
WriteNetworkByteOrder(outputBytes, 9, (uint)saltSize);
|
||||||
|
|
||||||
|
// Write the salt.
|
||||||
|
Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length);
|
||||||
|
|
||||||
|
// Write the subkey.
|
||||||
|
Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length);
|
||||||
|
return outputBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool VerifyHashedPasswordInternal(string hashedPassword, string password)
|
||||||
|
{
|
||||||
|
var decodedHashedPassword = Convert.FromBase64String(hashedPassword);
|
||||||
|
|
||||||
|
if (decodedHashedPassword.Length == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Verify hashing format.
|
||||||
|
if (decodedHashedPassword[0] != 0x01)
|
||||||
|
{
|
||||||
|
// Unknown format header.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read hashing algorithm version.
|
||||||
|
var prf = (KeyDerivationPrf)ReadNetworkByteOrder(decodedHashedPassword, 1);
|
||||||
|
|
||||||
|
// Read iteration count of the algorithm.
|
||||||
|
var iterCount = (int)ReadNetworkByteOrder(decodedHashedPassword, 5);
|
||||||
|
|
||||||
|
// Read size of the salt.
|
||||||
|
var saltLength = (int)ReadNetworkByteOrder(decodedHashedPassword, 9);
|
||||||
|
|
||||||
|
// Verify the salt size: >= 128 bits.
|
||||||
|
if (saltLength < 128 / 8)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the salt.
|
||||||
|
var salt = new byte[saltLength];
|
||||||
|
Buffer.BlockCopy(decodedHashedPassword, 13, salt, 0, salt.Length);
|
||||||
|
|
||||||
|
// Verify the subkey length >= 128 bits.
|
||||||
|
var subkeyLength = decodedHashedPassword.Length - 13 - salt.Length;
|
||||||
|
if (subkeyLength < 128 / 8)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the subkey.
|
||||||
|
var expectedSubkey = new byte[subkeyLength];
|
||||||
|
Buffer.BlockCopy(decodedHashedPassword, 13 + salt.Length, expectedSubkey, 0, expectedSubkey.Length);
|
||||||
|
|
||||||
|
// Hash the given password and verify it against the expected subkey.
|
||||||
|
var actualSubkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, subkeyLength);
|
||||||
|
return ByteArraysEqual(actualSubkey, expectedSubkey);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// This should never occur except in the case of a malformed payload, where
|
||||||
|
// we might go off the end of the array. Regardless, a malformed payload
|
||||||
|
// implies verification failed.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ReadNetworkByteOrder(byte[] buffer, int offset)
|
||||||
|
{
|
||||||
|
return ((uint)(buffer[offset + 0]) << 24)
|
||||||
|
| ((uint)(buffer[offset + 1]) << 16)
|
||||||
|
| ((uint)(buffer[offset + 2]) << 8)
|
||||||
|
| ((uint)(buffer[offset + 3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteNetworkByteOrder(byte[] buffer, int offset, uint value)
|
||||||
|
{
|
||||||
|
buffer[offset + 0] = (byte)(value >> 24);
|
||||||
|
buffer[offset + 1] = (byte)(value >> 16);
|
||||||
|
buffer[offset + 2] = (byte)(value >> 8);
|
||||||
|
buffer[offset + 3] = (byte)(value >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compares two byte arrays for equality.
|
||||||
|
// The method is specifically written so that the loop is not optimized.
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
|
||||||
|
private static bool ByteArraysEqual(byte[] a, byte[] b)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(a, b))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a == null || b == null || a.Length != b.Length)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var areSame = true;
|
||||||
|
for (var i = 0; i < a.Length; i++)
|
||||||
|
{
|
||||||
|
areSame &= (a[i] == b[i]);
|
||||||
|
}
|
||||||
|
return areSame;
|
||||||
|
}
|
||||||
|
}
|
||||||
117
ViewModels/Common/Tools.cs
Normal file
117
ViewModels/Common/Tools.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
namespace ViewModels
|
||||||
|
{
|
||||||
|
public class Tools
|
||||||
|
{
|
||||||
|
private static byte[] Keys = { 0xEF, 0xAB, 0x56, 0x78, 0x90, 0x34, 0xCD, 0x12 };
|
||||||
|
|
||||||
|
public static string encryptKey = "20su#pe1r%boolive";
|
||||||
|
/// <summary>
|
||||||
|
/// DES加密字符串
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="encryptString">待加密的字符串</param>
|
||||||
|
/// <param name="encryptKey">加密密钥,要求为8位</param>
|
||||||
|
/// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
|
||||||
|
public static string EncryptString(string encryptString)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
|
||||||
|
byte[] rgbIV = Keys;
|
||||||
|
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
|
||||||
|
var dCSP = new DESCryptoServiceProvider();
|
||||||
|
using MemoryStream mStream = new MemoryStream();
|
||||||
|
using CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
|
||||||
|
cStream.Write(inputByteArray, 0, inputByteArray.Length);
|
||||||
|
cStream.FlushFinalBlock();
|
||||||
|
return Convert.ToBase64String(mStream.ToArray());
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return encryptString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DES解密字符串
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decryptString">待解密的字符串</param>
|
||||||
|
/// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
|
||||||
|
/// <returns>解密成功返回解密后的字符串,失败返源串</returns>
|
||||||
|
public static string DecryptString(string decryptString)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
|
||||||
|
byte[] rgbIV = Keys;
|
||||||
|
byte[] inputByteArray = Convert.FromBase64String(decryptString);
|
||||||
|
var DCSP = new DESCryptoServiceProvider();
|
||||||
|
using MemoryStream mStream = new MemoryStream();
|
||||||
|
using CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
|
||||||
|
cStream.Write(inputByteArray, 0, inputByteArray.Length);
|
||||||
|
cStream.FlushFinalBlock();
|
||||||
|
return Encoding.UTF8.GetString(mStream.ToArray());
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return decryptString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string HashPassword(string pwd)
|
||||||
|
{
|
||||||
|
string v = CryptoHelper.Crypto.HashPassword(pwd);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
public static bool VerifyHashedPassword(string encrypwd, string original_pwd)
|
||||||
|
{
|
||||||
|
bool v = CryptoHelper.Crypto.VerifyHashedPassword(encrypwd, original_pwd);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 时间戳转本地时间-时间戳精确到秒
|
||||||
|
/// </summary>
|
||||||
|
public static DateTime ToLocalTimeDateBySeconds(long unix)
|
||||||
|
{
|
||||||
|
var dto = DateTimeOffset.FromUnixTimeSeconds(unix);
|
||||||
|
return dto.ToLocalTime().DateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 时间转时间戳Unix-时间戳精确到秒
|
||||||
|
/// </summary>
|
||||||
|
public static long ToUnixTimestampBySeconds(DateTime dt)
|
||||||
|
{
|
||||||
|
DateTimeOffset dto = new DateTimeOffset(dt);
|
||||||
|
return dto.ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 时间戳转本地时间-时间戳精确到毫秒
|
||||||
|
/// </summary>
|
||||||
|
public static DateTime ToLocalTimeDateByMilliseconds(long unix)
|
||||||
|
{
|
||||||
|
var dto = DateTimeOffset.FromUnixTimeMilliseconds(unix);
|
||||||
|
return dto.ToLocalTime().DateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 时间转时间戳Unix-时间戳精确到毫秒
|
||||||
|
/// </summary>
|
||||||
|
public static long ToUnixTimestampByMilliseconds(DateTime dt)
|
||||||
|
{
|
||||||
|
DateTimeOffset dto = new DateTimeOffset(dt);
|
||||||
|
return dto.ToUnixTimeMilliseconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
ViewModels/RequestData/LoginData.cs
Normal file
14
ViewModels/RequestData/LoginData.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ViewModels.RequestData
|
||||||
|
{
|
||||||
|
public class LoginData
|
||||||
|
{
|
||||||
|
public string username { get; set; }
|
||||||
|
public string password { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
45
ViewModels/ResponseData/ResLoginData.cs
Normal file
45
ViewModels/ResponseData/ResLoginData.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ViewModels.ResponseData
|
||||||
|
{
|
||||||
|
public class ResLoginData
|
||||||
|
{
|
||||||
|
public string AccessToken { get; set; }
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Username { get; set; }
|
||||||
|
public string Realname { get; set; }
|
||||||
|
|
||||||
|
public int? ComId { get; set; }
|
||||||
|
public int? RoleId { get; set; }
|
||||||
|
public string Avatar { get; set; }
|
||||||
|
public string Position { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JWTData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 发行人
|
||||||
|
/// </summary>
|
||||||
|
public string iss { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 到期时间
|
||||||
|
/// </summary>
|
||||||
|
public long exp { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 发布时间
|
||||||
|
/// </summary>
|
||||||
|
public string iat { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
///用于标识该JWT
|
||||||
|
/// </summary>
|
||||||
|
public string jti { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// token
|
||||||
|
/// </summary>
|
||||||
|
public string AccessToken { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
44
ViewModels/ReturnResult.cs
Normal file
44
ViewModels/ReturnResult.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ViewModels
|
||||||
|
{
|
||||||
|
public class ReturnResult
|
||||||
|
{
|
||||||
|
public int Status { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QueryAll_Or_Single
|
||||||
|
{
|
||||||
|
public bool IsAll { get; set; }
|
||||||
|
public int ID { get; set; }
|
||||||
|
}
|
||||||
|
public class QueryAll_Or_Single_ProjectInfo
|
||||||
|
{
|
||||||
|
public bool IsAll { get; set; }
|
||||||
|
public int? ID { get; set; }
|
||||||
|
public int? ComId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QueryAll_Or_Single_ProjectInfo_Page
|
||||||
|
{
|
||||||
|
//public bool IsAll { get; set; }
|
||||||
|
//public int ID { get; set; }
|
||||||
|
public int? ComId { get; set; }
|
||||||
|
public string? UpdateTime_Start { get; set; }
|
||||||
|
public string? UpdateTime_End { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ReturnInfo
|
||||||
|
{
|
||||||
|
public bool isok { set; get; } // 是否成功,true成功
|
||||||
|
public string message { set; get; } // 传递接口信息,or报错信息
|
||||||
|
public int status { set; get; } // 服务器报错信息,正确为200,错误404/500等
|
||||||
|
public object response { set; get; } // 获取到的信息本体,若报错则为null
|
||||||
|
}
|
||||||
|
}
|
||||||
14
ViewModels/ViewModels.csproj
Normal file
14
ViewModels/ViewModels.csproj
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CSRedisCore" Version="3.8.804" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.15" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
9
aas_pc_web/.editorconfig
Normal file
9
aas_pc_web/.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
|
||||||
|
charset = utf-8
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
end_of_line = lf
|
||||||
|
max_line_length = 100
|
||||||
1
aas_pc_web/.gitattributes
vendored
Normal file
1
aas_pc_web/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
30
aas_pc_web/.gitignore
vendored
Normal file
30
aas_pc_web/.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
*.tsbuildinfo
|
||||||
12
aas_pc_web/CHANGELOG.md
Normal file
12
aas_pc_web/CHANGELOG.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
This file explains how Visual Studio created the project.
|
||||||
|
|
||||||
|
The following tools were used to generate this project:
|
||||||
|
- create-vite
|
||||||
|
|
||||||
|
The following steps were used to generate this project:
|
||||||
|
- Create vue project with create-vite: `npm init --yes vue@latest aas_pc_web -- --eslint `.
|
||||||
|
- Updating `vite.config.js` with port.
|
||||||
|
- Create project file (`aas_pc_web.esproj`).
|
||||||
|
- Create `launch.json` to enable debugging.
|
||||||
|
- Add project to solution.
|
||||||
|
- Write this file.
|
||||||
35
aas_pc_web/README.md
Normal file
35
aas_pc_web/README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# aas_pc_web
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 in Vite.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
||||||
|
|
||||||
|
## Customize configuration
|
||||||
|
|
||||||
|
See [Vite Configuration Reference](https://vite.dev/config/).
|
||||||
|
|
||||||
|
## Project Setup
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compile and Hot-Reload for Development
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compile and Minify for Production
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lint with [ESLint](https://eslint.org/)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
25
aas_pc_web/aas_pc_web.esproj
Normal file
25
aas_pc_web/aas_pc_web.esproj
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/1.0.2191419">
|
||||||
|
<PropertyGroup>
|
||||||
|
<StartupCommand>npm run dev</StartupCommand>
|
||||||
|
<JavaScriptTestRoot>.\</JavaScriptTestRoot>
|
||||||
|
<JavaScriptTestFramework>Vitest</JavaScriptTestFramework>
|
||||||
|
<!-- Allows the build (or compile) script located on package.json to run on Build -->
|
||||||
|
<ShouldRunBuildScript>false</ShouldRunBuildScript>
|
||||||
|
<!-- Folder where production build objects will be placed -->
|
||||||
|
<BuildOutputFolder>$(MSBuildProjectDirectory)\dist</BuildOutputFolder>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="src\pages\layout\**" />
|
||||||
|
<None Remove="src\pages\新文件夹\**" />
|
||||||
|
<TypeScriptConfiguration Remove="src\pages\layout\**" />
|
||||||
|
<TypeScriptConfiguration Remove="src\pages\新文件夹\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="src\sftp.js" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="src\pages\404\" />
|
||||||
|
<Folder Include="src\pages\log\" />
|
||||||
|
<Folder Include="src\pages\usermanage\" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
24
aas_pc_web/eslint.config.js
Normal file
24
aas_pc_web/eslint.config.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||||
|
import globals from 'globals'
|
||||||
|
import js from '@eslint/js'
|
||||||
|
import pluginVue from 'eslint-plugin-vue'
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
name: 'app/files-to-lint',
|
||||||
|
files: ['**/*.{js,mjs,jsx,vue}'],
|
||||||
|
},
|
||||||
|
|
||||||
|
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
||||||
|
|
||||||
|
{
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
js.configs.recommended,
|
||||||
|
...pluginVue.configs['flat/essential'],
|
||||||
|
])
|
||||||
13
aas_pc_web/index.html
Normal file
13
aas_pc_web/index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>宝来威项目报备系统</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
8
aas_pc_web/jsconfig.json
Normal file
8
aas_pc_web/jsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
5230
aas_pc_web/package-lock.json
generated
Normal file
5230
aas_pc_web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
41
aas_pc_web/package.json
Normal file
41
aas_pc_web/package.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "aas_pc_web",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"lint": "eslint . --fix"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
|
"@vueuse/core": "^13.1.0",
|
||||||
|
"axios": "^1.8.3",
|
||||||
|
"china-location": "^2.1.0",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
|
"element-china-area-data": "^6.1.0",
|
||||||
|
"element-plus": "^2.9.6",
|
||||||
|
"jquery": "^3.7.1",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"ssh2-sftp-client": "^12.0.0",
|
||||||
|
"vue": "^3.5.13",
|
||||||
|
"vue-i18n": "^11.1.3",
|
||||||
|
"vue-router": "^4.5.0",
|
||||||
|
"vue-simple-verify": "^1.1.0",
|
||||||
|
"vuex": "^4.1.0",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.21.0",
|
||||||
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
|
"eslint": "^9.21.0",
|
||||||
|
"eslint-plugin-vue": "~10.0.0",
|
||||||
|
"globals": "^16.0.0",
|
||||||
|
"unplugin-auto-import": "^19.1.1",
|
||||||
|
"unplugin-vue-components": "^28.4.1",
|
||||||
|
"vite": "^6.2.1",
|
||||||
|
"vite-plugin-vue-devtools": "^7.7.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
10
aas_pc_web/public/config.js
Normal file
10
aas_pc_web/public/config.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
const config = {
|
||||||
|
// http访问后端接口 | prod | 生产
|
||||||
|
httpApi: "http://project.blv-oa.com:898/api/",
|
||||||
|
httpAds: "http://project.blv-oa.com:898/",
|
||||||
|
// http访问后端接口 | dev | 开发环境
|
||||||
|
/* httpApi: "http://localhost:46256/api/",
|
||||||
|
httpAds: "http://localhost:46256/",*/
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
||||||
BIN
aas_pc_web/public/favicon.ico
Normal file
BIN
aas_pc_web/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
19
aas_pc_web/public/logo.svg
Normal file
19
aas_pc_web/public/logo.svg
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!-- Creator: CorelDRAW 2020 (64-Bit) -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="10.8373mm" height="10.8373mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
|
||||||
|
viewBox="0 0 17.27 17.27"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
<![CDATA[
|
||||||
|
.fil0 {fill:#008C8C}
|
||||||
|
]]>
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<g id="图层_x0020_1">
|
||||||
|
<metadata id="CorelCorpID_0Corel-Layer"/>
|
||||||
|
<path class="fil0" d="M15.51 13.37c0.46,-0.85 0.72,-1.83 0.72,-2.87 0,-3.34 -2.71,-6.05 -6.05,-6.05 -1.05,0 -2.04,0.27 -2.9,0.74l0 2.5c0.73,-0.75 1.76,-1.22 2.9,-1.22 2.23,0 4.04,1.81 4.04,4.04 0,2.23 -1.81,4.04 -4.04,4.04 -1.11,0 -2.12,-0.45 -2.85,-1.18 -0.73,-0.71 -0.89,-1.79 -0.93,-2.87l0 -6.65 0 -3.25 0 -0.07 0 -0 0 -0.22c0.71,-0.19 1.46,-0.29 2.23,-0.29 4.77,0 8.63,3.87 8.63,8.63 0,4.77 -3.87,8.63 -8.63,8.63 -4.77,0 -8.63,-3.87 -8.63,-8.63 0,-3.18 1.72,-5.95 4.27,-7.45l0 0.25 0 0 0 0.08 0 2.32 0 6.23c0,0.99 0.04,1.49 0.25,2.25 0.48,1.72 1.65,3.02 3.26,3.73 0.74,0.32 1.55,0.5 2.41,0.5 0.64,0 1.27,-0.1 1.85,-0.29 1.41,-0.63 2.61,-1.63 3.48,-2.89z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
37
aas_pc_web/public/logobig.svg
Normal file
37
aas_pc_web/public/logobig.svg
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!-- Creator: CorelDRAW 2020 (64-Bit) -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="34.0028mm" height="5.4187mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
|
||||||
|
viewBox="0 0 183.31 29.21"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
<![CDATA[
|
||||||
|
.fil1 {fill:#008C8C}
|
||||||
|
.fil0 {fill:#008C8C;fill-rule:nonzero}
|
||||||
|
]]>
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<g id="图层_x0020_1">
|
||||||
|
<metadata id="CorelCorpID_0Corel-Layer"/>
|
||||||
|
<g id="_1914568022976">
|
||||||
|
<path class="fil0" d="M112.71 17.12l7.7 -4.25c-0.43,-0.45 -0.89,-0.8 -1.36,-1.06 -0.47,-0.26 -1.22,-0.39 -2.24,-0.39 -1,0 -1.88,0.25 -2.63,0.75 -0.75,0.5 -1.33,1.18 -1.73,2.03 -0.4,0.85 -0.62,1.8 -0.6,2.83 0.02,0.86 0.27,1.69 0.67,2.47 0.4,0.77 0.99,1.42 1.73,1.89 0.75,0.48 1.66,0.73 2.68,0.72 1.56,-0.02 2.74,-0.46 3.51,-1.26 0.77,-0.8 1.32,-2.01 1.64,-3.61l2.84 0.4c-0.02,0.75 -0.2,1.53 -0.55,2.36 -0.35,0.82 -0.87,1.62 -1.56,2.36 -0.69,0.74 -1.56,1.36 -2.58,1.81 -1.02,0.46 -2.19,0.71 -3.49,0.71 -1.36,0 -2.65,-0.35 -3.86,-1.05 -1.21,-0.7 -2.19,-1.66 -2.91,-2.85 -0.72,-1.19 -1.08,-2.48 -1.08,-3.86 0,-1.4 0.24,-2.64 0.71,-3.71 0.47,-1.06 1.11,-1.95 1.89,-2.65 0.78,-0.69 1.65,-1.21 2.58,-1.55 0.93,-0.33 1.85,-0.5 2.75,-0.5 1.77,0 3.25,0.4 4.45,1.2 1.2,0.8 2.24,2.03 3.11,3.7l-10.43 5.79 -1.23 -2.29z"/>
|
||||||
|
<path class="fil0" d="M92.27 9.1l3.09 0 4.53 12.01 4.51 -12.01 3.03 0 -5.41 14.33c-0.17,0.45 -0.48,0.82 -0.88,1.07 -0.4,0.25 -0.84,0.38 -1.31,0.38 -0.49,0 -0.95,-0.14 -1.36,-0.43 -0.41,-0.28 -0.67,-0.7 -0.86,-1.21l-5.35 -14.14z"/>
|
||||||
|
<polygon class="fil0" points="86.8,24.88 86.8,9.12 89.64,9.12 89.64,24.88 "/>
|
||||||
|
<path class="fil0" d="M86.53 5.65c0.01,-0.46 0.21,-0.85 0.54,-1.17 0.33,-0.31 0.72,-0.47 1.16,-0.47 0.45,0 0.84,0.17 1.17,0.49 0.33,0.32 0.5,0.73 0.5,1.22 0,0.52 -0.16,0.94 -0.47,1.24 -0.31,0.3 -0.69,0.46 -1.14,0.46 -0.48,0 -0.89,-0.17 -1.25,-0.49 -0.35,-0.32 -0.54,-0.76 -0.53,-1.28z"/>
|
||||||
|
<polygon class="fil0" points="80.15,2.31 82.98,2.31 82.98,24.88 80.15,24.88 "/>
|
||||||
|
<path class="fil0" d="M63.47 24.88l0 -9.43c0,-1.14 0.29,-2.2 0.87,-3.17 0.59,-0.97 1.39,-1.75 2.42,-2.32 1.02,-0.57 2.15,-0.9 3.37,-0.92 0.87,-0.02 1.83,0.22 2.86,0.67 1.03,0.45 1.91,1.18 2.64,2.18 0.74,1 1.11,2.28 1.11,3.82l0 9.18 -2.83 0 0 -9.11c0,-1.07 -0.35,-2.01 -1.06,-2.8 -0.71,-0.79 -1.61,-1.21 -2.71,-1.23 -1.05,-0.02 -1.94,0.37 -2.67,1.11 -0.73,0.74 -1.09,1.63 -1.09,2.66l0 9.37 -2.9 0z"/>
|
||||||
|
<path class="fil1" d="M52.44 8.9c4.41,0 7.99,3.58 7.99,7.99 0,4.41 -3.58,7.99 -7.99,7.99 -2.8,0 -5.26,-1.44 -6.69,-3.61 -1.43,2.18 -3.89,3.61 -6.69,3.61 -4.41,0 -7.99,-3.58 -7.99,-7.99 0,-4.41 3.58,-7.99 7.99,-7.99 2.8,0 5.26,1.44 6.69,3.61 1.43,-2.18 3.89,-3.61 6.69,-3.61zm0 2.77c2.89,0 5.22,2.34 5.22,5.22 0,2.89 -2.34,5.22 -5.22,5.22 -2.89,0 -5.22,-2.34 -5.22,-5.22 0,-2.89 2.34,-5.22 5.22,-5.22zm-13.37 0c2.89,0 5.22,2.34 5.22,5.22 0,2.89 -2.34,5.22 -5.22,5.22 -2.89,0 -5.22,-2.34 -5.22,-5.22 0,-2.89 2.34,-5.22 5.22,-5.22z"/>
|
||||||
|
<g>
|
||||||
|
<path class="fil1" d="M140.49 19.22l1.82 0c0.16,0 0.31,0.13 0.34,0.29l0.49 2.63c0.03,0.16 -0.07,0.29 -0.23,0.29l-1.82 0c-0.16,0 -0.31,-0.13 -0.34,-0.29l-0.5 -2.63c-0.03,-0.16 0.08,-0.29 0.23,-0.29z"/>
|
||||||
|
<path class="fil1" d="M129.14 9.06l6.05 0 0 -1.3c0,-0.16 0.13,-0.29 0.29,-0.29l2.55 0c0.16,0 0.29,0.13 0.29,0.29l0 1.3 6.05 0c0.16,0 0.29,0.13 0.29,0.29l0 2.61 -2.79 0 0 -1.12 -10.22 0 0 1.12 -2.79 0 0 -2.61c0,-0.16 0.13,-0.29 0.29,-0.29z"/>
|
||||||
|
<path class="fil1" d="M128.71 23.12l6.48 0 0 -4.68 -6.44 0 0 -1.47c0,-0.16 0.13,-0.29 0.29,-0.29l6.15 0 0 -2.16 -6.44 0 0 -1.47c0,-0.16 0.13,-0.29 0.29,-0.29l15.43 0c0.16,0 0.29,0.13 0.29,0.29l0 1.47 -6.44 0 0 2.16 6.15 0c0.16,0 0.29,0.13 0.29,0.29l0 1.47 -6.44 0 0 4.68 6.48 0c0.16,0 0.29,0.13 0.29,0.29l0 1.47 -16.66 0 0 -1.47c0,-0.16 0.13,-0.29 0.29,-0.29z"/>
|
||||||
|
<path class="fil1" d="M148.4 9.02l5.99 0 0 -1.25c0,-0.16 0.13,-0.29 0.29,-0.29l2.55 0c0.16,0 0.29,0.13 0.29,0.29l0 1.25 5.99 0c0.16,0 0.29,0.13 0.29,0.29l0 1.61 -6.27 0 0 4.6 6.36 0c0.19,0 0.34,0.15 0.34,0.34l0 1.89 -2.49 0 2.49 7.11 -2.86 0 -2.49 -7.11 -1.35 0 0 7.03 -3.12 0 0 -7.03 -1.35 0 -2.49 7.11 -2.85 0 2.49 -7.11 -2.49 0 0 -1.89c0,-0.19 0.15,-0.34 0.34,-0.34l6.36 0 0 -4.6 -6.27 0 0 -1.61c0,-0.16 0.13,-0.29 0.29,-0.29zm13.68 2.38l-2.28 0c-0.16,0 -0.33,0.13 -0.38,0.29l-1.09 3.31c-0.05,0.16 0.04,0.29 0.19,0.29l2.28 0c0.16,0 0.33,-0.13 0.38,-0.29l1.09 -3.31c0.05,-0.16 -0.03,-0.29 -0.19,-0.29zm-12.45 0l2.28 0c0.16,0 0.33,0.13 0.38,0.29l1.09 3.31c0.05,0.16 -0.04,0.29 -0.19,0.29l-2.28 0c-0.16,0 -0.33,-0.13 -0.38,-0.29l-1.09 -3.31c-0.05,-0.16 0.03,-0.29 0.19,-0.29z"/>
|
||||||
|
<path class="fil1" d="M170.46 12.11l6.72 0c0.16,0 0.29,0.13 0.29,0.29l0 0.84c0,0.16 -0.13,0.29 -0.29,0.29l-6.81 0 -0.72 11.34 -2.88 0 0.98 -15.56c0.01,-0.16 0.15,-0.29 0.31,-0.29l0.1 0 2.49 0 6.75 0 -0.25 -1.25c-0.03,-0.16 0.07,-0.29 0.23,-0.29l2.13 0c0.16,0 0.31,0.13 0.35,0.29l0.25 1.25 2.76 0c0.16,0 0.29,0.13 0.29,0.29l0 1.61 -2.67 0 0.45 2.22 0.24 -0.67c0.06,-0.16 0.23,-0.29 0.39,-0.29l1.61 0 -1.54 4.4 1.67 8.29 -2.41 0c-0.16,0 -0.31,-0.13 -0.35,-0.29l-0.63 -3.11 -1.09 3.11c-0.06,0.16 -0.23,0.29 -0.39,0.29l-1.61 0 2.39 -6.83 -1.44 -7.12 -7.25 0 -0.08 1.19zm10.53 -4.67l1.54 0c0.16,0 0.29,0.13 0.29,0.29l0 0.68c0,0.16 -0.13,0.29 -0.29,0.29l-1.54 0c-0.16,0 -0.29,-0.13 -0.29,-0.29l0 -0.68c0,-0.16 0.13,-0.29 0.29,-0.29z"/>
|
||||||
|
<path class="fil1" d="M172.98 19.71l0.99 0 1.09 -2.68 -1.11 0 -0.98 2.68zm2.64 -4.05l0 -0 1.96 0 -0 0 0.01 0 -0.49 1.36 -0.02 0c-0.34,0.98 -0.55,1.65 -1.06,3.03l-1.23 -0.06 -0 0.01 2.06 4.86 -2.44 0 -0.84 -1.99 -0.84 1.99 -2.44 0 2.06 -4.86 -0.01 -0.02 -1.17 0c-0.16,0 -0.24,-0.13 -0.18,-0.29l0.97 -2.67 -0.72 0c-0.16,0 -0.29,-0.13 -0.29,-0.29l0 -0.79c0,-0.16 0.13,-0.29 0.29,-0.29l1.21 0 0.44 -1.2c0.06,-0.16 0.23,-0.29 0.39,-0.29l1.42 0c0.16,0 0.24,0.13 0.18,0.29l-0.44 1.2 1.17 0z"/>
|
||||||
|
</g>
|
||||||
|
<path class="fil1" d="M26.23 22.62c0.78,-1.45 1.22,-3.1 1.22,-4.86 0,-5.65 -4.58,-10.23 -10.23,-10.23 -1.78,0 -3.44,0.45 -4.9,1.25l0 4.22c1.24,-1.28 2.98,-2.07 4.9,-2.07 3.77,0 6.83,3.06 6.83,6.83 0,3.77 -3.06,6.83 -6.83,6.83 -1.88,0 -3.58,-0.76 -4.82,-1.99 -1.23,-1.21 -1.51,-3.04 -1.57,-4.86l0 -11.24 0 -5.5 0 -0.12 0 -0 0 -0.38c1.2,-0.32 2.47,-0.49 3.78,-0.49 8.07,0 14.61,6.54 14.61,14.61 0,8.07 -6.54,14.61 -14.61,14.61 -8.07,0 -14.61,-6.54 -14.61,-14.61 0,-5.37 2.9,-10.07 7.22,-12.61l0 0.42 0 0 0 0.14 0 3.93 0 10.54c0,1.68 0.06,2.52 0.42,3.8 0.81,2.9 2.79,5.1 5.51,6.31 1.25,0.54 2.62,0.84 4.07,0.84 1.09,0 2.14,-0.17 3.13,-0.49 2.38,-1.06 4.42,-2.76 5.88,-4.89z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.6 KiB |
711
aas_pc_web/src/App.vue
Normal file
711
aas_pc_web/src/App.vue
Normal file
@@ -0,0 +1,711 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 移除多余的包裹层 -->
|
||||||
|
<div class="main-container">
|
||||||
|
<!-- 登录后的布局 -->
|
||||||
|
<template v-if="alreadyLogin">
|
||||||
|
<!-- 侧边菜单 -->
|
||||||
|
<el-menu ref="parentRef"
|
||||||
|
:collapse="isCollapse"
|
||||||
|
class="sidebar-menu"
|
||||||
|
:default-active="currentTitle.routes"
|
||||||
|
@select="menuChange">
|
||||||
|
<!-- Logo区域 -->
|
||||||
|
<div class="logo-container">
|
||||||
|
<img :src="isCollapse ? '../public/logo.svg' : '../public/logobig.svg'" @click="handleLeftClick('home')" style="cursor: pointer;" />
|
||||||
|
</div>
|
||||||
|
<!-- 菜单项 -->
|
||||||
|
<template v-for="menu in menuValue" :key="menu.label">
|
||||||
|
<el-sub-menu v-if="menu.options" :index="menu.value">
|
||||||
|
<template #title>
|
||||||
|
<el-icon>
|
||||||
|
<component :is="menu.icon" />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ menu.label }}</span>
|
||||||
|
</template>
|
||||||
|
<el-menu-item v-for="item in menu.options"
|
||||||
|
:key="item.value"
|
||||||
|
:index="item.value">
|
||||||
|
<el-icon>
|
||||||
|
<component :is="item.icon" />
|
||||||
|
</el-icon>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-menu-item>
|
||||||
|
</el-sub-menu>
|
||||||
|
<el-menu-item v-else :index="menu.value">
|
||||||
|
<el-icon>
|
||||||
|
<component :is="menu.icon" />
|
||||||
|
</el-icon>
|
||||||
|
{{ menu.label }}
|
||||||
|
</el-menu-item>
|
||||||
|
</template>
|
||||||
|
</el-menu>
|
||||||
|
|
||||||
|
<!-- 主内容区 -->
|
||||||
|
<div class="main-content">
|
||||||
|
<!-- 顶部导航栏 -->
|
||||||
|
<el-header class="page-header">
|
||||||
|
<!-- 左侧操作区 -->
|
||||||
|
<div class="header-left">
|
||||||
|
<el-button circle size="large" style="font-size:20px"
|
||||||
|
@click="collapseClick"
|
||||||
|
:icon="isCollapse ? 'Expand' : 'Fold'" />
|
||||||
|
</div>
|
||||||
|
<!-- 右侧操作区 -->
|
||||||
|
<div class="header-right">
|
||||||
|
<!-- 刷新 -->
|
||||||
|
<el-button link size="large" style="font-size:22px"
|
||||||
|
@click="refreshToHome"
|
||||||
|
icon="Refresh" />
|
||||||
|
<!-- 通知 -->
|
||||||
|
<el-badge :value="noticeValue"
|
||||||
|
:max="99" :show-zero="false"
|
||||||
|
class="item">
|
||||||
|
<el-popover trigger="click"
|
||||||
|
content=""
|
||||||
|
width="400"
|
||||||
|
placement="bottom-end">
|
||||||
|
<template #reference>
|
||||||
|
<el-button link size="large" style="font-size:22px"
|
||||||
|
icon="Bell" />
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<div>通知内容</div>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
|
||||||
|
</el-badge>
|
||||||
|
<!-- 主题切换 -->
|
||||||
|
<el-button link size="large" style="font-size:22px"
|
||||||
|
@click="toggleTheme"
|
||||||
|
:icon="isDarkMode ? 'Moon' : 'Sunny'" />
|
||||||
|
|
||||||
|
<!-- 用户头像 -->
|
||||||
|
<el-popover v-model:visible="showPopover"
|
||||||
|
placement="bottom-end"
|
||||||
|
trigger="click">
|
||||||
|
<template #reference>
|
||||||
|
<el-avatar class="user-avatar"
|
||||||
|
:src="userAvatar" />
|
||||||
|
</template>
|
||||||
|
<div class="user-menu">
|
||||||
|
<el-button link @click="handleAction('profile')">个人中心</el-button>
|
||||||
|
<el-divider />
|
||||||
|
<el-button link @click="handleAction('logout')">退出登录</el-button>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
</el-header>
|
||||||
|
<!-- 标签页导航 -->
|
||||||
|
<div class="tabs-container">
|
||||||
|
<el-tabs v-model="activeTab"
|
||||||
|
type="card"
|
||||||
|
closable
|
||||||
|
@tab-click="handleTabClick"
|
||||||
|
@tab-remove="handleTabRemove">
|
||||||
|
<el-tab-pane v-for="tab in openedTabs"
|
||||||
|
:key="tab.path"
|
||||||
|
:name="tab.path">
|
||||||
|
<template #label>
|
||||||
|
<span>{{ tab.label }}</span>
|
||||||
|
</template>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
<!-- 路由内容区 -->
|
||||||
|
<div class="router-container">
|
||||||
|
<keep-alive :include="cachedViews">
|
||||||
|
<router-view v-slot="{ Component }">
|
||||||
|
<component :is="Component"
|
||||||
|
:key="route.fullPath"
|
||||||
|
class="router-view-container" />
|
||||||
|
</router-view>
|
||||||
|
</keep-alive>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 未登录时的布局 -->
|
||||||
|
<template v-else>
|
||||||
|
<router-view />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 底部 -->
|
||||||
|
<el-footer class="global-footer">Copyright © 2025 宝来威智能(广东)有限公司. All Rights Reserved.</el-footer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!--<script>
|
||||||
|
/* import { provide, ref, onMounted, watchEffect, computed, reactive, watch } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
</script>-->
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useDark, useToggle } from '@vueuse/core'
|
||||||
|
import { provide, ref, onMounted, watchEffect, computed, reactive, inject, watch } from 'vue'
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||||
|
import en from 'element-plus/dist/locale/en.mjs'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
|
||||||
|
const language = ref('zh-cn')
|
||||||
|
const locale = computed(() => (language.value === 'zh-cn' ? zhCn : en))
|
||||||
|
|
||||||
|
const isDark = useDark()
|
||||||
|
const toggleDark = useToggle(isDark)
|
||||||
|
|
||||||
|
const toggle = () => {
|
||||||
|
language.value = language.value === 'zh-cn' ? 'en' : 'zh-cn'
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
webToDark(true);
|
||||||
|
} else {
|
||||||
|
webToDark(false);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
const checkLoginStatus = () => {
|
||||||
|
alreadyLogin.value = localStorage.getItem('login') == 'true'
|
||||||
|
|
||||||
|
}
|
||||||
|
provide('checkLoginStatus', checkLoginStatus)
|
||||||
|
|
||||||
|
const userAvatar = ref("")
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
helloworld()
|
||||||
|
// 初始检查登录状态
|
||||||
|
checkLoginStatus()
|
||||||
|
userAvatar.value = config.httpAds + localStorage.getItem('avatar')
|
||||||
|
// 主题初始化
|
||||||
|
const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
|
const handleColorSchemeChange = (e) => {
|
||||||
|
webToDark(e.matches)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始设置
|
||||||
|
webToDark(darkModeQuery.matches)
|
||||||
|
|
||||||
|
// 监听系统主题变化
|
||||||
|
darkModeQuery.addEventListener('change', handleColorSchemeChange)
|
||||||
|
|
||||||
|
// 清理监听器
|
||||||
|
return () => {
|
||||||
|
darkModeQuery.removeEventListener('change', handleColorSchemeChange)
|
||||||
|
}
|
||||||
|
|
||||||
|
findLabelByValue();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* if (lastSegment == '/home') {
|
||||||
|
disDbDrop.value = false
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const helloworld = () => {
|
||||||
|
try {
|
||||||
|
if (getUrl() == "/login") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const rs = $http.post('Login/Helloooo').then(rs => {
|
||||||
|
if (rs.data != 'hello') {
|
||||||
|
refreshToHome()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const getUrl = () => {
|
||||||
|
const url = window.location.href;
|
||||||
|
// 找到最后一个 '/' 的位置
|
||||||
|
const lastSlashIndex = url.lastIndexOf('/');
|
||||||
|
// 获取最后一个 '/' 后面的内容
|
||||||
|
return url.substring(lastSlashIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
const alreadyLogin = ref(false)
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
const showSidebar = ref(false)
|
||||||
|
|
||||||
|
const $http = inject('$http')
|
||||||
|
const config = inject('config')
|
||||||
|
const username = localStorage.getItem('username')
|
||||||
|
|
||||||
|
|
||||||
|
const product = reactive({
|
||||||
|
value: '',
|
||||||
|
options: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentTitle = reactive({
|
||||||
|
label: '',
|
||||||
|
routes: localStorage.getItem('url'),
|
||||||
|
}) // 当前页面
|
||||||
|
|
||||||
|
const isCollapse = ref(false)
|
||||||
|
const showPopover = ref(false)
|
||||||
|
const noticeValue = ref(999)
|
||||||
|
|
||||||
|
const menuValue = reactive([
|
||||||
|
{
|
||||||
|
label: "仪表盘",
|
||||||
|
value: "dashboard",
|
||||||
|
icon: "Menu",
|
||||||
|
options: [
|
||||||
|
{ label: "主页", value: "/home", icon: "House" },
|
||||||
|
/*{ label: "日志中心", value: "/log", icon: "Clock" }*/
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "系统操作",
|
||||||
|
value: "system",
|
||||||
|
icon: "Tools",
|
||||||
|
options: [
|
||||||
|
{ label: "用户管理", value: "/usermanage", icon: "User" },
|
||||||
|
{ label: "组织管理", value: "/commanage", icon: "OfficeBuilding" },
|
||||||
|
/*{ label: "权限管理", value: "/scopemanage", icon: "Operation" },*/
|
||||||
|
{ label: "字典管理", value: "/dicmanage", icon: "Notebook" },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "项目管理",
|
||||||
|
value: "quote",
|
||||||
|
icon: "HelpFilled",
|
||||||
|
options: [
|
||||||
|
{ label: "项目报备", value: "/projectquote", icon: "Money" },
|
||||||
|
{ label: "项目审核", value: "/quotereview", icon: "EditPen" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 左侧返回首页按钮点击处理
|
||||||
|
const handleLeftClick = (type) => {
|
||||||
|
// type 可能的值: 'home' 按钮
|
||||||
|
switch (type) {
|
||||||
|
case 'home':
|
||||||
|
menuChange("/home")
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log('跳转错误!');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 菜单操作处理
|
||||||
|
const handleAction = (action) => {
|
||||||
|
// action 可能的值: 'profile' 个人中心 / 'logout' 退出登录
|
||||||
|
showPopover.value = false
|
||||||
|
switch (action) {
|
||||||
|
case 'profile':
|
||||||
|
//disDbDrop.value = true
|
||||||
|
router.push('/user')
|
||||||
|
break;
|
||||||
|
case 'logout':
|
||||||
|
localStorage.setItem('login', false)
|
||||||
|
router.push('/login')
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log('跳转错误!');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const refreshToHome = () => {
|
||||||
|
$http.post('ConfigPY/RefreshConfig')
|
||||||
|
router.push('/home')
|
||||||
|
setTimeout(() => {
|
||||||
|
location.reload(true);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentRef = ref(null)
|
||||||
|
// 菜单处理
|
||||||
|
const menuChange = (val) => {
|
||||||
|
if (currentTitle.routes == val) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentTitle.label = val;
|
||||||
|
currentTitle.routes = val;
|
||||||
|
localStorage.setItem('url', val)
|
||||||
|
router.push(val)
|
||||||
|
}
|
||||||
|
const collapseClick = () => {
|
||||||
|
isCollapse.value = !isCollapse.value
|
||||||
|
if (isCollapse.value) {
|
||||||
|
document.querySelector('.router-container').style.width = 'calc(100vw - 64px)'
|
||||||
|
} else {
|
||||||
|
document.querySelector('.router-container').style.width = 'calc(100vw - 240px)'
|
||||||
|
}
|
||||||
|
document.documentElement.clientWidth // 触发回流
|
||||||
|
}
|
||||||
|
|
||||||
|
// 控制深色模式
|
||||||
|
const isDarkMode = ref(false)
|
||||||
|
const webToDark = (dark) => {
|
||||||
|
// 获取 <html> 元素的类名
|
||||||
|
let ishtmldark = null;
|
||||||
|
if (document.documentElement.className.indexOf('dark') !== -1) {
|
||||||
|
ishtmldark = false
|
||||||
|
} else {
|
||||||
|
ishtmldark = true
|
||||||
|
}
|
||||||
|
if (dark) {
|
||||||
|
document.documentElement.setAttribute('theme-mode', 'dark')
|
||||||
|
isDarkMode.value = true
|
||||||
|
if (ishtmldark) {
|
||||||
|
toggleDark()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document.documentElement.removeAttribute('theme-mode')
|
||||||
|
isDarkMode.value = false
|
||||||
|
if (!ishtmldark) {
|
||||||
|
toggleDark()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const toggleTheme = () => {
|
||||||
|
isDarkMode.value = !isDarkMode.value
|
||||||
|
let root = document.documentElement;
|
||||||
|
toggleDark()
|
||||||
|
if (!isDarkMode.value) {
|
||||||
|
// 如果当前是暗色主题,切换到亮色主题
|
||||||
|
root.style.setProperty('--color-background', '#ffffff');
|
||||||
|
root.style.setProperty('--color-background-soft', '#f8f8f8');
|
||||||
|
root.style.setProperty('--color-background-mute', '#f2f2f2');
|
||||||
|
root.style.setProperty('--color-border', 'rgba(60, 60, 60, 0.12)');
|
||||||
|
root.style.setProperty('--color-border-hover', 'rgba(60, 60, 60, 0.29)');
|
||||||
|
root.style.setProperty('--color-heading', '#2c3e50');
|
||||||
|
root.style.setProperty('--color-text', '#2c3e50');
|
||||||
|
root.setAttribute('data-theme', 'light');
|
||||||
|
setTimeout(() => {
|
||||||
|
root.removeAttribute('theme-mode');
|
||||||
|
}, 20);
|
||||||
|
} else {
|
||||||
|
// 如果当前是亮色主题,切换到暗色主题
|
||||||
|
root.style.setProperty('--color-background', '#242424');
|
||||||
|
root.style.setProperty('--color-background-soft', '#222222');
|
||||||
|
root.style.setProperty('--color-background-mute', '#282828');
|
||||||
|
root.style.setProperty('--color-border', 'rgba(84, 84, 84, 0.48)');
|
||||||
|
root.style.setProperty('--color-border-hover', 'rgba(84, 84, 84, 0.65)');
|
||||||
|
root.style.setProperty('--color-heading', '#ffffff');
|
||||||
|
root.style.setProperty('--color-text', 'rgba(235, 235, 235, 0.64)');
|
||||||
|
root.setAttribute('data-theme', 'dark');
|
||||||
|
setTimeout(() => {
|
||||||
|
root.setAttribute('theme-mode', 'dark');
|
||||||
|
}, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 确定当前地址
|
||||||
|
const findLabelByValue = () => {
|
||||||
|
const url = window.location.href;
|
||||||
|
// 找到最后一个 '/' 的位置
|
||||||
|
const lastSlashIndex = url.lastIndexOf('/');
|
||||||
|
// 获取最后一个 '/' 后面的内容
|
||||||
|
return url.substring(lastSlashIndex);
|
||||||
|
//const lastSegment = url.substring(lastSlashIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 已打开的标签页
|
||||||
|
const openedTabs = reactive([])
|
||||||
|
// 需要缓存的组件名称
|
||||||
|
const cachedViews = ref(new Set())
|
||||||
|
|
||||||
|
// 当前激活的标签页
|
||||||
|
const activeTab = computed({
|
||||||
|
get: () => route.path,
|
||||||
|
set: (val) => router.push(val)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听路由变化
|
||||||
|
watch(() => route.path, (newPath) => {
|
||||||
|
if (newPath === '/login') return
|
||||||
|
|
||||||
|
// 新增:同步更新当前激活菜单
|
||||||
|
currentTitle.routes = newPath
|
||||||
|
localStorage.setItem('url', newPath)
|
||||||
|
|
||||||
|
const existingTab = openedTabs.find(tab => tab.path == newPath)
|
||||||
|
const routeName = route.matched[0]?.name
|
||||||
|
|
||||||
|
if (routeName) {
|
||||||
|
if (!existingTab) {
|
||||||
|
cachedViews.value.add(routeName)
|
||||||
|
openedTabs.push({
|
||||||
|
path: newPath,
|
||||||
|
label: routeName || '未命名页面',
|
||||||
|
name: routeName
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// 标签点击处理
|
||||||
|
const handleTabClick = (tab) => {
|
||||||
|
router.push(tab.paneName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标签关闭处理
|
||||||
|
const handleTabRemove = (targetPath) => {
|
||||||
|
console.log(targetPath)
|
||||||
|
const index = openedTabs.findIndex(tab => tab.path === targetPath)
|
||||||
|
if (index != -1 && openedTabs.length > 1) {
|
||||||
|
const removedTab = openedTabs.splice(index, 1)[0]
|
||||||
|
|
||||||
|
// 清理缓存
|
||||||
|
if (removedTab.name) {
|
||||||
|
cachedViews.value.delete(removedTab.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果关闭的是当前页面则跳转
|
||||||
|
if (targetPath === route.path) {
|
||||||
|
const lastTab = openedTabs[openedTabs.length - 1]
|
||||||
|
menuChange(lastTab ? lastTab.path : '/home')
|
||||||
|
}
|
||||||
|
} else if (openedTabs.length == 1) {
|
||||||
|
menuChange("/home")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ajaxfile = async (form) => {
|
||||||
|
// 参数验证
|
||||||
|
if (!form.File || !form.File instanceof File) {
|
||||||
|
throw new Error('文件对象无效!');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 创建 FormData 对象并 append 文件
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('File', form.File);
|
||||||
|
formData.append('Folder', form.Folder);
|
||||||
|
|
||||||
|
// 设置请求配置
|
||||||
|
const settings = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
"Cookie": "isCN=zh-cn"
|
||||||
|
},
|
||||||
|
body: formData
|
||||||
|
};
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
settings.headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
// 发送请求
|
||||||
|
const response = await fetch(config.httpApi + 'FileUpload/UploadFile', settings);
|
||||||
|
|
||||||
|
return await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('error:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
provide('ajaxfile', ajaxfile)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu {
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1001;
|
||||||
|
transition: width 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu:not(.el-menu--collapse) {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-container {
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-container img {
|
||||||
|
max-width: 160px;
|
||||||
|
max-height: 30px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 240px; /* 与菜单展开宽度一致 */
|
||||||
|
z-index: 999;
|
||||||
|
transition: left 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu {
|
||||||
|
padding: 8px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 菜单折叠时的样式调整 */
|
||||||
|
/*.el-menu--collapse + .page-header {
|
||||||
|
left: 64px;
|
||||||
|
}*/
|
||||||
|
.sidebar-menu.el-menu--collapse ~ .main-content .page-header {
|
||||||
|
left: 64px;
|
||||||
|
transition: left 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-footer {
|
||||||
|
text-align: center;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 30px; /* 距离页面底部 30px */
|
||||||
|
left: 0;
|
||||||
|
width: 100%; /* 宽度设置为 100% */
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
--el-footer-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* :deep .t-footer__text {
|
||||||
|
bottom: 2px;
|
||||||
|
position: relative;
|
||||||
|
}*/
|
||||||
|
/* 整体布局 */
|
||||||
|
.main-container {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 登录后的主内容区 */
|
||||||
|
.main-content {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 240px; /* 初始左侧留出菜单宽度 */
|
||||||
|
transition: margin-left 0.6s; /* 同步菜单折叠动画 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 菜单折叠时的布局调整 */
|
||||||
|
.sidebar-menu.el-menu--collapse + .main-content {
|
||||||
|
margin-left: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 路由内容容器 */
|
||||||
|
.router-container {
|
||||||
|
height: calc(100vh - 60px - 40px); /* 计算高度:视窗高度 - 头部高度 - 底部高度 */
|
||||||
|
overflow: auto;
|
||||||
|
top: 100px;
|
||||||
|
width: calc(100vw - 240px);
|
||||||
|
position: fixed;
|
||||||
|
padding: 0px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 全局底部 */
|
||||||
|
.global-footer {
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
width: auto;
|
||||||
|
align-items: center;
|
||||||
|
/*color: #E5EAF3;
|
||||||
|
background: #008C8C;
|
||||||
|
border-top: 1px solid var(--el-border-color);*/
|
||||||
|
justify-content: center;
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 1003;
|
||||||
|
/* 设置半透明磨砂白背景 */
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 0 56px;
|
||||||
|
background: rgba(128, 128, 128, 0.2); /* 白色背景,50%透明度 */
|
||||||
|
backdrop-filter: blur(2px); /* 应用磨砂效果,模糊半径为10px */
|
||||||
|
-webkit-backdrop-filter: blur(10px); /* 兼容旧版Safari浏览器 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页签 */
|
||||||
|
.tabs-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 60px;
|
||||||
|
left: 240px;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
transition: left 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu.el-menu--collapse ~ .main-content .tabs-container {
|
||||||
|
left: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.router-view-container {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__header) {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__item) {
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
86
aas_pc_web/src/assets/base.css
Normal file
86
aas_pc_web/src/assets/base.css
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/* color palette from <https://github.com/vuejs/theme> */
|
||||||
|
:root {
|
||||||
|
--vt-c-white: #ffffff;
|
||||||
|
--vt-c-white-soft: #f8f8f8;
|
||||||
|
--vt-c-white-mute: #f2f2f2;
|
||||||
|
|
||||||
|
--vt-c-black: #181818;
|
||||||
|
--vt-c-black-soft: #222222;
|
||||||
|
--vt-c-black-mute: #282828;
|
||||||
|
|
||||||
|
--vt-c-indigo: #2c3e50;
|
||||||
|
|
||||||
|
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
||||||
|
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
||||||
|
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
||||||
|
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
||||||
|
|
||||||
|
--vt-c-text-light-1: var(--vt-c-indigo);
|
||||||
|
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
||||||
|
--vt-c-text-dark-1: var(--vt-c-white);
|
||||||
|
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* semantic color variables for this project */
|
||||||
|
:root {
|
||||||
|
--color-background: var(--vt-c-white);
|
||||||
|
--color-background-soft: var(--vt-c-white-soft);
|
||||||
|
--color-background-mute: var(--vt-c-white-mute);
|
||||||
|
|
||||||
|
--color-border: var(--vt-c-divider-light-2);
|
||||||
|
--color-border-hover: var(--vt-c-divider-light-1);
|
||||||
|
|
||||||
|
--color-heading: var(--vt-c-text-light-1);
|
||||||
|
--color-text: var(--vt-c-text-light-1);
|
||||||
|
|
||||||
|
--section-gap: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--color-background: var(--vt-c-black);
|
||||||
|
--color-background-soft: var(--vt-c-black-soft);
|
||||||
|
--color-background-mute: var(--vt-c-black-mute);
|
||||||
|
|
||||||
|
--color-border: var(--vt-c-divider-dark-2);
|
||||||
|
--color-border-hover: var(--vt-c-divider-dark-1);
|
||||||
|
|
||||||
|
--color-heading: var(--vt-c-text-dark-1);
|
||||||
|
--color-text: var(--vt-c-text-dark-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: var(--color-background);
|
||||||
|
transition:
|
||||||
|
color 0.5s,
|
||||||
|
background-color 0.5s;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-family:
|
||||||
|
Inter,
|
||||||
|
-apple-system,
|
||||||
|
BlinkMacSystemFont,
|
||||||
|
'Segoe UI',
|
||||||
|
Roboto,
|
||||||
|
Oxygen,
|
||||||
|
Ubuntu,
|
||||||
|
Cantarell,
|
||||||
|
'Fira Sans',
|
||||||
|
'Droid Sans',
|
||||||
|
'Helvetica Neue',
|
||||||
|
sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
37
aas_pc_web/src/assets/main.css
Normal file
37
aas_pc_web/src/assets/main.css
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
@import './base.css';
|
||||||
|
|
||||||
|
#app {
|
||||||
|
/*max-width: 1440px;*/
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
.green {
|
||||||
|
text-decoration: none;
|
||||||
|
color: hsla(160, 100%, 37%, 1);
|
||||||
|
transition: 0.4s;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (hover: hover) {
|
||||||
|
a:hover {
|
||||||
|
background-color: hsla(160, 100%, 37%, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
display: grid;
|
||||||
|
/*grid-template-columns: 1fr 1fr;*/
|
||||||
|
padding: 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
120
aas_pc_web/src/axios.js
Normal file
120
aas_pc_web/src/axios.js
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import config from '../public/config.js';
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const instance = axios.create({
|
||||||
|
baseURL: config.httpApi, // 设置基础URL
|
||||||
|
timeout: 60000
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加请求拦截器
|
||||||
|
instance.interceptors.request.use(config => {
|
||||||
|
// 设置默认的 Content-Type
|
||||||
|
if (config.headers['Content-Type'] == undefined) {
|
||||||
|
config.headers['Content-Type'] = 'application/json';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果发送的数据是对象,则使用JSON库进行序列化
|
||||||
|
if (config.data && typeof config.data === 'object') {
|
||||||
|
config.data = JSON.stringify(config.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从本地存储获取token
|
||||||
|
//const token = localStorage.getItem('token');
|
||||||
|
const url = window.location.href;
|
||||||
|
// 找到最后一个 '/' 的位置
|
||||||
|
const lastSlashIndex = url.lastIndexOf('/');
|
||||||
|
// 获取最后一个 '/' 后面的内容
|
||||||
|
const lastSegment = url.substring(lastSlashIndex);
|
||||||
|
// 如果是登录接口,则不添加token
|
||||||
|
if (config.url !== 'Login/Login') {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
if (token) {
|
||||||
|
config.headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
} else if (lastSegment != '/login') {
|
||||||
|
handleTokenExpiration()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}, error => {
|
||||||
|
// 请求错误处理
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加响应拦截器
|
||||||
|
instance.interceptors.response.use(response => {
|
||||||
|
// 对响应数据处理
|
||||||
|
if (response.config.url !== 'Login/Login' && response.status === 200) {
|
||||||
|
refreshToken();
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}, error => {
|
||||||
|
// 对响应错误处理
|
||||||
|
// 可以在这里添加例如token过期后的处理逻辑
|
||||||
|
console.log(error)
|
||||||
|
if (error.response && error.response.status == 401) {
|
||||||
|
// token过期,跳转到登录页面
|
||||||
|
handleTokenExpiration()
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default instance;
|
||||||
|
|
||||||
|
|
||||||
|
// Token刷新方法
|
||||||
|
async function refreshToken() {
|
||||||
|
try {
|
||||||
|
// 检查上次自动登录时间(新增)
|
||||||
|
const lastAutoLoginTime = localStorage.getItem('lastAutoLoginTime');
|
||||||
|
const currentTime = new Date().getTime();
|
||||||
|
|
||||||
|
// 如果15分钟内已自动登录过,则跳过(新增)
|
||||||
|
if (lastAutoLoginTime && currentTime - lastAutoLoginTime < 15 * 60 * 1000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const username = localStorage.getItem('rememberedUsername')
|
||||||
|
const password = localStorage.getItem('rememberedPassword')
|
||||||
|
|
||||||
|
if (!username || !password) {
|
||||||
|
throw new Error('登录过期 请重新登录')
|
||||||
|
}
|
||||||
|
|
||||||
|
const formdata = {
|
||||||
|
username: username,
|
||||||
|
password: password
|
||||||
|
}
|
||||||
|
// 更新自动登录时间(新增)
|
||||||
|
localStorage.setItem('lastAutoLoginTime', currentTime.toString());
|
||||||
|
|
||||||
|
instance.post('Login/Login', formdata)
|
||||||
|
.then(response => {
|
||||||
|
if (response.data.isok) {
|
||||||
|
localStorage.setItem('token', response.data.response.accessToken);
|
||||||
|
//console.log('自动登录成功')
|
||||||
|
} else {
|
||||||
|
throw new Error('token更新失败');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
// 登录失败时清除时间记录(新增)
|
||||||
|
localStorage.removeItem('lastAutoLoginTime');
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token过期处理
|
||||||
|
function handleTokenExpiration() {
|
||||||
|
ElMessage.error('token失效 请重新登录')
|
||||||
|
setTimeout(() => {
|
||||||
|
localStorage.removeItem('token')
|
||||||
|
window.location.href = '/login'
|
||||||
|
}, 233);
|
||||||
|
}
|
||||||
44
aas_pc_web/src/axiosfile.js
Normal file
44
aas_pc_web/src/axiosfile.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import $ from 'jquery';
|
||||||
|
import config from '../public/config.js';
|
||||||
|
|
||||||
|
// 定义初始化函数
|
||||||
|
const initFileUpload = ($) => {
|
||||||
|
// 直接上传FormData方法
|
||||||
|
$.uploadFile = function (formData) {
|
||||||
|
console.log(formData)
|
||||||
|
return $.ajax({
|
||||||
|
url: config.httpApi + "FileUpload/UploadFileFace",
|
||||||
|
method: "POST",
|
||||||
|
timeout: 0,
|
||||||
|
headers: {
|
||||||
|
"Cookie": "isCN=zh-cn"
|
||||||
|
},
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
data: formData
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表单插件方法
|
||||||
|
$.fn.uploadFile = function (options) {
|
||||||
|
const $form = this;
|
||||||
|
console.log(options)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
$form.ajaxSubmit({
|
||||||
|
url: config.httpApi + "FileUpload/UploadFileFace",
|
||||||
|
type: "POST",
|
||||||
|
headers: {
|
||||||
|
"Cookie": "isCN=zh-cn"
|
||||||
|
},
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
...options,
|
||||||
|
success: resolve,
|
||||||
|
error: reject
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 导出初始化函数
|
||||||
|
export default initFileUpload;
|
||||||
26
aas_pc_web/src/components/i18n.js
Normal file
26
aas_pc_web/src/components/i18n.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { createI18n } from 'vue-i18n';
|
||||||
|
import zhCn from 'element-plus/es/locale/lang/zh-cn';
|
||||||
|
import en from 'element-plus/es/locale/lang/en';
|
||||||
|
|
||||||
|
const messages = {
|
||||||
|
en: {
|
||||||
|
message: {
|
||||||
|
hello: 'hello world'
|
||||||
|
},
|
||||||
|
el: en // Element Plus的英文翻译
|
||||||
|
},
|
||||||
|
zh: {
|
||||||
|
message: {
|
||||||
|
hello: '你好,世界'
|
||||||
|
},
|
||||||
|
el: zhCn // Element Plus的中文翻译
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const i18n = createI18n({
|
||||||
|
locale: 'zh', // 设置默认语言
|
||||||
|
fallbackLocale: 'en', // 设置备用语言
|
||||||
|
messages, // 设置翻译信息
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
||||||
31
aas_pc_web/src/main.js
Normal file
31
aas_pc_web/src/main.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import router from './router'
|
||||||
|
import config from '../public/config.js';
|
||||||
|
import axios from './axios' // 导入配置好的实例
|
||||||
|
import axiosfile from './axiosfile' // 导入配置好的实例
|
||||||
|
import i18n from './components/i18n.js' // 导入i18n
|
||||||
|
import './assets/main.css'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
|
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||||
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
|
app.component(key, component)
|
||||||
|
}
|
||||||
|
// axios挂载到全局属性
|
||||||
|
app.config.globalProperties.$http = axios
|
||||||
|
|
||||||
|
// 提供依赖注入
|
||||||
|
app.provide('config', config)
|
||||||
|
app.provide('$http', axios)
|
||||||
|
app.provide('$httpfile', axiosfile)
|
||||||
|
|
||||||
|
app.use(router)
|
||||||
|
app.use(ElementPlus, { locale: zhCn })
|
||||||
|
app.use(i18n)
|
||||||
|
app.mount('#app')
|
||||||
110
aas_pc_web/src/pages/404/index.vue
Normal file
110
aas_pc_web/src/pages/404/index.vue
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<div class="interactive-container">
|
||||||
|
<div class="error-card">
|
||||||
|
<div class="liquid"></div>
|
||||||
|
<div class="content">
|
||||||
|
<h1>404</h1>
|
||||||
|
<p>错误(404):当前页面未找到</p>
|
||||||
|
<p>SYSTEM ERROR: PAGE NOT FOUND</p>
|
||||||
|
<el-button type="success" plain round
|
||||||
|
class="magnetic-btn" :icon="HomeFilled"
|
||||||
|
@mouseenter="playHoverSound"
|
||||||
|
@click="goHome">
|
||||||
|
返回主页
|
||||||
|
<span class="hover-effect"></span>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { HomeFilled } from '@element-plus/icons-vue'
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const goHome = () => {
|
||||||
|
router.push('home');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.interactive-container {
|
||||||
|
height: 80%;
|
||||||
|
width: 90%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-card {
|
||||||
|
position: relative;
|
||||||
|
width: 400px;
|
||||||
|
height: 500px;
|
||||||
|
border-radius: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 25px 45px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.liquid {
|
||||||
|
position: absolute;
|
||||||
|
top: -50%;
|
||||||
|
left: -50%;
|
||||||
|
width: 200%;
|
||||||
|
height: 200%;
|
||||||
|
animation: rotate 10s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
inset: 2px;
|
||||||
|
border-radius: 18px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 8rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 1rem 0 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.magnetic-btn {
|
||||||
|
position: relative;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
border: 2px solid rgba(255,255,255,0.5);
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.magnetic-btn:hover {
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-effect {
|
||||||
|
position: absolute;
|
||||||
|
background: radial-gradient(circle at center, rgba(255,255,255,0.4) 0%, transparent 70%);
|
||||||
|
transform: scale(0);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.magnetic-btn:hover .hover-effect {
|
||||||
|
transform: scale(2);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
561
aas_pc_web/src/pages/commanage/index.vue
Normal file
561
aas_pc_web/src/pages/commanage/index.vue
Normal file
@@ -0,0 +1,561 @@
|
|||||||
|
<template>
|
||||||
|
<div class="company-management">
|
||||||
|
<!-- 操作栏 -->
|
||||||
|
<div class="header">
|
||||||
|
<el-button type="primary" @click="handleAdd" :icon="Plus">添加企业</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 企业表格 -->
|
||||||
|
<el-table :data="companies" border style="width: 100%" v-loading="loading" empty-text="暂无数据">
|
||||||
|
<el-table-column label="操作" width="102">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="info" :icon="Edit" circle plain @click="handleEdit(row)" />
|
||||||
|
<el-button type="danger" :icon="Delete" circle plain @click="handleDelete(row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="code" label="公司代码" width="100" />
|
||||||
|
<el-table-column prop="nameCn" label="中文名称" width="180" />
|
||||||
|
<el-table-column prop="nameEn" label="英文名称" width="180" />
|
||||||
|
<el-table-column prop="industry" label="所属行业" width="120" />
|
||||||
|
<el-table-column prop="identity" label="身份" width="120" />
|
||||||
|
<el-table-column prop="region" label="地区" width="120" />
|
||||||
|
<!--<el-table-column prop="licenseCode" label="营业执照" width="220" />-->
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 添加/编辑对话框 -->
|
||||||
|
<el-dialog v-model="dialogVisible"
|
||||||
|
:title="isEdit ? '编辑企业' : '添加企业'"
|
||||||
|
width="800px">
|
||||||
|
<el-form :model="form"
|
||||||
|
:rules="rules"
|
||||||
|
ref="formRef"
|
||||||
|
label-width="120px"
|
||||||
|
label-position="right">
|
||||||
|
|
||||||
|
<el-form-item label="中文名称" prop="nameCn">
|
||||||
|
<el-input v-model="form.nameCn" placeholder="请输入中文名称" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="英文名称" prop="nameEn">
|
||||||
|
<el-input v-model="form.nameEn" placeholder="请输入英文名称" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="所属行业" prop="industry">
|
||||||
|
<el-select v-model="form.industry" placeholder="请选择行业">
|
||||||
|
<el-option v-for="item in industryOptions"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="公司身份" prop="identity">
|
||||||
|
<el-select v-model="form.identity" placeholder="请选择身份">
|
||||||
|
<el-option v-for="item in identityOptions"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="所属地区" prop="region">
|
||||||
|
<el-select v-model="form.region" placeholder="请选择地区">
|
||||||
|
<el-option v-for="(key,item) in regionOptions"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!--
|
||||||
|
<el-form-item label="营业执照代码" prop="licenseCode">
|
||||||
|
<el-input v-model="form.licenseCode" placeholder="请输入营业执照代码" />
|
||||||
|
</el-form-item>-->
|
||||||
|
<!--<el-form-item label="营业执照" prop="licenseImage">
|
||||||
|
<el-upload class="license-uploader"
|
||||||
|
drag
|
||||||
|
action="/api/upload"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-change="handleLicenseChange"
|
||||||
|
:auto-upload="false">-->
|
||||||
|
<!-- 预览区域 -->
|
||||||
|
<!--<div v-if="form.licenseImage || form.licensePreview" class="image-preview">
|
||||||
|
<img v-if="isImageFile(form.licenseImageFile)"
|
||||||
|
:src="form.licensePreview || getFullUrl(form.licenseImage)"
|
||||||
|
class="preview-image" />
|
||||||
|
<div v-else class="file-preview">
|
||||||
|
<el-icon size="33"><DocumentChecked /></el-icon>
|
||||||
|
<div>营业执照文件 <span style="color: #409EFF">√已上传</span></div>
|
||||||
|
<div class="file-name">{{ getFileName(form.licenseImage) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="preview-mask">
|
||||||
|
<el-icon><UploadFilled /></el-icon>
|
||||||
|
<div>点击更换文件</div>
|
||||||
|
</div>
|
||||||
|
</div>-->
|
||||||
|
<!-- 未上传状态 -->
|
||||||
|
<!--<template v-else>
|
||||||
|
<el-icon class="el-icon--upload"><UploadFilled /></el-icon>
|
||||||
|
<div class="el-upload__text">
|
||||||
|
拖拽文件到此 或 <em>点击上传</em>
|
||||||
|
</div>
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
支持JPG/PNG/PDF格式,大小不超过5MB
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>-->
|
||||||
|
|
||||||
|
<el-form-item label="公司Logo" prop="logo">
|
||||||
|
<el-upload class="logo-uploader"
|
||||||
|
drag
|
||||||
|
action="/api/upload"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-change="handleLogoChange"
|
||||||
|
:auto-upload="false">
|
||||||
|
<!-- 预览区域 -->
|
||||||
|
<div v-if="form.logoaddress || form.logoPreview" class="image-preview">
|
||||||
|
<img :src="form.logoPreview || getFullUrl(form.logoaddress)"
|
||||||
|
class="preview-image" />
|
||||||
|
<div class="preview-mask">
|
||||||
|
<el-icon><UploadFilled /></el-icon>
|
||||||
|
<div>点击更换Logo</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 未上传状态 -->
|
||||||
|
<template v-else>
|
||||||
|
<el-icon class="el-icon--upload"><UploadFilled /></el-icon>
|
||||||
|
<div class="el-upload__text">
|
||||||
|
拖拽图片到此 或 <em>点击上传</em>
|
||||||
|
</div>
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
支持JPG/PNG格式,大小不超过5MB
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, inject, onUnmounted } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { Plus, Delete, Edit, UploadFilled, DocumentChecked } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const $http = inject('$http')
|
||||||
|
const ajaxfile = inject('ajaxfile');
|
||||||
|
const config = inject('config');
|
||||||
|
|
||||||
|
// 数据列表
|
||||||
|
const companies = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 对话框相关
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const currentCompanyId = ref(null)
|
||||||
|
const formRef = ref(null)
|
||||||
|
|
||||||
|
// 表单初始数据
|
||||||
|
const defaultForm = {
|
||||||
|
code: '',
|
||||||
|
nameCn: '',
|
||||||
|
nameEn: '',
|
||||||
|
industry: '',
|
||||||
|
identity: '',
|
||||||
|
region: '',
|
||||||
|
licenseCode: '',
|
||||||
|
logoaddress: '',
|
||||||
|
licenseImage: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = reactive({ ...defaultForm })
|
||||||
|
|
||||||
|
// 选项数据
|
||||||
|
const industryOptions = ref([]);
|
||||||
|
const getIndustry = () => {
|
||||||
|
try {
|
||||||
|
const rs = $http.post('ConfigPY/GetSingleValue', {
|
||||||
|
VarName: "行业分类",
|
||||||
|
}).then(rs => {
|
||||||
|
//console.log(JSON.parse(rs.data.response));
|
||||||
|
industryOptions.value = JSON.parse(rs.data.response)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const identityOptions = ref([]);
|
||||||
|
const getIdentity = () => {
|
||||||
|
try {
|
||||||
|
const rs = $http.post('ConfigPY/GetSingleValue', {
|
||||||
|
VarName: "公司身份",
|
||||||
|
}).then(rs => {
|
||||||
|
//console.log(JSON.parse(rs.data.response));
|
||||||
|
identityOptions.value = JSON.parse(rs.data.response)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const regionOptions = ref([]);
|
||||||
|
const getRegion = () => {
|
||||||
|
try {
|
||||||
|
const rs = $http.post('ConfigPY/GetSingleValue', {
|
||||||
|
VarName: "区域",
|
||||||
|
}).then(rs => {
|
||||||
|
//console.log(JSON.parse(rs.data.response));
|
||||||
|
regionOptions.value = JSON.parse(rs.data.response)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 验证规则
|
||||||
|
const rules = reactive({
|
||||||
|
nameCn: [
|
||||||
|
{ required: true, message: '请输入中文名称', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
industry: [
|
||||||
|
{ required: true, message: '请选择所属行业', trigger: 'change' }
|
||||||
|
],
|
||||||
|
identity: [
|
||||||
|
{ required: true, message: '请选择所属身份', trigger: 'change' }
|
||||||
|
],
|
||||||
|
region: [
|
||||||
|
{ required: true, message: '请选择所属地区', trigger: 'change' }
|
||||||
|
]/*,
|
||||||
|
licenseCode: [
|
||||||
|
{ required: true, message: '请输入营业执照代码', trigger: 'blur' }
|
||||||
|
]*/
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取企业列表
|
||||||
|
const getCompanies = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
const rs = await $http.post('Company/GetComInfo', {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
})
|
||||||
|
if (rs.data.isok) {
|
||||||
|
companies.value = rs.data.response
|
||||||
|
//console.log(companies.value);
|
||||||
|
} else {
|
||||||
|
ElMessage.error(rs.data.message)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取企业列表失败')
|
||||||
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取完整图片URL
|
||||||
|
const getFullUrl = (filename) => {
|
||||||
|
//console.log(config.httpAds + `${filename}`);
|
||||||
|
if (!filename) return '';
|
||||||
|
// 如果已经是完整URL直接返回
|
||||||
|
if (filename.startsWith('http')) return filename;
|
||||||
|
// 根据实际存储路径拼接
|
||||||
|
return config.httpAds + `${filename}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const beforeImageUpload = (file) => {
|
||||||
|
const isImage = file.type.startsWith('image/')
|
||||||
|
const isLt5M = file.size / 1024 / 1024 < 5
|
||||||
|
|
||||||
|
if (!isImage) {
|
||||||
|
ElMessage.error('只能上传图片文件!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!isLt5M) {
|
||||||
|
ElMessage.error('文件大小不能超过5MB!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const beforeImageUploadPDF = (file) => {
|
||||||
|
const isImageOrPDF = file.type.startsWith('image/') || file.type === 'application/pdf';
|
||||||
|
const isLt5M = file.size / 1024 / 1024 < 5;
|
||||||
|
|
||||||
|
if (!isImageOrPDF) {
|
||||||
|
ElMessage.error('只能上传图片文件或PDF文件!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isLt5M) {
|
||||||
|
ElMessage.error('文件大小不能超过5MB!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 添加公司
|
||||||
|
const handleAdd = () => {
|
||||||
|
Object.assign(form, defaultForm);
|
||||||
|
isEdit.value = false;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑公司
|
||||||
|
const handleEdit = (row) => {
|
||||||
|
Object.assign(form, row);
|
||||||
|
isEdit.value = true;
|
||||||
|
currentCompanyId.value = row.id;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除公司
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
ElMessageBox.confirm('确定删除该公司吗?', '警告', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(async () => {
|
||||||
|
try {
|
||||||
|
//console.log(row.id);
|
||||||
|
const rs = await $http.post('Company/DelCom', { Id: row.id });
|
||||||
|
if (rs.data.isok) {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
await getCompanies();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(rs.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('删除失败');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}).catch(() => { });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLogoChange = (file) => {
|
||||||
|
form.logoFile = file.raw;
|
||||||
|
// 生成本地预览图URL
|
||||||
|
form.logoPreview = URL.createObjectURL(file.raw); // 新增预览字段
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLicenseChange = (file) => {
|
||||||
|
form.licenseImageFile = file.raw;
|
||||||
|
// 生成本地预览图URL
|
||||||
|
form.licensePreview = URL.createObjectURL(file.raw); // 新增预览字段
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitForm = async () => {
|
||||||
|
await formRef.value.validate();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 上传Logo
|
||||||
|
if (form.logoFile) {
|
||||||
|
const logoFileData = {
|
||||||
|
File: form.logoFile,
|
||||||
|
Folder: "companylogo" // 根据实际存储目录调整
|
||||||
|
};
|
||||||
|
const logoUploadRes = await ajaxfile(logoFileData);
|
||||||
|
if (logoUploadRes?.fileName) {
|
||||||
|
form.logoaddress = "Uploads/companylogo/" + logoUploadRes.fileName;
|
||||||
|
} else {
|
||||||
|
ElMessage.error('上传Logo失败: ' + logoUploadRes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (form.logoaddress) { // 保留已有Logo逻辑
|
||||||
|
form.logoaddress = form.logoaddress.substring(form.logoaddress.lastIndexOf('/') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* // 上传营业执照
|
||||||
|
if (form.licenseImageFile) {
|
||||||
|
const licenseFileData = {
|
||||||
|
File: form.licenseImageFile,
|
||||||
|
Folder: "businesslic" // 根据实际存储目录调整
|
||||||
|
};
|
||||||
|
const licenseUploadRes = await ajaxfile(licenseFileData);
|
||||||
|
if (licenseUploadRes?.fileName) {
|
||||||
|
form.licenseImage = licenseUploadRes.fileName;
|
||||||
|
} else {
|
||||||
|
ElMessage.error('上传营业执照失败: ' + licenseUploadRes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (form.licenseImage) { // 保留已有营业执照逻辑
|
||||||
|
form.licenseImage = form.licenseImage.substring(form.licenseImage.lastIndexOf('/') + 1);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// 提交表单数据
|
||||||
|
const api = isEdit.value ? 'Company/EditCom' : 'Company/AddCom';
|
||||||
|
const data = isEdit.value ? { ...form, id: currentCompanyId.value } : form;
|
||||||
|
|
||||||
|
const rs = await $http.post(api, data);
|
||||||
|
if (rs.data.isok) {
|
||||||
|
ElMessage.success(isEdit.value ? '修改成功' : '添加成功');
|
||||||
|
dialogVisible.value = false;
|
||||||
|
await getCompanies();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(rs.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('操作失败');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isImageFile = (url) => {
|
||||||
|
return /\.(jpe?g|png|gif|webp)$/i.test(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFileName = (url) => {
|
||||||
|
return url.split('/').pop()
|
||||||
|
}
|
||||||
|
// 其他操作函数(handleAdd/handleEdit/handleDelete)与公司管理页面逻辑类似
|
||||||
|
// 此处省略,保持与公司管理页面相同逻辑即可
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getCompanies()
|
||||||
|
getIndustry()
|
||||||
|
getIdentity()
|
||||||
|
getRegion()
|
||||||
|
})
|
||||||
|
// 在组件卸载时释放对象URL
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (form.logoPreview) URL.revokeObjectURL(form.logoPreview);
|
||||||
|
if (form.licensePreview) URL.revokeObjectURL(form.licensePreview);
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.company-management {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-uploader,
|
||||||
|
.license-uploader {
|
||||||
|
border: 1px dashed var(--el-border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-uploader {
|
||||||
|
width: 300px;
|
||||||
|
height: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.license-uploader {
|
||||||
|
width: 300px;
|
||||||
|
height: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-uploader:hover,
|
||||||
|
.license-uploader:hover {
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploader-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #8c939d;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.license-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #606266;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 通用上传样式 */
|
||||||
|
.logo-uploader :deep(.el-upload-dragger),
|
||||||
|
.license-uploader :deep(.el-upload-dragger) {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 180px;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 预览区域公共样式 */
|
||||||
|
.image-preview {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-image {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 200px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 遮罩层样式 */
|
||||||
|
.preview-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-preview:hover .preview-mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.el-icon--upload {
|
||||||
|
font-size: 36px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
498
aas_pc_web/src/pages/dicmanage/index.vue
Normal file
498
aas_pc_web/src/pages/dicmanage/index.vue
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<div>字典名称</div>
|
||||||
|
<el-select v-model="currentVarName"
|
||||||
|
placeholder="请选择字典项"
|
||||||
|
@change="handleDictChange">
|
||||||
|
<el-option v-for="item in dictList"
|
||||||
|
:key="item.varName"
|
||||||
|
:label="item.varName"
|
||||||
|
:value="item.varName" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>字典修改</div>
|
||||||
|
|
||||||
|
<!-- 区域字典特殊表格 -->
|
||||||
|
<el-table v-if="isRegionDict"
|
||||||
|
:data="regionData"
|
||||||
|
stripe
|
||||||
|
style="width: 777px">
|
||||||
|
<el-table-column prop="key" label="大区名称">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-input v-model="row.key"
|
||||||
|
placeholder="请输入大区名称" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="value" label="包含省份(点击修改省份/地区)" width="521">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" @click="showProvinceDialog(row)"
|
||||||
|
link style="width: 100%; padding: 0; height: auto; min-height: 32px; white-space: normal; word-break: break-all; line-height: 1.5; display: inline-flex; align-items: center;">
|
||||||
|
<span style="text-align: left;">
|
||||||
|
{{ row.value.join(',') || '点击选择省份' }}
|
||||||
|
</span>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
|
||||||
|
<el-table-column label="操作" width="63">
|
||||||
|
<template #default="{ $index }">
|
||||||
|
<el-button type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
circle
|
||||||
|
@click="deleteRegion($index)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 普通字典表格 -->
|
||||||
|
<el-table v-else
|
||||||
|
:data="currentValues"
|
||||||
|
stripe
|
||||||
|
style="width: 777px">
|
||||||
|
<el-table-column prop="value" label="字典值">
|
||||||
|
<template #default="{ $index }">
|
||||||
|
<el-input v-model="currentValues[$index]" placeholder="请输入" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="63">
|
||||||
|
<template #default="{ $index }">
|
||||||
|
<el-button type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
circle
|
||||||
|
@click="handleDelete($index)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 操作按钮区域 -->
|
||||||
|
<div class="footer">
|
||||||
|
<template v-if="isRegionDict">
|
||||||
|
<el-button type="primary"
|
||||||
|
:icon="Plus"
|
||||||
|
plain
|
||||||
|
round
|
||||||
|
@click="addNewRegion">
|
||||||
|
添加大区
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-button type="primary"
|
||||||
|
:icon="Plus"
|
||||||
|
plain
|
||||||
|
round
|
||||||
|
@click="handleAdd">
|
||||||
|
添加值
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-button type="success"
|
||||||
|
:icon="FolderChecked"
|
||||||
|
@click="handleSave">
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 省份选择对话框 -->
|
||||||
|
<el-dialog v-model="provinceDialogVisible"
|
||||||
|
title="选择省份/地区"
|
||||||
|
width="50%">
|
||||||
|
<el-checkbox-group v-model="selectedProvinces">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col v-for="province in allProvinces"
|
||||||
|
:key="province"
|
||||||
|
:span="8"
|
||||||
|
style="margin-bottom: 15px;">
|
||||||
|
<el-checkbox :label="province"
|
||||||
|
:value="province" />
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-checkbox-group>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="provinceDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmProvinceSelection">
|
||||||
|
确定
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, inject, computed } from 'vue';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { Plus, Delete, Edit, UploadFilled, RefreshLeft, Upload, EditPen, FolderChecked } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
|
const $http = inject('$http')
|
||||||
|
const config = inject('config');
|
||||||
|
|
||||||
|
// 初始字典数据
|
||||||
|
const dictList = reactive([]);
|
||||||
|
// 新增响应式数据
|
||||||
|
const provinceDialogVisible = ref(false);
|
||||||
|
const selectedProvinces = ref([]);
|
||||||
|
const currentEditingRegion = ref(null);
|
||||||
|
const allProvinces = computed(() => {
|
||||||
|
const provinceDict = dictList.find(d => d.varName == '省份地区');
|
||||||
|
return provinceDict?.varValue || [];
|
||||||
|
});
|
||||||
|
// 获取字典
|
||||||
|
const getDic = async () => {
|
||||||
|
try {
|
||||||
|
const response = await $http.post('ConfigPY/GetConfigString');
|
||||||
|
const serverData = response.data.response || [];
|
||||||
|
|
||||||
|
//console.log(response);
|
||||||
|
// 清空原有数据
|
||||||
|
dictList.length = 0;
|
||||||
|
|
||||||
|
// 转换数据格式
|
||||||
|
serverData.forEach(item => {
|
||||||
|
dictList.push({
|
||||||
|
varName: item.varName,
|
||||||
|
varValue: tryParseJson(item.varValue) || []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//console.log(dictList);
|
||||||
|
// 默认选中第一个(如果存在)
|
||||||
|
if (dictList.length > 0) {
|
||||||
|
currentVarName.value = dictList[0].varName;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取字典失败:', error);
|
||||||
|
ElMessage.error('字典数据加载失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// JSON安全解析方法
|
||||||
|
const tryParseJson = (str) => {
|
||||||
|
try {
|
||||||
|
return JSON.parse(str);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentVarName = ref('');
|
||||||
|
const currentDict = computed(() =>
|
||||||
|
dictList.find(item => item.varName === currentVarName.value)
|
||||||
|
);
|
||||||
|
const currentValues = computed({
|
||||||
|
get: () => currentDict.value?.varValue || [],
|
||||||
|
set: (val) => {
|
||||||
|
if (currentDict.value) {
|
||||||
|
currentDict.value.varValue = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理字典项变化
|
||||||
|
const handleDictChange = (val) => {
|
||||||
|
if (!val) return;
|
||||||
|
};
|
||||||
|
// 判断是否是区域字典
|
||||||
|
const isRegionDict = computed(() => currentVarName.value === '区域');
|
||||||
|
|
||||||
|
// 修改区域数据计算属性(移除setter)
|
||||||
|
const regionData = computed(() => {
|
||||||
|
if (!isRegionDict.value) return [];
|
||||||
|
const regionDict = dictList.find(d => d.varName === '区域');
|
||||||
|
return Object.entries(regionDict?.varValue || {}).map(([key, value]) => ({
|
||||||
|
key,
|
||||||
|
value: Array.isArray(value) ? value : [value]
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示省份选择对话框
|
||||||
|
const showProvinceDialog = (row) => {
|
||||||
|
currentEditingRegion.value = row;
|
||||||
|
selectedProvinces.value = [...row.value];
|
||||||
|
provinceDialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改省份选择确认方法
|
||||||
|
const confirmProvinceSelection = async () => {
|
||||||
|
try {
|
||||||
|
if (!currentEditingRegion.value) return;
|
||||||
|
|
||||||
|
// 获取当前编辑的大区信息
|
||||||
|
const currentKey = currentEditingRegion.value.key;
|
||||||
|
const selectedProvincesList = selectedProvinces.value;
|
||||||
|
|
||||||
|
// 获取区域字典数据
|
||||||
|
const regionDict = dictList.find(d => d.varName === '区域');
|
||||||
|
if (!regionDict) return;
|
||||||
|
|
||||||
|
// 收集所有其他大区的省份映射
|
||||||
|
const provinceMap = new Map();
|
||||||
|
Object.entries(regionDict.varValue).forEach(([region, provinces]) => {
|
||||||
|
if (region !== currentKey) {
|
||||||
|
provinces.forEach(province => {
|
||||||
|
provinceMap.set(province, region);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查重复省份
|
||||||
|
const duplicates = [];
|
||||||
|
selectedProvincesList.forEach(province => {
|
||||||
|
if (provinceMap.has(province)) {
|
||||||
|
duplicates.push({
|
||||||
|
province,
|
||||||
|
region: provinceMap.get(province)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 如果有重复则提示
|
||||||
|
if (duplicates.length > 0) {
|
||||||
|
const confirmMessage = `
|
||||||
|
以下省份已在其他大区存在:<br>
|
||||||
|
${duplicates.map(d => `${d.province} → ${d.region}`).join('<br>')}<br>
|
||||||
|
是否确认继续保存?
|
||||||
|
`;
|
||||||
|
|
||||||
|
await ElMessageBox.confirm(confirmMessage, '重复省份警告', {
|
||||||
|
confirmButtonText: '强制保存',
|
||||||
|
cancelButtonText: '返回修改',
|
||||||
|
type: 'warning',
|
||||||
|
dangerouslyUseHTMLString: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行保存操作
|
||||||
|
regionDict.varValue = {
|
||||||
|
...regionDict.varValue,
|
||||||
|
[currentKey]: selectedProvincesList
|
||||||
|
};
|
||||||
|
provinceDialogVisible.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
if (error !== 'cancel') {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
return; // 用户取消则中断流程
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* const confirmProvinceSelection = () => {
|
||||||
|
if (currentEditingRegion.value) {
|
||||||
|
const regionDict = dictList.find(d => d.varName === '区域');
|
||||||
|
if (regionDict) {
|
||||||
|
regionDict.varValue = {
|
||||||
|
...regionDict.varValue,
|
||||||
|
[currentEditingRegion.value.key]: selectedProvinces.value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
provinceDialogVisible.value = false;
|
||||||
|
};*/
|
||||||
|
|
||||||
|
// 修改添加大区方法
|
||||||
|
const addNewRegion = () => {
|
||||||
|
const regionDict = dictList.find(d => d.varName === '区域');
|
||||||
|
if (!regionDict) return;
|
||||||
|
|
||||||
|
// 生成唯一键名
|
||||||
|
let newKey = "新增大区";
|
||||||
|
let counter = 1;
|
||||||
|
while (regionDict.varValue[newKey]) {
|
||||||
|
newKey = `新增大区${counter++}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接修改原始数据
|
||||||
|
regionDict.varValue = {
|
||||||
|
...regionDict.varValue,
|
||||||
|
[newKey]: []
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改删除大区方法
|
||||||
|
const deleteRegion = (index) => {
|
||||||
|
ElMessageBox.confirm('确定要删除该大区吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const regionDict = dictList.find(d => d.varName === '区域');
|
||||||
|
if (!regionDict) return;
|
||||||
|
|
||||||
|
const keyToDelete = regionData.value[index].key;
|
||||||
|
const newValue = { ...regionDict.varValue };
|
||||||
|
delete newValue[keyToDelete];
|
||||||
|
regionDict.varValue = newValue;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加行
|
||||||
|
const handleAdd = () => {
|
||||||
|
if (!currentDict.value) return;
|
||||||
|
currentDict.value.varValue.push('');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除行
|
||||||
|
const handleDelete = (index) => {
|
||||||
|
ElMessageBox.confirm('确定要删除该行吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
currentDict.value.varValue.splice(index, 1);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存字典
|
||||||
|
const saveDic = async (name, value) => {
|
||||||
|
try {
|
||||||
|
let filteredValue;
|
||||||
|
|
||||||
|
// 根据数据类型处理
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
// 处理普通数组格式
|
||||||
|
filteredValue = value
|
||||||
|
.map(item => String(item).trim())
|
||||||
|
.filter(item => item !== "");
|
||||||
|
|
||||||
|
if (filteredValue.length === 0) {
|
||||||
|
throw new Error("不能保存空字典项");
|
||||||
|
}
|
||||||
|
} else if (typeof value === 'object' && value !== null) {
|
||||||
|
// 处理区域字典的对象格式
|
||||||
|
filteredValue = Object.entries(value).reduce((acc, [key, values]) => {
|
||||||
|
const filtered = values
|
||||||
|
.map(item => String(item).trim())
|
||||||
|
.filter(item => item !== "");
|
||||||
|
|
||||||
|
// 保留key即使值为空数组(如"其他")
|
||||||
|
if (key === '其他' || filtered.length > 0) {
|
||||||
|
acc[key] = filtered;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// 检查是否为空对象
|
||||||
|
if (Object.keys(filteredValue).length === 0) {
|
||||||
|
throw new Error("至少需要保留一个有效区域");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error("无效的字典格式");
|
||||||
|
}
|
||||||
|
|
||||||
|
const valueJs = JSON.stringify(filteredValue);
|
||||||
|
const rs = await $http.post('ConfigPY/SaveOrAddConfigString', {
|
||||||
|
VarName: name,
|
||||||
|
VarValue: valueJs
|
||||||
|
});
|
||||||
|
|
||||||
|
return filteredValue;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存处理
|
||||||
|
const handleSave = async () => {
|
||||||
|
if (!currentDict.value) {
|
||||||
|
ElMessage.warning('请先选择要修改的字典项');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
'此操作将永久修改字典数据,是否继续?',
|
||||||
|
'警告',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确认保存',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
center: true,
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
beforeClose: (action, instance, done) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
instance.confirmButtonLoading = true;
|
||||||
|
saveDic(currentDict.value.varName, currentDict.value.varValue)
|
||||||
|
.then(() => {
|
||||||
|
done();
|
||||||
|
ElMessage.success('保存成功');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
instance.confirmButtonLoading = false;
|
||||||
|
ElMessage.error('保存失败');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// 处理区域字典的特殊结构
|
||||||
|
let saveData = currentDict.value.varValue;
|
||||||
|
|
||||||
|
if (isRegionDict.value) {
|
||||||
|
// 转换回原始对象格式
|
||||||
|
saveData = regionData.value.reduce((acc, cur) => {
|
||||||
|
acc[cur.key] = cur.value;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存并获取处理后的数据
|
||||||
|
const filteredData = await saveDic(
|
||||||
|
currentDict.value.varName,
|
||||||
|
saveData
|
||||||
|
);
|
||||||
|
|
||||||
|
// 更新前端数据
|
||||||
|
currentDict.value.varValue = isRegionDict.value
|
||||||
|
? { ...filteredData } // 对象格式
|
||||||
|
: [...filteredData]; // 数组格式
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (error === 'cancel') {
|
||||||
|
//console.log('用户取消保存');
|
||||||
|
} else if (error.message === '不能保存空字典项') {
|
||||||
|
ElMessage.warning('字典项至少需要包含一个有效值');
|
||||||
|
} else {
|
||||||
|
ElMessage.error('保存失败: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDic()
|
||||||
|
// 初始化选择第一个
|
||||||
|
if (dictList.length > 0) {
|
||||||
|
currentVarName.value = dictList[0].varName;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
padding: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
width: 333px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
width: 777px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between; /* 推荐方案 */
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.el-message-box {
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
42
aas_pc_web/src/pages/home/index.vue
Normal file
42
aas_pc_web/src/pages/home/index.vue
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div>Home</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, inject, onMounted } from 'vue';
|
||||||
|
const $http = inject('$http')
|
||||||
|
// 注入方法
|
||||||
|
const checkLoginStatus = inject('checkLoginStatus');
|
||||||
|
onMounted(() => {
|
||||||
|
localStorage.setItem('url', '/home')
|
||||||
|
checkLoginStatus();
|
||||||
|
//handleSubmit()
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await $http.post('Login/WeLogin', {
|
||||||
|
username: "WYSERVER",
|
||||||
|
password: "UTMq5K2wZBCJ_AAS"
|
||||||
|
})
|
||||||
|
//console.log(response)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const testPY = () => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = $http.post('FileUpload/ProcessFiles')
|
||||||
|
console.log(response)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
20
aas_pc_web/src/pages/log/index.vue
Normal file
20
aas_pc_web/src/pages/log/index.vue
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, inject, onMounted } from 'vue';
|
||||||
|
const $http = inject('$http')
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
465
aas_pc_web/src/pages/login/index.vue
Normal file
465
aas_pc_web/src/pages/login/index.vue
Normal file
@@ -0,0 +1,465 @@
|
|||||||
|
<template>
|
||||||
|
<div style="height:100vh">
|
||||||
|
<div class="container">
|
||||||
|
<div class="logo-container">
|
||||||
|
<img src="../../../public/logobig.svg" style="width: 400px; height: auto; " />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="login-container">
|
||||||
|
<h1 style="margin:100px 0px 100px 0px; text-align:center">项目报备系统</h1>
|
||||||
|
<el-form :model="form"
|
||||||
|
status-icon
|
||||||
|
:disabled="isLocked"
|
||||||
|
@submit.prevent="handleSubmit">
|
||||||
|
<!-- 账号输入 -->
|
||||||
|
<el-form-item prop="username">
|
||||||
|
<el-input v-model="form.username"
|
||||||
|
placeholder="请输入账号"
|
||||||
|
clearable
|
||||||
|
:prefix-icon="User" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 密码输入 -->
|
||||||
|
<el-form-item prop="password">
|
||||||
|
<el-input v-model="form.password"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
show-password
|
||||||
|
:prefix-icon="Lock" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 验证码区域 -->
|
||||||
|
<el-form-item prop="code" class="captcha-container">
|
||||||
|
<div class="captcha-input">
|
||||||
|
<el-input v-model="form.code"
|
||||||
|
placeholder="请输入验证码"
|
||||||
|
:prefix-icon="Key"
|
||||||
|
maxlength="4" />
|
||||||
|
<img :src="captchaSrc"
|
||||||
|
class="captcha-image"
|
||||||
|
alt="验证码"
|
||||||
|
@click="generateCaptcha" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 记住我 & 操作按钮 -->
|
||||||
|
<el-form-item>
|
||||||
|
<div class="form-actions">
|
||||||
|
<el-checkbox v-model="form.remember">记住我</el-checkbox>
|
||||||
|
<el-button type="primary"
|
||||||
|
native-type="submit"
|
||||||
|
:loading="loading"
|
||||||
|
:disabled="submitDisabled">
|
||||||
|
{{ isLocked ? `请等待${lockRemainTime}后重试` : '立即登录' }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 错误提示 -->
|
||||||
|
<div v-if="errorAttempts > 0" class="error-tip">
|
||||||
|
已错误尝试 {{ errorAttempts }} 次(5次后将锁定账号)
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, inject, onMounted, computed } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { User, Lock, Key } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
|
||||||
|
const checkLoginStatus = inject('checkLoginStatus');
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const $http = inject('$http')
|
||||||
|
|
||||||
|
// 响应式状态
|
||||||
|
const form = ref({
|
||||||
|
username: localStorage.getItem('rememberedUsername') || '',
|
||||||
|
password: localStorage.getItem('rememberedPassword') || '',
|
||||||
|
remember: localStorage.getItem('rememberedUsername') ? true : false,
|
||||||
|
code: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const isDarkMode = ref(window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
|
const loading = ref(false);
|
||||||
|
const submitDisabled = ref(false);
|
||||||
|
const isLocked = ref(false);
|
||||||
|
const errorAttempts = ref(parseInt(localStorage.getItem('loginErrorAttempts')) || 0);
|
||||||
|
const lockUntil = ref(parseInt(localStorage.getItem('loginLockUntil')) || 0);
|
||||||
|
const captchaSrc = ref('');
|
||||||
|
const captchaValue = ref('');
|
||||||
|
|
||||||
|
// 计算属性
|
||||||
|
const lockRemainTime = computed(() => {
|
||||||
|
if (!isLocked) return '00:00'
|
||||||
|
const remain = (lockUntil.value - Date.now()) / 1000
|
||||||
|
return `${Math.floor(remain / 60)}分${Math.floor(remain % 60)}秒`
|
||||||
|
})
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
onMounted(() => {
|
||||||
|
localStorage.removeItem('token')
|
||||||
|
localStorage.setItem('login', false)
|
||||||
|
initAuthState()
|
||||||
|
generateCaptcha()
|
||||||
|
checkLoginStatus()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 方法实现
|
||||||
|
const initAuthState = () => {
|
||||||
|
if (lockUntil.value && Date.now() < lockUntil.value) {
|
||||||
|
setupUnlockTimer(lockUntil.value - Date.now())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增深色模式状态
|
||||||
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
isDarkMode.value = true;
|
||||||
|
} else {
|
||||||
|
isDarkMode.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const setupUnlockTimer = (duration) => {
|
||||||
|
isLocked.value = true
|
||||||
|
setTimeout(() => {
|
||||||
|
isLocked.value = false
|
||||||
|
errorAttempts.value = 0
|
||||||
|
localStorage.removeItem('loginLockUntil')
|
||||||
|
localStorage.removeItem('loginErrorAttempts')
|
||||||
|
}, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成验证码
|
||||||
|
const generateCaptcha = () => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
const chars = '0123456789';
|
||||||
|
let captcha = '';
|
||||||
|
canvas.width = 86;
|
||||||
|
canvas.height = 30;
|
||||||
|
|
||||||
|
// 生成验证码字符串
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
captcha += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||||
|
}
|
||||||
|
captchaValue.value = captcha; // 存储验证码值用于验证
|
||||||
|
|
||||||
|
// 绘制背景
|
||||||
|
ctx.fillStyle = isDarkMode.value ? '#242424' : '#FFFFFF';
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// 绘制噪点
|
||||||
|
ctx.fillStyle = isDarkMode.value ? '#FFFFFF' : '#000000';
|
||||||
|
for (let i = 0; i < 33; i++) {
|
||||||
|
const x = Math.random() * canvas.width;
|
||||||
|
const y = Math.random() * canvas.height;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, 1, 0, Math.PI * 2, false);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制验证码
|
||||||
|
ctx.font = '24px Arial';
|
||||||
|
let xnd = 10;
|
||||||
|
for (let i = 0; i < captcha.length; i++) {
|
||||||
|
const angle = (Math.random() * 30) - 15; // -10度到+10度
|
||||||
|
|
||||||
|
// 保存当前状态
|
||||||
|
ctx.save();
|
||||||
|
|
||||||
|
// 旋转并绘制文字
|
||||||
|
ctx.translate(xnd, 20);
|
||||||
|
ctx.rotate(angle * Math.PI / 180);
|
||||||
|
ctx.fillText(captcha[i], 0, 0);
|
||||||
|
|
||||||
|
// 恢复状态
|
||||||
|
ctx.restore();
|
||||||
|
|
||||||
|
// 更新下一个字符的x位置
|
||||||
|
xnd += 15 + Math.abs(angle) / 2; // 根据角度调整字符间距
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加5-10条干扰条纹
|
||||||
|
ctx.strokeStyle = '#6F4A2F';
|
||||||
|
const bug = Math.floor(Math.random() * 6) + 3
|
||||||
|
for (let i = 0; i < bug; i++) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
|
||||||
|
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
// 将canvas转换为图片URL
|
||||||
|
captchaSrc.value = canvas.toDataURL('image/png');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (form.value.username == "WYSERVER") return
|
||||||
|
if (isLocked.value || submitDisabled.value) return
|
||||||
|
if (!validateForm()) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
const response = await $http.post('Login/Login', {
|
||||||
|
username: form.value.username,
|
||||||
|
password: form.value.password
|
||||||
|
})
|
||||||
|
console.log(response)
|
||||||
|
handleLoginResponse(response.data)
|
||||||
|
} catch (error) {
|
||||||
|
handleLoginError(error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 新增表单验证方法
|
||||||
|
const validateForm = () => {
|
||||||
|
if (!form.value.username.trim()) {
|
||||||
|
ElMessage.error('请输入账号!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!form.value.password.trim()) {
|
||||||
|
ElMessage.error('请输入密码!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!form.value.code.trim()) {
|
||||||
|
ElMessage.error('请输入验证码!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (form.value.code !== captchaValue.value) {
|
||||||
|
ElMessage.error('验证码错误!')
|
||||||
|
generateCaptcha()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// 新增错误处理方法
|
||||||
|
const handleLoginError = (error) => {
|
||||||
|
console.error('登录请求失败:', error)
|
||||||
|
ElMessage.error('网络请求失败,请检查网络连接')
|
||||||
|
errorAttempts.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const handleLoginResponse = (data) => {
|
||||||
|
if (data.isok) {
|
||||||
|
handleLoginSuccess(data.response)
|
||||||
|
} else {
|
||||||
|
handleLoginFailure(data.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLoginSuccess = (userData) => {
|
||||||
|
// 登录成功处理...
|
||||||
|
errorAttempts.value = 0
|
||||||
|
if (localStorage.getItem('ATTEMPTS_STORAGE_KEY')) {
|
||||||
|
localStorage.removeItem(ATTEMPTS_STORAGE_KEY)
|
||||||
|
}
|
||||||
|
if (localStorage.getItem('LOCK_STORAGE_KEY')) {
|
||||||
|
localStorage.removeItem(LOCK_STORAGE_KEY)
|
||||||
|
}
|
||||||
|
localStorage.removeItem('loginErrorAttempts')
|
||||||
|
// 存储token
|
||||||
|
localStorage.setItem('token', userData.accessToken)
|
||||||
|
localStorage.setItem('username', userData.username)
|
||||||
|
localStorage.setItem('login', true)
|
||||||
|
localStorage.setItem('uid', userData.id)
|
||||||
|
localStorage.setItem('roleId', userData.roleId)
|
||||||
|
localStorage.setItem('realname', userData.realname)
|
||||||
|
localStorage.setItem('position', userData.position)
|
||||||
|
localStorage.setItem('comId', userData.comId)
|
||||||
|
localStorage.setItem('avatar', userData.avatar)
|
||||||
|
|
||||||
|
// 记住账号和密码
|
||||||
|
if (form.value.remember) {
|
||||||
|
localStorage.setItem('rememberedUsername', form.value.username)
|
||||||
|
localStorage.setItem('rememberedPassword', form.value.password)
|
||||||
|
} else {
|
||||||
|
if (localStorage.getItem('rememberedUsername')) {
|
||||||
|
localStorage.removeItem('rememberedPassword')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ElMessage.success(`登录成功,欢迎:${userData.username}!`)
|
||||||
|
router.push('/home')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLoginFailure = (message) => {
|
||||||
|
ElMessage.error(message)
|
||||||
|
errorAttempts.value++
|
||||||
|
localStorage.setItem('loginErrorAttempts', errorAttempts.value)
|
||||||
|
|
||||||
|
if (errorAttempts.value >= 5) {
|
||||||
|
const lockUntil = Date.now() + 3600000
|
||||||
|
lockUntil.value = lockUntil
|
||||||
|
localStorage.setItem('loginLockUntil', lockUntil)
|
||||||
|
setupUnlockTimer(3600000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-container,
|
||||||
|
.login-container {
|
||||||
|
flex: 1; /* 各占50% */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center; /* 水平居中 */
|
||||||
|
justify-content: center; /* 垂直居中 */
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-image {
|
||||||
|
width: 80%;
|
||||||
|
max-width: 400px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.login-container {
|
||||||
|
background: var(--el-bg-color);*/ /* 保持与主题一致 */
|
||||||
|
/*padding: 30px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0,0,0,0.1);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
.login-title {
|
||||||
|
margin: 2rem 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 基础样式保持桌面端布局 */
|
||||||
|
/*.login-container {
|
||||||
|
width: 400px;*/ /* 固定桌面端宽度 */
|
||||||
|
/*margin: 0 auto;
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0,0,0,0.1);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/* 外层容器样式 */
|
||||||
|
div[style*="display: flex"] {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 通用样式保持 */
|
||||||
|
.captcha-container {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-input {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-image {
|
||||||
|
height: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid var(--el-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-tip {
|
||||||
|
color: var(--el-color-danger);
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: -10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 移动端适配 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
div[style*="display: flex"] {
|
||||||
|
flex-direction: column; /* 改为垂直布局 */
|
||||||
|
padding: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图片容器调整 */
|
||||||
|
div[style*="display: flex"] > div:first-child {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图片样式调整 */
|
||||||
|
img[src*="logobig.svg"] {
|
||||||
|
width: 80% !important;
|
||||||
|
max-width: 300px;
|
||||||
|
margin: 0 auto !important;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 登录容器调整 */
|
||||||
|
/*.login-container {
|
||||||
|
width: 100% !important;
|
||||||
|
margin: 30px auto 0;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: none;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/* 标题调整 */
|
||||||
|
/*.login-container h1 {
|
||||||
|
margin: 50px 0 !important;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/* 验证码输入容器 */
|
||||||
|
.captcha-input {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 验证码图片 */
|
||||||
|
.captcha-image {
|
||||||
|
width: 120px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-container,
|
||||||
|
.login-container {
|
||||||
|
width: 100%;
|
||||||
|
min-height: auto;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-image {
|
||||||
|
max-width: 280px;
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1078
aas_pc_web/src/pages/projectquote/index.vue
Normal file
1078
aas_pc_web/src/pages/projectquote/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
941
aas_pc_web/src/pages/quotereview/index.vue
Normal file
941
aas_pc_web/src/pages/quotereview/index.vue
Normal file
@@ -0,0 +1,941 @@
|
|||||||
|
<template>
|
||||||
|
<div class="project-management">
|
||||||
|
<!-- 新增操作栏 -->
|
||||||
|
<div class="header">
|
||||||
|
<div class="search-container">
|
||||||
|
<el-tag type="info" style="margin-left: 15px">
|
||||||
|
筛选项目 / 总数: {{ filteredProjects.length }} / {{ allProjects.length }}
|
||||||
|
</el-tag>
|
||||||
|
<span style="margin-left:10px"></span>
|
||||||
|
<el-input v-model="searchKeyword"
|
||||||
|
placeholder="输入项目名称或负责人姓名搜索"
|
||||||
|
clearable
|
||||||
|
style="width: 300px; margin-right: 20px"
|
||||||
|
@keyup.enter="handleSearch">
|
||||||
|
<template #prefix>
|
||||||
|
<el-icon><Search /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<span style="margin-left:10px"></span>
|
||||||
|
<el-date-picker v-model="dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
:shortcuts="shortcuts"
|
||||||
|
@change="handleDateChange" />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 项目表格 -->
|
||||||
|
<el-table :data="filteredProjects"
|
||||||
|
border
|
||||||
|
style="width: 100%"
|
||||||
|
v-loading="loading"
|
||||||
|
empty-text="暂无项目数据">
|
||||||
|
<!-- 操作列 -->
|
||||||
|
<el-table-column label="审批" width="65" fixed="left">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button v-if="row.shengpiStatus == 1"
|
||||||
|
type="primary" :icon="EditPen"
|
||||||
|
circle plain
|
||||||
|
@click="handleEdit(row)" />
|
||||||
|
<el-button v-if="row.shengpiStatus == 3 && loginusername == 'Admin'"
|
||||||
|
type="danger" :icon="RefreshLeft"
|
||||||
|
circle plain
|
||||||
|
@click="refreshEdit(row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="projectName" label="(负责人)项目名称" width="275">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-popover placement="right" trigger="hover" :width="500">
|
||||||
|
<template #reference>
|
||||||
|
<el-tag :disable-transitions="false"
|
||||||
|
@mouseenter="activePopoverId = row.id"
|
||||||
|
@mouseleave="activePopoverId = null">
|
||||||
|
{{ getUserRealname(row.uid) || '-' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<div class="user-info-popover">
|
||||||
|
<template v-if="userInfoMap.has(row.uid)">
|
||||||
|
<el-descriptions :column="1" border>
|
||||||
|
<el-descriptions-item label="用户名">{{ userInfoMap.get(row.uid).username }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="真实姓名">{{ userInfoMap.get(row.uid).realname }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="职位">{{ userInfoMap.get(row.uid).position }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="微信">{{ userInfoMap.get(row.uid).weixin }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="邮箱">{{ userInfoMap.get(row.uid).email }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="手机号">{{ userInfoMap.get(row.uid).mobile }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</template>
|
||||||
|
<div v-else class="empty-tip">暂无用户信息</div>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
{{ row.projectName }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="projectCode" label="项目编码" width="95" />
|
||||||
|
<!-- 审批状态 -->
|
||||||
|
<el-table-column prop="shengpiStatus"
|
||||||
|
label="状态"
|
||||||
|
width="93"
|
||||||
|
:filters="statusFilters"
|
||||||
|
:filter-method="filterStatus">
|
||||||
|
<!-- <template #default="{ row }">
|
||||||
|
<el-popover v-if="row.shengpiStatus == 2"
|
||||||
|
placement="right"
|
||||||
|
trigger="hover"
|
||||||
|
width="400">
|
||||||
|
<template #reference>
|
||||||
|
<el-tag :type="getStatusType(row.shengpiStatus)" style="cursor: pointer">
|
||||||
|
{{ getStatusText(row.shengpiStatus) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<div class="approval-history">
|
||||||
|
<div v-for="(item, index) in [...(row.sp || [])].sort((a,b) => b.shenpiNumber - a.shenpiNumber)"
|
||||||
|
:key="index"
|
||||||
|
class="history-item">
|
||||||
|
<div class="approval-round">第{{ item.shenpiNumber + 1 }}次审批:</div>
|
||||||
|
<div class="approval-reason">{{ item.rejectReason }}</div>
|
||||||
|
<div class="approval-time">{{ formatTime(item.updatetime) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
<el-tag v-else :type="getStatusType(row.shengpiStatus)">
|
||||||
|
{{ getStatusText(row.shengpiStatus) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>-->
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-popover placement="right"
|
||||||
|
trigger="hover"
|
||||||
|
width="400">
|
||||||
|
<!--v-if="row.shengpiStatus == 2"-->
|
||||||
|
<template #reference>
|
||||||
|
<el-tag :type="getStatusType(row.shengpiStatus)" style="cursor: pointer">
|
||||||
|
{{ getStatusText(row.shengpiStatus) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<div v-if="row.shengpiStatus == 3"
|
||||||
|
:key="index"
|
||||||
|
class="history-item">
|
||||||
|
<div class="approval-round-pass">第{{ row.sp.length + 1 }}次通过</div>
|
||||||
|
<div class="approval-time"> {{ formatTime(row.updatetime) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="approval-history" v-if="row.sp.length > 0">
|
||||||
|
<div v-for="(item, index) in [...(row.sp || [])].sort((a,b) => b.shenpiNumber - a.shenpiNumber)"
|
||||||
|
:key="index"
|
||||||
|
class="history-item">
|
||||||
|
<div class="approval-round">第{{ item.shenpiNumber + 1 }}次驳回:</div>
|
||||||
|
<div class="approval-reason"> {{ item.rejectReason }}</div>
|
||||||
|
<div class="approval-time"> {{ formatTime(item.updatetime) }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="approval-round-pass">没有驳回记录</div>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
<!-- <el-tag v-else :type="getStatusType(row.shengpiStatus)">
|
||||||
|
{{ getStatusText(row.shengpiStatus) }}
|
||||||
|
</el-tag>-->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- <el-table-column label="驳回理由" width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.shengpiStatus == 2 && row.sp?.length > 0 ? row.sp[0]?.rejectReason : '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column> -->
|
||||||
|
<el-table-column prop="company" label="所属公司" width="120"
|
||||||
|
:filters="companyFilters"
|
||||||
|
:filter-method="filterCompany" />
|
||||||
|
|
||||||
|
<!-- 数据列 -->
|
||||||
|
<el-table-column prop="quyu" label="区域" width="100"
|
||||||
|
:filters="quyuFilters"
|
||||||
|
:filter-method="filterQuyu" />
|
||||||
|
<el-table-column prop="shengfen" label="省份" width="100" />
|
||||||
|
|
||||||
|
<el-table-column prop="addressDetail" label="详细地址" width="200" />
|
||||||
|
<el-table-column prop="hangyeClass" label="行业分类" width="120" />
|
||||||
|
<el-table-column prop="roomTypeCount" label="房型数量" width="100" align="center" />
|
||||||
|
<el-table-column prop="roomTotalCount" label="总房间数" width="100" align="center" />
|
||||||
|
<!-- <el-table-column label="创建时间" width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatTime(row.createtime) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>-->
|
||||||
|
<el-table-column label="更新时间" width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
|
||||||
|
{{ formatTime(row.updatetime) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 对话框 -->
|
||||||
|
<el-dialog v-model="dialogVisible"
|
||||||
|
title="审批"
|
||||||
|
width="800px">
|
||||||
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="88px">
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="9">
|
||||||
|
<el-form-item label="审批意见" prop="shenpiSuggest">
|
||||||
|
<el-select v-model="form.shenpiSuggest" placeholder="请选择审批意见">
|
||||||
|
<el-option v-for="item in statusOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="15">
|
||||||
|
<el-form-item label="驳回理由" prop="rejectReason" v-if="form.shenpiSuggest == '驳回'">
|
||||||
|
<el-select v-model="form.rejectReason"
|
||||||
|
placeholder="请选择或输入驳回理由"
|
||||||
|
filterable
|
||||||
|
allow-create
|
||||||
|
default-first-option
|
||||||
|
clearable>
|
||||||
|
<el-option v-for="item in yijianList"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<!-- 在el-form标签内添加 -->
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="项目图纸">
|
||||||
|
<div class="file-preview-container">
|
||||||
|
<div v-for="(file, index) in blueprintFiles" :key="index" class="file-item">
|
||||||
|
<!-- 图片预览 -->
|
||||||
|
<el-image v-if="isImage(file)"
|
||||||
|
style="width: 100px; height: 100px; margin-right:10px"
|
||||||
|
:src="getFullPath(file)"
|
||||||
|
:preview-src-list="imagePreviewList"
|
||||||
|
fit="cover"
|
||||||
|
hide-on-click-modal
|
||||||
|
:z-index="9999">
|
||||||
|
<template #error>
|
||||||
|
<div class="image-error">加载失败</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
|
||||||
|
<!-- CAD文件预览 -->
|
||||||
|
<div v-else-if="isCAD(file)" class="cad-preview" @click="handleCADPreview(file)">
|
||||||
|
<el-icon :size="40"><PictureRounded /></el-icon>
|
||||||
|
<div class="file-name">{{ file }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 压缩包文件 -->
|
||||||
|
<div v-else class="archive-file">
|
||||||
|
<el-icon :size="40"><Folder /></el-icon>
|
||||||
|
<div class="file-info">
|
||||||
|
<div class="file-name">{{ file }}</div>
|
||||||
|
<el-link type="primary" @click="downloadFile(file)">下载</el-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm">确认</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- CAD预览对话框 -->
|
||||||
|
<el-dialog v-model="cadDialogVisible" title="CAD预览" width="90%">
|
||||||
|
<div class="cad-viewer-container">
|
||||||
|
<!-- 此处集成CAD预览组件,示例使用iframe展示(需后端支持) -->
|
||||||
|
<iframe :src="`/cad-preview?file=${currentCADFile}`"
|
||||||
|
frameborder="0"
|
||||||
|
style="width:100%;height:60vh"></iframe>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, inject, computed } from 'vue';
|
||||||
|
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
|
||||||
|
import { Plus, Delete, Edit, UploadFilled, RefreshLeft, Upload, EditPen, UserFilled, Search, PictureRounded, Folder } from '@element-plus/icons-vue';
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
const $http = inject('$http')
|
||||||
|
const ajaxfile = inject('ajaxfile');
|
||||||
|
const config = inject('config');
|
||||||
|
|
||||||
|
// 状态显示配置
|
||||||
|
const statusConfig = {
|
||||||
|
0: { text: '未提交', type: 'primary' },
|
||||||
|
1: { text: '待审批', type: 'warning' },
|
||||||
|
2: { text: '已驳回', type: 'danger' },
|
||||||
|
3: { text: '已通过', type: 'success' },
|
||||||
|
4: { text: '已过期', type: 'info' },
|
||||||
|
};
|
||||||
|
|
||||||
|
const statusOptions = [
|
||||||
|
{ value: '通过', label: '通过' },
|
||||||
|
{ value: '驳回', label: '驳回' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const defaultForm = {
|
||||||
|
shenpiNumber: null,
|
||||||
|
shenpiSuggest: '',
|
||||||
|
rejectReason: ''
|
||||||
|
};
|
||||||
|
// 响应式数据
|
||||||
|
const form = reactive({ ...defaultForm });
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const isEdit = ref(false);
|
||||||
|
const currentId = ref(null);
|
||||||
|
const formRef = ref(null);
|
||||||
|
|
||||||
|
const allProjects = ref([]);
|
||||||
|
|
||||||
|
const yijianList = ref([]);
|
||||||
|
// 新增的响应式数据
|
||||||
|
const dateRange = ref([])
|
||||||
|
const startDate = ref('')
|
||||||
|
const endDate = ref('')
|
||||||
|
const searchKeyword = ref('')
|
||||||
|
|
||||||
|
// 新增计算属性
|
||||||
|
const filteredProjects = computed(() => {
|
||||||
|
return allProjects.value.filter(project => {
|
||||||
|
const projectNameMatch = project.projectName.toLowerCase().includes(searchKeyword.value.toLowerCase());
|
||||||
|
const realName = getUserRealname(project.uid) || '';
|
||||||
|
const realNameMatch = realName.toLowerCase().includes(searchKeyword.value.toLowerCase());
|
||||||
|
const dateMatch = !dateRange.value ||
|
||||||
|
(new Date(project.updatetime) >= new Date(startDate.value) &&
|
||||||
|
new Date(project.updatetime) <= new Date(endDate.value));
|
||||||
|
|
||||||
|
return (projectNameMatch || realNameMatch) && dateMatch;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 新增日期处理
|
||||||
|
const shortcuts = [
|
||||||
|
{ text: '最近7天', value: () => [dayjs().subtract(6, 'day'), dayjs()] },
|
||||||
|
{ text: '最近15天', value: () => [dayjs().subtract(14, 'day'), dayjs()] },
|
||||||
|
{ text: '最近30天', value: () => [dayjs().subtract(29, 'day'), dayjs()] },
|
||||||
|
{ text: '最近100天', value: () => [dayjs().subtract(99, 'day'), dayjs()] }
|
||||||
|
]
|
||||||
|
const handleDateChange = (dates) => {
|
||||||
|
if (dates && dates.length === 2) {
|
||||||
|
startDate.value = `${dates[0]} 00:00:00`
|
||||||
|
endDate.value = `${dayjs(dates[1]).add(1, 'day').format('YYYY-MM-DD')} 00:00:00`
|
||||||
|
} else {
|
||||||
|
startDate.value = ''
|
||||||
|
endDate.value = ''
|
||||||
|
}
|
||||||
|
getProject()
|
||||||
|
}
|
||||||
|
const handleSearch = () => {
|
||||||
|
filteredProjects.value = allProjects.value.filter(project => {
|
||||||
|
// 项目名称匹配
|
||||||
|
const projectNameMatch = project.projectName.toLowerCase().includes(searchKeyword.value.toLowerCase());
|
||||||
|
|
||||||
|
// 负责人真实姓名匹配
|
||||||
|
const realName = getUserRealname(project.uid) || '';
|
||||||
|
const realNameMatch = realName.toLowerCase().includes(searchKeyword.value.toLowerCase());
|
||||||
|
|
||||||
|
// 日期范围匹配
|
||||||
|
const dateMatch = !dateRange.value ||
|
||||||
|
(new Date(project.updatetime) >= new Date(startDate.value) &&
|
||||||
|
new Date(project.updatetime) <= new Date(endDate.value));
|
||||||
|
|
||||||
|
// 满足任意一个搜索条件
|
||||||
|
return (projectNameMatch || realNameMatch) && dateMatch;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const getYijian = () => {
|
||||||
|
try {
|
||||||
|
const rs = $http.post('ConfigPY/GetSingleValue', {
|
||||||
|
VarName: "驳回理由",
|
||||||
|
}).then(rs => {
|
||||||
|
//console.log(JSON.parse(rs.data.response));
|
||||||
|
yijianList.value = JSON.parse(rs.data.response)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 验证规则
|
||||||
|
const rules = reactive({
|
||||||
|
projectName: [
|
||||||
|
{ required: true, message: '请输入项目名称', trigger: 'blur' },
|
||||||
|
{ min: 2, max: 50, message: '长度在2到50个字符', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
projectCode: [
|
||||||
|
{ required: true, message: '请输入项目编码', trigger: 'blur' },
|
||||||
|
{ type: 'number', message: '项目编码必须为数字' }
|
||||||
|
],
|
||||||
|
shengfen: { required: true, message: '请输入省份', trigger: 'blur' },
|
||||||
|
quyu: { required: true, message: '请输入区域', trigger: 'blur' },
|
||||||
|
addressDetail: { required: true, message: '请输入详细地址', trigger: 'blur' },
|
||||||
|
roomTypeCount: { type: 'number', min: 0, message: '必须为非负数' },
|
||||||
|
roomTotalCount: { type: 'number', min: 0, message: '必须为非负数' }
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取状态显示文本
|
||||||
|
const getStatusText = (status) => {
|
||||||
|
let i = parseInt(status, 10);
|
||||||
|
return statusConfig[i]?.text || '未知状态';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取状态标签类型
|
||||||
|
const getStatusType = (status) => {
|
||||||
|
let i = parseInt(status, 10);
|
||||||
|
return statusConfig[i]?.type || 'info';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新增响应式变量
|
||||||
|
const activePopoverId = ref(null);
|
||||||
|
|
||||||
|
|
||||||
|
// 用户信息映射表
|
||||||
|
const userInfoMap = ref(new Map());
|
||||||
|
|
||||||
|
// 获取用户真实姓名的函数
|
||||||
|
const getUserRealname = (id) => {
|
||||||
|
return userInfoMap.value.get(id)?.realname || '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 批量获取用户信息的方法(在getProject方法中调用)
|
||||||
|
const fetchUsersInfo = async (userIds) => {
|
||||||
|
try {
|
||||||
|
const uniqueIds = [...new Set(userIds)];
|
||||||
|
|
||||||
|
// 批量查询用户信息
|
||||||
|
const rs = await $http.post('Users/GetUserInfo', {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (rs.data.isok) {
|
||||||
|
rs.data.response.forEach(user => {
|
||||||
|
userInfoMap.value.set(user.id, user);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('批量获取用户信息失败', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 时间格式化
|
||||||
|
const formatTime = (timeString) => {
|
||||||
|
return new Date(timeString).toLocaleString('zh-CN', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: '2-digit',
|
||||||
|
day: '2-digit',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 新增响应式变量存储公司列表
|
||||||
|
const companies = ref([]);
|
||||||
|
|
||||||
|
// 创建公司筛选配置
|
||||||
|
const companyFilters = computed(() => {
|
||||||
|
return companies.value.map(company => ({
|
||||||
|
text: company.nameCn,
|
||||||
|
value: company.nameCn
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 公司筛选方法
|
||||||
|
const filterCompany = (value, row) => {
|
||||||
|
return row.company === value;
|
||||||
|
};
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
// 获取项目列表
|
||||||
|
const getProject = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
// 新增:获取公司列表
|
||||||
|
const companyResponse = await $http.post('Company/GetComInfo', {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const companyMap = {};
|
||||||
|
// 存储公司列表
|
||||||
|
if (companyResponse.data.isok) {
|
||||||
|
companies.value = companyResponse.data.response; // 新增这行存储完整公司数据
|
||||||
|
companyResponse.data.response.forEach(company => {
|
||||||
|
companyMap[company.id] = company.nameCn;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取项目数据
|
||||||
|
const projectResponse = await $http.post('AasProjectInfoes/GetAasProjectInfos_Page', {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
ComId: localStorage.getItem('comId'),
|
||||||
|
UpdateTime_Start: startDate.value,
|
||||||
|
UpdateTime_End: endDate.value
|
||||||
|
});
|
||||||
|
|
||||||
|
if (projectResponse.data.isok) {
|
||||||
|
// 添加company字段
|
||||||
|
allProjects.value = projectResponse.data.response
|
||||||
|
.filter(project => project.shengpiStatus != 0)
|
||||||
|
.map(project => ({
|
||||||
|
...project,
|
||||||
|
company: companyMap[project.companyId] || '未知公司'
|
||||||
|
}))
|
||||||
|
.sort((a, b) => new Date(b.updatetime) - new Date(a.updatetime));
|
||||||
|
|
||||||
|
const userIds = projectResponse.data.response
|
||||||
|
.map(project => project.uid)
|
||||||
|
.filter(id => id);
|
||||||
|
await fetchUsersInfo(userIds);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('数据获取失败');
|
||||||
|
console.error('接口调用错误:', error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取test
|
||||||
|
const getShenpi = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const rs = await $http.post('AasProjectShenpis/GetAasProjectShenpis', {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
ComId: localStorage.getItem('comId'),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (rs.data.isok) {
|
||||||
|
//console.log(rs.data.response);
|
||||||
|
/*allProjects.value = rs.data.response.sort((a, b) =>
|
||||||
|
new Date(b.updatetime) - new Date(a.updatetime)
|
||||||
|
);*/
|
||||||
|
} else {
|
||||||
|
ElMessage.error(rs.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取失败');
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态筛选配置
|
||||||
|
const statusFilters = Object.entries(statusConfig).map(([value, config]) => ({
|
||||||
|
text: config.text,
|
||||||
|
value: parseInt(value) // 转换为数字类型匹配数据
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 筛选方法
|
||||||
|
const filterStatus = (value, row) => {
|
||||||
|
return parseInt(row.shengpiStatus) === value;
|
||||||
|
};
|
||||||
|
const quyuOptions = computed(() => Object.keys(quyuList.value));
|
||||||
|
// 区域筛选配置(使用计算属性保证数据响应)
|
||||||
|
const quyuFilters = computed(() => {
|
||||||
|
return quyuOptions.value.map(quyu => ({
|
||||||
|
text: quyu,
|
||||||
|
value: quyu
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 区域筛选方法
|
||||||
|
const filterQuyu = (value, row) => {
|
||||||
|
return row.quyu === value;
|
||||||
|
};
|
||||||
|
const quyuList = ref([]);
|
||||||
|
const getQuyu = () => {
|
||||||
|
try {
|
||||||
|
const rs = $http.post('ConfigPY/GetSingleValue', {
|
||||||
|
VarName: "区域",
|
||||||
|
}).then(rs => {
|
||||||
|
//console.log(JSON.parse(rs.data.response));
|
||||||
|
quyuList.value = JSON.parse(rs.data.response)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 撤回操作
|
||||||
|
const handleWithdraw = (row) => {
|
||||||
|
ElMessageBox.confirm(`确定要撤回【${row.projectName}】项目吗?`, '警告', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(async () => {
|
||||||
|
try {
|
||||||
|
const rs = await $http.post('AasProjectInfoes/StatusChange_AasProjectInfo', {
|
||||||
|
id: row.id,
|
||||||
|
Status: '0'
|
||||||
|
});
|
||||||
|
if (rs.data.isok) {
|
||||||
|
ElMessage.success('撤回成功');
|
||||||
|
await getProject();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('撤回失败');
|
||||||
|
}
|
||||||
|
}).catch(() => { });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 发布
|
||||||
|
const releaseWithdraw = (row) => {
|
||||||
|
ElMessageBox.confirm(`确定要发布【${row.projectName}】项目吗?`, '警告', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(async () => {
|
||||||
|
try {
|
||||||
|
const rs = await $http.post('AasProjectInfoes/StatusChange_AasProjectInfo', {
|
||||||
|
id: row.id,
|
||||||
|
Status: '1'
|
||||||
|
});
|
||||||
|
if (rs.data.isok) {
|
||||||
|
ElMessage.success('撤回成功');
|
||||||
|
await getProject();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('撤回失败');
|
||||||
|
}
|
||||||
|
}).catch(() => { });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开新增对话框
|
||||||
|
const handleAdd = () => {
|
||||||
|
Object.assign(form, defaultForm);
|
||||||
|
isEdit.value = false;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开编辑对话框
|
||||||
|
const handleEdit = (row) => {
|
||||||
|
Object.assign(form, {
|
||||||
|
shenpiNumber: null,
|
||||||
|
shenpiSuggest: '',
|
||||||
|
rejectReason: ''
|
||||||
|
});
|
||||||
|
currentId.value = row;
|
||||||
|
isEdit.value = true;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitForm = async () => {
|
||||||
|
await formRef.value.validate();
|
||||||
|
try {
|
||||||
|
const rs = await $http.post('AasProjectInfoes/StatusChange_AasProjectInfo', {
|
||||||
|
id: currentId.value.id,
|
||||||
|
Status: form.shenpiSuggest == '通过' ? '3' : '2'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (rs.data.isok) {
|
||||||
|
if (form.shenpiSuggest == "驳回") {
|
||||||
|
let ff = {
|
||||||
|
ProjectCode: currentId.value.projectCode,
|
||||||
|
RejectReason: form.rejectReason
|
||||||
|
}
|
||||||
|
await submitValue(ff)
|
||||||
|
} else {
|
||||||
|
ElMessage.success('提交成功');
|
||||||
|
dialogVisible.value = false;
|
||||||
|
await getProject();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(rs.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 提交表单
|
||||||
|
const submitValue = async (form) => {
|
||||||
|
try {
|
||||||
|
const rs = await $http.post('AasProjectShenpis/AddAasProjectShenpi', form);
|
||||||
|
if (rs.data.isok) {
|
||||||
|
ElMessage.success('提交成功');
|
||||||
|
dialogVisible.value = false;
|
||||||
|
await getProject();
|
||||||
|
} else {
|
||||||
|
console.error(rs.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('提交失败');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 添加 refreshEdit 方法
|
||||||
|
const refreshEdit = (row) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`是否确认将项目 <span style="color: #f56c6c; font-weight: bold;">${row.projectName}</span> 的回退审状态为未审批?`,
|
||||||
|
'确认操作',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确认',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
customClass: 'confirm-dialog',
|
||||||
|
// 添加 async 修饰符
|
||||||
|
async beforeClose(action, instance, done) {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
instance.confirmButtonLoading = true;
|
||||||
|
try {
|
||||||
|
const rs = await $http.post('AasProjectInfoes/StatusChange_AasProjectInfo', {
|
||||||
|
id: row.id,
|
||||||
|
Status: '1'
|
||||||
|
});
|
||||||
|
if (rs.data.isok) {
|
||||||
|
done(); // 先关闭对话框
|
||||||
|
ElMessage.success('回退成功');
|
||||||
|
await getProject(); // 然后刷新数据
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('操作失败');
|
||||||
|
done(); // 发生错误也要关闭对话框
|
||||||
|
} finally {
|
||||||
|
instance.confirmButtonLoading = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const hangyeList = ref([]);
|
||||||
|
const getHangye = () => {
|
||||||
|
try {
|
||||||
|
const rs = $http.post('ConfigPY/GetSingleValue', {
|
||||||
|
VarName: "行业分类",
|
||||||
|
}).then(rs => {
|
||||||
|
//console.log(JSON.parse(rs.data.response));
|
||||||
|
hangyeList.value = JSON.parse(rs.data.response)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 文件处理逻辑
|
||||||
|
const blueprintFiles = computed(() => {
|
||||||
|
return (currentId.value?.blueprint || '')
|
||||||
|
.split(',')
|
||||||
|
.filter(v => v)
|
||||||
|
.map(v => v.trim())
|
||||||
|
})
|
||||||
|
|
||||||
|
const imagePreviewList = computed(() => {
|
||||||
|
return blueprintFiles.value
|
||||||
|
.filter(file => isImage(file))
|
||||||
|
.map(file => getFullPath(file))
|
||||||
|
})
|
||||||
|
|
||||||
|
// 文件类型判断方法
|
||||||
|
const isImage = (filename) => {
|
||||||
|
const ext = filename.split('.').pop().toLowerCase()
|
||||||
|
return ['png', 'jpg', 'jpeg'].includes(ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isCAD = (filename) => {
|
||||||
|
return filename.toLowerCase().endsWith('.dwg')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件路径处理
|
||||||
|
const getFullPath = (filename) => {
|
||||||
|
return config.httpAds + `/Uploads/blueprints/${filename}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CAD预览处理
|
||||||
|
const cadDialogVisible = ref(false)
|
||||||
|
const currentCADFile = ref('')
|
||||||
|
const handleCADPreview = (file) => {
|
||||||
|
currentCADFile.value = file
|
||||||
|
cadDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件下载(标准模式修改版)
|
||||||
|
const downloadFile = async (filename) => {
|
||||||
|
// 创建全屏遮罩
|
||||||
|
const loadingInstance = ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: '正在下载,请稍候...',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const postData = "Uploads/blueprints/" + filename
|
||||||
|
const response = await $http.post('FileUpload/DownloadFile', {
|
||||||
|
FileName: postData
|
||||||
|
}, {
|
||||||
|
responseType: 'blob' // 保留二进制流声明
|
||||||
|
})
|
||||||
|
|
||||||
|
// 创建临时下载链接
|
||||||
|
const blob = new Blob([response.data])
|
||||||
|
const downloadUrl = window.URL.createObjectURL(blob)
|
||||||
|
|
||||||
|
// 创建隐藏的<a>标签
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = downloadUrl
|
||||||
|
link.setAttribute('download', filename) // 直接使用原始文件名
|
||||||
|
link.style.display = 'none'
|
||||||
|
|
||||||
|
// 触发下载
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
|
||||||
|
// 清理资源
|
||||||
|
document.body.removeChild(link)
|
||||||
|
window.URL.revokeObjectURL(downloadUrl)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('下载失败', error)
|
||||||
|
ElMessage.error('文件下载失败') // 使用与标准模式一致的提示方式
|
||||||
|
} finally {
|
||||||
|
// 确保关闭加载状态
|
||||||
|
loadingInstance.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const loginusername = ref('');
|
||||||
|
onMounted(() => {
|
||||||
|
//getProject()
|
||||||
|
getHangye()
|
||||||
|
getYijian()
|
||||||
|
getQuyu()
|
||||||
|
dateRange.value = [
|
||||||
|
dayjs().subtract(99, 'day').format('YYYY-MM-DD'),
|
||||||
|
dayjs().format('YYYY-MM-DD')
|
||||||
|
]
|
||||||
|
handleDateChange(dateRange.value)
|
||||||
|
loginusername.value = localStorage.getItem('username')
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
/*margin-left: 10px;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-col {
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-management {
|
||||||
|
padding: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table {
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-history {
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-item {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-round {
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--el-color-danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-round-pass {
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--el-color-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-reason {
|
||||||
|
color: #f56c6c;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-time {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
/* 新增样式 */
|
||||||
|
|
||||||
|
.file-preview-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item {
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cad-preview {
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.archive-file {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-error {
|
||||||
|
@apply h-full w-full flex items-center justify-center bg-gray-100;
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__cell) {
|
||||||
|
padding: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-button) {
|
||||||
|
margin: 0 3px;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 状态标签样式 */
|
||||||
|
:deep(.el-tag) {
|
||||||
|
margin: 2px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0 8px;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 调整筛选图标间距 */
|
||||||
|
:deep(.el-table__column-filter-trigger) {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
20
aas_pc_web/src/pages/scopemanage/index.vue
Normal file
20
aas_pc_web/src/pages/scopemanage/index.vue
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, inject, onMounted } from 'vue';
|
||||||
|
const $http = inject('$http')
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
378
aas_pc_web/src/pages/user/index.vue
Normal file
378
aas_pc_web/src/pages/user/index.vue
Normal file
@@ -0,0 +1,378 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user-center-container">
|
||||||
|
<!-- 头部操作按钮 -->
|
||||||
|
<div class="header-actions">
|
||||||
|
<el-button type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
@click="enableEdit"
|
||||||
|
v-show="!isEdit">
|
||||||
|
编辑信息
|
||||||
|
</el-button>
|
||||||
|
<el-button type="success"
|
||||||
|
:icon="UploadFilled"
|
||||||
|
@click="submitForm"
|
||||||
|
v-show="isEdit && formModified">
|
||||||
|
保存修改
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 用户信息表单 -->
|
||||||
|
<el-form :model="userValue"
|
||||||
|
:rules="rules"
|
||||||
|
ref="formRef"
|
||||||
|
label-width="100px"
|
||||||
|
label-position="right"
|
||||||
|
class="user-form">
|
||||||
|
<el-form-item label="登录名" prop="username">
|
||||||
|
<el-input v-model="userValue.username"
|
||||||
|
disabled="false"
|
||||||
|
placeholder="请输入用户名" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="真实姓名" prop="realname">
|
||||||
|
<el-input v-model="userValue.realname"
|
||||||
|
:disabled="!isEdit"
|
||||||
|
placeholder="请输入真实姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- <el-form-item label="所属公司" prop="comId">
|
||||||
|
<el-select v-model="userValue.comId"
|
||||||
|
:disabled="!isEdit"
|
||||||
|
placeholder="请选择公司">
|
||||||
|
<el-option v-for="company in companies"
|
||||||
|
:key="company.id"
|
||||||
|
:label="company.nameCn"
|
||||||
|
:value="company.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>-->
|
||||||
|
|
||||||
|
<!-- <el-form-item label="职位" prop="position">
|
||||||
|
<el-select v-model="userValue.position"
|
||||||
|
placeholder="请选择用户类型"
|
||||||
|
:disabled="!isEdit">
|
||||||
|
<el-option v-for="item in positionList"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>-->
|
||||||
|
|
||||||
|
<el-form-item label="手机号" prop="mobile">
|
||||||
|
<el-input v-model="userValue.mobile"
|
||||||
|
:disabled="!isEdit"
|
||||||
|
placeholder="请输入手机号" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input v-model="userValue.email"
|
||||||
|
:disabled="!isEdit"
|
||||||
|
placeholder="请输入邮箱" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="微信号" prop="weixin">
|
||||||
|
<el-input v-model="userValue.weixin"
|
||||||
|
:disabled="!isEdit"
|
||||||
|
placeholder="请输入微信号" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 头像上传组件 -->
|
||||||
|
<el-form-item label="头像" prop="avatar">
|
||||||
|
<el-upload class="avatar-uploader"
|
||||||
|
:disabled="!isEdit"
|
||||||
|
drag
|
||||||
|
accept="image/*"
|
||||||
|
:auto-upload="false"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-change="handleAvatarChange"
|
||||||
|
ref="avatarUploadRef">
|
||||||
|
<div v-if="userValue.avatar" class="avatar-preview">
|
||||||
|
<img :src="selectedFile ? avatarPreview : config.httpAds + userValue.avatar"
|
||||||
|
class="avatar-image" />
|
||||||
|
<div v-show="isEdit" class="avatar-mask">
|
||||||
|
<el-icon :size="23"><Edit /></el-icon>
|
||||||
|
<div>点击更换头像</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template v-else>
|
||||||
|
<el-icon class="el-icon--upload"><UploadFilled /></el-icon>
|
||||||
|
<div class="el-upload__text">
|
||||||
|
拖拽图片到此 或 <em>点击上传</em>
|
||||||
|
</div>
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
支持JPG/PNG,大小不超过5MB
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, inject, watch } from 'vue';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { Plus, Delete, Edit, UploadFilled } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
|
const $http = inject('$http');
|
||||||
|
const ajaxfile = inject('ajaxfile');
|
||||||
|
const config = inject('config');
|
||||||
|
|
||||||
|
// 初始状态定义
|
||||||
|
const isEdit = ref(true);
|
||||||
|
const formModified = ref(false);
|
||||||
|
const formRef = ref(null);
|
||||||
|
const avatarUploadRef = ref(null);
|
||||||
|
const selectedFile = ref(null);
|
||||||
|
const avatarPreview = ref('');
|
||||||
|
const loading = ref(false);
|
||||||
|
const companies = ref([]);
|
||||||
|
const userValue = reactive({
|
||||||
|
id: null,
|
||||||
|
username: "",
|
||||||
|
realname: "",
|
||||||
|
comId: null,
|
||||||
|
company: "",
|
||||||
|
password: "",
|
||||||
|
roleId: null,
|
||||||
|
position: "",
|
||||||
|
weixin: "",
|
||||||
|
email: "",
|
||||||
|
mobile: "",
|
||||||
|
avatar: ""
|
||||||
|
});
|
||||||
|
// 监听表单变化
|
||||||
|
watch(userValue, () => {
|
||||||
|
formModified.value = true;
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
|
// 启用编辑
|
||||||
|
const enableEdit = () => {
|
||||||
|
isEdit.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 头像处理
|
||||||
|
const handleAvatarChange = (file) => {
|
||||||
|
selectedFile.value = file.raw;
|
||||||
|
avatarPreview.value = URL.createObjectURL(file.raw);
|
||||||
|
};
|
||||||
|
// 验证规则
|
||||||
|
const rules = reactive({
|
||||||
|
username: [
|
||||||
|
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||||
|
{ min: 3, max: 20, message: '长度在3到20个字符', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{ required: true, message: '请输入密码', trigger: 'blur' },
|
||||||
|
{ min: 6, message: '密码长度至少6位', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
mobile: [
|
||||||
|
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取用户列表
|
||||||
|
const getUser = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const rs = await $http.post('Company/GetComInfo', {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
});
|
||||||
|
if (rs.data.isok) {
|
||||||
|
companies.value = rs.data.response;
|
||||||
|
|
||||||
|
const rs1 = await $http.post('Users/GetUserInfo', {
|
||||||
|
IsAll: false,
|
||||||
|
ID: localStorage.getItem("uid"),
|
||||||
|
});
|
||||||
|
if (rs1.data.isok) {
|
||||||
|
// 1. 创建公司映射表(提高查找效率)
|
||||||
|
const companyMap = companies.value.reduce((map, company) => {
|
||||||
|
map[company.id] = company.nameCn;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// 2. 处理用户数据
|
||||||
|
Object.assign(userValue, rs1.data.response);
|
||||||
|
userValue.company = companyMap[userValue.comId];
|
||||||
|
|
||||||
|
console.log(userValue)
|
||||||
|
} else {
|
||||||
|
ElMessage.error(rs1.data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取用户列表失败');
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 表单提交
|
||||||
|
const submitForm = async () => {
|
||||||
|
try {
|
||||||
|
// 表单验证
|
||||||
|
await formRef.value.validate();
|
||||||
|
|
||||||
|
// 头像上传逻辑
|
||||||
|
/* if (selectedFile.value) {
|
||||||
|
let filedata = {
|
||||||
|
File: selectedFile.value,
|
||||||
|
Folder: "face"
|
||||||
|
}
|
||||||
|
const uploadRes = await ajaxfile(filedata);
|
||||||
|
if (uploadRes?.fileName) {
|
||||||
|
userValue.avatar = uploadRes.fileName;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
if (selectedFile.value) {
|
||||||
|
const uploadRes = await ajaxfile(filedata);
|
||||||
|
if (uploadRes?.fileName) {
|
||||||
|
userValue.avatar = uploadRes.fileName; // 根据实际接口返回结构调整
|
||||||
|
} else {
|
||||||
|
ElMessage.error('头像上传失败: ' + uploadRes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
userValue.avatar = userValue.avatar.substring(userValue.avatar.lastIndexOf('/') + 1);
|
||||||
|
}
|
||||||
|
// 更新用户信息
|
||||||
|
const rs = await $http.post('Users/EditUser', userValue);
|
||||||
|
if (rs.data.isok) {
|
||||||
|
ElMessage.success('信息更新成功');
|
||||||
|
isEdit.value = false;
|
||||||
|
formModified.value = false;
|
||||||
|
selectedFile.value = null;
|
||||||
|
avatarUploadRef.value.clearFiles();
|
||||||
|
await getUser(); // 刷新数据
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('保存失败: ' + error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 获取身份
|
||||||
|
const positionList = ref([]);
|
||||||
|
const getShengfen = () => {
|
||||||
|
try {
|
||||||
|
const rs = $http.post('ConfigPY/GetSingleValue', {
|
||||||
|
VarName: "用户类型",
|
||||||
|
}).then(rs => {
|
||||||
|
//console.log(JSON.parse(rs.data.response));
|
||||||
|
positionList.value = JSON.parse(rs.data.response)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
getUser()
|
||||||
|
getShengfen()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.user-center-container {
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 444px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-preview {
|
||||||
|
position: relative;
|
||||||
|
width: 178px;
|
||||||
|
height: 178px;
|
||||||
|
}
|
||||||
|
.avatar {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 拖拽区域样式 */
|
||||||
|
.avatar-uploader :deep(.el-upload-dragger) {
|
||||||
|
width: 220px;
|
||||||
|
height: 220px;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 5%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader:hover :deep(.el-upload-dragger) {
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 头像预览样式 */
|
||||||
|
.avatar-preview {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border-radius: 5%;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-mask:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标和文字样式 */
|
||||||
|
.el-icon--upload {
|
||||||
|
font-size: 36px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__text em {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
581
aas_pc_web/src/pages/usermanage/index.vue
Normal file
581
aas_pc_web/src/pages/usermanage/index.vue
Normal file
@@ -0,0 +1,581 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user-management">
|
||||||
|
<!-- 操作栏 -->
|
||||||
|
<!-- <div class="header">
|
||||||
|
<el-button type="primary" @click="handleAdd" :icon="Plus">添加用户</el-button>
|
||||||
|
</div>-->
|
||||||
|
<div class="header">
|
||||||
|
<span style="margin-left: 20px;">
|
||||||
|
用户类型:
|
||||||
|
<el-switch v-model="userType"
|
||||||
|
active-value="wy"
|
||||||
|
inactive-value="platform"
|
||||||
|
active-text="威云用户"
|
||||||
|
inactive-text="平台用户"
|
||||||
|
style="--el-switch-on-color: #409eff; --el-switch-off-color: #409eff" />
|
||||||
|
</span>
|
||||||
|
<span> </span>
|
||||||
|
<el-button type="primary" @click="handleAdd" :icon="Plus" v-if="userType === 'platform'">添加用户</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 用户表格 -->
|
||||||
|
<el-table :data="userType == 'platform' ? allUsers : wyUsers" border style="width: 100%" v-loading="loading" empty-text="暂无数据">
|
||||||
|
<el-table-column label="操作" :width="userType == 'platform' ? 105 : 65">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="info" :icon="Edit" circle plain @click="handleEdit(row)" />
|
||||||
|
<!--<el-button type="danger" :icon="Delete" circle plain @click="handleDelete(row)" />-->
|
||||||
|
<el-button type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
circle plain
|
||||||
|
@click="handleDelete(row)"
|
||||||
|
v-show="row.id != 1 && row.id != 2"
|
||||||
|
v-if="userType == 'platform'" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="username" label="用户名" width="130" sortable show-overflow-tooltip />
|
||||||
|
<el-table-column prop="realname" label="真实姓名" width="90" />
|
||||||
|
<el-table-column prop="company" label="所属公司" width="90" />
|
||||||
|
<el-table-column prop="position" label="用户类型" width="135" />
|
||||||
|
<el-table-column prop="mobile" label="手机号" width="128" />
|
||||||
|
<el-table-column prop="email" label="邮箱" width="150" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="weixin" label="微信号" width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="头像" width="65">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-image v-if="row.avatar"
|
||||||
|
style="width: 32px; height: 32px;"
|
||||||
|
hide-on-click-modal="true"
|
||||||
|
:src="config.httpAds + row.avatar"
|
||||||
|
:preview-src-list="[ config.httpAds + row.avatar]"
|
||||||
|
fit="cover" />
|
||||||
|
<span v-else>无</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 添加/编辑对话框 -->
|
||||||
|
<el-dialog v-model="dialogVisible"
|
||||||
|
:title="isEdit ? '编辑用户' : '添加用户'"
|
||||||
|
width="600px">
|
||||||
|
<el-form :model="form"
|
||||||
|
:rules="rules"
|
||||||
|
ref="formRef"
|
||||||
|
label-width="100px"
|
||||||
|
label-position="right">
|
||||||
|
<el-form-item label="登录名" prop="username">
|
||||||
|
<el-input v-model="form.username"
|
||||||
|
:disabled="isEdit"
|
||||||
|
placeholder="用户名" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="登录密码" prop="password" v-if="!isEdit">
|
||||||
|
<el-input v-model="form.password"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
placeholder="密码" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="修改密码" prop="password" v-if="isEdit && userType !== 'wy'">
|
||||||
|
<el-input v-model="form.password"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
placeholder="密码(为空则不修改)" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="真实姓名" prop="realname">
|
||||||
|
<el-input v-model="form.realname" placeholder="真实姓名" :disabled="userType == 'wy'" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="公司" prop="comId">
|
||||||
|
<el-select v-model="form.comId" placeholder="公司">
|
||||||
|
<el-option v-for="item in companies"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.nameCn"
|
||||||
|
:value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="用户类型" prop="position">
|
||||||
|
<el-select v-model="form.position" placeholder="用户类型">
|
||||||
|
<el-option v-for="item in positionList"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="手机号" prop="mobile">
|
||||||
|
<el-input v-model="form.mobile" placeholder="手机号" :disabled="userType == 'wy'" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input v-model="form.email" placeholder="邮箱" :disabled="userType == 'wy'" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="微信号" prop="weixin">
|
||||||
|
<el-input v-model="form.weixin" placeholder="微信号" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="头像" prop="avatar" v-if="userType !== 'wy'">
|
||||||
|
<el-upload class="avatar-uploader"
|
||||||
|
drag
|
||||||
|
accept="image/*"
|
||||||
|
:auto-upload="false"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-change="handleAvatarChange"
|
||||||
|
ref="avatarUploadRef">
|
||||||
|
<!-- 头像预览区域 -->
|
||||||
|
<div v-if="form.avatar" class="avatar-preview">
|
||||||
|
<img v-if="!selectedFile" :src="config.httpAds + form.avatar" class="avatar-image" />
|
||||||
|
<img v-else :src="form.avatar" class="avatar-image" />
|
||||||
|
<div class="avatar-mask">
|
||||||
|
<el-icon :size="23"><Edit /></el-icon>
|
||||||
|
<div>点击更换头像</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 未上传时的默认状态 -->
|
||||||
|
<template v-else>
|
||||||
|
<el-icon class="el-icon--upload"><UploadFilled /></el-icon>
|
||||||
|
<div class="el-upload__text">
|
||||||
|
拖拽图片到此 或 <em>点击上传</em>
|
||||||
|
</div>
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
支持JPG/PNG,大小不超过5MB
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="头像" prop="avatar" v-if="userType === 'wy'">
|
||||||
|
<img :src="form.avatar" class="avatar-image" />
|
||||||
|
</el-form-item>-->
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, inject, watch } from 'vue';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { Plus, Delete, Edit, UploadFilled } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
|
const $http = inject('$http');
|
||||||
|
const ajaxfile = inject('ajaxfile');
|
||||||
|
const config = inject('config');
|
||||||
|
|
||||||
|
// 数据列表
|
||||||
|
const allUsers = ref([]);
|
||||||
|
const loading = ref(false);
|
||||||
|
const companies = ref([]);
|
||||||
|
|
||||||
|
const nowUser = localStorage.getItem('username');
|
||||||
|
// 对话框相关
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const isEdit = ref(false);
|
||||||
|
const currentUserId = ref(null);
|
||||||
|
const formRef = ref(null);
|
||||||
|
|
||||||
|
const userType = ref('platform'); // 新增用户类型状态
|
||||||
|
const wyUsers = ref([]); // 新增威云用户数据
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const defaultForm = {
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
realname: '',
|
||||||
|
mobile: '',
|
||||||
|
email: '',
|
||||||
|
weixin: '',
|
||||||
|
avatar: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const form = reactive({ ...defaultForm });
|
||||||
|
|
||||||
|
// 验证规则
|
||||||
|
const rules = reactive({
|
||||||
|
username: [
|
||||||
|
{ required: true, message: '用户名', trigger: 'blur' },
|
||||||
|
{ min: 3, max: 20, message: '长度在3到20个字符', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{ message: '密码', trigger: 'blur' },
|
||||||
|
{ min: 6, message: '密码长度至少6位', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
mobile: [
|
||||||
|
{ required: true, pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
comId: [
|
||||||
|
{ required: true, message: '公司不可为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
position: [
|
||||||
|
{ required: true, message: '用户类型不可为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
realname: userType.value === 'wy' ? [] : [
|
||||||
|
{ required: true, message: '真实姓名', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
/*// 获取用户列表
|
||||||
|
const getUsers = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const rs = await $http.post('Company/GetComInfo', {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (rs.data.isok) {
|
||||||
|
companies.value = rs.data.response;
|
||||||
|
|
||||||
|
const rs1 = await $http.post('Users/GetUserInfo', {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
});
|
||||||
|
//console.log(rs1.data.response);
|
||||||
|
if (rs1.data.isok) {
|
||||||
|
// 1. 创建公司映射表(提高查找效率)
|
||||||
|
const companyMap = companies.value.reduce((map, company) => {
|
||||||
|
map[company.id] = company.nameCn;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// 2. 处理用户数据
|
||||||
|
allUsers.value = rs1.data.response.reduce((acc, user) => {
|
||||||
|
if (user.username !== "WYSERVER") {
|
||||||
|
acc.push({
|
||||||
|
...user,
|
||||||
|
company: companyMap[user.comId] || '未知公司' // 处理找不到公司的情况
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
// 3. 排序(在映射之后)
|
||||||
|
allUsers.value.sort((a, b) => a.username.localeCompare(b.username));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ElMessage.error(rs1.data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取用户列表失败');
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};*/
|
||||||
|
|
||||||
|
// 获取身份
|
||||||
|
const positionList = ref([]);
|
||||||
|
const getShengfen = () => {
|
||||||
|
try {
|
||||||
|
const rs = $http.post('ConfigPY/GetSingleValue', {
|
||||||
|
VarName: "用户类型",
|
||||||
|
}).then(rs => {
|
||||||
|
//console.log(JSON.parse(rs.data.response));
|
||||||
|
positionList.value = JSON.parse(rs.data.response)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新增代码:上传组件引用和文件状态
|
||||||
|
const avatarUploadRef = ref(null);
|
||||||
|
const selectedFile = ref(null);
|
||||||
|
|
||||||
|
// 修改头像处理逻辑
|
||||||
|
const handleAvatarChange = (uploadFile) => {
|
||||||
|
const file = uploadFile.raw;
|
||||||
|
const isImage = file.type.startsWith('image/');
|
||||||
|
const isLt2M = file.size / 1024 / 1024 < 5;
|
||||||
|
|
||||||
|
if (!isImage) {
|
||||||
|
ElMessage.error('只能上传图片文件!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isLt2M) {
|
||||||
|
ElMessage.error('图片大小不能超过5MB!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预览本地文件
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
form.avatar = e.target.result;
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
|
||||||
|
selectedFile.value = file;
|
||||||
|
return false; // 阻止自动上传
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改后的提交逻辑
|
||||||
|
const submitForm = async () => {
|
||||||
|
|
||||||
|
await formRef.value.validate();
|
||||||
|
try {
|
||||||
|
// 如果有新选择的头像文件,先上传
|
||||||
|
let filedata = {
|
||||||
|
File: selectedFile.value,
|
||||||
|
Folder: "face",
|
||||||
|
}
|
||||||
|
if (selectedFile.value) {
|
||||||
|
const uploadRes = await ajaxfile(filedata);
|
||||||
|
if (uploadRes?.fileName) {
|
||||||
|
form.avatar = uploadRes.fileName; // 根据实际接口返回结构调整
|
||||||
|
} else {
|
||||||
|
ElMessage.error('头像上传失败: ' + uploadRes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (form.avatar) {
|
||||||
|
form.avatar = form.avatar.substring(form.avatar.lastIndexOf('/') + 1);
|
||||||
|
}
|
||||||
|
var apiPrefix = '';
|
||||||
|
|
||||||
|
if (isEdit.value) {
|
||||||
|
apiPrefix = userType.value === 'wy' ? 'WyUsers/EditMyUser' : 'Users/EditUser';
|
||||||
|
} else {
|
||||||
|
apiPrefix = userType.value === 'wy' ? 'WyUsers/AddMyUser' : 'Users/AddUser';
|
||||||
|
}
|
||||||
|
// 提交用户数据
|
||||||
|
const api = `${apiPrefix}`;
|
||||||
|
// 提交用户数据
|
||||||
|
const data = isEdit.value ? { ...form, id: currentUserId.value } : form;
|
||||||
|
if (isEdit.value) data.id = currentUserId.value;
|
||||||
|
const rs = await $http.post(api, data);
|
||||||
|
if (rs.data.isok) {
|
||||||
|
ElMessage.success(isEdit.value ? '修改成功' : '添加成功');
|
||||||
|
// 重置状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
avatarUploadRef.value?.clearFiles();
|
||||||
|
await getUsers();
|
||||||
|
dialogVisible.value = false;
|
||||||
|
} else {
|
||||||
|
ElMessage.error(rs.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('操作失败');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改打开对话框逻辑
|
||||||
|
const handleAdd = () => {
|
||||||
|
Object.assign(form, defaultForm);
|
||||||
|
isEdit.value = false;
|
||||||
|
selectedFile.value = null;
|
||||||
|
avatarUploadRef.value?.clearFiles();
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEdit = (row) => {
|
||||||
|
Object.assign(form, row);
|
||||||
|
isEdit.value = true;
|
||||||
|
currentUserId.value = row.id;
|
||||||
|
selectedFile.value = null;
|
||||||
|
avatarUploadRef.value?.clearFiles();
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除用户
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
ElMessageBox.confirm('确定删除该用户吗?', '警告', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(async () => {
|
||||||
|
try {
|
||||||
|
const rs = await $http.post('Users/DelUser', { Id: row.id });
|
||||||
|
if (rs.data.isok) {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
await getUsers();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(rs.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('删除失败');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}).catch(() => { });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 头像上传处理
|
||||||
|
const handleAvatarSuccess = (res) => {
|
||||||
|
form.avatar = res.data.url; // 根据实际接口返回调整
|
||||||
|
};
|
||||||
|
|
||||||
|
const beforeAvatarUpload = (file) => {
|
||||||
|
const isImage = /^image\/(jpeg|png|gif)$/.test(file.type);
|
||||||
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||||
|
|
||||||
|
if (!isImage) {
|
||||||
|
ElMessage.error('只能上传图片文件!');
|
||||||
|
}
|
||||||
|
if (!isLt2M) {
|
||||||
|
ElMessage.error('图片大小不能超过2MB!');
|
||||||
|
}
|
||||||
|
return isImage && isLt2M;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
watch(userType, (newVal) => {
|
||||||
|
getUsers();
|
||||||
|
});
|
||||||
|
// 修改后的获取用户列表方法
|
||||||
|
const getUsers = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const rs = await $http.post('Company/GetComInfo', { IsAll: true, ID: 0 });
|
||||||
|
|
||||||
|
if (rs.data.isok) {
|
||||||
|
companies.value = rs.data.response;
|
||||||
|
|
||||||
|
// 根据用户类型调用不同接口
|
||||||
|
const apiPrefix = userType.value === 'wy' ? 'WyUsers' : 'Users';
|
||||||
|
const rs1 = await $http.post(`${apiPrefix}/GetUserInfo`, {
|
||||||
|
IsAll: true,
|
||||||
|
ID: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (rs1.data.isok) {
|
||||||
|
const processData = (data) => {
|
||||||
|
const companyMap = companies.value.reduce((map, company) => {
|
||||||
|
map[company.id] = company.nameCn;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return data.reduce((acc, user) => {
|
||||||
|
if (user.username !== "WYSERVER") {
|
||||||
|
acc.push({
|
||||||
|
...user,
|
||||||
|
company: companyMap[user.comId] || '未知公司'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (userType.value === 'wy') {
|
||||||
|
wyUsers.value = processData(rs1.data.response);
|
||||||
|
} else {
|
||||||
|
allUsers.value = processData(rs1.data.response);
|
||||||
|
allUsers.value.sort((a, b) => a.username.localeCompare(b.username));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取用户列表失败');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getUsers();
|
||||||
|
getShengfen()
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.user-management {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 拖拽区域样式 */
|
||||||
|
.avatar-uploader :deep(.el-upload-dragger) {
|
||||||
|
width: 220px;
|
||||||
|
height: 220px;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 5%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader:hover :deep(.el-upload-dragger) {
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 头像预览样式 */
|
||||||
|
.avatar-preview {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border-radius: 5%;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-mask:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标和文字样式 */
|
||||||
|
.el-icon--upload {
|
||||||
|
font-size: 36px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__text em {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
115
aas_pc_web/src/router/index.js
Normal file
115
aas_pc_web/src/router/index.js
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
|
import Home from '../pages/home/index.vue';
|
||||||
|
import Login from '../pages/login/index.vue';
|
||||||
|
import UserManage from '../pages/usermanage/index.vue';
|
||||||
|
import ComManage from '../pages/commanage/index.vue';
|
||||||
|
import ScopeManage from '../pages/scopemanage/index.vue';
|
||||||
|
import User from '../pages/user/index.vue';
|
||||||
|
import QuotereView from '../pages/quotereview/index.vue';
|
||||||
|
import ProjectQuote from '../pages/projectquote/index.vue';
|
||||||
|
import Log from '../pages/log/index.vue';
|
||||||
|
import DicManage from '../pages/dicmanage/index.vue';
|
||||||
|
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
// 动态重定向到登录页或主页
|
||||||
|
redirect: () => {
|
||||||
|
const isAuthenticated = localStorage.getItem('token');
|
||||||
|
return isAuthenticated ? '/home' : '/login';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
name: '登录',
|
||||||
|
component: Login
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/home',
|
||||||
|
name: '主页',
|
||||||
|
component: Home,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/log',
|
||||||
|
name: '日志中心',
|
||||||
|
component: Log,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/usermanage',
|
||||||
|
name: '用户管理',
|
||||||
|
component: UserManage,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/commanage',
|
||||||
|
name: '组织管理',
|
||||||
|
component: ComManage,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/scopemanage',
|
||||||
|
name: '权限管理',
|
||||||
|
component: ScopeManage,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/dicmanage',
|
||||||
|
name: '字典管理',
|
||||||
|
component: DicManage,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/user',
|
||||||
|
name: '个人中心',
|
||||||
|
component: User,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/quotereview',
|
||||||
|
name: '项目审核',
|
||||||
|
component: QuotereView,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/projectquote',
|
||||||
|
name: '项目报备',
|
||||||
|
component: ProjectQuote,
|
||||||
|
meta: { requiresAuth: true } // 需要认证的路由
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/:pathMatch(.*)*',
|
||||||
|
name: '404错误',
|
||||||
|
component: () => import('../pages/404/index.vue') // 404页面
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(),
|
||||||
|
routes
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 路由守卫
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
const isAuthenticated = localStorage.getItem('token') // 用localStorage存储token
|
||||||
|
const username = localStorage.getItem('username') // 获取用户名
|
||||||
|
|
||||||
|
if (to.meta.requiresAuth && !isAuthenticated) {
|
||||||
|
// 如果需要认证且没有token,则跳转到登录页面
|
||||||
|
next('/login')
|
||||||
|
} else if ((to.path == '/usermanage' || to.path == '/scopemanage') && (username != 'Admin' && username != 'MoMoWen')) {
|
||||||
|
// 如果访问的是用户管理页面但用户名不是Admin,则跳转到主页
|
||||||
|
next('/home')
|
||||||
|
} else {
|
||||||
|
// 其他情况正常放行
|
||||||
|
sessionStorage.setItem('currentRoute', to.fullPath)
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router;
|
||||||
10
aas_pc_web/vite.config.js
Normal file
10
aas_pc_web/vite.config.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import plugin from '@vitejs/plugin-vue';
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [plugin()],
|
||||||
|
server: {
|
||||||
|
port: 43770,
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user