Browse Source

20250213

main
wxc 12 months ago
parent
commit
e393f3887e
  1. 2
      index.html
  2. 0
      public/a.json
  3. BIN
      public/imgs/video/1.jpg
  4. BIN
      public/imgs/video/2.jpg
  5. BIN
      public/imgs/video/3.jpg
  6. BIN
      public/imgs/video/4.jpg
  7. BIN
      public/imgs/video/5.jpg
  8. 14
      public/imgs/video/地址.txt
  9. 246
      public/js/authen.js
  10. 873
      public/js/pnxclient.js
  11. BIN
      public/mp4/1.mp4
  12. 50
      src/api/rightsComfort/comfort.ts
  13. 4
      src/api/rightsComfort/rights.ts
  14. 7
      src/api/screen/videoSupervise.ts
  15. 7
      src/api/system/police.ts
  16. 35
      src/api/system/rightPerson.ts
  17. 406
      src/components/comfort/dialog.vue
  18. 2
      src/components/icon/index.vue
  19. 44
      src/components/negative/dialog.vue
  20. 5
      src/components/negative/verify.vue
  21. 8
      src/layout/components/Header.vue
  22. 4
      src/router/routes.ts
  23. 5
      src/stores/modules/user.ts
  24. 4
      src/style/public.scss
  25. 86
      src/views/Support.vue
  26. 2
      src/views/books/Hdjq.vue
  27. 398
      src/views/datav/VideoInsp.vue
  28. 9
      src/views/datav/subonedatav/SubOneVideoInsp.vue
  29. 170
      src/views/rightsComfort/Comfort.vue
  30. 891
      src/views/rightsComfort/MyComfort.vue
  31. 167
      src/views/rightsComfort/Rights.vue
  32. 7
      src/views/system/Menu.vue
  33. 14
      src/views/system/Operating.vue
  34. 242
      src/views/system/Police.vue
  35. 265
      src/views/system/Wqzg.vue
  36. 661
      src/views/work/Comfort.vue
  37. 20
      src/views/work/Query.vue

2
index.html

@ -13,5 +13,7 @@
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script src="/js/authen.js"></script>
<script src="/js/pnxclient.js"></script>
</body>
</html>

0
public/a.json

BIN
public/imgs/video/1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

BIN
public/imgs/video/2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

BIN
public/imgs/video/3.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
public/imgs/video/4.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
public/imgs/video/5.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

14
public/imgs/video/地址.txt

@ -0,0 +1,14 @@
1
http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000033.live.flv
2
http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000028.live.flv
3
http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000002.live.flv
4
http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000019.live.flv
5
http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000011.live.flv

246
public/js/authen.js

@ -0,0 +1,246 @@
/* eslint-disable */
var JIT_AUTHEN = function () {
// initParam:PNX初始化参数,数据可从网关系统:认证管理->Key类型管理中导出
var initParam = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<authinfo><liblist>" +
"<lib type=\"CSP\" version=\"1.0\" dllname=\"\" ><algid val=\"SHA1\" sm2_hashalg=\"sm3\"/></lib>" + //软证书
"<lib type=\"SKF\" version=\"1.1\" dllname=\"U0tGQVBJMjAwNzkuZGxs\" ><algid val=\"SHA1\" sm2_hashalg=\"sm3\"/></lib>" + //SKFAPI20079.dll 海泰20079
"</liblist><checkkeytimes><item times=\"1\" ></item></checkkeytimes></authinfo>";
//请求随机数地址
var randomUrl = "/api/jitGWRandom";
//请求p7认证地址
var P7certAuthUrl = "/api/jitGWAuthP7";
//请求p1认证地址
var P1certAuthUrl = "/api/jitGWAuthP1";
return{
InitParam : initParam,
//请求生成随机数
random : function () {
var randomResult = "";
$.ajax({
url : randomUrl,
type : "post",
async: false,
data : "",
success : function (data) {
randomResult= data;
},
error : function () {
},
datatype : "json"
})
return randomResult;
},
//请求p7认证方法
P7certAuth : function (random,signed_data) {
var authResult = "";
$.ajax({
url : P7certAuthUrl,
type : "post",
async: false,
data : {"random":random,"signed_data":signed_data},
success : function (data) {
authResult = data ;
},
error : function () {
},
datatype : "json",
})
return authResult;
},
//请求p1认证
P1certAuth : function (random,signed_data,certBase64,hashAlg) {
var authResult = "";
$.ajax({
url : P1certAuthUrl,
type : "post",
async: false,
data : {"random":random,"signed_data":signed_data,"certBase64":certBase64,"hashAlg":hashAlg},
success : function (data) {
authResult = data ;
},
error : function () {
},
datatype : "json",
})
return authResult;
},
//p7方式签名数据处理
AuthP7Sign: function (random) {
// 调用网关工具脚本中的detachSignStr(P7)进行签名,并返回签名结果
var sign_Result = "";
try {
//用于判断插件是否可用(可选)
JIT_GW_ExtInterface.GetVersion();
} catch (e) {
alert("未安装控件,请进行安装控件");
window.location.href = "/PNXClient.exe";
}
try {
//清理过滤条件(可选)
JIT_GW_ExtInterface.ClearFilter();
// 初始化KEY信息
JIT_GW_ExtInterface.Initialize("", initParam);
// 控制证书为一个时,不弹出证书选择框(可选)
JIT_GW_ExtInterface.SetChooseSingleCert(1);
// 添加过滤条件,颁发者过滤、同DN时SM2优先级设置等(可选)
//同DN情况下优先使用sm2证书
// JIT_GW_ExtInterface.AddFilter(11,"2");
//强制弹PIN码(可选)
//JIT_GW_ExtInterface.SetForcePinDialog(0);
} catch (e) {
alert("调用方法失败:" + JIT_GW_ExtInterface.GetLastErrorMessage());
}
try {
// 原文做P7签名
sign_Result = JIT_GW_ExtInterface.P7SignString(random, true, true);
} catch (e) {
alert("生成签名信息失败:" + JIT_GW_ExtInterface.GetLastErrorMessage());
}
if (JIT_GW_ExtInterface.GetLastError() != 0) {
if (JIT_GW_ExtInterface.GetLastError() == 3758096386 || JIT_GW_ExtInterface.GetLastError() == 2148532334 || JIT_GW_ExtInterface.GetLastError() == 3758096385) {
alert("用户取消操作");
} else if (JIT_GW_ExtInterface.GetLastError() == -536870815 || JIT_GW_ExtInterface.GetLastError() == 3758096481) {
alert("没有找到有效的证书,如果使用的是KEY,请确认已经插入key");
} else {
alert(JIT_GW_ExtInterface.GetLastErrorMessage());
}
}
// 释放签名对象
JIT_GW_ExtInterface.Finalize();
// 返回签名结果
return sign_Result;
},
//p7带下拉框方式的签名数据处理
AuthP7Sign_certSelect : function(authContent, certsn) {
var sign_Result = "";
try {
// 用于判断插件是否可用(可选)
JIT_GW_ExtInterface.GetVersion();
} catch (e) {
alert("未安装控件,请进行安装控件");
window.location.href = "/PNXClient.exe";
}
try {
//清理过滤条件(可选)
JIT_GW_ExtInterface.ClearFilter();
// 初始化KEY信息
JIT_GW_ExtInterface.Initialize("", initParam);
//下拉框参考Cert_Select方法
// 根据SN过滤唯一证书
JIT_GW_ExtInterface.AddFilter(1,certsn);
// 设置单证书不弹出对话框
JIT_GW_ExtInterface.SetChooseSingleCert(1);
//强制弹PIN码(可选)
JIT_GW_ExtInterface.SetForcePinDialog(0);
} catch (e) {
alert("调用方法失败:" + JIT_GW_ExtInterface.GetLastErrorMessage());
}
try {
// 原文做P7签名
sign_Result = JIT_GW_ExtInterface.P7SignString (authContent, true, true);
} catch (e) {
alert("生成签名信息失败:" + JIT_GW_ExtInterface.GetLastErrorMessage());
}
if (JIT_GW_ExtInterface.GetLastError() != 0) {
if (JIT_GW_ExtInterface.GetLastError() == 3758096386
|| JIT_GW_ExtInterface.GetLastError() == 2148532334 || JIT_GW_ExtInterface.GetLastError() == 3758096385) {
alert("用户取消操作");
} else if (JIT_GW_ExtInterface.GetLastError() == -536870815
|| JIT_GW_ExtInterface.GetLastError() == 3758096481) {
alert("没有找到有效的证书,如果使用的是KEY,请确认已经插入key");
} else {
alert(JIT_GW_ExtInterface.GetLastErrorMessage());
}
}
// 释放签名对象
JIT_GW_ExtInterface.Finalize();
// 返回签名结果对象
return sign_Result;
},
//p1带下拉框方式的签名数据处理
AuthP1Sign_certSelect : function(random, certsn, pin) {
var sign_ResultObj = "";
try {
// 用于判断插件是否可用(可选)
JIT_GW_ExtInterface.GetVersion();
} catch (e) {
alert("未安装控件,请进行安装控件");
window.location.href = "/PNXClient.exe";
}
try {
//清理过滤条件(可选)
JIT_GW_ExtInterface.ClearFilter();
// 初始化KEY信息
JIT_GW_ExtInterface.Initialize("", initParam);
} catch (e) {
alert("调用方法失败:" + JIT_GW_ExtInterface.GetLastErrorMessage());
}
//下拉框展示部分参考p1Select方法
try {
// 原文做P1签名
var signobj = JIT_GW_ExtInterface.P1SignWithPin(certsn, pin, random);
sign_ResultObj = JSON.parse(signobj);
if (sign_ResultObj.result != 0) {
if (sign_ResultObj.remainretrycount < 0) {
var errorMessage = JIT_GW_ExtInterface.GetLastErrorMessage();
alert(errorMessage);
} else {
alert("输入的pin码不正确,还剩余" + sign_ResultObj.remainretrycount + "次重试次数");
}
}
} catch (e) {
alert("生成签名信息失败:" + JIT_GW_ExtInterface.GetLastErrorMessage());
}
if (JIT_GW_ExtInterface.GetLastError() != 0) {
if (JIT_GW_ExtInterface.GetLastError() == 3758096386
|| JIT_GW_ExtInterface.GetLastError() == 2148532334 || JIT_GW_ExtInterface.GetLastError() == 3758096385) {
alert("用户取消操作");
} else if (JIT_GW_ExtInterface.GetLastError() == -536870815
|| JIT_GW_ExtInterface.GetLastError() == 3758096481) {
alert("没有找到有效的证书,如果使用的是KEY,请确认已经插入key");
} else {
alert(JIT_GW_ExtInterface.GetLastErrorMessage());
}
}
// 释放签名对象
JIT_GW_ExtInterface.Finalize();
// 返回签名结果对象
return sign_ResultObj;
},
//获取证书列表
getCertList : function () {
// 初始化KEY信息
JIT_GW_ExtInterface.Initialize("",initParam);
// 添加过滤条件,颁发者过滤、同DN时SM2优先级设置等(可选)
//同DN情况下优先使用sm2证书
// JIT_GW_ExtInterface.AddFilter(11,"2");
// 获取证书列表
var cert = JIT_GW_ExtInterface.GetCertList();
var arr = cert.split("\r\n");
var options=[];
for (var i = 0; i < arr.length; i++) {
var option={};
var ele = arr[i];
var n = ele.lastIndexOf(" ");
var dn = ele.substr(0, n);
var sn = ele.substr(n + 1);
option.sn=sn;
option.dn=dn;
options.push(option);
}
// 释放签名对象
JIT_GW_ExtInterface.Finalize();
return options;
},
}
}();

873
public/js/pnxclient.js

@ -0,0 +1,873 @@
/* eslint-disable */
var JIT_GW_ExtInterface = function(){
var currentSessionWSURL = "";
var useActioveX = false;
var useNPPlugin = false;
/**
* simple polyfill Object.assign for IE <= 11
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
* @param {Object} target - target options
* @param {Object} options - new options
*/
var extendOptions = function (target, options) {
if (typeof Object.assign === 'function') {
Object.assign(target, options)
} else {
// for IE < 11
for (var key in options) {
target[key] = options[key]
}
}
}
var options = {};
var checkSessionWSURL = function ()
{
if( currentSessionWSURL=="" )
{
if ("https:" == document.location.protocol)
{
currentSessionWSURL = SendAndWaitMessage("https://127.0.0.1:10087/", "QueryService");
}
else
{
currentSessionWSURL = SendAndWaitMessage("http://127.0.0.1:10086/", "QueryService");
}
}
}
// 是否是IE
var isUseActioveX = function ()
{
if (!!window.ActiveXObject || "ActiveXObject" in window)
{
//try
//{
// var ax = new ActiveXObject("PNXClient.PNXDataTrans");
// useActioveX = true;
//}
//catch(e)
//{
// useActioveX = false;
//}
useActioveX = true;
}
else
{
useActioveX = false;
}
}
// 是否使用NPPlugin
var isUseNPPlugin = function()
{
checkSessionWSURL();
if ("{\"value\":\"\"}" == currentSessionWSURL)
{
useNPPlugin = true;
}
else
{
useNPPlugin = false;
}
}
var addActioveX = function(){
document.write("<object classid='clsid:9DD991F7-6FB0-4004-95A4-0A55006A8C42' width='0' height='0' id='PNXGWClient'></object>");
}
var addNPPlugin = function(){
document.write("<embed type='application/x-jit-auth-plugin' id='PNXGWClient' width='0' height='0'></embed>");
}
var SendAndWaitMessageEx = function (operatorCmd, sendMsg)
{
checkSessionWSURL();
var strSendMsg = operatorCmd + ":" + sendMsg;
return SendAndWaitMessage(currentSessionWSURL, strSendMsg);
}
var SendAndWaitMessage = function (wsurl, sendMsg)
{
var ResultMsg = "{\"value\":\"\"}";
if( ResultMsg == wsurl )
{
return ;
}
try{
var globalXmlHttpRequest = new XMLHttpRequest();
globalXmlHttpRequest.open("POST", wsurl, false);
globalXmlHttpRequest.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
globalXmlHttpRequest.send(sendMsg);
ResultMsg = globalXmlHttpRequest.responseText;
}catch(e){
currentSessionWSURL = "";
if (options.onError) {
options.onError.call(undefined, e);
}
}
return ResultMsg;
}
return {
Config: function(extendOption) {
if (extendOption && typeof extendOption === 'object') {
extendOptions(options, extendOption)
}
},
Init: function()
{
isUseActioveX();
if (useActioveX) {
addActioveX();
}
else
{
isUseNPPlugin();
if (useNPPlugin){
addNPPlugin();
}
}
},
// 功能:返回客户端的版本 HRESULT GetClientVersion([out,retval] BSTR* bstrClientVersion);
GetClientVersion: function()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetClientVersion();
}
else
{
var result = JSON.parse(SendAndWaitMessageEx("GetClientVersion", ""));
return result.value;
}
},
// 功能:下载客户端程序并安装 HRESULT SetupClient([in] BSTR strURL, [in] BSTR strHashValue, [in] BOOL bSync, [in] BOOL bOnlySSO, [out,retval] LONG* lRetVal);
SetupClient: function (bstrURL, bstrHashValue, bSync, bOnlySSO)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.SetupClient(bstrURL, bstrHashValue, bSync, bOnlySSO);
}
else
{
var jsonstr = {"strURL":bstrURL,"strHashValue":bstrHashValue,"bSync":bSync,"bOnlySSO":bOnlySSO};
var result = JSON.parse(SendAndWaitMessageEx("SetupClient", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取硬件指纹信息 HRESULT GetFinger([in] ULONG dwSign, [in] BSTR strGateWayIP, [out,retval] BSTR* bstrFinger);
GetFinger: function (dwSign, strGateWayIP)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetFinger(dwSign, strGateWayIP);
}
else
{
var jsonstr = {"dwSign":dwSign, "strGateWayIP":strGateWayIP};
var result = JSON.parse(SendAndWaitMessageEx("GetFinger", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:设置转发策略和代填策略 HRESULT SetPolicy([in] BSTR strProxyPolicy, [in] BSTR strSSOPolicy, [in] BSTR strGatewayAddress, [out,retval] LONG* lRetVal);
SetPolicy:function (strProxyPolicy, strSSOPolicy, strGatewayAddress)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.SetPolicy(strProxyPolicy, strSSOPolicy, strGatewayAddress);
}
else
{
var jsonstr = {"strProxyPolicy":strProxyPolicy, "strSSOPolicy":strSSOPolicy, "strGatewayAddress":strGatewayAddress};
var result = JSON.parse(SendAndWaitMessageEx("SetPolicy", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:启动认证信息模块 HRESULT GetAuthToken([in] BSTR strFileName,[in] BSTR strXmlData,[out,retval] BSTR* bstrInfo);
GetAuthToken: function (strFileName, strXmlData)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetAuthToken(strFileName, strXmlData);
}
else
{
var jsonstr = {"strFileName":strFileName, "strXmlData":strXmlData};
var result = JSON.parse(SendAndWaitMessageEx("GetAuthToken", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:打开BS应用 HRESULT NavigateURL([in] BSTR strUrl, [out,retval] LONG* lRetVal);
NavigateURL: function (strUrl)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.NavigateURL(strUrl);
}
else
{
var jsonstr = {"strUrl":strUrl};
var result = JSON.parse(SendAndWaitMessageEx("NavigateURL", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:打开CS应用 HRESULT ExecuteCS([in] BSTR strGatewayAddress, [in] BSTR strAppFlag, [in] BSTR strAppPath, [out,retval] LONG* lRetVal);
ExecuteCS: function (strGatewayAddress, strAppFlag, strAppPath)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.ExecuteCS(strGatewayAddress, strAppFlag, strAppPath);
}
else
{
var jsonstr = {"strGatewayAddress":strGatewayAddress, "strAppFlag":strAppFlag, "strAppPath":strAppPath};
var result = JSON.parse(SendAndWaitMessageEx("ExecuteCS", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:设置自动更新策略 HRESULT SetUpdatePolicy([in] BSTR strGatewayAddress, [in] SHORT nGatewayPort, [in] BSTR strUserToken, [in] ULONG ulUpdateDelay, [out, retval] LONG* lRetVal);
SetUpdatePolicy: function (strGatewayAddress, nGatewayPort, strUserToken, updatedelay)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.SetUpdatePolicy(strGatewayAddress, nGatewayPort, strUserToken, updatedelay);
}
else
{
var jsonstr = {"strGatewayAddress":strGatewayAddress, "nGatewayPort":nGatewayPort, "strUserToken":strUserToken, "ulUpdateDelay":updatedelay};
var result = JSON.parse(SendAndWaitMessageEx("SetUpdatePolicy", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取客户端IP HRESULT GetClientIP([in] BSTR strGatewayIP, [out, retval] BSTR* RetVal);
GetClientIP: function (strGatewayIP)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetClientIP(strGatewayIP);
}
else
{
var jsonstr = {"strGatewayIP":strGatewayIP};
var result = JSON.parse(SendAndWaitMessageEx("GetClientIP", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:登出网关 HRESULT GWLogout([in] BSTR strServerIP, [out, retval] LONG* lRetVal);
GWLogout: function (strServerIP)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GWLogout(strServerIP);
}
else
{
var jsonstr = {"strServerIP":strServerIP};
var result = JSON.parse(SendAndWaitMessageEx("GWLogout", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:运行安装包: 0 非静默安装,1 静默安装,2 同步安装,4 异步安装 HRESULT RunSetup([in] LONG lRunType, [in] BOOL bIsOnlySSO, [out, retval] LONG* lRetVal);
RunSetup: function (lRunType, bIsOnlySSO)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.RunSetup(lRunType, bIsOnlySSO);
}
else
{
var jsonstr = {"lRunType":lRunType, "bIsOnlySSO":bIsOnlySSO};
var result = JSON.parse(SendAndWaitMessageEx("RunSetup", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取下载进度 HRESULT GetDownloadProgress([out, retval] LONG* lRetVal);
GetDownloadProgress: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetDownloadProgress();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetDownloadProgress", jsonstr));
return result.value;
}
},
// 功能:是否安装完成 HRESULT IsInstallComplete([out, retval] BOOL* lRetVal);
IsInstallComplete: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.IsInstallComplete();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("IsInstallComplete", jsonstr));
return result.value;
}
},
// 功能:初始化签包对象 HRESULT Initialize([in] BSTR strAlgType, [in] BSTR strAuxParam, [out,retval] LONG* Result);
Initialize: function (strAlgType, strAuxParam)
{
if(useActioveX|| useNPPlugin )
{
return PNXGWClient.Initialize(strAlgType, strAuxParam);
}
else
{
var jsonstr = { "strAlgType":strAlgType, "strAuxParam":strAuxParam };
var result = JSON.parse(SendAndWaitMessageEx("Initialize", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:设置摘要算法 HRESULT SetDigestAlg([in] BSTR strDigestAlg, [out,retval] LONG* Result);
SetDigestAlg: function (strDigestAlg)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.SetDigestAlg(strDigestAlg);
}
else
{
var jsonstr = {"strDigestAlg":strDigestAlg};
var result = JSON.parse(SendAndWaitMessageEx("SetDigestAlg", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:设置单证书是否弹出对话框 HRESULT SetChooseSingleCert([in] ULONG isChoose, [out,retval] LONG* Result);
SetChooseSingleCert: function (isChoose)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.SetChooseSingleCert(isChoose);
}
else
{
var jsonstr = {"isChoose":isChoose};
var result = JSON.parse(SendAndWaitMessageEx("SetChooseSingleCert", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:添加证书过滤条件 HRESULT AddFilter([in] ULONG ulType, [in] BSTR strValue, [out,retval] LONG* Result);
AddFilter: function (ulType, strValue)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.AddFilter(ulType, strValue);
}
else
{
var jsonstr = {"ulType":ulType, "strValue":strValue};
var result = JSON.parse(SendAndWaitMessageEx("AddFilter", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:清除所有过滤条件 HRESULT ClearFilter([out,retval] LONG* Result);
ClearFilter: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.ClearFilter();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("ClearFilter", jsonstr));
return result.value;
}
},
// 功能:P1签名 HRESULT P1Sign([in] BSTR strValueBase64, [out,retval] BSTR* Result);
P1Sign: function (strValueBase64)
{
if(useActioveX|| useNPPlugin )
{
return PNXGWClient.P1Sign(strValueBase64);
}
else
{
var jsonstr = {"strValueBase64":strValueBase64};
var result = JSON.parse(SendAndWaitMessageEx("P1Sign", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:P1签名字符串 HRESULT P1SignString([in] BSTR strValue, [out,retval] BSTR* Result);
P1SignString: function (strValue)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.P1SignString(strValue);
}
else
{
var jsonstr = {"strValue":strValue};
var result = JSON.parse(SendAndWaitMessageEx("P1SignString", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:P7签名 HRESULT P7Sign([in] BSTR strValueBase64,[in] VARIANT_BOOL isDetach,[in] VARIANT_BOOL isIncludeCert, [out,retval] BSTR* Result);
P7Sign: function (strValueBase64, isDetach, isIncludeCert)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.P7Sign(strValueBase64, isDetach, isIncludeCert);
}
else
{
var jsonstr = {"strValueBase64":strValueBase64, "isDetach":isDetach, "isIncludeCert":isIncludeCert};
var result = JSON.parse(SendAndWaitMessageEx("P7Sign", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:P7签名字符串 HRESULT P7SignString([in] BSTR strValue,[in] VARIANT_BOOL isDetach,[in] VARIANT_BOOL isIncludeCert, [out,retval] BSTR* Result);
P7SignString: function (strValue, isDetach, isIncludeCert)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.P7SignString(strValue, isDetach, isIncludeCert);
}
else
{
var jsonstr = {"strValue":strValue, "isDetach":isDetach, "isIncludeCert":isIncludeCert};
var result = JSON.parse(SendAndWaitMessageEx("P7SignString", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:释放签名对象 HRESULT Finalize([out,retval] LONG* Result);
Finalize: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.Finalize();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("Finalize", jsonstr));
return result.value;
}
},
// 功能:获取签名版本 HRESULT GetSignVersion([out,retval] BSTR* Result);
GetSignVersion: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetSignVersion();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetSignVersion", jsonstr));
return result.value;
}
},
// 功能:获取签名证书 HRESULT GetSignCert([out,retval] BSTR* RetCert);
GetSignCert: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetSignCert();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetSignCert", jsonstr));
return result.value;
}
},
// 功能:获取错误码 HRESULT GetLastError([out,retval] ULONG* RetLong);
GetLastError: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetLastError();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetLastError", jsonstr));
return result.value;
}
},
// 功能:获取错误信息 HRESULT GetLastErrorMessage([out,retval] BSTR* RetStr);
GetLastErrorMessage: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetLastErrorMessage();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetLastErrorMessage", jsonstr));
return result.value;
}
},
// 功能:销毁认证对象 HRESULT DestoryAuth([out,retval] LONG* lRetVal);
DestoryAuth: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.DestoryAuth();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("DestoryAuth", jsonstr));
return result.value;
}
},
// 功能:获取证书类型 HRESULT GetSignCertType([out,retval] BSTR* RetCertType);
GetSignCertType: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetSignCertType();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetSignCertType", jsonstr));
return result.value;
}
},
// 功能:获取签名摘要算法 HRESULT GetSignHash([out,retval] BSTR* RetSignHash);
GetSignHash: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetSignHash();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetSignHash", jsonstr));
return result.value;
}
},
// 功能:使能调用序列 HRESULT CallQueueEnable([in] BOOL bCallQueueEnable, [in] BOOL bHeadInfoEnable, [out,retval] LONG* lRetVal);
CallQueueEnable: function (bCallQueueEnable, bHeadInfoEnable)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.CallQueueEnable(bCallQueueEnable, bHeadInfoEnable);
}
else
{
var jsonstr = {"bCallQueueEnable":bCallQueueEnable, "bHeadInfoEnable":bHeadInfoEnable};
var result = JSON.parse(SendAndWaitMessageEx("CallQueueEnable", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:清空调用序列结果 HRESULT CallQueueClear([out,retval] LONG* lRetVal);
CallQueueClear: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.CallQueueClear();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("CallQueueClear", jsonstr));
return result.value;
}
},
// 功能:获取调用序列结果 HRESULT CallQueueGet([out,retval] BSTR* bstrRetVal);
CallQueueGet: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.CallQueueGet();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("CallQueueGet", jsonstr));
return result.value;
}
},
// 功能:客户端安全策略检查 HRESULT DoClientSecurityCheck([in] BSTR strGatewayAddress, [in] SHORT usGatewayPort, [in] BSTR strSecurityPolicys, [out,retval] BOOL* RetVal);
DoClientSecurityCheck: function (strGatewayAddress, usGatewayPort, strSecurityPolicys)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.DoClientSecurityCheck(strGatewayAddress, usGatewayPort, strSecurityPolicys);
}
else
{
var jsonstr = {"strGatewayAddress":strGatewayAddress, "usGatewayPort":usGatewayPort, "strSecurityPolicys":strSecurityPolicys};
var result = JSON.parse(SendAndWaitMessageEx("DoClientSecurityCheck", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取通讯协议版本 HRESULT GetProtocolVersion([out,retval] BSTR* strProtocolVersion);
GetProtocolVersion: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetProtocolVersion();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetProtocolVersion", jsonstr));
return result.value;
}
},
// 功能:修改Key的Pin码 HRESULT ChangePinCode([in] BSTR strCertSn, [in] LONG lPinCodeType, [in] BSTR strCurPinCode, [in] BSTR strNewPinCode, [out,retval] LONG *pRet);
ChangePinCode: function (strCertSn, lPinCodeType, strCurPinCode, strNewPinCode)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.ChangePinCode(strCertSn, lPinCodeType, strCurPinCode, strNewPinCode);
}
else
{
var jsonstr = {"strCertSn":strCertSn, "lPinCodeType":lPinCodeType, "strCurPinCode":strCurPinCode, "strNewPinCode":strNewPinCode};
var result = JSON.parse(SendAndWaitMessageEx("ChangePinCode", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:等待策略设置完毕 HRESULT WaitSetPolicyFinish([in] BSTR strGatewayAddress, [out,retval] LONG* lRetVal);
WaitSetPolicyFinish: function (strGatewayAddress)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.WaitSetPolicyFinish(strGatewayAddress);
}
else
{
var jsonstr = {"strGatewayAddress":strGatewayAddress};
var result = JSON.parse(SendAndWaitMessageEx("WaitSetPolicyFinish", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取会话Token HRESULT GetSessionToken([in] BSTR strGatewayAddress, [out,retval] BSTR* bstrToken);
GetSessionToken: function (strGatewayAddress)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetSessionToken(strGatewayAddress);
}
else
{
var jsonstr = {"strGatewayAddress":strGatewayAddress};
var result = JSON.parse(SendAndWaitMessageEx("GetSessionToken", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取控件版本 HRESULT GetVersion([out,retval] BSTR* bstrRetVal);
GetVersion: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetVersion();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetVersion", jsonstr));
return result.value;
}
},
// 功能:设置语言资源 HRESULT SetLanguage([in] BSTR strLanguage, [out,retval] LONG* Result);
SetLanguage: function (strLanguage)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.SetLanguage(strLanguage);
}
else
{
var jsonstr = {"strLanguage":strLanguage};
var result = JSON.parse(SendAndWaitMessageEx("SetLanguage", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取用户属性 HRESULT GetAttribute([in] BSTR strGatewayAddress, [in] BSTR strAppFlag, [in] BSTR strAttributeName, [out, retval] BSTR* attributevalue);
GetAttribute: function (strGatewayAddress, strAppFlag, strAttributeName)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetAttribute(strGatewayAddress, strAppFlag, strAttributeName);
}
else
{
var jsonstr = {"strGatewayAddress":strGatewayAddress, "strAppFlag":strAppFlag, "strAttributeName":strAttributeName};
var result = JSON.parse(SendAndWaitMessageEx("GetAttribute", JSON.stringify(jsonstr)));
return result.value;
}
},
//功能:获取签名加密PIN码 HRESULT GetPinCode([out,retval] BSTR* Result);
GetPinCode: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetPinCode();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetPinCode", JSON.stringify(jsonstr)));
return result.value;
}
},
//功能:设置强制弹出PIN码框 HRESULT SetForcePinDialog([in] ULONG isForcePinDialog, [out,retval] LONG* Result);
SetForcePinDialog: function (isForcePinDialog)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.SetForcePinDialog(isForcePinDialog);
}
else
{
var jsonstr = {"isForcePinDialog":isForcePinDialog};
var result = JSON.parse(SendAndWaitMessageEx("SetForcePinDialog", JSON.stringify(jsonstr)));
return result.value;
}
},
//功能:返回报文认证属性 HRESULT MessageAuth([in] BSTR bstrGatewayAddress, [in] BSTR bstrAttributeName, [in] BSTR bstrAppID,[out,retval] BSTR* bstrAttributeValue);
MessageAuth: function (bstrGatewayAddress, bstrAttributeName, bstrAppID)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.MessageAuth(bstrGatewayAddress, bstrAttributeName, bstrAppID);
}
else
{
var jsonstr = {"bstrGatewayAddress":bstrGatewayAddress, "bstrAttributeName":bstrAttributeName, "bstrAppID":bstrAppID};
var result = JSON.parse(SendAndWaitMessageEx("MessageAuth", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取底板照片 HRESULT GetPhoto([in] BSTR bstrSvrIP, [in] USHORT usSvrPort, [in] BSTR bstrID, [out,retval] BSTR* bstrBase64);
GetPhoto: function (bstrSvrIP, usSvrPort, bstrID)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetPhoto(bstrSvrIP, usSvrPort, bstrID);
}
else
{
var jsonstr = {"bstrSvrIP":bstrSvrIP, "usSvrPort":usSvrPort, "bstrID":bstrID};
var result = JSON.parse(SendAndWaitMessageEx("GetPhoto", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:获取证书列表 HRESULT GetCertList([out,retval] BSTR* pbstrResult);
// 证书间用换行符分割,证书各项间用空格符分割
GetCertList: function()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.GetCertList();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("GetCertList", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:设置pin码并获取签名结果 HRESULT P1SignWithPin([in] BSTR bstrSN, [in] BSTR bstrPIN, [in] BSTR bstrOrg, [out, retval] BSTR* bstrResult);
P1SignWithPin: function(bstrSN, bstrPIN, bstrOrg)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.P1SignWithPin(bstrSN, bstrPIN, bstrOrg);
}
else
{
var jsonstr = {"bstrSN":bstrSN, "bstrPIN":bstrPIN, "bstrOrg":bstrOrg};
var result = JSON.parse(SendAndWaitMessageEx("P1SignWithPin", JSON.stringify(jsonstr)));
return result.value;
}
},
// 功能:清除所有过滤条件 HRESULT ClearFilterEx([out,retval] LONG* Result);
ClearFilterEx: function ()
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.ClearFilterEx();
}
else
{
var jsonstr = "";
var result = JSON.parse(SendAndWaitMessageEx("ClearFilterEx", jsonstr));
return result.value;
}
},
//功能:设置会话token HRESULT SetSessionToken([in] BSTR bstrGwAddr, [in] BSTR bstrToken, [out, retval] LONG* Result)
SetSessionToken: function(strGatewayAddress, strToken)
{
if( useActioveX || useNPPlugin )
{
return PNXGWClient.SetSessionToken(strGatewayAddress, strToken);
}
else
{
var jsonstr = {"strGatewayAddress":strGatewayAddress, "strToken":strToken};
var result = JSON.parse(SendAndWaitMessageEx("SetSessionToken", JSON.stringify(jsonstr)));
return result.value;
}
}
}
}();
(function(){
JIT_GW_ExtInterface.Init();
})();

BIN
public/mp4/1.mp4

Binary file not shown.

50
src/api/rightsComfort/comfort.ts

@ -0,0 +1,50 @@
import request from "@/api/request";
export function listComfort(query) {
return request.get({
url: `/comfort`,
query: query
});
}
export function listTodos(query) {
return request.get({
url: `/comfort/todo`,
query: query
});
}
export function listDone(query) {
return request.get({
url: `/comfort/done`,
query: query
});
}
export function getDetail(id) {
return request.get({
url: `/comfort/` + id,
});
}
export function applyComfort(body) {
return request.post({
url: `/comfort`,
body
});
}
export function delComfort(id) {
return request.del({
url: `/comfort/` + id
});
}
export function comfortApprove(body) {
return request.post({
url: `/comfort/approve`,
body
});
}

4
src/api/work/comfort.ts → src/api/rightsComfort/rights.ts

@ -1,9 +1,9 @@
import request from "@/api/request";
export function listComfort(query) {
export function listRights(query) {
return request.get({
url: `/comfort`,
url: `/rights`,
query: query
});
}

7
src/api/screen/videoSupervise.ts

@ -36,3 +36,10 @@ export function getVideoSuperviseProblemTypeRate(times) {
url: `/datav/videoSupervise/getVideoSuperviseProblemTypeRate?beginTime=${times[0]}&endTime=${times[1]}`
});
}
// 获取内部视频数量
export function getVideoStatus(times) {
return request.get({
url: `/datav/videoSupervise/getVideoStatus`
});
}

7
src/api/system/police.ts

@ -7,6 +7,13 @@ export function listPolice(query) {
});
}
export function listAbnormalPolice(query) {
return request.get({
url: '/police/abnormal',
query
});
}
export function addPolice(body) {
return request.post({
url: '/police',

35
src/api/system/rightPerson.ts

@ -0,0 +1,35 @@
import request from "@/api/request";
export function listRightPerson(query) {
return request.get({
url: '/rightPerson',
query
});
}
// 获取当前单位的维权专干
export function listRightPersonByDepartId(departId) {
return request.get({
url: '/rightPerson/depart/' + departId
});
}
export function addRightPerson(body) {
return request.post({
url: '/rightPerson',
body
});
}
export function updateRightPerson(body) {
return request.put({
url: '/rightPerson',
body
});
}
export function delRightPerson(id) {
return request.del({
url: '/rightPerson/' + id
});
}

406
src/components/comfort/dialog.vue

@ -0,0 +1,406 @@
<template>
<el-dialog
:title="comfort.apply.number"
v-model="dialogShow"
width="60vw"
top="2vh"
style="margin-bottom: 0"
>
<el-scrollbar max-height="calc(96vh - 150px)">
<h3>申请人信息</h3>
<div class="row">
<div class="col col-6">
<label>申请人姓名</label>
<span>{{ comfort.apply.applicantEmpName }}</span>
</div>
<div class="col col-6">
<label>性别</label>
<span>
<span v-if="comfort.person.sex === 0"></span>
<span v-if="comfort.person.sex === 1"></span>
</span>
</div>
<div class="col col-6">
<label>出生年月</label>
<span>{{ comfort.person.birthday }}</span>
</div>
<div class="col col-6">
<label>文化程度</label>
<span>{{ comfort.person.levelEducation }}</span>
</div>
<div class="col col-6">
<label>政治面貌</label>
<span>{{ comfort.person.politicCountenance }}</span>
</div>
<div class="col col-6">
<label>身份证号码</label>
<span>{{ comfort.person.idCode }}</span>
</div>
<div class="col col-6">
<label>联系电话</label>
<span>{{ comfort.person.mobile }}</span>
</div>
<div class="col col-6">
<label>单位</label>
<span>{{ comfort.person.departName }}</span>
</div>
<div class="col col-6">
<label>职务</label>
<span>{{ comfort.person.job }}</span>
</div>
<div class="col col-6">
<label>警号</label>
<span>{{ comfort.person.empNo }}</span>
</div>
<div class="col col-6">
<label>警衔</label>
<span>{{ comfort.person.policeRank }}</span>
</div>
<div class="col col-6">
<label>开户行</label>
<span>{{ comfort.person.bankCard }}</span>
</div>
<div class="col col-6">
<label>所属支行</label>
<span>{{ comfort.person.bankBranch }}</span>
</div>
<div class="col col-6">
<label>银行账号</label>
<span>{{ comfort.person.bankCardAccount }}</span>
</div>
</div>
<el-divider />
<h3>案发情况</h3>
<div class="row">
<div class="col col-6">
<label>事发时间</label>
<span>{{ comfort.apply.happenTime }}</span>
</div>
<div class="col col-6">
<label>案发环节</label>
<span>{{ comfort.apply.incidentLinkName }}</span>
</div>
<div class="col col-6">
<label>受伤程度</label>
<span>{{ comfort.applyPerson.injurySeverity }}</span>
</div>
<div class="col col-6">
<label>办案单位</label>
<span>{{ comfort.apply.handleDepartName }}</span>
</div>
<div class="col col-24">
<label>事实及理由</label>
<span>{{ comfort.apply.factReason }}</span>
</div>
<div class="col col-6">
<label>侵权形式</label>
<span>{{ comfort.apply.formsOfTortName }}</span>
</div>
<div class="col col-6">
<label>侵权人姓名</label>
<span>{{ comfort.apply.infringerName }}</span>
</div>
<div class="col col-6">
<label>处理方式</label>
<span>{{ comfort.apply.infringerHandle }}</span>
</div>
</div>
<el-divider />
<h3>佐证材料</h3>
<div>
<template v-if="comfort.apply.documentFile">
<file-todos
:files="JSON.parse(comfort.apply.documentFile)"
/>
</template>
<template v-else>
<el-empty
description="无附件"
style="--el-empty-image-width: 50px"
/>
</template>
</div>
<el-divider />
<h3>审批流程</h3>
<div class="comments-container flex gap-20">
<div class="item">
<div class="flex center mb-20 relative comments-header">
<icon
name="el-icon-CircleCheck"
:size="41"
color="var(--primary-color)"
/>
</div>
<h1 class="text-center mb-16">
<span class="text-primary">申请抚慰</span>
</h1>
<h2 class="text-center mb-20">
{{ comfort.apply.applicantEmpName }}
</h2>
<div style="padding: 8px">
<h4 class="text-right">
{{ comfort.apply.applyDate }}
</h4>
</div>
</div>
<div class="item">
<div class="flex center mb-20 relative comments-header">
<template
v-if="
comfort.approves.find((item) => item.step === 2)
"
>
<icon
name="local-icon-return"
:size="41"
color="#FF0606"
v-if="
comfort.approves.find(
(item) => item.step === 2
).returnFlag
"
/>
<icon
name="el-icon-CircleCheck"
:size="41"
color="var(--primary-color)"
v-else
/>
</template>
<div class="icon" v-else></div>
</div>
<h1 class="text-center mb-16">
<span>待审批</span>
</h1>
<h2 class="text-center mb-20">
维权专干 {{ comfort.apply.approver }}
</h2>
<div style="padding: 8px">
<h3>{{}}</h3>
<p style="font-weight: 700">{{}}</p>
<h4 class="text-right">{{}}</h4>
</div>
</div>
<div class="item">
<div class="flex center mb-20 relative comments-header">
<template
v-if="
comfort.approves.find((item) => item.step === 2)
"
>
<icon
name="local-icon-return"
:size="41"
color="#FF0606"
v-if="
comfort.approves.find(
(item) => item.step === 2
).returnFlag
"
/>
<icon
name="el-icon-CircleCheck"
:size="41"
color="var(--primary-color)"
v-else
/>
</template>
<div class="icon" v-else></div>
</div>
<h1 class="text-center mb-16">
<span>待审批</span>
</h1>
<h2 class="text-center mb-20">市局 维权专干</h2>
<div style="padding: 8px">
<h3>{{}}</h3>
<p style="font-weight: 700">{{}}</p>
<h4 class="text-right">{{}}</h4>
</div>
</div>
</div>
</el-scrollbar>
<div style="min-height: 40px">
<footer class="flex end mt-20" v-if="!disabled">
<el-button size="large" type="danger" @click="handleReturn"
>退回</el-button
>
<el-button type="primary" size="large" @click="handleApprove"
>审批通过</el-button
>
</footer>
</div>
</el-dialog>
<el-dialog
:title="formData.returnFlag ? '抚慰退回' : `抚慰审批`"
v-model="approveShow"
>
<el-form
label-position="top"
ref="formRef"
:model="form"
style="height: 400px"
>
<el-form-item
prop="comments"
:rules="{
required: true,
message: '请输入',
trigger: ['blur', 'change'],
}"
>
<template #label>
<h3 class="inline-block mb-10">
{{ formData.returnFlag ? "退回意见" : `审批意见` }}
</h3>
</template>
<el-input
type="textarea"
placeholder="请输入"
v-model="formData.comments"
:autosize="{ minRows: 5 }"
/>
</el-form-item>
</el-form>
<footer class="flex end">
<el-button type="primary" size="large" @click="submit"
>提交</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import { getDetail, comfortApprove } from "@/api/rightsComfort/comfort";
import feedback from "@/utils/feedback";
const comfort = ref({
apply: {},
applyPerson: {},
person: {},
approves: [],
});
const props = defineProps({
show: {
type: Boolean,
default: false,
},
id: {
type: String,
},
disabled: {
type: Boolean,
default: true,
},
});
const emit = defineEmits(["update", "update:show"]);
const dialogShow = ref(false);
watch(
() => props.show,
(val) => {
dialogShow.value = val;
}
);
watch(dialogShow, (val) => {
emit("update:show", val);
});
watch(
() => props.id,
(val) => {
getDetail(val).then((data) => {
comfort.value = data;
});
}
);
const approveShow = ref(false);
const formData = ref({});
const formRef = ref();
function handleReturn() {
approveShow.value = true;
formData.value.returnFlag = true;
}
function handleApprove() {
approveShow.value = true;
formData.value.returnFlag = false;
}
async function submit() {
await formRef.value.validate();
await comfortApprove({
rpcId: props.id,
returnFlag: formData.value.returnFlag,
comments: formData.value.comments,
});
approveShow.value = false
formData.value = {};
feedback.msgSuccess("操作成功");
dialogShow.value = false
emit("update");
}
</script>
<style lang="scss" scoped>
.item {
width: 100%;
padding: 8px;
--base-color: #999;
--second-color: #d8d8d8;
.comments-header {
&::before {
display: block;
content: "";
position: absolute;
top: 50%;
right: calc(50% + 30px);
width: calc(100% - 30px);
border-top: 2px solid var(--second-color);
}
}
&:first-child .comments-header::before {
display: none;
}
&[approved="true"] {
--base-color: var(--primary-color);
--second-color: #8595fb;
}
h1 {
color: var(--base-color);
font-size: 18px;
font-weight: 700;
}
h2 {
font-size: 16px;
font-weight: 500;
}
h3 {
font-size: 14px;
color: #666;
font-weight: 500;
margin-bottom: 8px;
margin-top: 0;
}
h4 {
font-size: 12px;
color: #666;
font-weight: 500;
}
p {
color: #333;
}
div[danger="true"] {
background-color: #feeded;
}
.icon {
width: 22px;
height: 22px;
border: 3px solid #e0e0e0;
border-radius: 50%;
margin: 6.5px;
}
}
</style>

2
src/components/icon/index.vue

@ -32,7 +32,7 @@ export default defineComponent({
() => [createVNode(resolveComponent(props.name.replace(EL_ICON_PREFIX, '')))]
)
}
if (props.name.indexOf(LOCAL_ICON_PREFIX) === 0) {
if (props.name?.indexOf(LOCAL_ICON_PREFIX) === 0) {
// icon
return () =>
h(

44
src/components/negative/dialog.vue

@ -137,7 +137,6 @@
</div>
</div>
<template
v-if="
(components.indexOf('negative-verify') > -1 &&
@ -207,7 +206,8 @@
/>
</template>
<div
v-if="negative.processingStatus ===
v-if="
negative.processingStatus ===
ProcessingStatus.COMPLETED
"
>
@ -292,29 +292,47 @@
>保存抽检结果</el-button
>
<div v-if="!disabled">
<el-button
size="large"
v-for="item in flowActions"
:key="item.actionKey"
:type="item.buttonType"
:plain="item.plain"
@click="handleExecute(item)"
:disabled="
loading ||
(!negative.extensionApplyFlag &&
<template v-for="item in flowActions" :key="item.actionKey">
<template
v-if="
!negative.extensionApplyFlag &&
(item.actionKey ===
FlowActionEnum.APPLY_COMPLETION ||
item.actionKey ===
FlowActionEnum.APPLY_EXTENSION ||
item.actionKey ===
FlowActionEnum.THREE_SIGN_RETURN))
FlowActionEnum.THREE_SIGN_RETURN)
"
>
<el-tooltip
effect="dark"
:content="`该问题目前正在${negative.currentProcessingObject}等待延期审批,请延期审批通过后再进行提交!`"
raw-content
placement="top"
>
<el-button
size="large"
:type="item.buttonType"
:plain="item.plain"
:disabled="true"
>{{ item.buttonLabel }}</el-button
>
</el-tooltip>
</template>
<el-button
v-else
size="large"
:type="item.buttonType"
:plain="item.plain"
@click="handleExecute(item)"
:disabled="loading"
>{{
item.actionKey === "update_verify" && verifyEditFlag
? "保存核查内容"
: item.buttonLabel
}}</el-button
>
</template>
</div>
</footer>
<template v-for="item in flowActions" :key="item.actionKey">

5
src/components/negative/verify.vue

@ -1547,6 +1547,10 @@ function handleAddPersonal() {
type: BlameType.PERSONAL,
problems: [{}],
});
if (form.value.blameLeaders.length == 0) {
handleAddBlameLeader()
}
}
function handleRemovePersonal(item) {
@ -1710,7 +1714,6 @@ const formRef = ref(null);
async function validate() {
//
if (form.value.accountabilityTarget === AccountabilityTarget.PERSONAL) {
debugger
form.value.blames = form.value.blames.filter(
(item) => item.type === BlameType.PERSONAL
);

8
src/layout/components/Header.vue

@ -16,14 +16,14 @@
</section>
</header>
<ul class="userinfo-dropdown" v-if="dropdownShow">
<!-- <li class="flex gap v-center" @click="openHelp">
<icon name="local-icon-question" :size="22" />
<span>帮助手册</span>
</li> -->
<li class="flex gap v-center" @click="supportShow = true">
<icon name="el-icon-Star" :size="22" />
<span>技术支持</span>
</li>
<li class="flex gap v-center" @click="openHelp">
<icon name="local-icon-question" :size="22" />
<span>帮助教程</span>
</li>
<li class="flex gap v-center" @click="goBackV1">
<icon name="el-icon-Back" :size="20" />
<span>返回旧版</span>

4
src/router/routes.ts

@ -99,6 +99,10 @@ export const routes = [
path: '/work/verifySubmit',
component: () => import('@/views/work/VerifySubmit.vue'),
},
{
path: '/system/Operating',
component: () => import('@/views/system/Operating.vue'),
},
];

5
src/stores/modules/user.ts

@ -41,7 +41,10 @@ const useUserStore = defineStore({
const random = await jitRandom();
console.log(random)
return new Promise((resolve, reject) => {
jitLogin(random)
jitLogin({
random,
signed_data: JIT_AUTHEN.AuthP7Sign(random)
})
.then((data) => {
setToken(data.token)
resolve(data)

4
src/style/public.scss

@ -283,6 +283,10 @@ svg + span {
margin-top: 40px;
}
.mt-60 {
margin-top: 60px;
}
.mb-0 {
margin-bottom: 0;
}

86
src/views/Support.vue

@ -1,21 +1,71 @@
<template>
<div class="wrapper">
<div class="wrapper" ref="containerRef">
<div class="container">
<h1 class="text-center">帮助手册</h1>
<h2>核查办理</h2>
<img
src="https://saas.bk-cdn.com/t/127c4188-9a34-4d69-b2e8-921e912e4581/u/c23bff65-075f-49c1-9279-d0e91745ebfa/1655715330647/%E7%99%BE%E5%88%86%E6%AF%94.gif"
alt=""
/>
<h2>核查办理</h2>
<img
src="https://saas.bk-cdn.com/t/127c4188-9a34-4d69-b2e8-921e912e4581/u/c23bff65-075f-49c1-9279-d0e91745ebfa/1655715330647/%E7%99%BE%E5%88%86%E6%AF%94.gif"
alt=""
/>
<el-row>
<el-col :span="6">
<el-anchor
:container="containerRef"
direction="vertical"
type="default"
:offset="30"
@click="handleClick"
style="position: fixed"
>
<el-anchor-link href="#part1" title="1. 数字督察-登录及功能简介" />
<el-anchor-link href="#part2" title="2. 数字督察-问题下发" />
<el-anchor-link href="#part3" title="3. 数字督察-问题处理" />
<el-anchor-link href="#part4" title="4. 数字督察-问题审批" />
<el-anchor-link href="#part5" title="5. 数字督察-警员调整" />
</el-anchor>
</el-col>
<el-col :span="18">
<div >
<div id="part1" class="part">
<h1>1. 数字督察-登录及功能简介</h1>
<video controls>
<source :src="`/教程视频/1登录及功能简介.mp4`" type="video/mp4" />
</video>
<el-divider />
</div>
<div id="part2" class="part">
<h1>2. 数字督察-问题下发</h1>
<video controls>
<source :src="`/教程视频/2数字督察-问题下发.mp4`" type="video/mp4" />
</video>
<el-divider />
</div>
<div id="part3" class="part">
<h1>3. 数字督察-问题处理</h1>
<video controls>
<source :src="`/教程视频/3数字督察-问题处理.mp4`" type="video/mp4" />
</video>
<el-divider />
</div>
<div id="part4" class="part">
<h1>4. 数字督察-问题审批</h1>
<video controls>
<source :src="`/教程视频/4问题审批.mp4`" type="video/mp4" />
</video>
<el-divider />
</div>
<div id="part5" class="part">
<h1>5. 数字督察-警员调整</h1>
<video controls>
<source :src="`/教程视频/5警员调整.mp4`" type="video/mp4" />
</video>
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup>
const containerRef = ref(null);
const handleClick = (e) => {
e.preventDefault();
};
</script>
<style lang="scss" scoped>
.wrapper {
@ -23,12 +73,20 @@
overflow: auto;
}
.container {
width: 1100px;
width: 1400px;
margin: auto;
h1 {
font-size: 32px;
font-weight: normal;
}
video {
width: 100%;
}
}
.part {
padding-top: 20px;
&:last-child {
margin-bottom: 200px;
}
}
</style>

2
src/views/books/Hdjq.vue

@ -140,7 +140,7 @@
<el-table-column
label="期数"
prop="reportNumber"
width="80"
width="180"
/>
<el-table-column
label="涉及单位"

398
src/views/datav/VideoInsp.vue

@ -9,27 +9,46 @@
<div class="row mt-4 mb-20">
<div class="col col-8">
<label>视频总数</label>
<span>107</span>
<span>{{ videoStatus.all }}</span>
</div>
<div class="col col-8">
<label>在线数</label>
<span>97</span>
<span>{{ videoStatus.on }}</span>
</div>
<div class="col col-8">
<label>在线率</label>
<span>91%</span>
<span>{{ videoStatus.percentage }}</span>
</div>
</div>
<div class="mb-12">
<iframe :src="activeVideoUrl" style="height: 180px"></iframe>
<iframe
:src="activeVideoUrl"
style="height: 180px"
></iframe>
</div>
<el-row :gutter="12">
<el-col :span="8" v-for="item in videos" :key="item" @click="activeVideoUrl = item">
<iframe :src="item" style="height: 90px"></iframe>
</el-col>
</el-row>
<el-scrollbar max-width="100%">
<div class="flex gap" style="width: 840px">
<div
v-for="item in videos"
:key="item"
@click="activeVideoUrl = item.url"
style="width: 160px"
>
<img
:src="item.img"
:active="
activeVideoUrl === item.url
"
/>
</div>
</div>
</el-scrollbar>
</datav-card>
<datav-card title="问题数排名" sub-title="查实问题数" style="height: 370px;">
<datav-card
title="问题数排名"
sub-title="查实问题数"
style="height: 370px"
>
<datav-tabs
type="bottom-button"
v-model="proRankTab"
@ -55,7 +74,6 @@
</el-scrollbar>
</datav-tab-item>
</datav-tabs>
</datav-card>
</el-col>
@ -104,13 +122,22 @@
ref="videoProTrend"
/>
<div class="gobal-dropdown-container">
<el-dropdown class="test" @command="handleCommand">
<span class="el-dropdown-link my-gobal-yearselect">
{{ selectedYear + ' 年' }}
<el-dropdown
class="test"
@command="handleCommand"
>
<span
class="el-dropdown-link my-gobal-yearselect"
>
{{ selectedYear + " 年" }}
</span>
<template #dropdown>
<el-dropdown-menu style="width: 90px">
<el-dropdown-item v-for="year in years" :key="year" :command="year">{{ year + " " }}
<el-dropdown-item
v-for="year in years"
:key="year"
:command="year"
>{{ year + " 年" }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
@ -125,7 +152,9 @@
<div class="message message-error">
<div class="message-title">待处理</div>
<div>
芙蓉-定王台-办案区-问室 湖南省长沙市公安局芙蓉分局定王台派出所 &emsp; 民警单人询的违规问题
芙蓉-定王台-办案区-问室
湖南省长沙市公安局芙蓉分局定王台派出所
&emsp; 民警单人询的违规问题
</div>
<div class="message-footer flex between">
<span>芙蓉分局定王台派出所</span>
@ -135,7 +164,8 @@
<div class="message message-info">
<div class="message-title">待处理</div>
<div>
望城-管理中心-办案区-询问室湖南省长沙市望城区公安局法制大队&emsp; 民警单人询的违规问题
望城-管理中心-办案区-询问室湖南省长沙市望城区公安局法制大队&emsp;
民警单人询的违规问题
</div>
<div class="message-footer flex between">
<span>望城区公安局法制大队</span>
@ -145,7 +175,8 @@
<div class="message">
<div class="message-title">待处理</div>
<div>
执法办案中心-询问室7湖南省长沙市公安局芙蓉分局蓉园派出所 &emsp;同时讯问多名嫌疑对象
执法办案中心-询问室7湖南省长沙市公安局芙蓉分局蓉园派出所
&emsp;同时讯问多名嫌疑对象
</div>
<div class="message-footer flex between">
<span>芙蓉分局蓉园派出所</span>
@ -155,7 +186,8 @@
<div class="message">
<div class="message-title">待处理</div>
<div>
开福-直属-执法办案管理-讯询问室湖南省长沙市公安局开福分局法制大队 &emsp;民警单人询的违规问题
开福-直属-执法办案管理-讯询问室湖南省长沙市公安局开福分局法制大队
&emsp;民警单人询的违规问题
</div>
<div class="message-footer flex between">
<span>开福分局法制大队</span>
@ -186,10 +218,14 @@ import * as echarts from "echarts/core";
import {
getAllVideoSuperviseCount,
getVideoSuperviseProblemTypeRate,
getVideoSuperviseProblemRank, getVideoSuperviseMap, getVideoSuperviseTrend
getVideoSuperviseProblemRank,
getVideoSuperviseMap,
getVideoSuperviseTrend,
getVideoStatus,
} from "@/api/screen/videoSupervise.ts";
import moment from "moment/moment.js";
import { mapOrgNameMapping } from "@/enums/orgMapping.js";
import { onMounted } from "vue";
// region
const router = useRouter();
@ -207,21 +243,27 @@ const overview = ref({
relativePer: 0,
changedRate: 0,
});
const mapIconList = ref([{
const mapIconList = ref([
{
originalName: "浏阳市局",
name: "浏阳市",
discoverProblem: 135,
changedProblem: 135,
relativeOrg: 89,
relativePer: 152,
changedRate: 100
}])
changedRate: 100,
},
]);
const currentYear = new Date().getFullYear();
const years = ref([currentYear.toString(), (currentYear - 1).toString(), (currentYear - 2).toString()]); //
const years = ref([
currentYear.toString(),
(currentYear - 1).toString(),
(currentYear - 2).toString(),
]); //
const selectedYear = ref(currentYear); //
const videoProRank = ref(null)
const videoProRank = ref(null);
const videoMap = ref(null);
const videoProTrend = ref(null);
const videoProblemTypeRate = ref(null);
@ -237,7 +279,7 @@ const colors = [
{
color: "linear-gradient( 270deg, #FFB90E 0%, #71501D 100%)",
percentage: 60,
}
},
];
// endregion
@ -247,10 +289,22 @@ const proTrend = ref({
xAxis: {
type: "category",
boundaryGap: true,
data: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月",],
data: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
],
axisTick: {
// X线
show: false
show: false,
},
},
yAxis: {
@ -263,13 +317,13 @@ const proTrend = ref({
},
},
tooltip: {
trigger: 'axis',
trigger: "axis",
axisPointer: {
type: 'line',
type: "line",
label: {
backgroundColor: '#6a7985'
}
}
backgroundColor: "#6a7985",
},
},
},
series: [
{
@ -295,11 +349,11 @@ const proTrend = ref({
},
],
grid: {
left: '5%', //
right: '2%', //
top: '10%', //
bottom: '20%', //
containLabel: false //
left: "5%", //
right: "2%", //
top: "10%", //
bottom: "20%", //
containLabel: false, //
},
});
echarts.registerMap("changsha", changshaMap);
@ -308,15 +362,17 @@ const option = ref({
map: "changsha",
itemStyle: {
normal: {
opacity: 0 //
opacity: 0, //
},
},
}
},
tooltip: {
trigger: 'item',
trigger: "item",
position: "bottom",
formatter: function (params) {
const dataItem = mapIconList.value.find(item => item.name.includes(params.name.substring(0, 2)));
const dataItem = mapIconList.value.find((item) =>
item.name.includes(params.name.substring(0, 2))
);
if (dataItem) {
return `
<div class="tooltip">
@ -352,8 +408,14 @@ const option = ref({
bottom: 10,
pieces: [
{ gte: 0, lte: 200, label: "低于平均问题30%", color: "#4987F6" },
{gte: 200, lte: 400, label: "平均问题上下浮动30%内", color: "#F6A149"},
{gte: 400, label: "高于平均问题30%", color: "#D34343"},],
{
gte: 200,
lte: 400,
label: "平均问题上下浮动30%内",
color: "#F6A149",
},
{ gte: 400, label: "高于平均问题30%", color: "#D34343" },
],
right: 10,
realtime: false,
orient: "horizontal",
@ -381,18 +443,18 @@ const option = ref({
normal: {
areaColor: "#02215E",
borderColor: "#24D2EE",
borderWidth: 1 //
borderWidth: 1, //
},
},
emphasis: {
areaColor: "#FFD700", //
borderColor: "#FF0000", //
borderWidth: 4 //
borderWidth: 4, //
},
data: [],
}
},
],
})
});
const ProblemTypeRateChart = ref({
series: [
{
@ -413,54 +475,71 @@ const ProblemTypeRateChart = ref({
// region
const getVideoSuperviseProblemRankData = async (timeValue) => {
const res = await getVideoSuperviseProblemRank(timeValue);
fxsjRankList.value = res.fxsjVideoSuperviseProblemRankList
jsdwRankList.value = res.jsdwVideoSuperviseProblemRankList
}
fxsjRankList.value = res.fxsjVideoSuperviseProblemRankList;
jsdwRankList.value = res.jsdwVideoSuperviseProblemRankList;
};
const getAllVideoSuperviseCountData = async (timeValue) => {
const res = await getAllVideoSuperviseCount(timeValue);
overview.value = res.overview;
}
};
const getVideoSuperviseMapData = async (timeValue) => {
const res = await getVideoSuperviseMap(timeValue);
const mappedData = mapOrgNameMapping(res.videoSuperviseMapIconVoList, "discoverProblem");
const mappedData = mapOrgNameMapping(
res.videoSuperviseMapIconVoList,
"discoverProblem"
);
//
const maxItem = mappedData.reduce((max, item) => (Number(item.value) > Number(max.value) ? item : max), mappedData[0]);
const range60Percent = maxItem.value * 0.6 //
const range80Percent = maxItem.value * 0.8 //
mapIconList.value = mappedData
option.value.series[0].data = mappedData
const maxItem = mappedData.reduce(
(max, item) => (Number(item.value) > Number(max.value) ? item : max),
mappedData[0]
);
const range60Percent = maxItem.value * 0.6; //
const range80Percent = maxItem.value * 0.8; //
mapIconList.value = mappedData;
option.value.series[0].data = mappedData;
option.value.visualMap.pieces = [
{gte: 0, lte: range60Percent, label: "低于最大问题的60%", color: "#4987F6"},
{gte: range60Percent, lte: range80Percent, label: "介于最大问题的60%~80%", color: "#F6A149"},
{
gte: 0,
lte: range60Percent,
label: "低于最大问题的60%",
color: "#4987F6",
},
{
gte: range60Percent,
lte: range80Percent,
label: "介于最大问题的60%~80%",
color: "#F6A149",
},
{ gte: range80Percent, label: "高于最大问题80%", color: "#D34343" },
];
}
};
const getVideoSuperviseTrendData = async (year) => {
const res = await getVideoSuperviseTrend(year);
const temp = res.videoSuperviseTrendList;
const categories = temp.map(item => item.name);
const values = temp.map(item => item.value);
const categories = temp.map((item) => item.name);
const values = temp.map((item) => item.value);
proTrend.value.xAxis.data = categories;
proTrend.value.series[0].data = values;
}
};
const getVideoSuperviseProblemTypeRateData = async (timeValue) => {
const res = await getVideoSuperviseProblemTypeRate(timeValue);
ProblemTypeRateChart.value.series[0].data = res.videoSuperviseProblemTypeRate
}
ProblemTypeRateChart.value.series[0].data =
res.videoSuperviseProblemTypeRate;
};
const getData = () => {
getVideoSuperviseProblemRankData(time.value)
getVideoSuperviseProblemRankData(time.value);
getAllVideoSuperviseCountData(time.value);
getVideoSuperviseMapData(time.value)
getVideoSuperviseTrendData(selectedYear.value)
getVideoSuperviseMapData(time.value);
getVideoSuperviseTrendData(selectedYear.value);
getVideoSuperviseProblemTypeRateData(time.value);
}
};
// endregion
// region
//
const videoProRankAnimation = () => {
proRankTab.value = (parseInt(proRankTab.value) % 2 + 1).toString();
proRankTab.value = ((parseInt(proRankTab.value) % 2) + 1).toString();
};
videoProRankIntervalId = setInterval(videoProRankAnimation, 3000);
//
@ -492,11 +571,11 @@ const videoTrendAnimation = () => {
if (!trendTemp) return;
const randomNum = Math.floor(Math.random() * 12);
trendTemp.dispatchAction({
type: 'showTip',
type: "showTip",
seriesIndex: 0,
dataIndex: randomNum,
});
}
};
videoTrendIntervalId = setInterval(videoTrendAnimation, 2000);
//
const videoProblemTypeRateAnimation = () => {
@ -504,25 +583,35 @@ const videoProblemTypeRateAnimation = () => {
if (!temp) return;
const length = ProblemTypeRateChart.value.series[0].data.length;
const randomNum = Math.floor(Math.random() * length);
temp?.dispatchAction({type: 'downplay', seriesIndex: 0});
temp?.dispatchAction({type: 'highlight', seriesIndex: 0, dataIndex: randomNum}); //
temp?.dispatchAction({type: 'showTip', seriesIndex: 0, dataIndex: randomNum});
}
videoProblemTypeRateIntervalId = setInterval(videoProblemTypeRateAnimation, 2000);
temp?.dispatchAction({ type: "downplay", seriesIndex: 0 });
temp?.dispatchAction({
type: "highlight",
seriesIndex: 0,
dataIndex: randomNum,
}); //
temp?.dispatchAction({
type: "showTip",
seriesIndex: 0,
dataIndex: randomNum,
});
};
videoProblemTypeRateIntervalId = setInterval(
videoProblemTypeRateAnimation,
2000
);
// endregion
// region ||
onMounted(() => {
getData();
setupEventListeners();
})
});
watch(time, () => {
getData()
})
getData();
});
const handleCommand = (year) => {
selectedYear.value = year; //
getVideoSuperviseTrendData(selectedYear.value)
getVideoSuperviseTrendData(selectedYear.value);
};
const handleClick = (params) => {
const departId = params.data.departId;
@ -531,7 +620,7 @@ const handleClick = (params) => {
query: { departId: departId },
}).href;
window.open(url, "_blank");
}
};
//
const setupEventListeners = () => {
@ -542,66 +631,111 @@ const setupEventListeners = () => {
};
const videoProRankAnimationStop = () => {
const temp = videoProRank.value?.$el;
temp.addEventListener('mouseenter', () => {
clearInterval(videoProRankIntervalId)
temp.addEventListener("mouseenter", () => {
clearInterval(videoProRankIntervalId);
});
temp.addEventListener('mouseleave', () => {
temp.addEventListener("mouseleave", () => {
clearInterval(videoProRankIntervalId); //
videoProRankIntervalId = setInterval(videoProRankAnimation, 3000);
});
}
};
const videoMapAnimationStop = () => {
const temp = videoMap?.value?.chart;
//
temp.on('mousemove', (e) => {
temp.on("mousemove", (e) => {
clearInterval(videoMapIntervalId);
temp.dispatchAction({type: "downplay", seriesIndex: 0,});
temp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,});
temp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,});
temp.dispatchAction({ type: "downplay", seriesIndex: 0 });
temp.dispatchAction({
type: "highlight",
seriesIndex: 0,
dataIndex: e.dataIndex,
});
temp.dispatchAction({
type: "showTip",
seriesIndex: 0,
dataIndex: e.dataIndex,
});
});
//
temp.on('mouseout', () => {
temp.on("mouseout", () => {
clearInterval(videoMapIntervalId); //
videoMapIntervalId = setInterval(videoMapAnimation, 2000);
});
}
};
// videoProTrend
const videoTrendAnimationStop = () => {
const temp = videoProTrend?.value.getDom();
temp.addEventListener('mouseenter', () => {
temp.addEventListener("mouseenter", () => {
clearInterval(videoTrendIntervalId);
});
temp.addEventListener('mouseleave', () => {
temp.addEventListener("mouseleave", () => {
clearInterval(videoTrendIntervalId);
videoTrendIntervalId = setInterval(videoTrendAnimation, 2000);
});
}
};
const videoProblemTypeRateAnimationStop = () => {
const temp = videoProblemTypeRate?.value?.chart;
temp.on('mousemove', (e) => {
temp.on("mousemove", (e) => {
clearInterval(videoProblemTypeRateIntervalId);
temp.dispatchAction({type: "downplay", seriesIndex: 0,});
temp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,});
temp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,});
})
temp.on('mouseout', () => {
temp.dispatchAction({ type: "downplay", seriesIndex: 0 });
temp.dispatchAction({
type: "highlight",
seriesIndex: 0,
dataIndex: e.dataIndex,
});
temp.dispatchAction({
type: "showTip",
seriesIndex: 0,
dataIndex: e.dataIndex,
});
});
temp.on("mouseout", () => {
clearInterval(videoProblemTypeRateIntervalId);
videoProblemTypeRateIntervalId = setInterval(videoProblemTypeRateAnimation, 2000);
})
}
videoProblemTypeRateIntervalId = setInterval(
videoProblemTypeRateAnimation,
2000
);
});
};
// endregion
const videos = [
'http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A80%2Frtp%2F43012457021185000003_34020000001320000016.flv',
'http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A80%2Frtp%2F43012457021185000003_34020000001320000003.flv',
'http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A80%2Frtp%2F43012457021185000003_34020000001320000004.flv'
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000033.live.flv",
img: `/v2/imgs/video/1.jpg`,
},
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000028.live.flv",
img: `/v2/imgs/video/2.jpg`,
},
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000002.live.flv",
img: `/v2/imgs/video/3.jpg`,
},
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000019.live.flv",
img: `/v2/imgs/video/4.jpg`,
},
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000011.live.flv",
img: `/v2/imgs/video/5.jpg`,
},
];
const activeVideoUrl = ref(videos[0])
const activeVideoUrl = ref(videos[0].url);
const videoStatus = ref({
all: 0,
percentage: '0%',
on: 0
});
onMounted(() => {
getVideoStatus().then((data) => {
videoStatus.value = data;
});
});
</script>
<style lang="scss" scoped>
@import "@/style/datav.scss";
@ -615,7 +749,7 @@ img {
display: block;
border: 1px solid transparent;
&.active {
&[active="true"] {
border-color: #1cd9ff;
}
}
@ -633,7 +767,8 @@ img {
180deg,
rgba(255, 255, 255, 0.28),
rgba(255, 255, 255, 0.26)
) 1 1;
)
1 1;
&.message-error {
background: linear-gradient(
@ -646,7 +781,8 @@ img {
180deg,
rgba(255, 71, 71, 0.59),
rgba(251, 95, 95, 1)
) 1 1;
)
1 1;
.message-title {
color: #ff0017;
@ -664,7 +800,8 @@ img {
180deg,
rgba(71, 209, 255, 0.28),
rgba(8, 177, 255, 1)
) 1 1;
)
1 1;
.message-title {
color: #1cd9ff;
@ -685,15 +822,18 @@ img {
}
}
:deep() {
//
.tooltip {
position: relative;
width: 169.88px;
height: 178px;
background: linear-gradient(180deg, rgba(1, 4, 87, 0.8) 0%, rgba(3, 21, 119, 0.8) 100%);
border: 1px solid #4E8FFF;
background: linear-gradient(
180deg,
rgba(1, 4, 87, 0.8) 0%,
rgba(3, 21, 119, 0.8) 100%
);
border: 1px solid #4e8fff;
margin: -10px -10px -10px -10px;
}
@ -701,19 +841,22 @@ img {
.tooltip-title {
width: 169.88px;
height: 43px;
background: linear-gradient(180deg, rgba(1, 4, 87, 0.8) 0%, rgba(3, 21, 119, 0.8) 100%);
background: linear-gradient(
180deg,
rgba(1, 4, 87, 0.8) 0%,
rgba(3, 21, 119, 0.8) 100%
);
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
text-align: center; /* 水平居中 */
font-weight: 400;
font-size: 16px;
color: #FFFFFF;
color: #ffffff;
line-height: 22px;
border-bottom: 1px solid #253755; /* 设置下边框 */
}
.tooltip-content {
width: 170px;
height: 132px;
@ -725,17 +868,15 @@ img {
.tooltip-content ul {
list-style-type: none; /* 移除默认的小圆点 */
padding: 0;
}
.tooltip-content ul li {
margin-left: 5px;
height: 25px;
color: #597AE9;
color: #597ae9;
font-size: 13px;
}
// span
.tooltip-ul span {
float: right;
@ -746,10 +887,9 @@ img {
font-size: 13px;
}
/* 小尖角 */
.tooltip::before {
content: '';
content: "";
position: absolute;
top: 90px; /* 调整尖角的垂直位置 */
left: -10px; /* 调整尖角的水平位置 */
@ -759,8 +899,6 @@ img {
//border-bottom: 10px solid green; /* */
//border-right: 10px solid blue; /* */
}
}
.gobal-dropdown-container {
@ -772,7 +910,7 @@ img {
.test {
width: 95px;
height: 25px;
background: #1C3472;
background: #1c3472;
}
.gobal-dropdown-container {
@ -788,6 +926,4 @@ img {
width: 90px;
color: #fff;
}
</style>

9
src/views/datav/subonedatav/SubOneVideoInsp.vue

@ -21,14 +21,7 @@
</div>
</div>
<div class="mb-12">
<video
width="100%"
height="250"
controls="controls"
autoplay
>
<source src="/mp4/1.mp4" type="video/ogg"/>
</video>
</div>
<el-row :gutter="12">
<el-col :span="8">

170
src/views/rightsComfort/Comfort.vue

@ -0,0 +1,170 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="申请时间">
<date-time-range-picker-ext
v-model="query.applyDate"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="事发时间">
<date-time-range-picker-ext
v-model="query.happenTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="姓名">
<el-input
placeholder="请输入姓名"
v-model="query.applicantEmpName"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申请人单位">
<depart-tree-select v-model="query.departId" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex end">
<div>
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</header>
<div class="table-container">
<el-table :data="list">
<el-table-column
label="抚慰编号"
prop="number"
show-overflow-tooltip
/>
<el-table-column
label="申请时间"
prop="applyDate"
width="160"
/>
<el-table-column
label="事发时间"
prop="happenTime"
width="160"
/>
<el-table-column
label="申请人姓名"
prop="applicantEmpName"
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column label="开户行">
<template #default="{ row }">
<span>{{ row.bankCard }}</span>
<span>{{ row.bankBranch }}</span>
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag type="primary">{{
getDictLable(dict.comfortStatus, row.rpcStatus)
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button link type="primary" @click="handleShow(row)"
>查看</el-button
>
<el-button link type="danger" @click="handleDelete(row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList"
@current-change="getList"
:page-sizes="[10, 20, 50]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
</div>
<comfort-dialog v-model:show="actionShow" :id="activeRpcId" />
</template>
<script setup>
import moment from "moment";
import { listComfort, delComfort } from "@/api/rightsComfort/comfort";
import { listPolice } from "@/api/system/police";
import { getDictLable } from "@/utils/util";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts([
"formsOfTort",
"injurySeverity",
"incidentLink",
"comfortStatus",
]);
const list = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
function getList() {
listComfort(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
getList();
const actionShow = ref(false);
const activeRpcId = ref(false);
function handleShow(row) {
actionShow.value = true;
activeRpcId.value = row.rpcId;
}
const handleDelete = async (row) => {
await feedback.confirm(`确定要删除 ${row.number}`);
await delComfort(row.rpcId);
feedback.msgSuccess("删除成功");
getList();
};
</script>
<style lang="scss" scoped>
h5 {
margin: 10px 0;
}
</style>

891
src/views/rightsComfort/MyComfort.vue

@ -0,0 +1,891 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="申请时间">
<date-time-range-picker-ext
v-model="query.applyDate"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="事发时间">
<date-time-range-picker-ext
v-model="query.happenTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="姓名">
<el-input
placeholder="请输入姓名"
v-model="query.applicantEmpName"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申请人单位">
<depart-tree-select v-model="query.departId" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex between">
<el-button type="primary" @click="handleShowAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
申请抚慰</el-button
>
<div>
<el-button type="primary" @click="search">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</header>
<el-tabs>
<el-tab-pane label="我的待办">
<div class="table-container">
<el-table :data="todos">
<el-table-column
label="抚慰编号"
prop="number"
show-overflow-tooltip
/>
<el-table-column
label="申请时间"
prop="applyDate"
width="160"
/>
<el-table-column
label="事发时间"
prop="happenTime"
width="160"
/>
<el-table-column
label="申请人姓名"
prop="applicantEmpName"
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column label="开户行">
<template #default="{ row }">
<span>{{ row.bankCard }}</span>
<span>{{ row.bankBranch }}</span>
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag type="primary" v-if="row.rpcStatus">{{
getDictLable(
dict.comfortStatus,
row.rpcStatus
)
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button
link
type="primary"
@click="handleShow(row, false)"
>立即处理</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getTodos"
@current-change="getTodos"
:page-sizes="[10, 20, 50]"
v-model:page-size="todoPage.size"
v-model:current-page="todoPage.current"
layout="total, sizes, prev, pager, next"
:total="todoPage.total"
>
</el-pagination>
</div>
</el-tab-pane>
<el-tab-pane label="我的已办">
<div class="table-container">
<el-table :data="dones">
<el-table-column
label="抚慰编号"
prop="number"
show-overflow-tooltip
/>
<el-table-column
label="申请时间"
prop="applyDate"
width="160"
/>
<el-table-column
label="事发时间"
prop="happenTime"
width="160"
/>
<el-table-column
label="申请人姓名"
prop="applicantEmpName"
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column label="当前审批人" prop="approver">
</el-table-column>
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag type="primary">{{
getDictLable(
dict.comfortStatus,
row.rpcStatus
)
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button link type="primary" @click="handleShow(row, true)">查看</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getDones"
@current-change="getDones"
:page-sizes="[10, 20, 50]"
v-model:page-size="donePage.size"
v-model:current-page="donePage.current"
layout="total, sizes, prev, pager, next"
:total="donePage.total"
>
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
</div>
<el-dialog
title="申请抚慰"
v-model="show"
width="60vw"
top="2vh"
style="margin-bottom: 0"
>
<el-scrollbar max-height="calc(96vh - 130px)">
<el-form :label-width="140" ref="formRef" :model="formData">
<h5>办理信息</h5>
<el-row>
<el-col :span="12">
<el-form-item
label="申请时间"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-date-picker
v-model="formData.applyDate"
type="date"
placeholder="请选择"
value-format="YYYY-MM-DD"
style="width: 300px"
:disabled-date="disabledDate"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="主办单位"
:rules="{
required: true,
message: '请选择',
}"
prop="handleDepartId"
>
<div style="width: 300px">
<depart-tree-select
v-model="formData.handleDepartId"
:check-strictly="true"
@node-click="
(node) =>
(formData.handleDepartName =
node.shortName)
"
/>
</div>
</el-form-item>
</el-col>
</el-row>
<el-divider />
<el-row>
<el-col :span="12">
<el-form-item
label="是否为本人申请"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-radio-group v-model="formData.isSelf">
<el-radio :value="1"></el-radio>
<el-radio :value="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.isSelf === 0">
<el-form-item
label="关系"
:rules="{
required: true,
trigger: ['blur'],
message: '请选择',
}"
prop="relation"
>
<el-radio-group v-model="formData.relation">
<el-radio :value="1">同事</el-radio>
<el-radio :value="2">亲属</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.isSelf === 0">
<el-form-item
label="代理人姓名"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-input
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.isSelf === 0">
<el-form-item
label="代理人单位"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<div style="width: 300px">
<depart-tree-select
v-model="formData.handleDepartId"
:check-strictly="true"
@node-click="
(node) =>
(formData.handleDepartName =
node.shortName)
"
/>
</div>
</el-form-item>
</el-col>
</el-row>
<h5>申请人信息</h5>
<el-row>
<el-col :span="12">
<el-form-item
label="申请人姓名"
:rules="{
required: true,
message: '请输入',
}"
prop="applicantEmpName"
>
<el-autocomplete
v-model="formData.applicantEmpName"
:fetch-suggestions="querySearch"
:trigger-on-focus="false"
value-key="name"
clearable
placeholder="请输入姓名搜索"
@select="handleSelect"
style="width: 300px"
>
<template #default="{ item }">
<span class="mr-10">{{ item.name }}</span>
<span class="text-primary">{{
item.empNo
}}</span>
</template>
</el-autocomplete>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="性别"
:rules="{
required: true,
message: '请选择性别',
}"
prop="sex"
>
<el-radio-group v-model="formData.sex">
<el-radio :value="0"></el-radio>
<el-radio :value="1"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="出生年月"
:rules="{
required: true,
message: '请选择出生年月',
}"
prop="birthday"
>
<el-date-picker
v-model="formData.birthday"
type="date"
placeholder="请选择"
value-format="YYYY-MM-DD"
style="width: 300px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="文化程度"
:rules="{
required: true,
message: '请选择',
}"
prop="levelEducation"
>
<el-select
clearable
style="width: 300px"
v-model="formData.levelEducation"
>
<el-option value="高中">高中</el-option>
<el-option value="大专">大专</el-option>
<el-option value="本科">本科</el-option>
<el-option value="研究生及以上"
>研究生及以上</el-option
>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="政治面貌"
:rules="{
required: true,
message: '请选择',
}"
prop="politicCountenance"
>
<el-select
clearable
style="width: 300px"
v-model="formData.politicCountenance"
>
<el-option value="群众">群众</el-option>
<el-option value="团员">团员</el-option>
<el-option value="预备党员">预备党员</el-option>
<el-option value="党员">党员</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="身份证号码"
:rules="{
required: true,
message: '请输入',
}"
prop="idCode"
>
<el-input
v-model="formData.idCode"
clearable
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="联系电话"
:rules="{
required: true,
message: '请输入',
}"
prop="mobile"
>
<el-input
v-model="formData.mobile"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="单位"
:rules="{
required: true,
message: '请选择',
}"
prop="departId"
>
<div style="width: 300px">
<depart-tree-select
v-model="formData.departId"
:check-strictly="true"
@node-click="
(node) =>
(formData.departName =
node.shortName)
"
/>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职务" prop="job">
<el-input
v-model="formData.job"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="警号"
:rules="{
required: true,
message: '请输入',
}"
prop="empNo"
>
<el-input
v-model="formData.empNo"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="警衔" prop="policeRank">
<el-input
v-model="formData.policeRank"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="开户行" prop="bankCard">
<el-input
v-model="formData.bankCard"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属支行" prop="bankBranch">
<el-input
v-model="formData.bankBranch"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="银行账号" prop="bankCardAccount">
<el-input
v-model="formData.bankCardAccount"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
</el-row>
<el-divider />
<h5>案发情况</h5>
<el-row>
<el-col :span="12">
<el-form-item
label="事发时间"
prop="happenTime"
:rules="{
required: true,
message: '请选择',
}"
>
<el-date-picker
v-model="formData.happenTime"
type="datetime"
placeholder="请选择"
value-format="YYYY-MM-DD HH:mm"
time-format="HH:mm"
style="width: 300px"
:disabled-date="disabledDate"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item
label="事实及理由"
prop="factReason"
:rules="{
required: true,
message: '请输入',
}"
>
<el-input
v-model="formData.factReason"
type="textarea"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="案发环节"
prop="incidentLink"
:rules="{
required: true,
message: '请选择',
}"
>
<el-select
v-model="formData.incidentLink"
style="width: 300px"
clearable
@change="
(val) =>
(formData.incidentLinkName =
dict.incidentLink.find(
(item) => item.dictValue === val
)?.dictLabel)
"
>
<el-option
v-for="item in dict.incidentLink"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="受伤程度"
prop="injurySeverity"
:rules="{
required: true,
message: '请选择',
}"
>
<el-select
v-model="formData.injurySeverity"
style="width: 300px"
clearable
@change="
(val) =>
(formData.injurySeverityName =
dict.injurySeverity.find(
(item) => item.dictValue === val
)?.dictLabel)
"
>
<el-option
v-for="item in dict.injurySeverity"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="侵权形式"
prop="formsOfTort"
:rules="{
required: true,
message: '请选择',
}"
>
<el-select
v-model="formData.formsOfTort"
style="width: 300px"
clearable
@change="
(val) =>
(formData.formsOfTortName =
dict.formsOfTort.find(
(item) => item.dictValue === val
)?.dictLabel)
"
>
<el-option
v-for="item in dict.formsOfTort"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="办案单位"
prop=""
:rules="{
required: true,
message: '请选择',
}"
>
<div style="width: 300px">
<depart-tree-select :check-strictly="true" />
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="侵权人姓名"
prop="infringerName"
:rules="{
required: true,
message: '请输入',
}"
>
<el-input
v-model="formData.infringerName"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="处理方式"
prop="infringerHandle"
:rules="{
required: true,
message: '请输入',
}"
>
<el-input
v-model="formData.infringerHandle"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
</el-row>
<el-divider />
<h5>佐证材料</h5>
<el-row>
<el-col :span="12">
<el-form-item label="附件" prop="documentFile">
<file-upload v-model:files="formData.documentFile" />
</el-form-item>
</el-col>
</el-row>
<el-divider />
<h5>呈报审批</h5>
<el-row>
<el-col :span="12">
<el-form-item
label="审批人"
:rules="{
required: true,
message:
'未选择主办单位或当前主办单位的未配置维权专干(请联系系统管理员)',
}"
prop="approverEmpNo"
>
<el-input disabled v-model="formData.approver" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-scrollbar>
<footer class="flex end">
<el-button @click="show = false" size="large">取消</el-button>
<el-button type="primary" @click="submit" size="large"
>确定</el-button
>
</footer>
</el-dialog>
<comfort-dialog v-model:show="actionShow" :id="activeRpcId" :disabled="dialogDisabled" />
</template>
<script setup>
import moment from "moment";
import { listTodos, listDone, applyComfort } from "@/api/rightsComfort/comfort";
import { listPolice } from "@/api/system/police";
import { listRightPersonByDepartId } from "@/api/system/rightPerson";
import { getDictLable } from "@/utils/util";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
import { onMounted } from "vue";
const catchStore = useCatchStore();
const dict = catchStore.getDicts([
"formsOfTort",
"injurySeverity",
"incidentLink",
"comfortStatus",
]);
const query = ref({
});
const todos = ref([]);
const todoPage = reactive({
total: 0,
current: 1,
size: 10,
});
const dones = ref([])
const donePage = reactive({
total: 0,
current: 1,
size: 10,
});
function getTodos() {
const queryParam = {...query.value}
queryParam.current = todoPage.current
queryParam.size = todoPage.size
listTodos(queryParam).then((data) => {
todos.value = data.records;
todoPage.total = data.total;
});
}
function getDones() {
const queryParam = {...query.value}
queryParam.current = donePage.current
queryParam.size = donePage.size
listDone(queryParam).then((data) => {
dones.value = data.records;
donePage.total = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getTodos();
getDones()
}
function search() {
getTodos()
getDones()
}
onMounted(() => {
getTodos();
getDones()
})
const show = ref(false);
const formData = ref({
applyDate: moment().format("YYYY-MM-DD"),
});
const formRef = ref(null);
function submit() {
formRef.value.validate((flag) => {
if (flag) {
applyComfort(formData.value).then(() => {
feedback.msgSuccess("操作成功");
show.value = false;
formData.value = {
applyDate: moment().format("YYYY-MM-DD"),
};
getDones()
});
}
});
}
function handleShowAdd() {
show.value = true;
}
async function querySearch(queryString, cb) {
if (!queryString) {
cb([]);
}
const data = await listPolice({
size: 20,
current: 1,
name: queryString,
});
cb(data.records);
}
function handleSelect(item) {
formData.value.empNo = item.empNo;
formData.value.idCode = item.idCode;
formData.value.mobile = item.mobile;
}
watch(
() => formData.value.handleDepartId,
(val) => {
listRightPersonByDepartId(val).then((data) => {
if (data.length) {
formData.value.approverEmpNo = data.map(item => item.empNo)
formData.value.approver = data.map(item => item.empName).join('、')
} else {
delete formData.value.approverEmpNo;
delete formData.value.approver;
}
});
}
);
const actionShow = ref(false);
const activeRpcId = ref(false)
const dialogDisabled = ref(true)
function handleShow(row, disabled) {
actionShow.value = true
activeRpcId.value = row.rpcId
dialogDisabled.value = disabled
}
</script>
<style lang="scss" scoped>
h5 {
margin: 10px 0;
}
</style>

167
src/views/rightsComfort/Rights.vue

@ -0,0 +1,167 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="申请时间">
<date-time-range-picker-ext
v-model="query.applyDate"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="事发时间">
<date-time-range-picker-ext
v-model="query.happenTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="姓名">
<el-input
placeholder="请输入姓名"
v-model="query.applicantEmpName"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申请人单位">
<depart-tree-select v-model="query.departId" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex end">
<div>
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</header>
<div class="table-container">
<el-table :data="list">
<el-table-column
label="维权编号"
prop="number"
show-overflow-tooltip
/>
<el-table-column
label="申请时间"
prop="applyDate"
width="160"
/>
<el-table-column
label="事发时间"
prop="happenTime"
width="160"
/>
<el-table-column
label="申请人姓名"
prop="applicantEmpName"
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column label="状态" width="100">
<template #default="{ row }">
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button
link
type="primary"
@click="handleShow(row)"
>查看</el-button
>
<el-button
link
type="danger"
@click="handleShow(row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList"
@current-change="getList"
:page-sizes="[10, 20, 50]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
</div>
</template>
<script setup>
import moment from "moment";
import { listRights } from "@/api/rightsComfort/rights";
import { listPolice } from "@/api/system/police";
import { getDictLable } from "@/utils/util";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts([
"formsOfTort",
"injurySeverity",
"incidentLink",
"comfortStatus"
]);
const list = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
function getList() {
listRights(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
getList();
const actionShow = ref(false);
const activeRpcId = ref(false)
function handleShow(row) {
actionShow.value = true
activeRpcId.value = row.rpcId
}
const handleDelete = async (row) => {
await feedback.confirm(`确定要删除 ${row.number}`);
// await delComfort(row.rpcId);
feedback.msgSuccess("删除成功");
getList();
};
</script>
<style lang="scss" scoped>
h5 {
margin: 10px 0;
}
</style>

7
src/views/system/Menu.vue

@ -125,7 +125,12 @@
</el-form-item>
<el-form-item
label="菜单图标"
v-if="formData.menuType !== MenuEnum.BUTTON"
v-if="formData.menuType === MenuEnum.CATALOGUE"
:rules="{
required: true,
message: '请选择图标'
}"
prop="icon"
>
<icon-picker class="flex-1" v-model="formData.icon" />
</el-form-item>

14
src/views/system/Operating.vue

@ -0,0 +1,14 @@
<template>
<iframe :src="`${BASE_PATH}/templates/长沙市公安局数字督察一体化平台-操作手册V1.pdf`"></iframe>
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
</script>
<style lang="scss" scoped>
iframe {
width: 100%;
height: 100vh;
display: block;
border: none;
}
</style>

242
src/views/system/Police.vue

@ -1,5 +1,7 @@
<template>
<div class="container">
<el-tabs>
<el-tab-pane label="警员列表">
<header>
<el-form :label-width="114">
<el-row>
@ -45,7 +47,10 @@
</el-col>
<el-col :span="12">
<el-form-item label="所属单位">
<div class="flex gap v-center" style="width: 100%">
<div
class="flex gap v-center"
style="width: 100%"
>
<div style="width: 220px">
<depart-tree-select
v-model="query.departId"
@ -158,7 +163,10 @@
<label>入职时间</label>
<span>{{ row.employmentDate }}</span>
</div>
<div class="col col-6" v-if="row.employmentDate">
<div
class="col col-6"
v-if="row.employmentDate"
>
<label>工龄</label>
<span>{{
getWorkYear(row.employmentDate)
@ -197,14 +205,25 @@
</div>
</template>
</el-table-column>
<el-table-column label="人员属性" width="120" align="center">
<el-table-column
label="人员属性"
width="120"
align="center"
>
<template #default="{ row }">
<span>{{
getDictLable(dict.personType, row.personType)
getDictLable(
dict.personType,
row.personType
)
}}</span>
</template>
</el-table-column>
<el-table-column label="职位" width="120" align="center">
<el-table-column
label="职位"
width="120"
align="center"
>
<template #default="{ row }">
<span v-if="row.position">
<span v-if="row.level === 0"
@ -222,13 +241,18 @@
</span>
</template>
</el-table-column>
<el-table-column label="身份证" prop="idCode" width="200" />
<el-table-column
label="身份证"
prop="idCode"
width="200"
/>
<el-table-column label="角色" show-overflow-tooltip>
<template #default="{ row }">
<div class="flex gap" v-if="row.role">
<el-tag v-for="item in row.role.split(',')">{{
item
}}</el-tag>
<el-tag
v-for="item in row.role.split(',')"
>{{ item }}</el-tag
>
</div>
</template>
</el-table-column>
@ -277,6 +301,161 @@
>
</el-pagination>
</div>
</el-tab-pane>
<el-tab-pane label="异常警员">
<header>
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="警员姓名">
<el-input
placeholder="请输入警员姓名"
v-model="abnormalQuery.name"
clearable
style="width: 220px"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="警号">
<el-input
placeholder="请输入"
v-model="abnormalQuery.empNo"
clearable
style="width: 220px"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="身份证">
<el-input
placeholder="请输入身份证号码"
v-model="abnormalQuery.idCode"
clearable
style="width: 220px"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="电话">
<el-input
placeholder="请输入电话"
v-model="abnormalQuery.phone"
clearable
style="width: 220px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属单位">
<div
class="flex gap v-center"
style="width: 100%"
>
<div style="width: 220px">
<depart-tree-select
v-model="abnormalQuery.departId"
/>
</div>
<el-checkbox
v-model="abnormalQuery.departBranch"
label="当前单位及所有子单位"
size="large"
/>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="mb-25 flex end">
<div>
<el-button type="primary" @click="getAbnormalList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="abnormalReset">重置</el-button>
</div>
</div>
</header>
<div class="table-container" v-loading="loading">
<el-table :data="abnormalPolices" row-key="id">
<el-table-column label="姓名" prop="name" width="90" />
<el-table-column
label="警号"
prop="empNo"
width="100"
show-overflow-tooltip
/>
<el-table-column label="所属机构" show-overflow-tooltip>
<template #default="{ row }">
<div class="flex gap-4">
<span v-if="row.parentDepartShortName"
>{{ row.parentDepartShortName }}/</span
><span>{{ row.departShortName }}</span>
</div>
</template>
</el-table-column>
<el-table-column
label="人员属性"
width="120"
align="center"
>
<template #default="{ row }">
<span>{{
getDictLable(
dict.personType,
row.personType
)
}}</span>
</template>
</el-table-column>
<el-table-column
label="职位"
width="120"
align="center"
>
<template #default="{ row }">
<span v-if="row.position">
<span v-if="row.level === 0"
>局领导{{ row.position }}</span
>
<span v-if="row.level === 2"
>二级机构{{ row.position }}</span
>
<span v-if="row.level === 3"
>三机机构{{ row.position }}</span
>
<span v-if="row.level === 4"
>四机机构{{ row.position }}</span
>
</span>
</template>
</el-table-column>
<el-table-column
label="身份证"
prop="idCode"
width="200"
/>
<el-table-column label="异常原因" prop="delReason" show-overflow-tooltip />
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getAbnormalList"
@current-change="getAbnormalList"
:page-sizes="[10, 20, 50]"
v-model:page-size="abnormalQuery.size"
v-model:current-page="abnormalQuery.current"
layout="total, sizes, prev, pager, next"
:total="abnormalTotal"
>
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
</div>
<el-dialog
@ -370,11 +549,17 @@
:headers="{ Authorization: getToken() }"
:show-file-list="false"
@success="handleUploadImgSuccess"
accept="image/*"
>
<img v-if="form.avatarUrl" :src="`${BASE_PATH}/file/stream/${form.avatarUrl}`" class="police-avatar" />
<div class="flex v-center center column upload-action" v-else>
<img
v-if="form.avatarUrl"
:src="`${BASE_PATH}/file/stream/${form.avatarUrl}`"
class="police-avatar"
/>
<div
class="flex v-center center column upload-action"
v-else
>
<icon :size="16" name="el-icon-Plus" />
<span>上传照片</span>
</div>
@ -536,6 +721,7 @@ import { BASE_PATH } from "@/api/request";
import { UserFilled } from "@element-plus/icons-vue";
import {
listPolice,
listAbnormalPolice,
getPoliceAuths,
addPolice,
updatePolice,
@ -580,6 +766,7 @@ function getList() {
const roles = ref([]);
onMounted(() => {
getList();
getAbnormalList();
listRole().then((data) => {
roles.value = data;
});
@ -593,6 +780,30 @@ function reset() {
getList();
}
const abnormalPolices = ref([]);
const abnormalQuery = ref({
current: 1,
size: 10,
})
const abnormalTotal = ref(0)
function getAbnormalList() {
loading.value = true;
listAbnormalPolice(abnormalQuery.value).then((data) => {
loading.value = false;
abnormalPolices.value = data.records;
abnormalTotal.value = data.total;
});
}
function abnormalReset() {
abnormalQuery.value = {
current: 1,
size: 10,
};
getList();
}
const authShow = ref(false);
const authForm = ref({});
let activeIdCode = "";
@ -714,14 +925,15 @@ async function handleDel(row) {
delDialog.value = false;
delFormData.value = {};
getList();
getAbnormalList()
}
function handleUploadImgSuccess(result, file) {
if (result.code !== 200) {
feedback.msgError('上传失败')
return
feedback.msgError("上传失败");
return;
}
form.value.avatarUrl = result.data.filePath
form.value.avatarUrl = result.data.filePath;
}
</script>
<style lang="scss" scoped>

265
src/views/system/Wqzg.vue

@ -0,0 +1,265 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="所属单位">
<depart-tree-select v-model="query.departId" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="警员姓名">
<el-input
placeholder="请输入警员姓名"
v-model="query.empName"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="警号">
<el-input
placeholder="请输入警号"
v-model="query.empNo"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex between">
<el-button type="primary" @click="handleShowAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增维权专干</el-button
>
<div>
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</header>
<div class="table-container">
<el-table :data="list">
<el-table-column label="所属单位" prop="departName">
<template #default="{ row }">
<span v-if="row.council === '1'">长沙市公安局</span>
<span v-else>{{ row.departName }}</span>
</template>
</el-table-column>
<el-table-column label="警员姓名" prop="empName" width="200" />
<el-table-column label="警号" prop="empNo" width="200" />
<el-table-column
label="市局维权专干"
align="center"
width="180"
>
<template #default="{ row }">
<span v-if="row.council === '1'"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleEdit(row)"
v-perms="['user:edit']"
>编辑</el-button
>
<el-button
type="danger"
link
@click="handleDelete(row)"
v-perms="['user:del']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList"
@current-change="getList"
:page-sizes="[10, 20, 50]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
</div>
<el-dialog
:title="mode === 'add' ? '新增维权专干' : '编辑维权专干'"
v-model="show"
width="600"
>
<el-form :label-width="120" ref="formRef" :model="formData">
<el-form-item
label="市局维权专干"
:rules="{
required: true,
message: '请选择',
}"
prop="council"
>
<el-radio-group v-model="formData.council">
<el-radio value="1"></el-radio>
<el-radio value="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="单位"
:rules="{
required: true,
message: '请选择',
}"
prop="departId"
v-if="formData.council === '0'"
>
<depart-tree-select v-model="formData.departId" @node-click="(node) => formData.departName = node.shortName" />
</el-form-item>
<el-form-item
label="警员"
:rules="{
required: true,
message: '请选择警员',
}"
prop="empName"
>
<el-autocomplete
v-model="formData.empName"
:fetch-suggestions="querySearch"
:trigger-on-focus="false"
value-key="name"
clearable
placeholder="请输入警号搜索"
@select="handleSelect"
>
<template #default="{ item }">
<span class="mr-10">{{ item.name }}</span>
<span class="text-primary">{{ item.empNo }}</span>
</template>
</el-autocomplete>
</el-form-item>
</el-form>
<footer class="flex end mt-60">
<el-button @click="show = false" size="large">取消</el-button>
<el-button type="primary" @click="submit" size="large"
>确定</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import {
listRightPerson,
addRightPerson,
updateRightPerson,
delRightPerson,
} from "@/api/system/rightPerson";
import { listPolice } from "@/api/system/police";
import feedback from "@/utils/feedback";
const list = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
function getList() {
listRightPerson(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
getList();
const show = ref(false);
const mode = ref("add");
const formData = ref({});
const formRef = ref(null);
function handleEdit(row) {
show.value = true;
mode.value = "edit";
formData.value = row;
}
function submit() {
formRef.value.validate((flag) => {
if (flag) {
if (mode.value === "edit") {
updateRightPerson(formData.value).then(() => {
show.value = false;
getList();
feedback.msgSuccess("操作成功");
});
} else {
addRightPerson(formData.value).then(() => {
show.value = false;
formData.value = {};
getList();
feedback.msgSuccess("操作成功");
});
}
}
});
}
watch(mode, (val) => {
if (val === "add") {
formData.value = {};
}
});
function handleShowAdd() {
mode.value = "add";
show.value = true;
}
async function querySearch(queryString, cb) {
if (!queryString) {
cb([]);
}
const data = await listPolice({
size: 20,
current: 1,
empNo: queryString,
});
cb(data.records);
}
function handleSelect(item) {
console.log(item)
formData.value.empName = item.name;
formData.value.empNo = item.empNo;
formData.value.idCode = item.idCode;
}
const handleDelete = async (row) => {
await feedback.confirm(`确定要删除 ${row.empName}`);
await delRightPerson(row.id);
feedback.msgSuccess("删除成功");
getList();
};
</script>
<style lang="scss" scoped>
</style>

661
src/views/work/Comfort.vue

@ -1,661 +0,0 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="申请时间">
<date-time-range-picker-ext
v-model="query.applyDate"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="事发时间">
<date-time-range-picker-ext
v-model="query.happenTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="姓名">
<el-input
placeholder="请输入姓名"
v-model="query.applicantEmpName"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申请人单位">
<depart-tree-select v-model="query.departId" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex between">
<el-button type="primary" @click="handleShowAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
申请抚慰</el-button
>
<div>
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</header>
<div class="table-container">
<el-table :data="list">
<el-table-column
label="抚慰编号"
prop="number"
show-overflow-tooltip
/>
<el-table-column
label="申请时间"
prop="applyDate"
width="160"
/>
<el-table-column
label="事发时间"
prop="happenTime"
width="160"
/>
<el-table-column
label="申请人姓名"
prop="applicantEmpName"
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column label="开户行">
<template #default="{ row }">
<span>{{ row.bankCard }}</span>
<span>{{ row.bankBranch }}</span>
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag type="success" v-if="row.status === 1"
>正常</el-tag
>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<!-- <el-button
link
>查看</el-button
>
<el-button
link
>下载</el-button
>
<el-button
link
type="danger"
>删除</el-button
> -->
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList"
@current-change="getList"
:page-sizes="[10, 20, 50]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
</div>
<el-dialog
:title="mode === 'add' ? '申请抚慰' : '编辑抚慰信息'"
v-model="show"
width="60vw"
top="5vh"
>
<el-form :label-width="140" ref="formRef" :model="form">
<h5>办理信息</h5>
<el-form-item
label="申请时间"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-date-picker
v-model="formData.applyDate"
type="date"
placeholder="请选择"
value-format="YYYY-MM-DD"
style="width: 300px"
:disabled-date="disabledDate"
/>
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item
label="主办民警"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-input style="width: 300px" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="主办单位"
:rules="{
required: true,
trigger: ['blur'],
}"
prop="handleDepartId"
>
<div style="width: 300px">
<depart-tree-select
v-model="formData.handleDepartId"
:check-strictly="true"
@node-click="
(node) =>
(formData.handleDepartName =
node.shortName)
"
/>
</div>
</el-form-item>
</el-col>
</el-row>
<el-divider />
<el-row>
<el-col :span="12">
<el-form-item
label="是否为本人申请"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-radio-group v-model="formData.isSelf">
<el-radio :value="1"></el-radio>
<el-radio :value="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.isSelf === 0">
<el-form-item
label="关系"
:rules="{
required: true,
trigger: ['blur'],
message: '请选择',
}"
prop="relation"
>
<el-radio-group v-model="formData.relation">
<el-radio :value="1">同事</el-radio>
<el-radio :value="2">亲属</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.isSelf === 0">
<el-form-item
label="代理人姓名"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-input style="width: 300px" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.isSelf === 0">
<el-form-item
label="代理人单位"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<div style="width: 300px">
<depart-tree-select
v-model="formData.handleDepartId"
:check-strictly="true"
@node-click="
(node) =>
(formData.handleDepartName =
node.shortName)
"
/>
</div>
</el-form-item>
</el-col>
</el-row>
<h5>申请人信息</h5>
<el-row>
<el-col :span="12">
<el-form-item
label="申请人姓名"
:rules="{
required: true,
message: '请输入',
}"
prop="applicantEmpName"
>
<el-input
v-model="formData.applicantEmpName"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="性别"
:rules="{
required: true,
}"
prop=""
>
<el-radio-group v-model="formData.sex">
<el-radio value="男"></el-radio>
<el-radio value="女"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="出生年月"
:rules="{
required: true,
}"
prop=""
>
<el-date-picker
v-model="formData.birthday"
type="date"
placeholder="请选择"
value-format="YYYY-MM-DD"
style="width: 300px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="文化程度"
:rules="{
required: true,
}"
prop=""
>
<el-select
clearable
style="width: 300px"
v-model="formData.levelEducation"
>
<el-option value="高中">高中</el-option>
<el-option value="大专">大专</el-option>
<el-option value="本科">本科</el-option>
<el-option value="研究生及以上"
>研究生及以上</el-option
>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="政治面貌"
:rules="{
required: true,
}"
prop=""
>
<el-input
v-model="formData.idCode"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="身份证号码"
:rules="{
required: true,
}"
prop=""
>
<el-input
v-model="formData.idCode"
clearable
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="联系电话"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-input
v-model="formData.idCode"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="单位"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<div style="width: 300px">
<depart-tree-select
v-model="formData.involveDepartId"
:check-strictly="true"
/>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职务" prop="">
<el-input
v-model="formData.bankCard"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="警种"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<el-select
v-model="formData.policeType"
clearable
style="width: 300px"
>
<el-option
v-for="item in dict.policeType"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="警号"
:rules="{
required: true,
trigger: ['blur'],
}"
prop="applicantEmpNo"
>
<el-input
v-model="formData.applicantEmpNo"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="警衔" prop="">
<el-input
v-model="formData.applicantEmpNo"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="开户行" prop="bankCard">
<el-input
v-model="formData.bankCard"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属支行" prop="bankBranch">
<el-input
v-model="formData.bankBranch"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="银行账号" prop="bankCardAccount">
<el-input
v-model="formData.bankCardAccount"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
</el-row>
<el-divider />
<h5>案发情况</h5>
<el-row>
<el-col :span="12">
<el-form-item label="事发时间" prop="">
<el-date-picker
v-model="formData.discoveryTime"
type="datetime"
placeholder="请选择"
value-format="YYYY-MM-DD HH:mm"
time-format="HH:mm"
style="width: 300px"
:disabled-date="disabledDate"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="事实及理由" prop="">
<el-input
v-model="formData.bankCardAccount"
type="textarea"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="案发环节" prop="">
<el-input
v-model="formData.bankCardAccount"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="受伤程度" prop="">
<el-input
v-model="formData.bankCardAccount"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="侵权形式" prop="">
<el-input
v-model="formData.bankCardAccount"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="办案单位" prop="">
<el-input
v-model="formData.bankCardAccount"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="侵权人姓名" prop="">
<el-input
v-model="formData.bankCardAccount"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="处理方式" prop="">
<el-input
v-model="formData.bankCardAccount"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
</el-row>
<el-divider />
<h5>佐证材料</h5>
<el-row>
<el-col :span="12">
<el-form-item label="附件" prop="">
<file-upload />
</el-form-item>
</el-col>
</el-row>
<el-divider />
<h5>呈报审批</h5>
<el-row>
<el-col :span="12">
<el-form-item label="审批人" prop="">
<el-input />
</el-form-item>
</el-col>
</el-row>
</el-form>
<footer class="flex end">
<el-button @click="show = false" size="large">取消</el-button>
<el-button type="primary" @click="submit" size="large"
>确定</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import { listUser, addUser, updateUser } from "@/api/system/user";
import { listComfort } from "@/api/work/comfort";
import { listRole } from "@/api/system/role";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts(["policeType"]);
const list = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
function getList() {
listComfort(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
getList();
const show = ref(false);
const mode = ref("add");
const formData = ref({});
const formRef = ref(null);
function handleEdit(row) {
show.value = true;
mode.value = "edit";
form.value = row;
}
function submit() {
formRef.value.validate((flag) => {
if (flag) {
if (mode.value === "edit") {
updateUser(form.value).then(() => {
show.value = false;
getList();
feedback.msgSuccess("操作成功");
});
} else {
addUser(form.value).then(() => {
show.value = false;
form.value = {};
getList();
feedback.msgSuccess("操作成功");
});
}
}
});
}
watch(mode, (val) => {
if (val === "add") {
form.value = {
password: "123456",
};
}
});
function handleShowAdd() {
mode.value = "add";
show.value = true;
}
</script>
<style lang="scss" scoped>
h5 {
margin: 10px 0;
}
</style>

20
src/views/work/Query.vue

@ -185,14 +185,26 @@
</el-select>
<el-select
style="width: 120px"
placeholder="是否超时"
style="width: 160px"
placeholder="办理中是否超时"
clearable
v-model="query.timeoutFlag"
v-model="query.handleTimeoutFlag"
>
<el-option label="未超时" :value="false" />
<el-option label="已超时" :value="true" />
</el-select>
<el-select
style="width: 140px"
placeholder="办结是否超时"
clearable
v-model="query.timeoutFlag"
>
<el-option label="办结未超时" :value="false" />
<el-option label="办结超时" :value="true" />
</el-select>
<div class="flex gap-4" style="height: 32px">
<el-select
v-model="query.responderKey"
@ -227,6 +239,8 @@
<el-option label="市局下发" :value="0" />
<el-option label="二级机构下发" :value="2" />
</el-select>
</div>
</div>
</el-form>

Loading…
Cancel
Save