Compare commits

...

21 Commits

Author SHA1 Message Date
zzq ccfcbcefdd bug问题修改 2024-04-27 10:25:14 +08:00
Zhufu c3e5fcc1c1 【字典分类】删除空判断 2024-04-27 09:04:50 +08:00
滕嵩 6476e95c42 两个查询-地图版,版本管理 2024-04-26 16:55:56 +08:00
刘妍 4c635ebc0f Merge branch 'ly' 2024-04-26 16:35:36 +08:00
刘妍 ee73c2d697 优化详情视频,案件判读接口对接,图片上传页面搭建 2024-04-26 16:34:50 +08:00
Zhufu b8b6ffe6cc 【部门管理】【部门列表】点击后获取孩子节点 2024-04-26 15:13:13 +08:00
Zhufu 5433f662bd 【字典分类】分类标识需为数字 2024-04-26 11:41:57 +08:00
刘妍 db498456f1 Merge branch 'ly' 2024-04-26 10:49:23 +08:00
刘妍 4845f18684 文件上传内容优化,详情相关图片地址修改 2024-04-26 10:48:19 +08:00
石超 6260ca4275 地图无参数修改 2024-04-26 10:26:12 +08:00
zzq 3454c5a540 Merge branch 'main' of http://123.132.248.154:10000/HC_YFZX/ShiJiTianKongDiPingTai 2024-04-26 10:01:18 +08:00
石超 2c4349b71f 修改地图maxzoom到22层 2024-04-26 09:20:06 +08:00
石超 4468011267 Merge branch 'main' of http://123.132.248.154:10000/HC_YFZX/ShiJiTianKongDiPingTai 2024-04-26 09:17:39 +08:00
石超 d4ac33eb25 1. 修改绘制面时最后一个点的保存 2. 修改地图maxzoom到17层 2024-04-26 09:17:31 +08:00
Zhufu 31dfcd0441 【线索举报】画面列表显示 2024-04-26 09:06:19 +08:00
Zhufu 4518393108 【字典分类】画面 2024-04-26 08:44:07 +08:00
滕嵩 235cb9f371 办结查询、退回查询-无地图版 2024-04-25 16:51:42 +08:00
刘妍 fa25527257 案件详情优化适配,增加文件上传内容 2024-04-25 16:27:43 +08:00
刘妍 bc51ed3991 Merge branch 'ly' 2024-04-25 15:00:26 +08:00
刘妍 4e4ec20f40 案件判读初步搭建 2024-04-25 14:59:20 +08:00
石超 5a64936e28 添加控制绘制按钮显示隐藏的参数 2024-04-25 10:33:48 +08:00
68 changed files with 5695 additions and 583 deletions

View File

@ -10,7 +10,7 @@ VITE_GLOB_API_URL=http://192.168.10.104:9020
# File upload address optional
VITE_GLOB_UPLOAD_URL=/upload
VITE_GLOB_UPLOAD_URL=http://60.213.14.14:6070
# Interface prefix
VITE_GLOB_API_URL_PREFIX=

View File

@ -0,0 +1,11 @@
import { BasicFetchResult } from '@/api/model/baseModel';
// 常用返回消息
export interface responses {
code: number;
columnHeaders: [];
count: number;
result: [];
msg: string;
}
export type responsesmodel = BasicFetchResult<responses>;

100
src/api/demo/query.ts Normal file
View File

@ -0,0 +1,100 @@
import { responsesmodel } from './model/queryModal';
import { defHttp } from '@/utils/http/axios';
enum Api {
// complete-分页获取列表数据
Get_LoadCaseInfoList = '/api/DroneCaseinfo/LoadCaseInfoList',
// complete-
Get_LoadList = '/api/Categorys/LoadList',
// 获取数据字典明显根据分类编号
Get_load = '/api/SysDataItemDetail/Load',
// complete-
Get_OrgList = '/api/Orgs/OrgList',
// complete-导出
Get_ExportCaseInfoList = '/api/DroneCaseinfo/ExportCaseInfoList',
// 案件详情
Get_getCaseInfo = '/api/DroneCaseinfo/GetCaseInfo',
// 获取案件处理流程
Get_GetCaseFlowLog = '/api/DroneCaseinfo/GetCaseFlowLog',
// 处理详情
Get_GetDroneCaseDeal = '/api/DroneCaseinfo/GetDroneCaseDeal',
}
// complete-分页获取列表数据
export function fun_LoadDataBaseInfo(params) {
params.typeid = params.value.typeid;
params.org = params.value.org;
params.is_illegal = params.value.is_illegal;
params.case_no = params.value.case_no;
params.key = params.value.key;
params.deal_username = params.value.deal_username;
params.verifyuser = params.value.verifyuser;
params.report_start_time = params.value.report_start_time;
params.report_end_time = params.value.report_end_time;
params.countyid = params.value.countyid;
params.streetid = params.value.streetid;
params.communityid = params.value.communityid;
delete params.value;
return defHttp.get<responsesmodel>({
url: Api.Get_LoadCaseInfoList,
params,
});
}
// complete-分页获取列表数据
export function fun_LoadList(params) {
return defHttp.get<responsesmodel>({
url: Api.Get_LoadList,
params,
});
}
// 获取数据字典明显根据分类编号
export function fun_load(params) {
return defHttp.get<responsesmodel>({
url: Api.Get_load,
params,
});
}
// complete-分页获取列表数据
export function fun_OrgList(params) {
return defHttp.get<responsesmodel>({
url: Api.Get_OrgList,
params,
});
}
// complete-导出
export function fun_ExportCaseInfoList(params) {
return defHttp.get<responsesmodel>({
url: Api.Get_ExportCaseInfoList,
params,
});
}
// 案件详情
export function fun_getCaseInfo(params) {
return defHttp.get<responsesmodel>({
url: Api.Get_getCaseInfo,
params,
});
}
// 处理详情
export function fun_GetCaseFlowLog(params) {
return defHttp.get<responsesmodel>({
url: Api.Get_GetCaseFlowLog,
params,
});
}
// 获取案件处理流程
export function fun_GetDroneCaseDeal(params) {
return defHttp.get<responsesmodel>({
url: Api.Get_GetDroneCaseDeal,
params,
});
}

View File

@ -10,7 +10,7 @@ import {
AccountListGetResultModel,
RolePageListGetResultModel,
RoleListGetResultModel,
addDept
addDept,
} from './model/systemModel';
import { defHttp } from '@/utils/http/axios';
@ -18,7 +18,7 @@ enum Api {
DeptList = '/api/Orgs/OrgsTree',
AccountList = '/api/users/load',
AddAccount = '/api/Users/AddOrUpdate',
DeleteAccount = "/api/Users/Delete",
DeleteAccount = '/api/Users/Delete',
AddDept = '/api/Orgs/Add',
UpdateDept = '/api/Orgs/Update',
DeleteDept = '/api/Orgs/Delete',
@ -55,6 +55,7 @@ enum Api {
LoadDataBaseLinkTree = '/api/SysDatabaseLink/LoadDataBaseLinkTree',
GetPosInfo = '/api/SysPosition/Get',
UpdatePosition = '/api/SysPosition/Update',
getChildrenTree = '/api/Orgs/LoadChildren',
}
export const getPositionsTree = (params?: AccountParams) =>
@ -84,187 +85,143 @@ export const loadForRole = (params?: DeptListItem) =>
export const loadByRole = (params?: DeptListItem) =>
defHttp.get<DeptListGetResultModel>({ url: Api.LoadByRole, params });
export const getChildrenTree = (params:{parentId:number}) =>
defHttp.get({ url: Api.getChildrenTree, params });
export function addAccount(params) {
return defHttp.post(
{
url: Api.AddAccount,
params,
},
);
return defHttp.post({
url: Api.AddAccount,
params,
});
}
export function deleteAccount(params) {
return defHttp.post(
{
url: Api.DeleteAccount,
params,
},
);
return defHttp.post({
url: Api.DeleteAccount,
params,
});
}
export function addPosGroup(params) {
return defHttp.post(
{
url: Api.AddPosGroup,
params,
},
);
return defHttp.post({
url: Api.AddPosGroup,
params,
});
}
export function orgPosGroup(params) {
return defHttp.post(
{
url: Api.OrgPosGroup,
params,
},
);
return defHttp.post({
url: Api.OrgPosGroup,
params,
});
}
export function userRoles(params) {
return defHttp.post(
{
url: Api.UserRoles,
params,
},
);
return defHttp.post({
url: Api.UserRoles,
params,
});
}
export function userOrgs(params) {
return defHttp.post(
{
url: Api.UserOrgs,
params,
},
);
return defHttp.post({
url: Api.UserOrgs,
params,
});
}
export function addPosition(params) {
return defHttp.post(
{
url: Api.AddPosition,
params,
},
);
return defHttp.post({
url: Api.AddPosition,
params,
});
}
export function updatePosition(params) {
return defHttp.post(
{
url: Api.UpdatePosition,
params,
},
);
return defHttp.post({
url: Api.UpdatePosition,
params,
});
}
export function addDept(params) {
return defHttp.post(
{
url: Api.AddDept,
params,
},
);
return defHttp.post({
url: Api.AddDept,
params,
});
}
export function updateDept(params) {
return defHttp.post(
{
url: Api.UpdateDept,
params,
},
);
return defHttp.post({
url: Api.UpdateDept,
params,
});
}
export function deleteDept(params) {
return defHttp.post(
{
url: Api.DeleteDept,
params,
},
);
return defHttp.post({
url: Api.DeleteDept,
params,
});
}
export function addMenu(params) {
return defHttp.post(
{
url: Api.AddMenu,
params,
},
);
return defHttp.post({
url: Api.AddMenu,
params,
});
}
export function addButton(params) {
return defHttp.post(
{
url: Api.AddButton,
params,
},
);
return defHttp.post({
url: Api.AddButton,
params,
});
}
export function editMenu(params) {
return defHttp.post(
{
url: Api.EditMenu,
params,
},
);
return defHttp.post({
url: Api.EditMenu,
params,
});
}
export function editButton(params) {
return defHttp.post(
{
url: Api.EditButton,
params,
},
);
return defHttp.post({
url: Api.EditButton,
params,
});
}
export function deleteMenu(params) {
return defHttp.post(
{
url: Api.DeleteMenu,
params,
},
);
return defHttp.post({
url: Api.DeleteMenu,
params,
});
}
export function deleteButton(params) {
return defHttp.post(
{
url: Api.DeleteButton,
params,
},
);
return defHttp.post({
url: Api.DeleteButton,
params,
});
}
export function addRole(params) {
return defHttp.post(
{
url: Api.AddRole,
params,
},
);
return defHttp.post({
url: Api.AddRole,
params,
});
}
export function updateRole(params) {
return defHttp.post(
{
url: Api.UpdateRole,
params,
},
);
return defHttp.post({
url: Api.UpdateRole,
params,
});
}
export function deleteRole(params) {
return defHttp.post(
{
url: Api.DeleteRole,
params,
},
);
return defHttp.post({
url: Api.DeleteRole,
params,
});
}
export function assignModule(params) {
return defHttp.post(
{
url: Api.AssignModule,
params,
},
);
return defHttp.post({
url: Api.AssignModule,
params,
});
}
export const getMenuDetail = (params?: MenuParams) =>
defHttp.get({ url: Api.MenuDetail, params });
export const getMenuDetail = (params?: MenuParams) => defHttp.get({ url: Api.MenuDetail, params });
export const getMenuList = (params?: MenuParams) =>
defHttp.get<MenuListGetResultModel>({ url: Api.MenuList, params });
@ -287,10 +244,6 @@ export const isAccountExist = (account: string) =>
export const getLoadPositionByOrg = (params?: PositionByOrgParams) =>
defHttp.get<RolePageListGetResultModel>({ url: Api.LoadPositionByOrg, params });
export const getLoadDataBaseLinkTree = () =>
defHttp.get({ url: Api.LoadDataBaseLinkTree });
export const getPosInfo = (params) =>
defHttp.get({ url: Api.GetPosInfo, params });
export const getLoadDataBaseLinkTree = () => defHttp.get({ url: Api.LoadDataBaseLinkTree });
export const getPosInfo = (params) => defHttp.get({ url: Api.GetPosInfo, params });

29
src/api/demo/version.ts Normal file
View File

@ -0,0 +1,29 @@
import { responsesmodel } from './model/queryModal';
import { defHttp } from '@/utils/http/axios';
enum Api {
Get_GetUpdateFiles = '/api/SysAppFiles/GetUpdateFiles',
Post_Upload = '/api/Files/Upload',
Post_AddAppFiles = '/api/SysAppFiles/AddAppFiles',
}
export function fun_GetUpdateFiles(params) {
return defHttp.get<responsesmodel>({
url: Api.Get_GetUpdateFiles,
params,
});
}
export function fun_Upload(params) {
return defHttp.post<responsesmodel>({
url: Api.Post_Upload,
params,
});
}
export function fun_AddAppFiles(params) {
return defHttp.post<responsesmodel>({
url: Api.Post_AddAppFiles,
params,
});
}

View File

@ -1,25 +1,40 @@
// WFProcess 流程模版基本信息
// WFProcess 流程模版基本信息
import { defHttp } from '@/utils/http/axios';
import { caseFlowLogParams , flowLogModel , droneCaseDealModel ,droneCaseDealParams} from './model/index'
import {
caseFlowLogParams,
flowLogModel,
droneCaseDealModel,
droneCaseDealParams,
picListTaskParams,
} from './model/index';
enum Api {
// 获取案件详情步骤条
GetCaseFlowLog = '/api/DroneCaseinfo/GetCaseFlowLog',
// 获取案件处理详情
GetDroneCaseDeal = '/api/DroneCaseinfo/GetDroneCaseDeal',
// 获取案件详情
GetCaseInfo = '/api/DroneCaseinfo/GetCaseInfo',
// 获取案件详情
GetCaseInfo = '/api/DroneCaseinfo/GetCaseInfo',
// 案件列表
LoadCaseInfoList = '/api/DroneCaseinfo/LoadCaseInfoList',
// 获取GeoJson图层
GetDroneGeoJson='/api/DroneCaseinfo/GetDroneGeoJson'
GetDroneGeoJson = '/api/DroneCaseinfo/GetDroneGeoJson',
// 上报案件(案件判读保存)
AddDroneCaseInfo = '/api/DroneCaseinfo/AddDroneCaseInfo',
// 案件判读
UpdateDroneCaseInfoIntact = '/api/DroneCaseinfo/UpdateDroneCaseInfoIntact',
// 关闭案件
CloseDroneCaseInfo = '/api/DroneCaseinfo/CloseDroneCaseInfo',
// 上传图片任务列表
PicListTask = '/api/DroneShpImageexif/ListTask',
// 图片上传,创建任务
PicAddTask = '/api/DroneShpImageexif/AddTask',
}
/**
* @description: getCaseFlowLog
*/
export function getCaseFlowLog(params?: caseFlowLogParams) {
export function getCaseFlowLog(params?: caseFlowLogParams) {
return defHttp.get<flowLogModel>({ url: Api.GetCaseFlowLog, params });
}
/**
@ -47,4 +62,29 @@ export function getDroneGeoJson(params?: caseFlowLogParams) {
return defHttp.get<flowLogModel>({ url: Api.GetDroneGeoJson, params });
}
export function addDroneCaseInfo(params) {
return defHttp.post({
url: Api.AddDroneCaseInfo,
params,
});
}
export function updateDroneCaseInfoIntact(params) {
return defHttp.post({
url: Api.UpdateDroneCaseInfoIntact,
params,
});
}
export function closeDroneCaseInfo(params?: caseFlowLogParams) {
return defHttp.get<flowLogModel>({ url: Api.CloseDroneCaseInfo, params });
}
export function getPicListTask(params?: picListTaskParams) {
return defHttp.get<flowLogModel>({ url: Api.PicListTask, params });
}
export function addPicTask(params) {
return defHttp.post({
url: Api.PicAddTask,
params,
});
}

View File

@ -1,21 +1,22 @@
export interface caseFlowLogParams {
id?: string;
}
export interface droneCaseDealParams{
caseid?:string;
export interface droneCaseDealParams {
caseid?: string;
id?: string;
}
export interface flowLog {
name: string;
time: string;
user_name: string;
status: number;
state?:string;
state?: string;
}
export type flowLogModel = flowLog[];
export interface fileList{
filePath?:string | undefined;
s_filePath?:string;
export interface fileList {
filePath?: string | undefined;
s_filePath?: string;
}
export type fileListModel = fileList[];
@ -30,5 +31,9 @@ export type droneCaseDealModel = {
payment_pic_list?: any;
agree_checkout_pic_list?: any;
checkout_pic_list?: any;
};
export interface picListTaskParams {
beginDate?: string;
endDate?: string;
}

View File

@ -1,16 +1,15 @@
// WFDelegate 流程模版基本信息
// WFDelegate 流程模版基本信息
import { defHttp } from '@/utils/http/axios';
import {DetailParams} from './model/wfSchemeInfoModel'
import { DetailParams } from './model/wfSchemeInfoModel';
enum Api {
enum Api {
// 创建流程
LoadMyUserList = '/api/WFDelegate/LoadMyUserList',
}
/**
* @description: getLoadMyUserList
*/
export function getLoadMyUserList(params?: DetailParams) {
export function getLoadMyUserList(params?: DetailParams) {
return defHttp.get({ url: Api.LoadMyUserList, params });
}
}

View File

@ -1,8 +1,12 @@
// WFProcess 流程模版基本信息
// WFProcess 流程模版基本信息
import { defHttp } from '@/utils/http/axios';
import { CreateParams, DeleteDraftParams, RevokeAuditParams,LoadNextAuditorsParams } from './model/WFProcessModel'
import { MyUncompletedParams } from './model/WFTaskModel'
import {
CreateParams,
DeleteDraftParams,
RevokeAuditParams,
LoadNextAuditorsParams,
} from './model/WFProcessModel';
import { MyUncompletedParams } from './model/WFTaskModel';
enum Api {
// 创建流程
@ -28,73 +32,63 @@ enum Api {
// 加签审核
SignAudit = '/api/WFProcess/SignAudit',
// 流程审核
Audit='/api/WFProcess/Audit',
Audit = '/api/WFProcess/Audit',
// 获取下一节点审核人
LoadNextAuditors='/api/WFProcess/LoadNextAuditors',
LoadNextAuditors = '/api/WFProcess/LoadNextAuditors',
// 确认阅读
ReadFlow='/api/WFProcess/ReadFlow',
ReadFlow = '/api/WFProcess/ReadFlow',
}
/**
* @description: getLoadMyPage
*/
export function getLoadNextAuditors(params?: LoadNextAuditorsParams) {
export function getLoadNextAuditors(params?: LoadNextAuditorsParams) {
return defHttp.get({ url: Api.LoadNextAuditors, params });
}
/**
* @description:
*/
export function create(params?: CreateParams) {
return defHttp.post(
{
url: Api.Create,
params,
},
);
return defHttp.post({
url: Api.Create,
params,
});
}
/**
* @description:
*/
export function createAgain(params?: CreateParams) {
return defHttp.post(
{
url: Api.CreateAgain,
params,
},
);
return defHttp.post({
url: Api.CreateAgain,
params,
});
}
/**
* @description:
*/
export function signAudit(id?:String,params?: CreateParams) {
return defHttp.post(
{
url: Api.SignAudit+"?id="+id,
params,
},
);
export function signAudit(id?: String, params?: CreateParams) {
return defHttp.post({
url: Api.SignAudit + '?id=' + id,
params,
});
}
/**
* @description:
*/
export function audit(id:String,params?: CreateParams) {
return defHttp.post(
{
url: Api.Audit+"?id="+id,
params,
},
);
export function audit(id: String, params?: CreateParams) {
return defHttp.post({
url: Api.Audit + '?id=' + id,
params,
});
}
/**
* @description: 稿
*/
export function saveDraft(params?: CreateParams) {
return defHttp.post(
{
url: Api.SaveDraft,
params,
},
);
return defHttp.post({
url: Api.SaveDraft,
params,
});
}
/**
* @description: getLoadMyPage
@ -112,45 +106,37 @@ export function getLoadMyDraftPage(params?: MyUncompletedParams) {
* @description: 稿
*/
export function deleteDraft(params: DeleteDraftParams) {
return defHttp.post(
{
url: Api.DeleteDraft + "?id=" + params.id,
params,
},
);
return defHttp.post({
url: Api.DeleteDraft + '?id=' + params.id,
params,
});
}
/**
* @description:
*/
export function urge(params: DeleteDraftParams) {
return defHttp.post(
{
url: Api.Urge + "?id=" + params.id,
params,
},
);
return defHttp.post({
url: Api.Urge + '?id=' + params.id,
params,
});
}
/**
* @description:
*/
export function revoke(params: DeleteDraftParams) {
return defHttp.post(
{
url: Api.Revoke + "?id=" + params.id,
params,
},
);
return defHttp.post({
url: Api.Revoke + '?id=' + params.id,
params,
});
}
/**
* @description:
*/
export function revokeAudit(params: RevokeAuditParams) {
return defHttp.post(
{
url: Api.RevokeAudit + "?id=" + params.id + "&taskId=" + params.taskId,
params,
},
);
return defHttp.post({
url: Api.RevokeAudit + '?id=' + params.id + '&taskId=' + params.taskId,
params,
});
}
/**
* @description: getPBMN
@ -162,10 +148,8 @@ export function getBPMN(params: DeleteDraftParams) {
/**
* @description:
*/
export function ReadFlow(id: string) {
return defHttp.post(
{
url: Api.ReadFlow + "?id=" + id ,
},
);
}
export function ReadFlow(id: string) {
return defHttp.post({
url: Api.ReadFlow + '?id=' + id,
});
}

View File

@ -1,25 +1,35 @@
// WFSchemeInfo 流程模版基本信息
// WFSchemeInfo 流程模版基本信息
import { defHttp } from '@/utils/http/axios';
import {SchemeListParams,GetSchemeModel,AddParams,
DeleteParams,UpdateParams,StateParams,HistoryParams,GetHistoryModel,SchemeParams,DetailParams} from './model/wfSchemeInfoModel'
import {
SchemeListParams,
GetSchemeModel,
AddParams,
DeleteParams,
UpdateParams,
StateParams,
HistoryParams,
GetHistoryModel,
SchemeParams,
DetailParams,
} from './model/wfSchemeInfoModel';
enum Api {
enum Api {
// 流程模板基本信息
LoadPage = '/api/WFSchemeInfo/LoadPage',
Add = '/api/WFSchemeInfo/Add',
Update = '/api/WFSchemeInfo/Update',
Delete = '/api/WFSchemeInfo/Delete',
UpDateState = '/api/WFSchemeInfo/UpDateState',
GetDetail='/api/WFSchemeInfo/Get',
GetDetail = '/api/WFSchemeInfo/Get',
// 可用模板合集
Load='/api/WFSchemeInfo/Load',
Load = '/api/WFSchemeInfo/Load',
// 流程模板详细信息
LoadHistoryPage= '/api/WFScheme/LoadPage',
UpdateScheme='/api/WFSchemeInfo/UpdateScheme',
LoadHistoryPage = '/api/WFScheme/LoadPage',
UpdateScheme = '/api/WFSchemeInfo/UpdateScheme',
// 获取某模板历史数据
VerisonsLoad='/api/WFScheme/Load',
VerisonsLoad = '/api/WFScheme/Load',
// 获取自定义流程列表(流程发起页)
GetInfoList='/api/WFSchemeInfo/GetInfoList'
GetInfoList = '/api/WFSchemeInfo/GetInfoList',
}
/**
@ -28,57 +38,56 @@ import {SchemeListParams,GetSchemeModel,AddParams,
export function getLoadPage(params?: SchemeListParams) {
return defHttp.get<GetSchemeModel>({ url: Api.LoadPage, params });
}
export function getDetail(params?: DetailParams){
export function getDetail(params?: DetailParams) {
return defHttp.get({ url: Api.GetDetail, params });
}
/**
* @description: getLoad
*/
export function getLoad(params?: SchemeListParams) {
export function getLoad(params?: SchemeListParams) {
return defHttp.get<GetSchemeModel>({ url: Api.Load, params });
}
/**
* @description: postAdd
*/
export function postAdd( params?:AddParams) {
return defHttp.post(
{
url: Api.Add,
params,
},
);
}
export function update(params:UpdateParams) {
export function postAdd(params?: AddParams) {
return defHttp.post({
url: Api.Update+"?id="+params.schemeinfo.id,
params
url: Api.Add,
params,
});
}
export function del(params:DeleteParams) {
return defHttp.post({ url: Api.Delete + "?id=" + params.id });
export function update(params: UpdateParams) {
return defHttp.post({
url: Api.Update + '?id=' + params.schemeinfo.id,
params,
});
}
export function updateState(params:StateParams){
return defHttp.post({ url: Api.UpDateState + "?id=" + params.id +"&state="+params.state});
export function del(params: DeleteParams) {
return defHttp.post({ url: Api.Delete + '?id=' + params.id });
}
export function getLoadHistoryPage(params?:HistoryParams){
return defHttp.get<GetHistoryModel>({url:Api.LoadHistoryPage,params})
}
export function getVerisonsLoad(params?:HistoryParams){
return defHttp.get<GetHistoryModel>({url:Api.VerisonsLoad,params})
export function updateState(params: StateParams) {
return defHttp.post({ url: Api.UpDateState + '?id=' + params.id + '&state=' + params.state });
}
export function updateScheme(params:SchemeParams){
return defHttp.post({ url: Api.UpdateScheme + "?id=" + params.id +"&schemeId="+params.schemeId});
export function getLoadHistoryPage(params?: HistoryParams) {
return defHttp.get<GetHistoryModel>({ url: Api.LoadHistoryPage, params });
}
export function getVerisonsLoad(params?: HistoryParams) {
return defHttp.get<GetHistoryModel>({ url: Api.VerisonsLoad, params });
}
export function updateScheme(params: SchemeParams) {
return defHttp.post({
url: Api.UpdateScheme + '?id=' + params.id + '&schemeId=' + params.schemeId,
});
}
/**
* @description: getInfoList
*/
export function getInfoList(params) {
export function getInfoList(params) {
return defHttp.get({ url: Api.GetInfoList, params });
}

View File

@ -1,55 +1,53 @@
// WFTask
import { defHttp } from '@/utils/http/axios';
import {MyUncompletedParams,TaskDetailParam} from './model/WFTaskModel'
import { MyUncompletedParams, TaskDetailParam } from './model/WFTaskModel';
enum Api {
enum Api {
// 我的待办
LoadMyUncompletedPage = '/api/WFTask/LoadMyUncompletedPage',
// 我的已办
LoadMyCompletedPage='/api/WFTask/LoadMyCompletedPage',
LoadMyCompletedPage = '/api/WFTask/LoadMyCompletedPage',
// 我的传阅
LoadMyReadPage='/api/WFTask/LoadMyReadPage',
LoadMyReadPage = '/api/WFTask/LoadMyReadPage',
// 我的委托
LoadMyDelegatePage='/api/WFTask/LoadMyDelegatePage',
GetTaskDetail='/api/WFTask/Get',
GetBPMNTask='/api/WFTask/GetBPMN'
LoadMyDelegatePage = '/api/WFTask/LoadMyDelegatePage',
GetTaskDetail = '/api/WFTask/Get',
GetBPMNTask = '/api/WFTask/GetBPMN',
}
/**
* @description: getLoadMyUncompletedPage
*/
export function getLoadMyUncompletedPage(params?: MyUncompletedParams) {
export function getLoadMyUncompletedPage(params?: MyUncompletedParams) {
return defHttp.get({ url: Api.LoadMyUncompletedPage, params });
}
/**
* @description: getLoadMyCompletedPage
*/
export function getLoadMyCompletedPage(params?: MyUncompletedParams) {
export function getLoadMyCompletedPage(params?: MyUncompletedParams) {
return defHttp.get({ url: Api.LoadMyCompletedPage, params });
}
/**
* @description: getLoadMyReadPage
*/
export function getLoadMyReadPage(params?: MyUncompletedParams) {
export function getLoadMyReadPage(params?: MyUncompletedParams) {
return defHttp.get({ url: Api.LoadMyReadPage, params });
}
/**
* @description: getLoadMyDelegatePage
*/
export function getLoadMyDelegatePage(params?: MyUncompletedParams) {
export function getLoadMyDelegatePage(params?: MyUncompletedParams) {
return defHttp.get({ url: Api.LoadMyDelegatePage, params });
}
/**
* @description: GetTaskDetail
*/
export function getTaskDetail(params?: TaskDetailParam) {
export function getTaskDetail(params?: TaskDetailParam) {
return defHttp.get({ url: Api.GetTaskDetail, params });
}
/**
* @description: getBPMNTask
*/
export function getBPMNTask(params?: TaskDetailParam) {
export function getBPMNTask(params?: TaskDetailParam) {
return defHttp.get({ url: Api.GetBPMNTask, params });
}

31
src/api/sys/categories.ts Normal file
View File

@ -0,0 +1,31 @@
import { defHttp } from '@/utils/http/axios';
enum Api{
getLeftTree = '/api/SysDataItem/Load',
getRightTable = '/api/SysDataItemDetail/Load',
addLeftItem = '/api/SysDataItem/Add',
addRightItem = '/api/SysDataItemDetail/Add',
delLeftItem = '/api/SysDataItem/Delete',
delRightItem = '/api/SysDataItemDetail/Delete',
editRightItem = '/api/SysDataItemDetail/Update',
}
export function getLeftTree(params) {
return defHttp.get({ url: Api.getLeftTree, params });
}
export function getRightTable(params) {
return defHttp.get({ url: Api.getRightTable, params });
}
export function addLeftItem(params){
return defHttp.post({ url: Api.addLeftItem, params });
}
export function addRightItem(params){
return defHttp.post({ url: Api.addRightItem + '?code=' + params.itemCode, params });
}
export function delLeftItem(params){
return defHttp.post({ url: Api.delLeftItem + '?id=' + params.id });
}
export function delRightItem(params){
return defHttp.post({ url: Api.delRightItem + '?id=' + params.id });
}
export function editRightItem(params){
return defHttp.post({ url: Api.editRightItem, params });
}

View File

@ -1,5 +1,10 @@
import { defHttp } from '@/utils/http/axios';
import {TableListParams,TableListModel,TableFormsParams,TableFormsModel} from './model/flowPenal'
import {
TableListParams,
TableListModel,
TableFormsParams,
TableFormsModel,
} from './model/flowPenalModel';
enum Api {
GetTableList = '/api/FormModule/GetTableList',
@ -15,7 +20,7 @@ export function getTableList(params: TableListParams) {
}
/**
* @description: getTableForms
*/
export function getTableForms(params: TableFormsParams) {
*/
export function getTableForms(params: TableFormsParams) {
return defHttp.get<TableFormsModel>({ url: Api.GetTableForms, params });
}
}

View File

@ -0,0 +1,7 @@
import { defHttp } from '@/utils/http/axios';
enum Api{
LoadPage = '/api/DroneClueReporting/QueryClueReporting',
}
export function getLoadPage(params) {
return defHttp.get({ url: Api.LoadPage, params });
}

View File

@ -1,45 +1,44 @@
/**
* @description:
*/
export interface CreateParams {
processId?: string | null,
schemeCode?: string,
title?: string,
userId?: string,
toUserId?: string,
export interface CreateParams {
processId?: string | null;
schemeCode?: string;
title?: string;
userId?: string;
toUserId?: string;
nextUsers?: {
additionalProp1: string,
additionalProp2: string,
additionalProp3: string
},
des?: string,
code?: string,
name?: string,
stampImg?: string,
stampPassWord?: string,
nextId?: string
additionalProp1: string;
additionalProp2: string;
additionalProp3: string;
};
des?: string;
code?: string;
name?: string;
stampImg?: string;
stampPassWord?: string;
nextId?: string;
}
/**
* @description: 稿
*/
export interface DeleteDraftParams {
id: string,
export interface DeleteDraftParams {
id: string;
}
/**
* @description:
*/
export interface RevokeAuditParams {
id: string,
taskId:string,
export interface RevokeAuditParams {
id: string;
taskId: string;
}
/**
* @description:
*/
export interface LoadNextAuditorsParams {
code: string,
processId?:string | number,
nodeId:string,
operationCode:string,
userId:string,
export interface LoadNextAuditorsParams {
code: string;
processId?: string | number;
nodeId: string;
operationCode: string;
userId: string;
}

View File

@ -1,7 +1,7 @@
/**
* @description:
*/
export interface MyUncompletedParams {
export interface MyUncompletedParams {
keyWord: string;
page: number;
limit: number;
@ -10,4 +10,4 @@
}
export interface TaskDetailParam {
id: string;
}
}

View File

@ -1,7 +1,7 @@
/**
* @description:
*/
export interface TableListModel {
export interface TableListModel {
name: string;
description: number;
dbObjectType: number;
@ -15,7 +15,7 @@ export interface TableListParams {
/**
* @description:
*/
export interface TableFormsParams {
export interface TableFormsParams {
dbCode: string;
tableNames: string;
}
@ -23,7 +23,7 @@ export interface TableListParams {
/**
* @description:
*/
export interface TableFormsModel {
export interface TableFormsModel {
db_codetable: object;
db_codecolumnsList:object
}
db_codecolumnsList: object;
}

View File

@ -19,8 +19,8 @@ export interface AddParams {
/**
* @description:
*/
export interface UpdateParams {
itemDetailId?:string;
export interface UpdateParams {
itemDetailId?: string;
itemName?: string;
itemValue?: string;
sortCode?: number;
@ -28,12 +28,11 @@ export interface AddParams {
description?: string;
}
/**
* @description:
*/
export interface DeleteParams {
id: string ;
id: string;
}
/**

View File

@ -20,41 +20,41 @@ export interface DetailParams {
*/
export interface AddParams {
schemeinfo: {
id: string,
code: string,
name: string,
category: string,
color: string,
icon: string,
schemeId: string,
enabledMark: 0,
mark: 0,
isInApp: 0,
authType: 0,
description: string,
type: 0,
createDate: string,
createUserId: string,
createUserName: string
},
id: string;
code: string;
name: string;
category: string;
color: string;
icon: string;
schemeId: string;
enabledMark: 0;
mark: 0;
isInApp: 0;
authType: 0;
description: string;
type: 0;
createDate: string;
createUserId: string;
createUserName: string;
};
schemeAuthList: [
{
id: string,
schemeInfoId: string,
objName: string,
objId: string,
objType: 0
}
],
id: string;
schemeInfoId: string;
objName: string;
objId: string;
objType: 0;
},
];
scheme: {
id: string,
schemeInfoId: string,
type: 0,
createDate: string,
createUserId: string,
createUserName: string,
content: string
}
id: string;
schemeInfoId: string;
type: 0;
createDate: string;
createUserId: string;
createUserName: string;
content: string;
};
}
/**
@ -62,44 +62,43 @@ export interface AddParams {
*/
export interface UpdateParams {
schemeinfo: {
id: string,
code: string,
name: string,
category: string,
color: string,
icon: string,
schemeId: string,
enabledMark: 0,
mark: 0,
isInApp: 0,
authType: 0,
description: string,
type: 0,
createDate: string,
createUserId: string,
createUserName: string
},
id: string;
code: string;
name: string;
category: string;
color: string;
icon: string;
schemeId: string;
enabledMark: 0;
mark: 0;
isInApp: 0;
authType: 0;
description: string;
type: 0;
createDate: string;
createUserId: string;
createUserName: string;
};
schemeAuthList: [
{
id: string,
schemeInfoId: string,
objName: string,
objId: string,
objType: 0
}
],
id: string;
schemeInfoId: string;
objName: string;
objId: string;
objType: 0;
},
];
scheme: {
id: string,
schemeInfoId: string,
type: 0,
createDate: string,
createUserId: string,
createUserName: string,
content: string
}
id: string;
schemeInfoId: string;
type: 0;
createDate: string;
createUserId: string;
createUserName: string;
content: string;
};
}
/**
* @description:
*/
@ -149,18 +148,18 @@ export interface HistoryParams {
* @description:
*/
export interface GetHistoryModel {
id: string,
schemeInfoId: string,
type: number,
createDate: string,
createUserId: string,
createUserName: string,
content: string
id: string;
schemeInfoId: string;
type: number;
createDate: string;
createUserId: string;
createUserName: string;
content: string;
}
/**
* @description:
*/
export interface SchemeParams {
id: string,
schemeId: string
id: string;
schemeId: string;
}

View File

@ -1,6 +1,12 @@
// sysDataItemDetail 字典明细接口api
import { defHttp } from '@/utils/http/axios';
import {CodeParams,AddParams,UpdateParams ,DeleteParams,GetSysDataItemDetailModel} from './model/sysDataItemDetailModel'
import {
CodeParams,
AddParams,
UpdateParams,
DeleteParams,
GetSysDataItemDetailModel,
} from './model/sysDataItemDetailModel';
enum Api {
Load = '/api/SysDataItemDetail/Load',
Add = '/api/SysDataItemDetail/Add',
@ -11,13 +17,11 @@ enum Api {
/**
* @description: postAdd
*/
export function postAdd(code:string, params?:AddParams) {
return defHttp.post(
{
url: Api.Add + "?code=" + code,
params,
},
);
export function postAdd(code: string, params?: AddParams) {
return defHttp.post({
url: Api.Add + '?code=' + code,
params,
});
}
/**
@ -27,16 +31,14 @@ export function getLoad(params: CodeParams) {
return defHttp.get<GetSysDataItemDetailModel>({ url: Api.Load, params });
}
export function update(params?:UpdateParams) {
console.log(params)
export function update(params?: UpdateParams) {
console.log(params);
return defHttp.post({
url: Api.Update,
params
params,
});
}
export function del(params:DeleteParams) {
return defHttp.post({ url: Api.Delete + "?id=" + params.id });
export function del(params: DeleteParams) {
return defHttp.post({ url: Api.Delete + '?id=' + params.id });
}

View File

@ -4,8 +4,9 @@ import { UploadFileParams } from '#/axios';
import { useGlobSetting } from '@/hooks/setting';
import { AxiosProgressEvent } from 'axios';
const { uploadUrl = '' } = useGlobSetting();
const { uploadUrl } = useGlobSetting();
const uploadFileUrl = uploadUrl + '/api/Platform/Upload';
/**
* @description: Upload interface
*/
@ -15,7 +16,7 @@ export function uploadApi(
) {
return defHttp.uploadFile<UploadApiResult>(
{
url: uploadUrl,
url: uploadFileUrl,
onUploadProgress,
},
params,

View File

@ -17,15 +17,17 @@ enum Api {
* @description: user login api
*/
export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal') {
console.log(defHttp.post<LoginResultModel>(
{
url: Api.Login,
params,
},
{
errorMessageMode: mode,
},
))
console.log(
defHttp.post<LoginResultModel>(
{
url: Api.Login,
params,
},
{
errorMessageMode: mode,
},
),
);
return defHttp.post<LoginResultModel>(
{
url: Api.Login,

View File

@ -2,28 +2,44 @@
<div class="map-container">
<div id="mapContainer" class="map-box"></div>
<div class="map-control">
<img @click="drawPoint" src="/point.png" alt="image1" />
<img @click="drawLine" src="/line.png" alt="image1" />
<img @click="drawPolygon" src="/polygon.png" alt="image1" />
<img @click="unDrawPolygon" src="/del.png" alt="image1" />
<img
v-for="(item, index) in nextMapControl"
:key="index"
:src="item.icon"
:title="item.title"
@click="handlerMapControlClick(item.handler)"
/>
<img v-show="nextMapControl.length > 0" @click="handlerUnDraw" src="/del.png" title="清除" />
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, defineProps } from 'vue';
import { onMounted, onUnmounted, defineProps, reactive } from 'vue';
import mapboxgl, { Map } from 'mapbox-gl';
import U from 'mapbox-gl-utils';
import 'mapbox-gl/dist/mapbox-gl.css';
import './src/index.less';
import { MapboxConfig, MapboxDefaultStyle } from './src/config';
import { MapboxConfig, MapboxDefaultStyle, MapControlConfig } from './src/config';
import { MP } from './src/MP';
import { DrawingType } from '@/enums/mapEnum';
// map
interface MapboxOptionsInterface {
mapOptions: mapboxgl.MapboxOptions;
control: DrawingType[];
}
const props = defineProps<MapboxOptionsInterface>();
let nextMapControl: Array<any> = reactive([]);
nextMapControl = props.control
? props.control.map((item) => {
console.log('item::: ', item);
return MapControlConfig[item];
})
: [];
console.log('nextMapControl::: ', nextMapControl);
//
let map: Map;
let mp: any = null;
@ -53,32 +69,40 @@
language: 'zh-cmn',
projection: 'equirectangular', // wgs84
style: MapboxDefaultStyle,
maxZoom: 22,
minZoom: 6,
...props.mapOptions,
});
};
const handlerMapControlClick = (handler: string) => {
handler === 'handlerDrawPoint' && handlerDrawPoint();
handler === 'handlerDrawLineString' && handlerDrawLineString();
handler === 'handlerDrawPolygon' && handlerDrawPolygon();
};
//
const drawPoint = () => {
const handlerDrawPoint = () => {
mp.draw('Point');
mp.on('Point', function (e) {
emit('mapDraw', 'Point', e);
});
};
//线
const drawLine = () => {
const handlerDrawLineString = () => {
mp.draw('LineString');
mp.on('LineString', function (e) {
emit('mapDraw', 'LineString', e);
});
};
//
const drawPolygon = () => {
const handlerDrawPolygon = () => {
mp.draw('Polygon');
mp.on('Polygon', function (e) {
emit('mapDraw', 'Polygon', e);
});
};
//
const unDrawPolygon = () => {
const handlerUnDraw = () => {
mp.deleteDraw();
emit('mapDraw', 'cancel');
};

View File

@ -198,9 +198,9 @@ export class MP extends BaseMP {
polygon: string;
};
currentMouseLocation: null;
correctionMouseLocation: null;
correctionMouseLocation: any;
clickCount: number;
clickTimeout: null;
clickTimeout: any;
constructor(map) {
super(map);
this.drawModelChoose = {
@ -270,8 +270,12 @@ export class MP extends BaseMP {
this._addOrUpdateSource(lastGSPL, this.drawCurrentId.polygon);
}
};
//绘制当前的layer
_currentDrawLayer = () => {
// 如果是点,直接绘制点
this._addLayer(this.drawCurrentId.point, this.drawCurrentId.point, 'Point', CIRCLE_STYLE);
// 如果是线,在点的基础上,加上线
// 如果是面,在线的基础上,加上面
if (
this.drawModel === this.drawModelChoose.LineString ||
this.drawModel === this.drawModelChoose.Polygon
@ -385,6 +389,9 @@ export class MP extends BaseMP {
// 在这里编写双击事件的操作
console.log('在这里编写双击事件的操作');
if (this.drawModel === this.drawModelChoose.LineString) {
_this.drawLocal.push(e.lngLat);
_this._currentDrawSource();
_this._currentDrawLayer();
this.drawIsFinish();
}
}

View File

@ -21,7 +21,25 @@ export const MapboxDefaultStyle = {
type: 'raster',
source: 'raster-tiles',
minzoom: 0,
maxzoom: 22,
maxzoom: 18,
},
],
};
export const MapControlConfig = {
DrawPoint: {
handler: 'handlerDrawPoint',
icon: '/point.png',
title: '绘制点',
},
DrawLineString: {
handler: 'handlerDrawLineString',
icon: '/line.png',
title: '绘制线',
},
DrawPolygon: {
handler: 'handlerDrawPolygon',
icon: '/polygon.png',
title: '绘制面',
},
};

View File

@ -0,0 +1,22 @@
.mapboxgl-ctrl-logo {
display: none !important;
}
.map-container {
position: relative;
}
.map-box,
.map-container {
width: 100%;
height: 100%;
}
.map-control {
position: absolute;
right: 10px;
top: 10px;
display: flex;
}
.map-control img {
width: 40px;
height: 40px;
cursor: pointer;
}

View File

@ -21,4 +21,7 @@
height: 40px;
cursor: pointer;
}
img:hover {
scale: 1.2;
}
}

5
src/enums/mapEnum.ts Normal file
View File

@ -0,0 +1,5 @@
export enum DrawingType {
Point = 'DrawPoint',
Line = 'DrawLineString',
Polygon = 'DrawPolygon',
}

View File

@ -1,7 +1,5 @@
import { defineStore } from 'pinia';
export const flowStore = defineStore({
id: 'flow',
state: () => ({
@ -20,44 +18,44 @@ export const flowStore = defineStore({
setWfDataName(id, name) {
this.flowWfData.forEach((element: any) => {
if (element.id == id && name) {
element.name = name
element.name = name;
}
});
},
setElments(data) {
this.flowElements = data
this.flowElements = data;
},
// 获取单个节点的数据
getWfDataNode(id) {
var currentIndex = (this.flowWfData || []).findIndex((element) => element.id === id);
if (currentIndex == -1) {
return null
return null;
} else {
return this.flowWfData[currentIndex]
return this.flowWfData[currentIndex];
}
},
// 添加单个节点的数据
setWfDataNode(data) {
let flowWfData = this.flowWfData
let flowWfData = this.flowWfData;
var currentIndex = (flowWfData || []).findIndex((element) => element.id === data.id);
if (currentIndex == -1) {
this.flowWfData.push(data)
this.flowWfData.push(data);
}
},
// 全覆盖,供更新和详情使用
setWfDataAll(list) {
this.flowWfData = list
this.flowWfData = list;
},
// 修改单个节点的某项数据
updataWfDataNode(id, key, value) {
let flowWfData = this.flowWfData
let flowWfData = this.flowWfData;
var currentIndex = (flowWfData || []).findIndex((element) => element.id === id);
this.flowWfData[currentIndex][key] = value
this.flowWfData[currentIndex][key] = value;
},
deleteWfData(data) {
let flowWfData = this.flowWfData
let flowWfData = this.flowWfData;
var currentIndex = (flowWfData || []).findIndex((element) => element.id === data.id);
this.flowWfData.splice(currentIndex, 1)
}
this.flowWfData.splice(currentIndex, 1);
},
},
});

View File

@ -128,8 +128,7 @@ export class VAxios {
*/
uploadFile<T = any>(config: AxiosRequestConfig, params: UploadFileParams) {
const formData = new window.FormData();
const customFilename = params.name || 'file';
const customFilename = 'files';
if (params.filename) {
formData.append(customFilename, params.file, params.filename);
} else {

View File

@ -1,15 +1,22 @@
<template>
<div class="w-full" style="height: 100%">
<MapboxMaps :mapOptions="mapOptions" @map-on-load="mapOnLoad" @map-draw="handlerMapDraw" />
<MapboxMaps
:mapOptions="mapOptions"
:control="mapDrawControl"
@map-on-load="mapOnLoad"
@map-draw="handlerMapDraw"
/>
</div>
</template>
<script lang="ts" setup>
import MapboxMaps from '@/components/MapboxMaps/index.vue';
import { DrawingType } from '@/enums/mapEnum';
const mapOptions = {
center: [116.404, 39.905],
zoom: 8,
};
const mapDrawControl: DrawingType[] = [DrawingType.Polygon, DrawingType.Line];
const mapOnLoad = (map) => {
// map
console.log('map::: ', map);

View File

@ -0,0 +1,54 @@
<template>
<a-button :size="props.size" :class="`${props.type}`" :type="getType(props.type)" :icon="h(getIcon(props.type))">{{props.text}}</a-button>
</template>
<script setup lang="ts">
import {defineProps,h} from "vue"
import { PlusOutlined,FormOutlined,DeleteOutlined,SearchOutlined } from '@ant-design/icons-vue';
const props = defineProps(['text','type','size'])
const getIcon = (icon:string) => {
switch (icon) {
case 'add':
return PlusOutlined
case 'edit':
return FormOutlined
case 'del':
return DeleteOutlined
case 'search':
return SearchOutlined
default:
return null
}
}
const getType = (type:string) => {
switch (type) {
case 'search':
return 'default'
default:
return 'primary'
}
}
</script>
<style lang="scss" scoped>
.add{
background-color: #409167;
}
.add:hover{
background-color: #66a785;
}
.edit{
background-color: #0076c8
}
.edit:hover{
background-color: #3391d3;
}
.del{
background-color: #d63737
}
.del:hover{
background-color: #de5f5f;
}
.position{
margin-left:10px
}
</style>

View File

@ -0,0 +1,105 @@
<template>
<div class="categories-modal-container">
<a-form
ref="formRef"
:model="props.modalData.data"
:rules="props.modalData.type.indexOf('left') > -1? rules: rightRules"
labelAlign="right"
:label-col="{ span: 5 }"
>
<template v-if="props.modalData.type.indexOf('left') > -1">
<a-form-item label="分类ID" name="itemCode">
<a-input v-model:value="props.modalData.data.itemCode" />
</a-form-item>
<a-form-item label="分类名称" name="itemName">
<a-input v-model:value="props.modalData.data.itemName" />
</a-form-item>
</template>
<template v-else>
<a-form-item label="ID" name="id">
<a-input v-model:value="props.modalData.data.id" disabled placeholder="系统自动处理"/>
</a-form-item>
<a-form-item label="分类标识" name="isDefault">
<a-input v-model:value="props.modalData.data.isDefault" type="number"/>
</a-form-item>
<a-form-item label="名称" name="itemName">
<a-input v-model:value="props.modalData.data.itemName" />
</a-form-item>
<a-form-item label="值" name="itemValue">
<a-input v-model:value="props.modalData.data.itemValue" />
</a-form-item>
<a-form-item label="是否可用" name="enabledMark">
<a-select v-model:value="props.modalData.data.enabledMark">
<a-select-option value="0">停用</a-select-option>
<a-select-option value="1">正常</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="排序号" name="sortCode">
<a-input-number v-model:value="props.modalData.data.sortCode" addon-before="-" addon-after="+" :min="1" :max="10"></a-input-number>
</a-form-item>
<a-form-item label="描述" name="description">
<a-input v-model:value="props.modalData.data.description" />
</a-form-item>
<a-form-item label="所属分类ID" name="itemCode">
<a-select v-model:value="props.modalData.data.itemCode">
<a-select-option v-for="item in props.lTree" :value="item.key">{{ item.title }}</a-select-option>
</a-select>
</a-form-item>
</template>
</a-form>
<div class="modal-footer">
<a-button style="margin-right: 10px;" @click="closeModal"></a-button>
<a-button type="primary" @click="submit"></a-button>
</div>
</div>
</template>
<script setup lang="ts">
import {defineProps, defineEmits,ref} from "vue"
const props = defineProps(['modalData','modalForm','lTree'])
const emit = defineEmits(['closeModal','submit'])
const formRef = ref()
const rules = {
itemCode: [
{ required: true, message: '分类ID不能为空', trigger: 'blur' },
],
itemName: [
{ required: true, message: '分类名称不能为空', trigger: 'blur' },
],
}
const rightRules = {
itemName: [
{ required: true, message: '分类名称不能为空', trigger: 'blur' },
],
itemCode: [
{ required: true, message: '所属分类不能为空', trigger: 'blur' },
],
}
const submit = () => {
formRef.value.validate().then(() => {
emit('submit')
}).catch(error => {
console.log('error', error)
})
}
const closeModal = () => {
emit('closeModal')
formRef.value.resetFields()
}
const clearModalData = () => {
formRef.value.resetFields()
}
defineExpose({
clearModalData
})
</script>
<style lang="scss" scoped>
.categories-modal-container{
padding: 10px 25px;
.modal-footer{
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
}
</style>

View File

@ -0,0 +1,285 @@
<template>
<div class="page-div categories-page">
<div class="left-div">
<div class="header">
<div class="buttons-div">
<HeaderButton :text="'删除分类'" :type="'del'" :size="'small'" @click="buttonClick('left','del')"/>
<HeaderButton :text="'添加分类'" :type="'add'" :size="'small'" @click="buttonClick('left','add')"/>
</div>
<div class="search-div">
<a-input v-model:value="LValue" placeholder="请输入内容" size="small"/>
<HeaderButton :text="'搜索'" :type="'search'" :size="'small'" @click="searchData('left')"/>
</div>
</div>
<div class="content">
<div class="show-all-button">
<a-button type="link" @click="changeTypeId('')">>></a-button>
</div>
<BasicTree :treeData="lTree" :loading="lLoading" @select="(selectedKeys,{node}) => {getLeftSelectId(node.id);changeTypeId(node.key)}"/>
</div>
</div>
<div class="right-div">
<div class="header">
<div class="buttons-div">
<a-input style="width:150px" v-model:value="RValue" placeholder="名称" size="small"/>
<HeaderButton :text="'搜索'" :type="'search'" :size="'small'" @click="searchData('right')"/>
<HeaderButton :text="'添加'" :type="'add'" :size="'small'" @click="buttonClick('right','add')"/>
<HeaderButton :text="'编辑'" :type="'edit'" :size="'small'" @click="buttonClick('right','edit')"/>
<HeaderButton :text="'删除'" :type="'del'" :size="'small'" @click="buttonClick('right','del')"/>
</div>
</div>
<div class="content">
<BasicTable @register="registerTable">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'enabledMark'">
<a-tag v-if="record.enabledMark" color="success"></a-tag>
<a-tag v-else color="error">停用</a-tag>
</template>
</template>
</BasicTable>
</div>
</div>
<a-modal class="categories-modal" v-model:open="openModal"
:title="modalData.title" :afterClose="clearModal">
<UseModal ref="modalForm" :modalData="modalData" @closeModal="closeModal" @submit="submit" :lTree="lTree"/>
</a-modal>
</div>
</template>
<script setup lang="ts">
import HeaderButton from './Button/index.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import UseModal from './Modal/index.vue'
import { BasicTree } from '@/components/Tree';
import {BasicTable,useTable} from '@/components/Table'
import {ref,onMounted,reactive,watch,createVNode } from "vue"
import {getLeftTree,getRightTable,addLeftItem,addRightItem,delLeftItem,editRightItem,delRightItem} from '@/api/sys/categories.ts'
import {columns,emptyRightItem,emptyLeftItem,dataProcess} from './util.ts'
import {Modal,message} from 'ant-design-vue'
const modalForm = ref()
let LValue = ref('')
let RValue = ref('')
let lLoading = ref(false)
let typeId = ref('')
let selectLeftId = ref('')
let lTree = ref([])
let openModal = ref(false)
const modalData = reactive({
title:'',
data:{},
type:'',
})
const [registerTable,{reload,getSelectRows}] = useTable({
beforeFetch: (params) => {
return {...params, code:typeId.value, key:RValue.value}
},
api:getRightTable,
columns,
showIndexColumn: false,
rowSelection: {
type: 'checkbox',
},
})
const getLeftTreeData = (value='') => {
lLoading.value = true
getLeftTree({key:value}).then(res => {
let data = dataProcess(res)
lTree.value = data
lLoading.value = false
}).catch(err => {
console.log(err)
lLoading.value = false
})
}
onMounted(() => {
getLeftTreeData()
})
const changeTypeId = (value) => {
typeId.value = value
reload()
}
const getLeftSelectId = (value) => {
selectLeftId.value = value
}
const searchData = (type) => {
if (type === 'left') {
console.log(LValue.value)
getLeftTreeData(LValue.value)
}else{
reload()
}
}
const submit = () => {
switch(modalData.type){
case 'leftadd':
addLeftItem(modalData.data).then(res => {
getLeftTreeData()
openModal.value = false
}).catch(err => {
console.log(err)
})
break;
case 'rightadd':
addRightItem(modalData.data).then(res => {
reload()
openModal.value = false
}).catch(err => {
console.log(err)
})
break;
case 'rightedit':
editRightItem(modalData.data).then(res => {
reload()
openModal.value = false
}).catch(err => {
console.log(err)
})
break;
default:
break;
}
}
const buttonClick = (diff,type) => {
let isLeft = diff === 'left'
switch(type){
case 'add':
openModal.value = true
modalData.title = isLeft? '添加分组': '添加'
modalData.data = isLeft? emptyLeftItem: emptyRightItem
modalData.type = `${diff}${type}`
break;
case 'del':
let check = isLeft? (selectLeftId.value === ''? true: false) : (getSelectRows().length !== 1? true: false)
if(check){
message.warning(isLeft? '请选择一条分组数据': '请选择一条数据')
return
}
Modal.confirm({
title:'是否确认删除?',
icon: createVNode(ExclamationCircleOutlined),
onCancel() {},
onOk() {
if(isLeft){
return delLeftItem({id:selectLeftId.value}).then(res => {
getLeftTreeData()
typeId.value = ''
reload()
}).catch(err => {
console.log(err)
})
}else{
let selectRightId = getSelectRows()[0].itemDetailId
console.log(selectRightId)
return delRightItem({id:selectRightId}).then(res => {
reload()
}).catch(err => {
console.log(err)
})
}
}
})
break;
case 'edit':
if(getSelectRows().length !== 1){
message.warning('请选择一条数据')
return
}
let editData = getSelectRows()[0]
console.log(editData)
modalData.title = '编辑'
modalData.data = {...editData}
modalData.type = `${diff}${type}`
openModal.value = true
break;
}
}
const closeModal = () => {
openModal.value = false
}
const clearModal = () => {
modalForm.value.clearModalData()
}
</script>
<style lang="scss" scoped>
.page-div{
position: relative;
top:10px;
left:10px;
width:calc(100% - 20px);
height:calc(100% - 20px);
display:flex;
border: 1px solid #ccc;
.left-div{
width:230px;
border-right: 1px solid #ccc;
display: flex;
flex-direction: column;
.header{
display: flex;
flex-direction: column;
padding:10px;
.buttons-div{
display: flex;
justify-content: space-between;
}
.search-div{
margin-top:10px;
display: flex;
}
}
.content{
background-color: #fff;
border-radius: 5px;
height:100%;
.show-all-button{
height:34px;
line-height: 34px;
padding-left: 20px;
border-bottom: 1px solid #ccc;
}
}
}
.right-div{
width: calc(100% - 230px);
flex:1;
display: flex;
flex-direction: column;
.header{
height: 42px;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 10px;
.buttons-div > button{
margin-left: 10px;
}
}
.content{
flex: 1;
background-color: #fff;
}
}
}
</style>
<style lang="scss">
.categories-page{
.left-div{
.h-full{
height:auto;
}
}
}
.categories-modal{
.ant-modal-footer > button{
display: none;
}
.ant-modal-footer{
margin-top:0px;
border-top: 0px;
}
}
// ant-table-header
</style>

View File

@ -0,0 +1,92 @@
export const columns = [
{
title: '名称',
dataIndex: 'itemName',
resizable:true,
width:100,
},
{
title: '代码',
dataIndex: 'isDefault',
resizable:true,
width:100,
},
{
title: '值',
dataIndex: 'itemValue',
resizable:true,
width:100,
},
{
title: '是否可用',
dataIndex: 'enabledMark',
resizable:true,
width:100,
},
{
title: '排序号',
dataIndex: 'sortCode',
resizable:true,
width:100,
},
{
title: '描述',
dataIndex: 'description',
resizable:true,
width:100,
},
{
title: '分类标识',
dataIndex: 'itemCode',
resizable:true,
width:100,
},
{
title: '创建时间',
dataIndex: 'createDate',
resizable:true,
width:100,
},
{
title: '创建人',
dataIndex: 'createUserName',
resizable:true,
width:100,
},
{
title: '最后更新时间',
dataIndex: 'modifyDate',
resizable:true,
width:100,
},
{
title: '最后更新人',
dataIndex: 'modifyUserName',
resizable:true,
width:100,
},
]
export const emptyLeftItem = {
itemCode:"",
itemName:"",
}
export const emptyRightItem = {
id:"",
itemCode:"",
itemName:"",
itemValue:"",
enabledMark:"1",
sortCode:"",
description:"",
typeId:"",
}
export const dataProcess = (list) => {
return list.map((item) => {
return {
id: item.itemId,
title:item.itemName,
icon: 'home|svg',
key: item.itemCode,
}
})
}

View File

@ -1,6 +1,6 @@
<template>
<div>
<a-form :model="caseHandlingData" name="basic" :label-col="{ span: 6 }" disabled>
<a-form :model="caseHandlingData" name="basic" :label-col="{ span: 6 }" disabled labelWrap>
<a-form-item>
<a-divider orientation="left">案件核查信息</a-divider>
</a-form-item>
@ -32,11 +32,11 @@
margin-bottom: 6px;
"
>
<a-image :width="125" :src="item.s_filePath" />
<a-image :width="125" :height="112" :src="item.s_filePath" />
</div>
</a-form-item>
<a-form-item label="现场视频:">
<div
<!-- <div
style="margin-top: 10px; width: 240px; height: 150px"
v-for="(item, index) in videoList"
:key="index"
@ -45,7 +45,11 @@
<source :src="item" type="video/mp4" />
您的浏览器不支持Video标签
</video>
</div>
</div> -->
<video width="240" height="150" controls v-for="(item, index) in videoList" :key="index">
<source :src="item" type="video/mp4" />
您的浏览器不支持Video标签
</video>
<a-empty v-show="videoList.length <= 0">
<template #description>
<span>暂无视频</span>
@ -106,7 +110,7 @@
margin-bottom: 6px;
"
>
<a-image :width="125" :src="item.s_filePath" />
<a-image :width="125" :height="112" :src="item.s_filePath" />
</div>
<a-empty v-if="evidenceFileList.length <= 0">
<template #description>
@ -130,7 +134,7 @@
margin-bottom: 6px;
"
>
<a-image :width="125" :src="item.s_filePath" />
<a-image :width="125" :height="112" :src="item.s_filePath" />
</div>
<a-empty v-if="boundaryImageList.length <= 0">
<template #description>
@ -196,7 +200,7 @@
margin-bottom: 6px;
"
>
<a-image :width="125" :src="item.s_filePath" />
<a-image :width="125" :height="112" :src="item.s_filePath" />
</div>
<a-empty v-if="afterImageList.length <= 0">
<template #description>
@ -258,7 +262,7 @@
margin-bottom: 6px;
"
>
<a-image :width="125" :src="item.s_filePath" />
<a-image :width="125" :height="112" :src="item.s_filePath" />
</div>
<a-empty v-if="punishImageList.length <= 0">
<template #description>
@ -281,7 +285,7 @@
margin-bottom: 6px;
"
>
<a-image :width="125" :src="item.s_filePath" />
<a-image :width="125" :height="112" :src="item.s_filePath" />
</div>
<a-empty v-if="paymentImagesList.length <= 0">
<template #description>
@ -334,7 +338,7 @@
margin-bottom: 6px;
"
>
<a-image :width="125" :src="item.s_filePath" />
<a-image :width="125" :height="112" :src="item.s_filePath" />
</div>
<a-empty v-if="agreeImageList.length <= 0">
<template #description>
@ -380,7 +384,7 @@
margin-bottom: 6px;
"
>
<a-image :width="125" :src="item.s_filePath" />
<a-image :width="125" :height="112" :src="item.s_filePath" />
</div>
<a-empty v-if="boundaryImageList.length <= 0">
<template #description>
@ -486,16 +490,16 @@
imageList.value = [];
if (res.pic_info_list.length > 0) {
res.pic_info_list.forEach((item) => {
item.s_filePath = 'http://60.213.14.14:6070/' + '/S_' + item.filePath;
item.filePath = 'http://60.213.14.14:6070/' + '/' + item.filePath;
item.s_filePath = 'http://60.213.14.14:6070/' + item.filePath;
item.filePath = 'http://60.213.14.14:6070/' + item.filePath;
imageList.value.push(item);
});
}
afterImageList.value = [];
if (res.after_pic_list.length > 0) {
res.after_pic_list.forEach((item) => {
item.s_filePath = 'http://60.213.14.14:6070/' + '/S_' + item.filePath;
item.filePath = 'http://60.213.14.14:6070/' + '/' + item.filePath;
item.s_filePath = 'http://60.213.14.14:6070/' + item.filePath;
item.filePath = 'http://60.213.14.14:6070/' + item.filePath;
afterImageList.value.push(item);
});
}
@ -503,7 +507,7 @@
evidenceFileList.value = [];
if (res.evidence_file_list.length > 0) {
res.evidence_file_list.forEach((item) => {
item.s_filePath = 'http://60.213.14.14:6070/' + '/S_' + item.filePath;
item.s_filePath = 'http://60.213.14.14:6070/' + item.filePath;
item.filePath = 'http://60.213.14.14:6070/' + '/' + item.filePath;
evidenceFileList.value.push(item);
});
@ -528,6 +532,7 @@
if (res.boundary_pic_list.length > 0) {
boundaryImageList.value = handleImageArray(res.boundary_pic_list);
}
console.log('rrrr', res);
if (res.video_list) {
res.video_list.forEach((item) => {
videoList.value.push('http://60.213.14.14:6070/' + item);
@ -539,7 +544,7 @@
let returnArray: any = ref([]);
imageArr.forEach((item) => {
let obj = {
s_filePath: 'http://60.213.14.14:6070/' + '/S_' + item,
s_filePath: 'http://60.213.14.14:6070/' + item,
filePath: 'http://60.213.14.14:6070/' + '/' + item,
};
returnArray.value.push(obj);

View File

@ -161,16 +161,16 @@
</a-empty>
</template>
<template #videoSlot>
<div
style="margin-top: 10px; width: 240px; height: 150px"
<video
width="240"
height="150"
controls
v-for="(item, index) in videoList"
:key="index"
>
<video width="100%" height="100%" controls>
<source :src="item" type="video/mp4" />
您的浏览器不支持Video标签
</video>
</div>
<source :src="item" type="video/mp4" />
您的浏览器不支持Video标签
</video>
<a-empty v-show="videoList.length <= 0">
<template #description>
<span>暂无视频</span>
@ -341,8 +341,10 @@
caseAudiSteps(param).then((res) => {
if (res) {
createMessage.success('审核成功');
reload1();
reload2();
setTimeout(() => {
reload1();
reload2();
}, 500);
}
});
}
@ -405,6 +407,8 @@
if (rel) {
createMessage.success('收藏成功');
getCollentionLength();
reload2();
getCaseCollList();
}
});
});
@ -585,7 +589,7 @@
&-mapbox {
width: calc(30% - 20px);
margin: 0 15px 15px 15px;
border: 1px solid red;
border: 1px solid #eee;
}
}
}

View File

@ -0,0 +1,189 @@
<template>
<div class="leadreport-information-component">
<div style="display: flex;height:calc(100% - 62px);">
<div style="flex: 1;">
<a-divider>线索详情</a-divider>
<a-descriptions :column="1" bordered>
<a-descriptions-item>
<template #label>
<TabletOutlined />
举报人
</template>
<!-- TODO 加密 -->
{{detail.name}}
</a-descriptions-item>
<el-descriptions-item>
<template #label>
<TabletOutlined />
手机号
</template>
<!-- TODO 加密 -->
{{detail.phone}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<TabletOutlined />
地点
</template>
{{detail.address}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<TabletOutlined />
举报内容
</template>
{{detail.content}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<TabletOutlined />
举报时间
</template>
{{detail.createTime}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<TabletOutlined />
图片
</template>
<a-image-preview-group>
<a-image :width="200" v-for="(item,index) in imageList" :key="index" :src="item" />
</a-image-preview-group>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<TabletOutlined />
视频
</template>
<video-player class="video-player vjs-custom-skin" v-for="(item,index) in videoList"
:key="index" ref="videoPlayer" :playsinline="true" :options="item"
style="width:400px;margin-top: 10px;">
</video-player>
</el-descriptions-item>
</a-descriptions>
</div>
<div style="flex: 1;">
<a-divider>地址</a-divider>
<div class="amap-wrapper">
<!-- <MapboxMaps :mapOptions="mapOptions" @map-on-load="mapOnLoad"/> -->
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { TabletOutlined } from "@ant-design/icons-vue";
import MapboxMaps from '@/components/MapboxMaps/index.vue'
import {defineProps, onMounted,ref,reactive} from 'vue'
const props = defineProps(['showInfoId'])
const BASE_IMAGE_URL = import.meta.env.VITE_BASE_IMAGE_URL
let detail = ref({})
const mapOptions = reactive({
center: [0,0],
zoom: 13,
})
let imageList:string[] = reactive([])
let videoList = reactive([])
const mapOnload = (map) => {
const testSource = 'http://123.132.248.154:9205/geoserver/gwc/service/tms/1.0.0/TEST_WORK_SPACE%3Alindi@EPSG:900913@pbf/{z}/{x}/{y}.pbf';
map.U.addVector('name', testSource).addLineLayer('layerId',{
source: 'sourceId',
'source-layer': 'lindi'
});
}
onMounted(() => {
console.log(props.showInfoId,detail)
loadDetailCaseInfo()
console.log(detail)
})
const loadDetailCaseInfo = () => {
// TODO request /ClueReporting/GetClueReportingDetail?id=
let response = {
result:{
reporting:{
id:1,
name:"张三",
phone:"11111111111",
address:"啊手动阀啊手动阀啊手动阀啊手动阀",
createTime:"2022-08-09 12:00:00",
content:"aaa",
lng:116.404,
lat:39.915
},
imageFiles:[
"x43I27A55%26/photo-1438109491414-7198515b166b.webp",
"cV16ZqzMjW/photo-1473091540282-9b846e7965e3.webp",
"LlvErxo8H9/photo-1503185912284-5271ff81b9a8.webp",
],
videoFiles:[
// "1.mp4",
// "2.mp4",
// "3.mp4"
]
}
}
Promise.resolve(response).then((res) => {
let obj = res.result.reporting
detail.value = {...obj}
mapOptions.center = [obj.lng, obj.lat]
if (res.result.imageFiles) {
res.result.imageFiles.forEach(element => {
imageList.push(
// BASE_IMAGE_URL + "/" + element
`https://gw.alipayobjects.com/zos/antfincdn/${element}`
)
});
}
if (res.result.videoFiles) {
res.result.videoFiles.forEach(element => {
let options = {
playbackRates: [0.5, 1.0, 1.5, 2.0], //
autoplay: false, //true,
muted: false, //
loop: false, //
preload: 'auto', // <video>auto,
language: 'zh-CN',
aspectRatio: '16:9', // 使 - "16:9""4:3"
fluid: true, // trueVideo.js player
sources: [
{
type: "",
src: BASE_IMAGE_URL + "/" + element//url
}
],
poster: "", //
// width: document.documentElement.clientWidth,
notSupportedMessage: '此视频暂无法播放,请稍后再试', //Video.js
controlBar: {
timeDivider: true,//
durationDisplay: true,//
remainingTimeDisplay: false,//
fullscreenToggle: true //
}
}
videoList.push(options)
});
}
})
}
</script>
<style lang="scss" scoped>
.leadreport-information-component{
height: 600px;
overflow-y: auto;
overflow-x: hidden;
}
.amap-wrapper{
width: 100%;
height: 100%
}
.amap-demo{
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,193 @@
<template>
<div class="page-div">
<!-- <Header @reload="reload" @setPagination="setPagination" @getSelectRows="getSelectRows"></Header> -->
<div class="report-content filter-container" style="display:flex;overflow:auto;height:50px; background-color:#f8f8f8;align-items: center;
justify-content: flex-end;padding-right: 20px;">
<div style="margin-right:10px;">
<a-range-picker :presets="rangePresets" @change="onRangeChange" >
</a-range-picker>
</div>
<div style="margin-right:10px">
<a-input v-model:value="content" placeholder="请输入举报内容" />
</div>
<a-button style="background-color: #0076c8;" type="primary" :icon="h(SearchOutlined)" @click="searchTable"></a-button>
<a-button style="background-color: #409167; margin-left:10px" type="primary"
:icon="h(VerticalAlignBottomOutlined)" @click="distribute">下发</a-button>
</div>
<div class="content">
<BasicTable rowKey="id" @register="registerTable">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'isDistribute'">
<a-tag v-if="record.isDistribute" color="success"></a-tag>
<a-tag v-else color="error"></a-tag>
</template>
<template v-if="column.key === 'action'">
<a-button @click="openInfo(record)"></a-button>
</template>
</template>
</BasicTable>
</div>
<a-modal style="width: 80vw;height:600px" v-model:open="modal" title="案件详情" :mask="true"
:maskClosable="false" :keyboard="false" :afterClose="closeModal">
<InfoComponent v-if="modal" :showInfoId="showInfoId"></InfoComponent>
</a-modal>
</div>
</template>
<script setup lang="ts">
// import Header from './header/index.vue'
// import Table from './Table/index.vue'
import InfoComponent from './InfoComponent/index.vue'
import dayjs, {Dayjs} from 'dayjs';
import {ref, h, } from "vue"
import { SearchOutlined, VerticalAlignBottomOutlined } from '@ant-design/icons-vue';
import {BasicTable, useTable} from '@/components/Table'
import { getLoadPage } from '@/api/sys/leadreporting';
import {message,} from 'ant-design-vue'
type RangeValue = [Dayjs, Dayjs];
let beginDate = ref()
let endDate = ref()
let content = ref()
let modal = ref(false)
let showInfoId = ref()
const rangePresets = ref([
{ label: '今天', value: [dayjs(), dayjs()] },
{ label: '最近一周', value: [dayjs().add(-1, 'w'), dayjs()] },
{ label: '最近一个月', value: [dayjs().add(-1, 'M'), dayjs()] },
{ label: '最近三个月', value: [dayjs().add(-3, 'M'), dayjs()] },
{ label: '最近六个月', value: [dayjs().add(-6, 'M'), dayjs()] },
{ label: '最近一年', value: [dayjs().add(-1, 'y'), dayjs()] },
]);
const columns = [
{
title: '举报人',
dataIndex: 'name',
},
{
title: '手机号',
dataIndex: 'phone',
},
{
title: '地点',
dataIndex: 'address',
},
{
title: '举报内容',
dataIndex: 'content',
},
{
title: '举报时间',
dataIndex: 'createTime',
},
{
title: '是否下发',
dataIndex: 'isDistribute',
},
];
const onRangeChange = (dates: RangeValue, dateStrings: string[]) => {
if (dates) {
beginDate.value = dateStrings[0]
endDate.value = dateStrings[1]
} else {
beginDate.value = null
endDate.value = null
}
}
const [registerTable,{reload, setPagination,getSelectRows}] = useTable({
beforeFetch: (params) => {
console.log(params)
let useParams = {...params}
if(beginDate.value) useParams = {...useParams,beginDate:beginDate.value}
if(endDate.value) useParams = {...useParams,endDate:endDate.value}
if(content.value) useParams = {...useParams,content:content.value}
return useParams
},
api:getLoadPage,
columns,
showIndexColumn: false,
rowSelection: {
type: 'checkbox',
},
actionColumn:{
width: 80,
title: '操作',
dataIndex: 'action',
}
})
const distribute = () => {
const selectList = getSelectRows()
if(selectList.length == 1){
if(selectList[0].isDistribute){
message.warning('已经下发的不能再次下发')
return
}
let query = {id: selectList[0].id}
// TODO request
Promise.resolve("success").then(res => {
message.success(res)
})
reload()
}else{
message.warning('选中一个进行下发')
}
console.log(selectList)
}
const searchTable = () => {
setPagination({current:1,pageSize:10})
reload()
}
const openInfo = (info) => {
modal.value = true
showInfoId.value = info.id
}
const closeModal = () => {
modal.value = false
showInfoId.value = null
}
</script>
<style lang="scss" scoped>
.content{
width: calc(100% - 20px);
margin: auto;
height: 823px;
background-color: #fff;
padding: 10px;
overflow: hidden;
}
.page-div{
background-color: #efefef;
}
.amap-wrapper {
width: 100%;
height: 100%;
}
.desc-container {
overflow-y: scroll;
}
/* 滑道样式 */
.desc-container::-webkit-scrollbar {
width: 5px;
background: rgba(255, 255, 255, 0.2);
border-radius: 6px;
}
/* 定义滑块的样式 */
.desc-container::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.3);
background-color: rgba(255, 255, 255, 0.3);
}
/* 定义滑块鼠标移入时的样式 */
.desc-container::-webkit-scrollbar-thumb:hover {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.3);
background-color: rgba(255, 255, 255, 0.4);
}
</style>

View File

@ -92,7 +92,6 @@ export const columns: BasicColumn[] = [
},
];
export const searchFormSchema: FormSchema[] = [
{
field: 'is_drawback',
component: 'Select',

View File

@ -1,12 +1,7 @@
<template>
<div class="case-view">
<div class="case-view_step">
<a-steps
v-model:current="current"
type="navigation"
size="small"
:style="stepStyle"
>
<a-steps v-model:current="current" type="navigation" size="small" :style="stepStyle">
<a-step
v-for="(item, index) in flowLog"
:key="index"
@ -17,13 +12,13 @@
</a-steps>
</div>
<div class="case-view_content">
<div class="file-box w-1/2 xl:w-1/2" v-if="caseHandleInfo">
<div :class="props.mapShow ? 'file-box w-1/2 xl:w-1/2' : 'file-all'" v-if="caseHandleInfo">
<CollapseContainer
title="【案件下发信息】"
:canExpan="false"
v-if="current == 0 || current == 4"
>
<Issue :data="detailData"></Issue>
<Issue :data="detailData" :imageList="imageList"></Issue>
</CollapseContainer>
<CollapseContainer
@ -138,7 +133,12 @@
</a-descriptions>
</CollapseContainer>
</div>
<CollapseContainer title="地图位置" :canExpan="false" class="map-box ml-1 w-1/2 xl:w-1/2">
<CollapseContainer
v-if="props.mapShow"
title="地图位置"
:canExpan="false"
class="map_box ml-1 w-1/2 xl:w-1/2"
>
<MapDetail :ruleForm="detailData" :isOnce="true"></MapDetail>
</CollapseContainer>
</div>
@ -161,7 +161,9 @@
Investigate,
Procedure,
} from '../index';
const BASE_IMAGE_URL = ref('http://192.168.104:9011');
//
import { useGlobSetting } from '@/hooks/setting';
const { uploadUrl } = useGlobSetting();
const current = ref<number>(0);
const stepStyle = ref({
marginBottom: '60px',
@ -172,12 +174,16 @@
});
const props = defineProps({
caseId: String,
mapShow: {
type: Boolean,
default: () => {
return true;
},
},
});
console.log(props);
watch(
() => props.caseId,
(newVal, oldVal) => {
console.log(newVal);
getCaseFlowLogData();
loadDetailCaseInfo();
getCaseHandleInfo();
@ -186,6 +192,8 @@
const detailData = ref();
const caseHandleInfo = ref();
const playerOptions = ref();
//
const imageList = ref<fileListModel>([]);
//
const threadImageList = ref<fileListModel>([]);
//
@ -236,14 +244,16 @@
}
//
async function loadDetailCaseInfo() {
imageList.value = [];
const data = await getCaseInfo({ id: props.caseId });
console.log(data);
detailData.value = data;
for (let i = 0; i < data.pic_list.length; i++) {
imageList.value.push(uploadUrl + '/' + data.pic_list[i]);
}
}
//
async function getCaseHandleInfo() {
const data = await getDroneCaseDeal({ caseid: props.caseId });
console.log(data);
caseHandleInfo.value = data;
if (caseHandleInfo.value.is_illegal == 0) {
caseHandleInfo.value.is_illegal = '合法';
@ -268,7 +278,7 @@
sources: [
{
type: '',
src: BASE_IMAGE_URL + '/' + item, //url
src: uploadUrl + '/' + item, //url
},
],
poster: '', //
@ -286,23 +296,17 @@
}
//
if (data.pic_info_list.length > 0) {
threadImageList.value = []
data.pic_info_list.forEach((item) => {
threadImageList.value.push(item.filePath);
threadImageList.value.push(uploadUrl + '/' + item.filePath);
});
for (let i = 0; i < threadImageList.value.length; i++) {
let obj = {
filePath: BASE_IMAGE_URL + '/' + threadImageList.value[i],
s_filePath: BASE_IMAGE_URL + '/S_' + threadImageList.value[i],
};
threadImageList.value[i] = obj;
}
}
//
if (data.after_pic_list.length > 0) {
threadAfterImageList.value = [];
data.after_pic_list.forEach((item: fileList) => {
threadAfterImageList.value.push(BASE_IMAGE_URL + '/S_' + item.filePath);
data.after_pic_list.forEach((item) => {
threadAfterImageList.value.push(uploadUrl + '/' + item.filePath);
});
}
@ -323,7 +327,7 @@
sources: [
{
type: '',
src: BASE_IMAGE_URL + '/' + item, //url
src: uploadUrl + '/' + item, //url
},
],
poster: '', //
@ -343,22 +347,14 @@
if (data.evidence_file_list.length > 0) {
evidenceFileList.value = [];
data.evidence_file_list.forEach((item: fileList) => {
let obj = {
filePath: BASE_IMAGE_URL + '/' + item.filePath,
s_filePath: BASE_IMAGE_URL + '/' + item.filePath,
};
evidenceFileList.value.push(obj);
evidenceFileList.value.push(uploadUrl + '/' + item.filePath);
});
}
if (data.boundary_pic_list.length > 0) {
boundaryImageList.value = [];
data.boundary_pic_list.forEach((item) => {
let obj = {
filePath: BASE_IMAGE_URL + '/' + item,
s_filePath: BASE_IMAGE_URL + '/' + item,
};
boundaryImageList.value.push(obj);
boundaryImageList.value.push(uploadUrl + '/' + item);
});
}
@ -366,11 +362,7 @@
if (data.punish_pic_list.length > 0) {
punishImageList.value = [];
data.punish_pic_list.forEach((item) => {
let obj = {
filePath: BASE_IMAGE_URL + '/' + item,
s_filePath: BASE_IMAGE_URL + '/S_' + item,
};
punishImageList.value.push(obj);
punishImageList.value.push(uploadUrl + '/' + item);
});
}
@ -378,11 +370,7 @@
if (data.payment_pic_list.length > 0) {
paymentImageList.value = [];
data.payment_pic_list.forEach((item) => {
let obj = {
filePath: BASE_IMAGE_URL + '/' + item,
s_filePath: BASE_IMAGE_URL + '/S_' + item,
};
paymentImageList.value.push(obj);
paymentImageList.value.push(uploadUrl + '/' + item);
});
}
@ -390,11 +378,7 @@
if (data.agree_checkout_pic_list.length > 0) {
agreeImageList.value = [];
data.agree_checkout_pic_list.forEach((item) => {
let obj = {
filePath: BASE_IMAGE_URL + '/' + item,
s_filePath: BASE_IMAGE_URL + '/S_' + item,
};
agreeImageList.value.push(obj);
agreeImageList.value.push(uploadUrl + '/' + item);
});
}
@ -402,11 +386,7 @@
if (data.checkout_pic_list.length > 0) {
checkoutImageList.value = [];
data.checkout_pic_list.forEach((item) => {
let obj = {
filePath: BASE_IMAGE_URL + '/' + item,
s_filePath: BASE_IMAGE_URL + '/S_' + item,
};
checkoutImageList.value.push(obj);
checkoutImageList.value.push(uploadUrl + '/' + item);
});
}
}
@ -430,11 +410,15 @@
display: flex;
height: 65vh;
.file-box {
overflow: auto;
overflow-y: auto;
}
.file-all {
overflow-y: auto;
width: 100%;
}
}
}
.map-box {
.map_box {
height: 100%;
}
</style>

View File

@ -15,11 +15,11 @@ export interface caseDetailObj {
remark?: string;
case_description?: string;
}
export interface infoObj{
export interface infoObj {
createusername?: string;
createtime?:string;
verifystatusname?:string;
measure_name?:string;
createtime?: string;
verifystatusname?: string;
measure_name?: string;
result_name?: string;
contacts_people?: string;
contacts_phone?: string;
@ -43,9 +43,20 @@ export interface infoObj{
evidence_file_indate?: string;
illegal_contact_idcard?: string;
registr_number?: string;
procedure_indate?:string;
procedure_indate?: string;
}
export interface caseHandleInfoObj {
info:infoObj
info: infoObj;
is_illegal?: string;
}
}
export interface ListItem {
title: string;
icon: string;
color?: string;
}
export interface TabItem {
key: string;
name: string;
component: string;
}

View File

@ -33,7 +33,7 @@
</script>
<style lang="less" scoped>
::v-deep .ant-image .ant-image-img {
width: 85px;
width: 100px;
margin-bottom: 10px;
}
</style>

View File

@ -8,12 +8,12 @@
</a-descriptions-item>
<a-descriptions-item label="拟拆除后照片">
<div>
<ImagePreview :imageList="imgList" />
<ImagePreview :imageList="threadAfterImageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="视频">
<div v-if="videoOptions.length > 0">
<video-player
<!-- <video-player
class="video-player vjs-custom-skin"
v-for="(item, index) in videoOptions"
:key="index"
@ -21,7 +21,11 @@
:playsinline="true"
:options="item"
style="width: 200px"
></video-player>
></video-player> -->
<!-- <video v-for="(item, index) in videoOptions" :src="item.sources[0].src" style="width: 200px"></video> -->
<video ref="videoPlayer" class="video-js vjs-default-skin" controls preload="auto" width="1024" v-for="(item, index) in videoOptions" style="width: 200px">
<source :src="item.sources[0].src" type="video/mp4" />
</video>
</div>
</a-descriptions-item>
</a-descriptions>
@ -58,6 +62,7 @@
},
},
});
console.log(props.videoOptions)
caseHandleInfo.value = props.data;
videoOptions.value = props.videoOptions;
threadAfterImageList.value = props.threadImageList;
@ -79,7 +84,7 @@
</script>
<style lang="less" scoped>
::v-deep .ant-image .ant-image-img {
width: 85px;
width: 100px;
margin-bottom: 10px;
}
</style>

View File

@ -90,7 +90,7 @@
</script>
<style lang="less" scoped>
::v-deep .ant-image .ant-image-img {
width: 85px;
width: 100px;
margin-bottom: 10px;
}
</style>

View File

@ -170,12 +170,12 @@
<a-descriptions-item label="现场照片">
<div>
<ImagePreview :imageList="imgList" />
<ImagePreview :imageList="threadImageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="现场视频">
<div v-if="playerOptions.length > 0">
<video-player
<!-- <video-player
class="video-player vjs-custom-skin"
v-for="(item, index) in playerOptions"
:key="index"
@ -183,7 +183,11 @@
:playsinline="true"
:options="item"
style="width: 200px"
></video-player>
></video-player> -->
<!-- <video v-for="(item, index) in playerOptions" :src="item.sources[0].src" style="width: 200px"></video> -->
<video ref="videoPlayer" class="video-js vjs-default-skin" controls preload="auto" width="1024" v-for="(item, index) in playerOptions" style="width: 200px">
<source :src="item.sources[0].src" type="video/mp4" />
</video>
</div>
</a-descriptions-item>
</a-descriptions>
@ -192,6 +196,8 @@
import { reactive, watch, ref } from 'vue';
import { ImagePreview } from '@/components/Preview';
import { caseHandleInfoObj } from '../model';
import { videoPlayer } from 'vue-video-player/src';
import 'vue-video-player/src/custom-theme.css';
const labelStyle = ref({
width: '100px',
});
@ -220,8 +226,8 @@
},
},
});
console.log(props)
caseHandleInfo.value = props.data;
console.log(props.playerOptions);
playerOptions.value = props.playerOptions;
threadImageList.value = props.threadImageList;
const imgList = ref([
@ -241,7 +247,7 @@
</script>
<style lang="less" scoped>
::v-deep .ant-image .ant-image-img {
width: 85px;
width: 100px;
margin-bottom: 10px;
}
</style>

View File

@ -93,7 +93,7 @@
</script>
<style lang="less" scoped>
::v-deep .ant-image .ant-image-img {
width: 85px;
width: 100px;
margin-bottom: 10px;
}
</style>

View File

@ -25,7 +25,7 @@
<a-descriptions-item label="经纬度"
>{{ caseDetail.lng }} , {{ caseDetail.lat }}</a-descriptions-item
>
<a-descriptions-item label="案件地址">{{ caseDetail.area }}&nbsp;()</a-descriptions-item>
<a-descriptions-item label="案件面积">{{ caseDetail.area }}&nbsp;()</a-descriptions-item>
<a-descriptions-item label="案件类型">{{ caseDetail.typename }}</a-descriptions-item>
<a-descriptions-item label="案件备注">{{ caseDetail.remark }}</a-descriptions-item>
<a-descriptions-item label="案件描述">{{ caseDetail.case_description }}</a-descriptions-item>
@ -41,6 +41,7 @@
import { reactive, watch, ref } from 'vue';
import { ImagePreview } from '@/components/Preview';
import { DetailModel, caseDetailObj } from '../model';
const labelStyle = ref({
width: '100px',
});
@ -52,26 +53,30 @@
return {};
},
},
imageList: {
type: Object,
default: () => {
return [];
},
},
});
if(Object.keys(props.data).length != 0){
console.log(props)
const imgList = ref([]);
if (Object.keys(props.data).length != 0) {
caseDetail.value = props.data.info;
imgList.value = props.imageList;
}
const imgList = ref([
'https://picsum.photos/id/66/346/216',
'https://picsum.photos/id/67/346/216',
'https://picsum.photos/id/68/346/216',
]);
watch(
() => props.data,
(newVal, oldVal) => {
caseDetail.value = newVal.info;
imgList.value = props.imageList;
},
);
</script>
<style lang="less" scoped>
::v-deep .ant-image .ant-image-img {
width: 85px;
width: 100px;
margin-bottom: 10px;
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="w-full">
<MapboxMaps :mapOptions="mapOptions" @map-on-load="mapOnLoad" />
<MapboxMaps :mapOptions="mapOptions" :control="[]" @map-on-load="mapOnLoad" />
</div>
</template>
<script lang="ts" setup>
@ -8,6 +8,7 @@
import { ref, watch } from 'vue';
import MapboxMaps from '@/components/MapboxMaps/index.vue';
import { getDroneGeoJson } from '@/api/monitor/index';
const detailMap = ref();
const props = defineProps({
ruleForm: {
@ -199,7 +200,6 @@
</script>
<style scoped lang="less">
.w-full {
width: 100%;
height: 50vh;
}
</style>

View File

@ -105,7 +105,7 @@
</script>
<style lang="less" scoped>
::v-deep .ant-image .ant-image-img {
width: 85px;
width: 100px;
margin-bottom: 10px;
}
</style>

View File

@ -16,7 +16,9 @@ export { default as Evidence } from './caseview/src/evidence.vue';
export { default as Investigate } from './caseview/src/investigate.vue';
// 【案件办理信息-违法-拟完善手续】
export { default as Procedure } from './caseview/src/procedure.vue';
// 案件判读
export { default as Interpret } from './interpretation/src/interpret.vue';
// 案件处理
export { default as Dispose } from './interpretation/src/dispose.vue';
// 案件判读地图
export { default as InterpretMap } from './interpretation/src/interpretMap.vue';

View File

@ -0,0 +1,255 @@
<template>
<div class="interpretation-box">
<InterpretMap :interpretData="interpretData" @setArea="setArea"></InterpretMap>
<div :class="prefixCls" v-if="disabledType">
<div :class="`${prefixCls}__top`">
<a-form ref="formRef" :model="listQuery" labelAlign="left">
<a-form-item placeholder="状态">
<a-select
v-model:value="listQuery.is_intact"
placeholder="请选择"
:options="data.intactDatas"
:field-names="{ label: 'itemName', value: 'itemValue' }"
>
</a-select>
</a-form-item>
<a-form-item placeholder="办理状态">
<a-select
v-model:value="listQuery.handle_status_id"
placeholder="请选择"
:options="data.handleDealOptions"
:field-names="{ label: 'itemName', value: 'itemValue' }"
>
</a-select>
</a-form-item>
<a-form-item placeholder="办理状态">
<a-tree-select
v-model:value="value"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
:tree-data="data.OrgList"
placeholder="查询地区"
/>
</a-form-item>
<a-form-item>
<a-input v-model:value="listQuery.key" placeholder="请输入关键字" />
</a-form-item>
<a-form-item>
<a-input v-model:value="listQuery.identification_user" placeholder="判读人姓名" />
</a-form-item>
<a-form-item class="btn_item">
<a-button @click="getList">
<template #icon><SearchOutlined /></template>
</a-button>
<a-button>
<template #icon><VerticalAlignBottomOutlined /></template>
</a-button>
</a-form-item>
</a-form>
<div class="clear"></div>
</div>
<div :class="`${prefixCls}__content`">
<List :pagination="pagination">
<template v-for="item in data.dataList" :key="item.id">
<List.Item class="list">
<List.Item.Meta>
<template #avatar>
<a-image
:width="60"
:src="uploadUrl+'/'+item.case_pic_list[0]"
/>
</template>
<template #title>
<span>{{ item.case_description }}</span>
</template>
<template #description>
<div class="description-box">
<div class="description">
<span>{{ item.streetname }}&nbsp;{{ item.communityname }}</span>
&nbsp;&nbsp;&nbsp;&nbsp;
<span style="float: right">{{ item.createtime }}</span>
</div>
<div class="description">
{{ item.identification_user }}
</div>
<div class="extra">
<a-button type="primary" @click="interpretBnt(item)"></a-button>
</div>
</div>
</template>
</List.Item.Meta>
</List.Item>
</template>
</List>
</div>
</div>
<div class="case_info" v-else>
<CollapseContainer title="案件信息" :canExpan="false">
<template #action>
<div class="case_close" @click="changeType">
<CloseOutlined />
</div>
</template>
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="案件判读">
<Interpret ref="interpretRef" :interpretData="interpretData" @close="changeType"></Interpret>
</a-tab-pane>
<a-tab-pane key="2" tab="案件处理">
<Dispose :id="interpretData.id"></Dispose>
</a-tab-pane>
</a-tabs>
</CollapseContainer>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { Progress, Row, Col, List, Tag, Tabs } from 'ant-design-vue';
import Icon from '@/components/Icon/Icon.vue';
import { CollapseContainer } from '@/components/Container';
import { SearchOutlined } from '@ant-design/icons-vue';
import { VerticalAlignBottomOutlined, CloseOutlined } from '@ant-design/icons-vue';
import { BasicForm } from '@/components/Form';
import MapboxMaps from '@/components/MapboxMaps/index.vue';
import { getCaseInfoList } from '@/api/monitor/index';
import { Interpret, Dispose, InterpretMap } from '../index';
import { useGlobSetting } from '@/hooks/setting';
const { uploadUrl } = useGlobSetting();
const disabledType = ref(true);
const prefixCls = 'list-basic';
const activeKey = ref('1');
const interpretData = ref({});
const interpretRef = ref()
const pagination = ref({
onChange: (page: number) => {
console.log(page);
listQuery.value.page = page;
getList();
},
pageSize: 5,
total: 0,
});
const listQuery = ref({
page: 1,
limit: 5,
is_intact: 0,
});
const data = reactive({
OrgList: [],
handleDealOptions: [],
intactDatas: [],
dataList: [],
});
const mapOptions = {
center: [117.84714891969796, 35.22152309532066],
zoom: 10,
};
const detailMap = ref();
const mapBox = ref();
const mapOnLoad = (map) => {
mapBox.value = map;
//
const testSource =
'http://123.132.248.154:9205/geoserver/gwc/service/tms/1.0.0/TEST_WORK_SPACE%3Alindi@EPSG:900913@pbf/{z}/{x}/{y}.pbf';
map.U.addVector('name', testSource);
map.U.addLineLayer('ffff', {
source: 'name',
'source-layer': 'lindi',
});
detailMap.value = map;
};
async function getList() {
const obj = await getCaseInfoList(listQuery.value);
console.log(obj);
data.dataList = obj.items;
pagination.value.total = obj.total;
}
function changeType() {
disabledType.value = true;
}
function interpretBnt(item) {
disabledType.value = false;
console.log(item);
interpretData.value = item;
}
function setArea(area) {
interpretData.value.area = area;
interpretRef.value.setMap(area)
}
onMounted(() => {
getList();
});
</script>
<style scoped lang="less">
.w-full {
width: 100%;
position: relative;
height: 90vh;
}
.case_info {
position: absolute;
top: 12px;
left: 25px;
width: 40%;
height: 87vh;
.vben-collapse-container {
height: 100%;
}
.case_close {
cursor: pointer;
}
}
.list-basic {
position: absolute;
top: 12px;
left: 25px;
width: 30%;
height: 90vh;
&__top {
padding: 10px;
background-color: @component-background;
text-align: center;
height: 10vh;
.clear {
clear: both;
}
}
&__content {
height: 76vh;
overflow: auto;
margin-top: 12px;
padding: 10px 0;
background-color: @component-background;
.list {
position: relative;
}
.icon {
font-size: 40px !important;
}
.extra {
display: flex;
justify-content: flex-end;
}
.description-box {
display: flex;
flex-direction: column;
}
}
}
::v-deep .ant-form {
.ant-form-item {
float: left;
margin-bottom: 4px;
margin-left: 4px;
width: 30%;
button {
margin-right: 10px;
}
}
}
</style>

View File

@ -0,0 +1,382 @@
<template>
<div>
<CollapseContainer title="【案件核查信息】" :canExpan="false">
<a-descriptions bordered :column="1" size="small" :labelStyle="labelStyle">
<a-descriptions-item label="核查人">{{
caseHandlingData.createusername
}}</a-descriptions-item>
<a-descriptions-item label="核查时间">
{{ caseHandlingData.createtime }}
</a-descriptions-item>
<a-descriptions-item label="是否违法">
<span v-if="illegal == 0"></span>
<span v-else-if="illegal == 1">违法</span>
<span v-else-if="illegal == 2">伪变化</span>
</a-descriptions-item>
<a-descriptions-item label="现场照片">
<div>
<ImagePreview :imageList="imageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="现场视频">
<div v-if="playerOptions.length > 0">
<video-player
class="video-player vjs-custom-skin"
v-for="(item, index) in playerOptions"
:key="index"
ref="videoPlayer"
:playsinline="true"
:options="item"
style="width: 200px"
></video-player>
</div>
</a-descriptions-item>
<a-descriptions-item label="处理措施" v-if="illegal == 1">
{{ caseHandlingData.createtime }}
</a-descriptions-item>
<template v-if="illegal == 0">
<a-descriptions-item label="项目名称">
{{ caseHandlingData.result_name }}
</a-descriptions-item>
<a-descriptions-item label="建设情况">
{{ caseHandlingData.actual_scene_case }}
</a-descriptions-item>
<a-descriptions-item label="建筑结构">
{{ caseHandlingData.build_structure }}
</a-descriptions-item>
<a-descriptions-item label="实际用途">
{{ caseHandlingData.actual_use_to }}
</a-descriptions-item>
<a-descriptions-item label="当事人">
{{ caseHandlingData.illegal_contact }}
</a-descriptions-item>
<a-descriptions-item label="当事人电话">
{{ caseHandlingData.illegal_contact_phone }}
</a-descriptions-item>
</template>
</a-descriptions>
</CollapseContainer>
<CollapseContainer title="【案件办理信息-合法】" :canExpan="false" v-if="illegal == 0">
<a-descriptions-item label="批准文件名称">
{{ caseHandlingData.evidence_file_name }}
</a-descriptions-item>
<a-descriptions-item label="批准文件编号">
{{ caseHandlingData.evidence_file_number }}
</a-descriptions-item>
<a-descriptions-item label="批准文件有效期">
{{ caseHandlingData.evidence_file_indate }}
</a-descriptions-item>
<a-descriptions-item label="合法批准文件">
<div>
<ImagePreview :imageList="evidenceFileList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="勘测定界图">
<div>
<ImagePreview :imageList="boundaryImageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="是否超范围">
{{ caseHandlingData.is_out_boundary == 1 ? '是' : '否' }}
</a-descriptions-item>
<a-descriptions-item label="是否超层">
{{ caseHandlingData.is_over_floor == 1 ? '是' : '否' }}
</a-descriptions-item>
<a-descriptions-item label="办理人">
{{ caseHandlingData.transactor_name }}
</a-descriptions-item>
<a-descriptions-item label="办理时间">
{{ caseHandlingData.transact_time }}
</a-descriptions-item>
</CollapseContainer>
<CollapseContainer title="【案件办理信息-伪变化】" :canExpan="false" v-if="illegal == 2">
<a-descriptions-item label="伪变化原因">
{{ caseHandlingData.pseudo_change_reason }}
</a-descriptions-item>
<a-descriptions-item label="实际用途">
{{ caseHandlingData.actual_use_to }}
</a-descriptions-item>
<a-descriptions-item label="实际面积">
{{ caseHandlingData.actual_area }}
</a-descriptions-item>
<a-descriptions-item label="是否有建筑物">
{{ caseHandlingData.is_have_build == 1 ? '是' : '否' }}
</a-descriptions-item>
<a-descriptions-item label="是否永久性建筑">
{{ caseHandlingData.is_have_build == 1 ? '是' : '否' }}
</a-descriptions-item>
<a-descriptions-item label="办理人">
{{ caseHandlingData.transactor_name }}
</a-descriptions-item>
<a-descriptions-item label="办理时间">
{{ caseHandlingData.transact_time }}
</a-descriptions-item>
</CollapseContainer>
<CollapseContainer
title="【案件办理信息-拟拆除】"
:canExpan="false"
v-if="illegal == 1 && caseHandlingData.measure_name == '拟拆除'"
>
<a-descriptions-item label="实际用途">
{{ caseHandlingData.actual_use_to }}
</a-descriptions-item>
<a-descriptions-item label="当事人">
{{ caseHandlingData.illegal_contact }}
</a-descriptions-item>
<a-descriptions-item label="当事人电话">
{{ caseHandlingData.illegal_contact_phone }}
</a-descriptions-item>
<a-descriptions-item label="建设情况">
{{ caseHandlingData.is_build_complete == 1 ? '已建成' : '建设中' }}
</a-descriptions-item>
<a-descriptions-item label="建筑结构">
{{ caseHandlingData.build_structure }}
</a-descriptions-item>
<a-descriptions-item label="拆除后照片">
<div>
<ImagePreview :imageList="afterImageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="办理人">
{{ caseHandlingData.transactor_name }}
</a-descriptions-item>
<a-descriptions-item label="办理时间">
{{ caseHandlingData.transact_time }}
</a-descriptions-item>
</CollapseContainer>
<CollapseContainer
title="【案件办理信息-查处】"
:canExpan="false"
v-if="illegal == 1 && caseHandlingData.measure_name == '查处'"
>
<a-descriptions-item label="实际用途">
{{ caseHandlingData.actual_use_to }}
</a-descriptions-item>
<a-descriptions-item label="当事人">
{{ caseHandlingData.illegal_contact }}
</a-descriptions-item>
<a-descriptions-item label="当事人电话">
{{ caseHandlingData.illegal_contact_phone }}
</a-descriptions-item>
<a-descriptions-item label="身份证号码">
{{ caseHandlingData.illegal_contact_idcard }}
</a-descriptions-item>
<a-descriptions-item label="违法类型">
{{ caseHandlingData.illegal_type }}
</a-descriptions-item>
<a-descriptions-item label="立案号">
{{ caseHandlingData.build_structure }}
</a-descriptions-item>
<a-descriptions-item label="处罚通知书">
<div>
<ImagePreview :imageList="punishImageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="交款通知书">
<div>
<ImagePreview :imageList="paymentImagesList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="办理人">
{{ caseHandlingData.transactor_name }}
</a-descriptions-item>
<a-descriptions-item label="办理时间">
{{ caseHandlingData.transact_time }}
</a-descriptions-item>
</CollapseContainer>
<CollapseContainer
title="【案件办理信息-拟完善手续】"
:canExpan="false"
v-if="illegal == 1 && caseHandlingData.measure_name == '拟完善手续'"
>
<a-descriptions-item label="实际用途">
{{ caseHandlingData.actual_use_to }}
</a-descriptions-item>
<a-descriptions-item label="当事人">
{{ caseHandlingData.illegal_contact }}
</a-descriptions-item>
<a-descriptions-item label="当事人电话">
{{ caseHandlingData.illegal_contact_phone }}
</a-descriptions-item>
<a-descriptions-item label="拟完善手续名称">
{{ caseHandlingData.result_name }}
</a-descriptions-item>
<a-descriptions-item label="完善手续条件">
{{ caseHandlingData.is_have_checkout_condition == 1 ? '是' : '否' }}
</a-descriptions-item>
<a-descriptions-item label="违法类型">
{{ caseHandlingData.illegal_type }}
</a-descriptions-item>
<a-descriptions-item label="政府同意完善手续证明">
<div>
<ImagePreview :imageList="agreeImageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="办理手续照片">
<div>
<ImagePreview :imageList="checkoutImageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="勘测定界图">
<div>
<ImagePreview :imageList="boundaryImageList" />
</div>
</a-descriptions-item>
<a-descriptions-item label="手续有效期">
{{ caseHandlingData.procedure_indate }}
</a-descriptions-item>
<a-descriptions-item label="办理人">
{{ caseHandlingData.transactor_name }}
</a-descriptions-item>
<a-descriptions-item label="办理时间">
{{ caseHandlingData.transact_time }}
</a-descriptions-item>
</CollapseContainer>
</div>
</template>
<script lang="ts" setup>
import { reactive, watch, ref , onMounted} from 'vue';
import { ImagePreview } from '@/components/Preview';
import { CollapseContainer } from '@/components/Container';
import { caseHandleInfoObj } from '../model';
import { getDroneCaseDeal } from '@/api/monitor/index'
const illegal = ref(0);
const labelStyle = ref({
width: '100px',
});
const caseHandlingData = ref({});
const playerOptions = ref([]);
const imageList = ref([
'https://picsum.photos/id/66/346/216',
'https://picsum.photos/id/67/346/216',
'https://picsum.photos/id/68/346/216',
]);
const evidenceFileList = ref([
'https://picsum.photos/id/66/346/216',
'https://picsum.photos/id/67/346/216',
'https://picsum.photos/id/68/346/216',
]);
const boundaryImageList = ref([
'https://picsum.photos/id/66/346/216',
'https://picsum.photos/id/67/346/216',
'https://picsum.photos/id/68/346/216',
]);
const afterImageList = ref([
'https://picsum.photos/id/66/346/216',
'https://picsum.photos/id/67/346/216',
'https://picsum.photos/id/68/346/216',
]);
const punishImageList = ref([]);
const paymentImagesList = ref([]);
const agreeImageList = ref([]);
const checkoutImageList = ref([]);
const props = defineProps({
id: String
});
watch(
() => props.id,
(newVal, oldVal) => {
getCaseHandlingDetail()
},
);
onMounted(() => {
getCaseHandlingDetail();
});
async function getCaseHandlingDetail() {
const data = await getDroneCaseDeal({ caseid: props.id });
illegal.value = data.is_illegal;
caseHandlingData.value = data.info;
imageList.value = [];
if (data.pic_info_list.length > 0) {
data.pic_info_list.forEach((item) => {
item.s_filePath = BASE_IMAGE_URL + '/S_' + item.filePath;
item.filePath = BASE_IMAGE_URL + '/' + item.filePath;
imageList.value.push(item);
});
}
afterImageList.value = [];
if (data.after_pic_list.length > 0) {
data.after_pic_list.forEach((item) => {
item.s_filePath = BASE_IMAGE_URL + '/S_' + item.filePath;
item.filePath = BASE_IMAGE_URL + '/' + item.filePath;
afterImageList.value.push(item);
});
}
//
evidenceFileList.value = [];
if (data.evidence_file_list.length > 0) {
data.evidence_file_list.forEach((item) => {
item.s_filePath = BASE_IMAGE_URL + '/S_' + item.filePath;
item.filePath = BASE_IMAGE_URL + '/' + item.filePath;
evidenceFileList.value.push(item);
});
}
//
if (data.punish_pic_list.length > 0) {
punishImageList.value = this.handleImageArray(data.punish_pic_list);
}
//
if (data.payment_pic_list.length > 0) {
paymentImagesList.value = this.handleImageArray(data.payment_pic_list);
}
//
if (data.agree_checkout_pic_list.length > 0) {
agreeImageList.value = this.handleImageArray(data.agree_checkout_pic_list);
}
//
if (data.checkout_pic_list.length > 0) {
checkoutImageList.value = this.handleImageArray(data.checkout_pic_list);
}
//
if (data.boundary_pic_list.length > 0) {
boundaryImageList.value = this.handleImageArray(data.boundary_pic_list);
}
playerOptions.value = [];
if (data.video_list.length > 0) {
data.video_list.forEach((item, index) => {
let options = {
playbackRates: [0.5, 1.0, 1.5, 2.0], //
autoplay: false, //true,
muted: false, //
loop: false, //
preload: 'auto', // <video>auto,
language: 'zh-CN',
aspectRatio: '16:9', // 使 - "16:9""4:3"
fluid: true, // trueVideo.js player
sources: [
{
type: '',
src: BASE_IMAGE_URL + '/' + item, //url
},
],
poster: '', //
// width: document.documentElement.clientWidth,
notSupportedMessage: '此视频暂无法播放,请稍后再试', //Video.js
controlBar: {
timeDivider: true, //
durationDisplay: true, //
remainingTimeDisplay: false, //
fullscreenToggle: true, //
},
};
playerOptions.value.push(options);
});
}
}
</script>
<style lang="less" scoped>
::v-deep .ant-image .ant-image-img {
width: 100px;
margin-bottom: 10px;
}
</style>

View File

@ -0,0 +1,309 @@
<template>
<div class="interpret-box">
<div class="interpret-form">
<a-form
ref="formRef"
:rules="data.rules"
:model="ruleForm"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-form-item label="案件编号">
<a-input v-model:value="ruleForm.case_no" disabled />
</a-form-item>
<a-form-item label="案件详情">
<a-input v-model:value="ruleForm.case_description" placeholder="请输入" />
</a-form-item>
<a-form-item label="违规类型" name="typeid">
<a-select
v-model:value="ruleForm.typeid"
placeholder="请选择"
:options="data.violationOptions"
:field-names="{ label: 'itemName', value: 'itemValue' }"
>
</a-select>
</a-form-item>
<a-form-item label="图斑面积">
<a-input v-model:value="ruleForm.area" placeholder="请输入" />
</a-form-item>
<a-form-item label="县/区">
<a-select
v-model:value="ruleForm.countyid"
placeholder="请选择"
:options="data.cityDatas"
:field-names="{ label: 'itemName', value: 'itemValue' }"
>
</a-select>
</a-form-item>
<a-form-item label="乡镇/街道">
<a-select
v-model:value="ruleForm.streetid"
placeholder="请选择"
:options="data.streetDatas"
:field-names="{ label: 'itemName', value: 'itemValue' }"
>
</a-select>
</a-form-item>
<a-form-item label="社区/村">
<a-select
v-model:value="ruleForm.communityname"
placeholder="请选择"
:options="data.communtDatas"
:field-names="{ label: 'itemName', value: 'itemValue' }"
>
</a-select>
</a-form-item>
<a-form-item label="详细地址">
<a-input v-model:value="ruleForm.address" placeholder="请输入" />
</a-form-item>
<a-form-item label="备注">
<a-textarea
v-model:value="ruleForm.description"
placeholder="备注"
:auto-size="{ minRows: 1, maxRows: 3 }"
/>
</a-form-item>
<a-form-item label="现场照片">
<ImagePreview :imageList="picListData" />
<ImageUpload
file-list="fileList"
:maxSize="20"
:maxNumber="10"
:api="imgApi"
:multiple="true"
@delete="handleRemove"
/>
</a-form-item>
</a-form>
</div>
<div class="btn-box">
<a-button color="info" class="ml-2" @click="resetForm"></a-button>
<a-button color="info" class="ml-2" type="primary" @click="saveForm"></a-button>
<a-button color="success" class="ml-2" type="primary" @click="submitForm"></a-button>
<a-button color="info" class="ml-2" type="primary" danger @click="eventClose"></a-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { ImageUpload } from '@/components/Upload';
import { ref, reactive, watch, onMounted } from 'vue';
import { ImagePreview } from '@/components/Preview';
import { getCaseInfo, addDroneCaseInfo, updateDroneCaseInfoIntact } from '@/api/monitor/index';
import { uploadApi } from '@/api/sys/upload';
//
import { useGlobSetting } from '@/hooks/setting';
const { uploadUrl } = useGlobSetting();
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
const emit = defineEmits(['close']);
const formRef = ref();
const labelCol = { span: 7 };
const wrapperCol = { span: 17 };
const ruleForm = ref({});
const fileList = ref([]);
const filSuccessList = ref([]);
const formData = ref({});
const picListData = ref([]);
const abbreviationPicListData = ref([]);
const data = reactive({
violationOptions: [],
communtDatas: [],
streetDatas: [],
cityDatas: [],
rules: {
typeid: [{ required: true, message: '请选择违规类型' }],
},
});
watch(fileList, (newValue) => {
// fileList
// newValue formUser === formUser.value
console.log(newValue);
});
const props = defineProps({
interpretData: {
type: Object,
default: () => {
return {};
},
},
});
ruleForm.value = props.interpretData;
watch(
() => props.interpretData,
(newVal, oldVal) => {
ruleForm.value = newVal;
getFormData();
},
);
onMounted(() => {
getFormData();
});
//
async function getFormData() {
picListData.value = [];
const data = await getCaseInfo({ id: ruleForm.value.id });
formData.value = data;
data.pics.forEach((item) => {
picListData.value.push(uploadUrl + '/' + item.path);
//
abbreviationPicListData.value.push(uploadUrl + '/S_' + item.path);
});
}
async function imgApi(file, progress) {
const data = await uploadApi(file, progress);
if (data.result.length > 0) {
filList.value.push(file);
filSuccessList.value.push(data.data.result[0]);
}
}
function handleRemove(file) {
console.log(file);
var currentIndex = (fileList.value || []).findIndex((element) => element.uid === file.uid);
fileList.value.splice(currentIndex, 1);
filSuccessList.value.splice(currentIndex, 1);
}
//
async function getNoBuildStatus() {
getMethodCommon('/Categorys/LoadList', { typeid: 'DRONE_CASE_TYPE' }).then((res) => {
this.violationOptions = res.result;
});
}
//
async function getAreasData() {
getMethodCommon('/Orgs/LoadOrgList', { name: '费县' }).then((res) => {
this.areasDatas = res.result;
res.result.forEach((item) => {
if (item.parentName == '临沂市') {
this.cityDatas.push(item);
}
if (item.parentId == this.ruleForm.countyid) {
this.streetDatas.push(item);
}
if (item.parentId == this.ruleForm.streetid) {
this.communtDatas.push(item);
}
});
});
}
//
async function validateForm() {
let res = await formRef.value
.validate()
.then((values) => {
return true;
})
.catch((error) => {
return false;
});
return res;
}
//
function resetForm() {
emit('close');
}
//
async function saveForm() {
formData.value.info = ruleForm.value;
filSuccessList.value.forEach((element) => {
formData.value.pic_list.push(element.filePath);
});
console.log(formData.value);
const data = await addDroneCaseInfo(formData.value);
if (data) {
resetForm();
return createMessage.success('成功');
} else {
return createMessage.error('失败');
}
}
//
async function submitForm() {
const success = await validateForm();
console.log(success);
if (!success) {
return;
}
formData.value.info = ruleForm.value;
formData.value.info.is_intact = 1;
filSuccessList.value.forEach((element) => {
formData.value.pic_list.push(element.filePath);
});
console.log(formData.value);
const data = await updateDroneCaseInfoIntact(formData.value);
if (data) {
resetForm();
return createMessage.success('成功');
} else {
return createMessage.error('失败');
}
}
//
async function eventClose() {
createConfirm({
iconType: 'warning',
title: '关闭',
content: '确认关闭此案件?',
onOk: async () => {
const data = await closeDroneCaseInfo({ id: ruleForm.value.id });
if (data) {
return createMessage.success('成功');
} else {
return createMessage.error('失败');
}
},
});
}
function setMap(data) {
ruleForm.value.area = data;
}
defineExpose({
setMap,
});
</script>
<style lang="less" scoped>
.interpret-box {
width: 100%;
height: 74vh;
position: relative;
.interpret-form {
overflow-y: auto;
height: 100%;
padding-bottom: 20px;
}
.ant-form {
padding: 20px;
display: flex;
flex-direction: column;
.ant-form-item {
float: left;
margin-bottom: 10px;
margin-left: 4px;
width: 100%;
button {
margin-right: 10px;
}
}
}
::v-deep .ant-image-img {
width: 50%;
}
}
::v-deep .ant-image .ant-image-img {
width: 100px;
margin-bottom: 10px;
}
.btn-box {
width: 100%;
padding: 10px 10%;
display: flex;
align-items: center;
justify-content: space-around;
position: absolute;
bottom: 0px;
left: 0;
background-color: @component-background;
}
</style>

View File

@ -0,0 +1,104 @@
<template>
<div class="w-full">
<MapboxMaps :mapOptions="mapOptions" @map-on-load="mapOnLoad" :control="mapControl" @map-draw="handlerMapDraw" />
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, watch } from 'vue';
import rodeImg from '@/assets/images/icon_fly2.png';
import MapboxMaps from '@/components/MapboxMaps/index.vue';
import { DrawingType } from '@/enums/mapEnum';
const mapControl: DrawingType[] = [DrawingType.Polygon];
const emit = defineEmits(['setArea']);
const mapOptions = {
center: [117.84714891969796, 35.22152309532066],
zoom: 10,
};
const detailMap = ref();
const mapBox = ref();
const ruleForm = ref({});
const props = defineProps({
interpretData: {
type: Object,
default: () => {
return {};
},
},
});
console.log(props.interpretData);
ruleForm.value = props.interpretData;
watch(
() => props.interpretData,
(newVal, oldVal) => {
ruleForm.value = newVal;
detailMap.value.flyTo({
center: [newVal.lng, newVal.lat], //
zoom: 16, //
pitch: 0, //
});
loadDroneMarker(newVal.lng, newVal.lat);
},
);
const mapOnLoad = (map) => {
mapBox.value = map;
//
const testSource =
'http://123.132.248.154:9205/geoserver/gwc/service/tms/1.0.0/TEST_WORK_SPACE%3Alindi@EPSG:900913@pbf/{z}/{x}/{y}.pbf';
map.U.addVector('name', testSource);
map.U.addLineLayer('ffff', {
source: 'name',
'source-layer': 'lindi',
});
detailMap.value = map;
};
//
const handlerMapDraw = (type: string, data: any) => {
console.log('data::: ', data);
console.log('type::: ', type);
emit('setArea',data)
};
//
function loadDroneMarker(lng, lat) {
if (detailMap.value.getLayer('cat-on-building')) {
detailMap.value.removeLayer('cat-on-building');
detailMap.value.removeSource('cat-on-building');
detailMap.value.removeImage('cat');
}
detailMap.value.loadImage(rodeImg, (error, image) => {
detailMap.value.addImage('cat', image);
detailMap.value.addLayer({
id: 'cat-on-building',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [lng, lat],
},
},
],
},
},
slot: 'top',
type: 'symbol',
layout: {
'icon-image': 'cat',
'icon-size': 0.05,
'symbol-placement': 'point',
'symbol-z-elevate': true,
},
});
});
}
</script>
<style scoped lang="less">
.w-full {
width: 100%;
position: relative;
height: 90vh;
}
</style>

View File

@ -0,0 +1,60 @@
import { BasicColumn, FormSchema } from '@/components/Table';
import { h } from 'vue';
import { Switch, Tag } from 'ant-design-vue';
import { setRoleStatus } from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
type CheckedType = boolean | string | number;
export const columns: BasicColumn[] = [
{
title: '任务名称',
dataIndex: 'taskName',
},
{
title: '任务时间',
dataIndex: 'taskDate',
},
{
title: '图片数量',
dataIndex: 'imageCount',
},
{
title: '创建时间',
dataIndex: 'createTime',
},
];
export const searchFormSchema: FormSchema[] = [
{
field: 'taskName',
label: '任务名称',
component: 'Input',
colProps: { span: 8 },
},
{
field: '[beginDate, endDate]',
component: 'RangePicker',
label: '日期范围',
componentProps: {
format: 'YYYY-MM-DD',
placeholder: ['开始日期', '结束日期'],
},
colProps: { span: 8 },
},
];
export const formSchema: FormSchema[] = [
{
field: 'taskName',
label: '任务名称',
required: true,
component: 'Input',
},
{
field: 'taskDate',
label: '任务时间',
required: true,
component: 'DatePicker',
},
];

View File

@ -0,0 +1,150 @@
<template>
<div>
<BasicTable @register="registerTable" :searchInfo="searchInfo">
<template #toolbar>
<PermissionBtn @btn-event="onBtnClicked" />
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
// icon: 'ant-design:ellipsis-outlined',
label: '查看',
onClick: viewAccount.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
<TaskModal @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { getRoleListByPage, deleteRole } from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
import { useModal } from '@/components/Modal';
import TaskModal from './src/taskModel.vue';
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { columns, searchFormSchema } from './data';
defineOptions({ name: 'RoleManagement' });
const { createConfirm, createMessage } = useMessage();
const [registerModal, { openModal: openRoleModal }] = useModal();
const [registerModulesModal, { openModal: openModulesModal }] = useModal();
const [registerAccountModal, { openModal: openAccountModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys }] = useTable({
//
title: '任务列表',
//
api: getRoleListByPage,
// BasicColumn[]
columns,
rowKey: 'id',
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
// 使
useSearchForm: true,
//
showTableSetting: true,
//
bordered: true,
//
showIndexColumn: false,
//
rowSelection: {
//
// type: 'checkbox',
type: 'radio',
},
//
handleSearchInfoFn(info) {
return info;
},
});
function handleCreate() {
openRoleModal(true, {
isUpdate: false,
});
}
function viewAccount(record: Recordable) {
openAccountModal(true, {
record,
});
}
function handleEdit() {
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请勾选一个角色进行编辑');
}
const record = rows[0];
openRoleModal(true, {
record,
isUpdate: true,
});
}
async function handleDelete() {
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请勾选一个角色进行删除');
}
const query = [rows[0].id];
createConfirm({
iconType: 'info',
title: '删除',
content: '确定要删除当前角色吗',
onOk: async () => {
const data = await deleteRole(query);
if (data) {
handleSuccess();
return createMessage.success('删除成功');
} else {
return createMessage.error('删除失败');
}
},
});
}
function handleSuccess() {
clearSelectedRowKeys();
reload();
}
function onBtnClicked(domId) {
switch (domId) {
case 'btnAdd':
handleCreate();
break;
case 'btnEdit':
handleEdit();
break;
case 'btnDelete':
handleDelete();
break;
case 'btnModules':
let rows = getSelectRows();
if (rows.length == 0) {
return createMessage.warn('请勾选一个角色进行编辑');
}
const record = rows[0];
openModulesModal(true, {
record,
});
break;
default:
break;
}
}
</script>

View File

@ -0,0 +1,53 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="添加任务" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from '../data';
import { addPicTask } from '@/api/monitor/index';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
defineOptions({ name: 'DeptModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 100,
baseColProps: { span: 24 },
schemas: formSchema,
showActionButtonGroup: false,
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
});
async function handleSubmit() {
try {
const values = await validate();
let query = values;
const data = await addPicTask(query);
if (data) {
setModalProps({ confirmLoading: true });
// TODO custom api
closeModal();
emit('success');
return createMessage.success('新增成功');
} else {
return createMessage.error('新增失败');
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

View File

@ -0,0 +1,58 @@
import { BasicColumn, FormSchema } from '@/components/Table';
export const tableColums: BasicColumn[] = [
{
title: '案件编号',
dataIndex: 'case_no',
width: 120,
},
{
title: '上报时间',
dataIndex: 'createtime',
width: 120,
},
{
title: '地点',
dataIndex: 'address',
width: 120,
},
{
title: '案件描述',
dataIndex: 'case_description',
width: 120,
},
{
title: '处理时间',
dataIndex: 'deal_time',
width: 120,
},
{
title: '案件处理人',
dataIndex: 'deal_username',
width: 120,
},
{
title: '处理进度',
dataIndex: 'verifystatusname',
width: 120,
},
{
title: '处理状态',
dataIndex: 'handle_status_name',
width: 120,
},
{
title: '办结时间',
dataIndex: 'verifytime',
width: 120,
},
];
export const searchFormSchema: FormSchema[] = [
{
field: 'keyword',
label: '关键字',
component: 'Input',
colProps: { span: 8 },
},
];

View File

@ -0,0 +1,334 @@
<!-- eslint-disable vue/no-deprecated-v-on-native-modifier -->
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<BasicTable
class="w-4/4 xl:w-5/5"
@register="registerTable"
@fetch-success="onFetchSuccess"
:searchInfo="searchInfo"
>
<template #toolbar>
<!-- 日期选择框 -->
<div style="display: inline; margin-right: 10px; width: 200px">
<a-range-picker
v-model:value="startEndTime"
size="mini"
align="right"
:presets="rangePresets"
@change="getCaseList"
/>
</div>
<!-- 案件类型 -->
<div style="display: inline; margin-right: 10px; width: 200px">
<a-select
v-model:value="listQuery.typeid"
:options="caseTypeOptions"
placeholder="案件类型"
style="width: 200px"
:field-names="{ label: 'itemName', value: 'itemDetailId' }"
@change="getCaseList"
/>
</div>
<!-- 查询地区 -->
<div style="display: inline; margin-right: 10px; width: 100px">
<a-cascader
:options="OrgList"
v-model:value="listQuery.org"
placeholder="查询地区"
size="mini"
style="width: 100px"
@change="handleChange"
/>
</div>
<!-- 现场状况 -->
<div style="display: inline; margin-right: 10px; width: 100px">
<a-select
:options="illegalOptions"
v-model:value="listQuery.is_illegal"
placeholder="现场状况"
style="width: 100px"
:field-names="{ label: 'name', value: 'id' }"
@change="getCaseList"
/>
</div>
<!-- 案件编号 -->
<div style="display: inline; margin-right: 10px">
<a-input
@keyup.enter="getCaseList"
size="mini"
style="width: 120px"
class="filter-item"
:placeholder="'案件编号'"
v-model:value="listQuery.case_no"
/>
</div>
<!-- 处理人姓名 -->
<div style="display: inline; margin-right: 10px">
<a-input
@keyup.enter="getCaseList"
size="mini"
style="width: 120px"
class="filter-item"
:placeholder="'处理人姓名'"
v-model:value="listQuery.deal_username"
/>
</div>
<!-- 审核人姓名 -->
<div style="display: inline; margin-right: 10px">
<a-input
@keyup.enter="getCaseList"
size="mini"
style="width: 120px"
class="filter-item"
:placeholder="'审核人姓名'"
v-model:value="listQuery.verifyuser"
/>
</div>
<!-- 请输入关键字 -->
<div style="display: inline; margin-right: 10px">
<a-input
@keyup.enter="getCaseList"
size="mini"
style="width: 120px"
class="filter-item"
:placeholder="'请输入关键字'"
v-model:value="listQuery.key"
/>
</div>
<!-- 搜索按钮 -->
<a-button class="filter-item" type="primary" @click="getCaseList" size="mini">
查询
</a-button>
<a-button class="filter-item" @click="resetListQuery" size="mini"> 重置 </a-button>
<a-button class="filter-item" type="success" @click="exportExcelList" size="mini">
导出
</a-button>
</template>
<template #bodyCell="{ column, record }">
<!-- 地点特殊处理 -->
<template v-if="column.key === 'address'">
<span>{{ record.streetname }}</span>
<span>{{ record.streetname }}</span>
<span>{{ record.communityname }}</span>
</template>
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '详情',
onClick: () => {
openDetailModal(record);
},
},
]"
/>
</template>
</template>
</BasicTable>
<DetailModal
@register="registerModal"
@close-modal="closeModal"
:caseDetailId="caseDetailId"
:isShowMap="true"
width="80%"
/>
</PageWrapper>
</template>
<script lang="ts" setup>
// vue
import { ref, reactive, onMounted } from 'vue';
// vben
import { PageWrapper } from '@/components/Page';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { TreeItem } from '@/components/Tree';
import { useModal } from '@/components/Modal';
import dayjs, { Dayjs } from 'dayjs';
//
import DetailModal from '@/views/demo/query/detailModal.vue';
// api
import {
fun_LoadDataBaseInfo,
fun_LoadList,
fun_load,
fun_OrgList,
fun_ExportCaseInfoList,
} from '@/api/demo/query';
// ts
import { tableColums, searchFormSchema } from './columns.data';
//
type RangeValue = [Dayjs, Dayjs];
const startEndTime = ref<RangeValue>();
// -
const rangePresets = ref([
{ label: '今天', value: [dayjs(), dayjs()] },
{ label: '最近三天', value: [dayjs().add(-3, 'd'), dayjs()] },
{ label: '最近一周', value: [dayjs().add(-7, 'd'), dayjs()] },
{ label: '最近两周', value: [dayjs().add(-14, 'd'), dayjs()] },
{ label: '最近一个月', value: [dayjs().add(-30, 'd'), dayjs()] },
{ label: '最近三个月', value: [dayjs().add(-90, 'd'), dayjs()] },
{ label: '最近半年', value: [dayjs().add(-180, 'd'), dayjs()] },
{ label: '最近一年', value: [dayjs().add(-365, 'd'), dayjs()] },
]);
//
const searchInfo = reactive<Recordable>({});
//
const BASE_API = process.env.VUE_APP_BASE;
//
let listQuery = ref({
typeid: null,
org: null,
is_illegal: null,
case_no: null,
key: undefined,
deal_username: null,
verifyuser: null,
report_start_time: null,
report_end_time: null,
countyid: null,
streetid: null,
communityid: null,
});
//
let illegalOptions = [
{ id: 0, name: '合法' },
{ id: 1, name: '违法' },
{ id: 2, name: '伪变化' },
];
//
const caseTypeOptions: any = ref([]);
//
const OrgList = ref<TreeItem[]>([]);
//
const [registerModal, { openModal }] = useModal();
//
const [registerTable, { reload, clearSelectedRowKeys }] = useTable({
api: fun_LoadDataBaseInfo,
columns: tableColums,
rowKey: 'id',
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
striped: false,
useSearchForm: false,
showTableSetting: false,
bordered: true,
//
showIndexColumn: true,
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
},
beforeFetch: (data) => {
//
var temp = {
page: data.page,
rows: data.limit,
value: data.value,
handle_status_id: 2, //
};
return temp;
},
handleSearchInfoFn(info) {
return info;
},
});
// -
function handleChange(itemIdArr) {
if (itemIdArr.length === 0) {
listQuery.value.countyid = null;
listQuery.value.streetid = null;
listQuery.value.communityid = null;
}
if (itemIdArr.length === 1) {
listQuery.value.countyid = itemIdArr[0];
listQuery.value.streetid = null;
listQuery.value.communityid = null;
} else if (itemIdArr.length == 2) {
listQuery.value.countyid = null;
listQuery.value.streetid = itemIdArr[1];
listQuery.value.communityid = null;
} else if (itemIdArr.length == 3) {
listQuery.value.countyid = null;
listQuery.value.streetid = null;
listQuery.value.communityid = itemIdArr[2];
}
getCaseList();
}
//
async function getCaseList() {
//
if (startEndTime.value != null) {
listQuery.value.report_start_time = startEndTime.value[0].format('YYYY-MM-DD');
listQuery.value.report_end_time = startEndTime.value[1].format('YYYY-MM-DD');
} else {
listQuery.value.report_start_time = null;
listQuery.value.report_end_time = null;
}
searchInfo.value = listQuery.value;
clearSelectedRowKeys();
reload();
}
//
function resetListQuery() {
startEndTime.value = null;
//
listQuery.value = {
typeid: null,
org: null,
is_illegal: null,
case_no: null,
key: undefined,
deal_username: null,
verifyuser: null,
report_start_time: null,
report_end_time: null,
countyid: null,
streetid: null,
communityid: null,
};
getCaseList();
}
//
async function exportExcelList() {
await fun_ExportCaseInfoList(listQuery.value).then((res) => {
console.log('导出', res);
if (res) {
window.location.href = BASE_API + '/' + res;
}
});
}
//
let caseDetailId = '';
function openDetailModal(record: Recordable) {
caseDetailId = record.id;
openModal(true, { record });
}
//
async function fetch() {
getCaseList();
// let data0 = await fun_LoadList({ typeid: 'SYS_NOBUILD_TYPE' });
// console.log(data0);
//
caseTypeOptions.value = await fun_load({ code: 'DRONE_CASE_TYPE' });
//
// let data2 = await fun_OrgList({ name: '' });
// // OrgList.value =
// console.log(data2);
}
onMounted(() => {
fetch();
});
</script>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,205 @@
<template>
<div class="w-full">
<MapboxMaps :mapOptions="mapOptions" :control="[]" @map-on-load="mapOnLoad" />
</div>
</template>
<script lang="ts" setup>
import rodeImg from '@/assets/images/icon_fly2.png';
import { ref, watch } from 'vue';
import MapboxMaps from '@/components/MapboxMaps/index.vue';
import { getDroneGeoJson } from '@/api/monitor/index';
const detailMap = ref();
const props = defineProps({
ruleForm: {
type: Object,
default: () => {
return {};
},
},
});
const geojson = ref();
const droneMarker = ref();
const mapBox = ref();
const mapOptions = {
center: [117.84714891969796, 35.22152309532066],
zoom: 10,
};
watch(
() => props.ruleForm,
(newVal, oldVal) => {
console.log(newVal);
loadCaseGeoJson();
detailMap.value.flyTo({
center: [newVal.lng, newVal.lat], //
zoom: 18, //
pitch: 0, //
});
loadDroneMarker(newVal.lng, newVal.lat);
},
);
const mapOnLoad = (map) => {
mapBox.value = map;
//
const testSource =
'http://123.132.248.154:9205/geoserver/gwc/service/tms/1.0.0/TEST_WORK_SPACE%3Alindi@EPSG:900913@pbf/{z}/{x}/{y}.pbf';
map.U.addVector('name', testSource);
map.U.addLineLayer('ffff', {
source: 'name',
'source-layer': 'lindi',
});
detailMap.value = map;
loadImageLayer();
loadStreetBorderLayer();
loadCaseGeoJson();
};
//
function loadImageLayer() {
detailMap.value.addLayer({
id: 'wms-test-layer',
type: 'raster',
source: {
type: 'raster',
tiles: [
'http://175.27.168.120:8080/geoserver/feixian/wms?service=WMS&version=1.1.0&request=GetMap&layers=feixian:yingxiang&styles=&bbox={bbox-epsg-3857}&width=256&height=256&srs=EPSG:3857&format=image/png&TRANSPARENT=TRUE',
],
tileSize: 256,
},
paint: {},
});
}
//
function loadStreetBorderLayer() {
detailMap.value.addLayer({
id: 'street-border',
type: 'raster',
source: {
type: 'raster',
tiles: [
'http://175.27.168.120:8080/geoserver/feixian/wms?service=WMS&version=1.1.0&request=GetMap&layers=feixian:zhenjie&styles=&bbox={bbox-epsg-3857}&width=256&height=256&srs=EPSG:3857&format=image/png&TRANSPARENT=TRUE',
],
tileSize: 256,
},
paint: {},
layout: {
visibility: 'visible',
},
});
detailMap.value.resize();
}
// GeoJSON
async function loadCaseGeoJson() {
const data = await getDroneGeoJson({ id: props.ruleForm.info.id });
console.log(data);
geojson.value = data;
if (geojson.value.features.length == 0) {
detailMap.value.addLayer({
id: 'points',
type: 'symbol',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [props.ruleForm.info.lng, props.ruleForm.info.lng],
},
properties: {
title: 'Mapbox DC',
icon: 'monument',
},
},
],
},
},
layout: {},
});
}
// There is already a source with ID "geojsonfill"
if (detailMap.value.getLayer('geojsonfill')) {
detailMap.value.removeLayer('geojsonfill');
detailMap.value.removeSource('geojsonfill');
}
if (detailMap.value.getLayer('geojsonline')) {
detailMap.value.removeLayer('geojsonline');
detailMap.value.removeSource('geojsonline');
}
detailMap.value.addLayer({
id: 'geojsonfill',
type: 'fill',
source: {
type: 'geojson',
data: geojson.value,
},
paint: {
'fill-color': '#FE9003',
'fill-opacity': 0.2,
'fill-outline-color': '#FE9003',
},
});
detailMap.value.addLayer({
id: 'geojsonline',
type: 'line',
source: {
type: 'geojson',
data: geojson.value,
},
layout: {
'line-join': 'round',
'line-cap': 'round',
},
paint: {
'line-color': '#FE9003',
'line-width': 4,
},
});
}
//
function loadDroneMarker(lng, lat) {
if (detailMap.value.getLayer('cat-on-building')) {
detailMap.value.removeLayer('cat-on-building');
detailMap.value.removeSource('cat-on-building');
detailMap.value.removeImage('cat');
}
detailMap.value.loadImage(rodeImg, (error, image) => {
detailMap.value.addImage('cat', image);
detailMap.value.addLayer({
id: 'cat-on-building',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [lng, lat],
},
},
],
},
},
slot: 'top',
type: 'symbol',
layout: {
'icon-image': 'cat',
'icon-size': 0.05,
'symbol-placement': 'point',
'symbol-z-elevate': true,
},
});
});
}
</script>
<style scoped lang="less">
.w-full {
height: 50vh;
}
</style>

View File

@ -0,0 +1,48 @@
import { BasicColumn, FormSchema } from '@/components/Table';
export const tableColums: BasicColumn[] = [
{
title: '案件编号',
dataIndex: 'case_no',
width: 120,
},
{
title: '上报时间',
dataIndex: 'createtime',
width: 120,
},
{
title: '地点',
dataIndex: 'address',
width: 120,
},
{
title: '案件描述',
dataIndex: 'case_description',
width: 120,
},
{
title: '处理时间',
dataIndex: 'deal_time',
width: 120,
},
{
title: '案件处理人',
dataIndex: 'deal_username',
width: 120,
},
{
title: '退回次数',
dataIndex: 'drawbackcount',
width: 80,
},
];
export const searchFormSchema: FormSchema[] = [
{
field: 'keyword',
label: '关键字',
component: 'Input',
colProps: { span: 8 },
},
];

View File

@ -0,0 +1,326 @@
<!-- eslint-disable vue/no-deprecated-v-on-native-modifier -->
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<BasicTable
class="w-4/4 xl:w-5/5"
@register="registerTable"
@fetch-success="onFetchSuccess"
:searchInfo="searchInfo"
>
<template #toolbar>
<!-- 日期选择框 -->
<div style="display: inline; margin-right: 10px; width: 200px">
<a-range-picker
v-model:value="startEndTime"
size="mini"
align="right"
:presets="rangePresets"
@change="getCaseList"
/>
</div>
<!-- 案件类型 -->
<div style="display: inline; margin-right: 10px; width: 200px">
<a-select
:options="caseTypeOptions"
v-model:value="listQuery.typeid"
placeholder="案件类型"
style="width: 200px"
:field-names="{ label: 'itemName', value: 'itemDetailId' }"
@change="getCaseList"
/>
</div>
<!-- 查询地区 -->
<div style="display: inline; margin-right: 10px; width: 100px">
<a-cascader
:options="OrgList"
v-model:value="listQuery.org"
placeholder="查询地区"
size="mini"
style="width: 100px"
@change="handleChange"
/>
</div>
<!-- 现场状况 -->
<div style="display: inline; margin-right: 10px; width: 100px">
<a-select
:options="illegalOptions"
v-model:value="listQuery.is_illegal"
placeholder="现场状况"
style="width: 100px"
:field-names="{ label: 'name', value: 'id' }"
@change="getCaseList"
/>
</div>
<!-- 案件编号 -->
<div style="display: inline; margin-right: 10px">
<a-input
@keyup.enter="getCaseList"
size="mini"
style="width: 120px"
class="filter-item"
:placeholder="'案件编号'"
v-model:value="listQuery.case_no"
/>
</div>
<!-- 处理人姓名 -->
<div style="display: inline; margin-right: 10px">
<a-input
@keyup.enter="getCaseList"
size="mini"
style="width: 120px"
class="filter-item"
:placeholder="'处理人姓名'"
v-model:value="listQuery.deal_username"
/>
</div>
<!-- 请输入关键字 -->
<div style="display: inline; margin-right: 10px">
<a-input
@keyup.enter="getCaseList"
size="mini"
style="width: 120px"
class="filter-item"
:placeholder="'请输入关键字'"
v-model:value="listQuery.key"
/>
</div>
<!-- 搜索按钮 -->
<a-button class="filter-item" type="primary" @click="getCaseList" size="mini">
查询
</a-button>
<a-button class="filter-item" @click="resetListQuery" size="mini"> 重置 </a-button>
<a-button class="filter-item" type="success" @click="exportExcelList" size="mini">
导出
</a-button>
</template>
<template #bodyCell="{ column, record }">
<!-- 地点特殊处理 -->
<template v-if="column.key === 'address'">
<span>{{ record.streetname }}</span>
<span>{{ record.streetname }}</span>
<span>{{ record.communityname }}</span>
</template>
<template v-if="column.key === 'drawbackcount'">
<span>{{ record.drawbackcount >= 1 ? record.drawbackcount : 1 }}</span>
</template>
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '详情',
onClick: () => {
openDetailModal(record);
},
},
]"
/>
</template>
</template>
</BasicTable>
<DetailModal
@register="registerModal"
@close-modal="closeModal"
:caseDetailId="caseDetailId"
:isShowMap="true"
width="80%"
/>
</PageWrapper>
</template>
<script lang="ts" setup>
// vue
import { ref, reactive, onMounted } from 'vue';
// vben
import { PageWrapper } from '@/components/Page';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { TreeItem } from '@/components/Tree';
import { useModal } from '@/components/Modal';
import dayjs, { Dayjs } from 'dayjs';
//
import DetailModal from '@/views/demo/query/detailModal.vue';
// api
import {
fun_LoadDataBaseInfo,
fun_LoadList,
fun_load,
fun_OrgList,
fun_ExportCaseInfoList,
} from '@/api/demo/query';
// ts
import { tableColums, searchFormSchema } from './columns.data';
//
type RangeValue = [Dayjs, Dayjs];
const startEndTime = ref<RangeValue>();
// -
const rangePresets = ref([
{ label: '今天', value: [dayjs(), dayjs()] },
{ label: '最近三天', value: [dayjs().add(-3, 'd'), dayjs()] },
{ label: '最近一周', value: [dayjs().add(-7, 'd'), dayjs()] },
{ label: '最近两周', value: [dayjs().add(-14, 'd'), dayjs()] },
{ label: '最近一个月', value: [dayjs().add(-30, 'd'), dayjs()] },
{ label: '最近三个月', value: [dayjs().add(-90, 'd'), dayjs()] },
{ label: '最近半年', value: [dayjs().add(-180, 'd'), dayjs()] },
{ label: '最近一年', value: [dayjs().add(-365, 'd'), dayjs()] },
]);
//
const searchInfo = reactive<Recordable>({});
//
const BASE_API = process.env.VUE_APP_BASE;
//
let listQuery = ref({
typeid: null,
org: null,
is_illegal: null,
case_no: null,
key: undefined,
deal_username: null,
report_start_time: null,
report_end_time: null,
countyid: null,
streetid: null,
communityid: null,
is_drawback: 1,
});
//
let illegalOptions = [
{ id: 0, name: '合法' },
{ id: 1, name: '违法' },
{ id: 2, name: '伪变化' },
];
//
const caseTypeOptions: any = ref([]);
//
const OrgList = ref<TreeItem[]>([]);
//
const [registerModal, { openModal }] = useModal();
//
const [registerTable, { reload, clearSelectedRowKeys }] = useTable({
api: fun_LoadDataBaseInfo,
columns: tableColums,
rowKey: 'id',
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
striped: false,
useSearchForm: false,
showTableSetting: false,
bordered: true,
//
showIndexColumn: true,
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
},
beforeFetch: (data) => {
//
var temp = {
page: data.page,
rows: data.limit,
value: data.value,
is_drawback: 1, //退
};
return temp;
},
handleSearchInfoFn(info) {
return info;
},
});
// -
function handleChange(itemIdArr) {
if (itemIdArr.length === 0) {
listQuery.value.countyid = null;
listQuery.value.streetid = null;
listQuery.value.communityid = null;
}
if (itemIdArr.length === 1) {
listQuery.value.countyid = itemIdArr[0];
listQuery.value.streetid = null;
listQuery.value.communityid = null;
} else if (itemIdArr.length == 2) {
listQuery.value.countyid = null;
listQuery.value.streetid = itemIdArr[1];
listQuery.value.communityid = null;
} else if (itemIdArr.length == 3) {
listQuery.value.countyid = null;
listQuery.value.streetid = null;
listQuery.value.communityid = itemIdArr[2];
}
getCaseList();
}
//
async function getCaseList() {
//
if (startEndTime.value != null) {
listQuery.value.report_start_time = startEndTime.value[0].format('YYYY-MM-DD');
listQuery.value.report_end_time = startEndTime.value[1].format('YYYY-MM-DD');
} else {
listQuery.value.report_start_time = null;
listQuery.value.report_end_time = null;
}
searchInfo.value = listQuery.value;
clearSelectedRowKeys();
reload();
}
//
function resetListQuery() {
startEndTime.value = null;
//
listQuery.value = {
typeid: null,
org: null,
is_illegal: null,
case_no: null,
key: undefined,
deal_username: null,
report_start_time: null,
report_end_time: null,
countyid: null,
streetid: null,
communityid: null,
is_drawback: 1,
};
getCaseList();
}
//
async function exportExcelList() {
await fun_ExportCaseInfoList(listQuery.value).then((res) => {
console.log('导出', res);
if (res.code === 200) {
window.location.href = BASE_API + '/' + res.result;
}
});
}
//
let caseDetailId = '';
function openDetailModal(record: Recordable) {
caseDetailId = record.id;
openModal(true, { record });
}
//
async function fetch() {
getCaseList();
// let data0 = await fun_LoadList({ typeid: 'SYS_NOBUILD_TYPE' });
//
caseTypeOptions.value = await fun_load({ code: 'DRONE_CASE_TYPE' });
//
// let data2 = await fun_OrgList({ name: '' });
// // OrgList.value =
// console.log(data2);
}
onMounted(() => {
fetch();
});
</script>

View File

@ -168,6 +168,10 @@
},
beforeFetch: (data) => {
let temp = {
is_intact: 1,
is_dealer: 1,
is_verification: 0,
handle_status_id: 2,
page: data.page,
limit: data.limit,
is_illegal: is_illegal.value,
@ -323,7 +327,7 @@
&-mapbox {
width: calc(30% - 20px);
margin: 0 15px 15px 15px;
border: 1px solid red;
border: 1px solid #eee;
}
}
}

View File

@ -3,14 +3,16 @@
<BasicTree ref="asyncExpandTreeRef" title="部门列表" toolbar search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto" loadData :actionList="actionList"
:renderIcon="createIcon" :clickRowToExpand="false" :treeData="treeData" :fieldNames="{ key: 'id', title: 'name' }"
:defaultExpandAll="true" @select="handleSelect" />
@select="handleSelect" :load-data="onLoadData"/>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref , nextTick, unref} from 'vue';
import { BasicTree, TreeItem ,TreeActionType} from '@/components/Tree';
import { getDeptList } from '@/api/demo/system';
import { getDeptList, getChildrenTree } from '@/api/demo/system';
import { isArray } from '@/utils/is';
import { uniq } from 'lodash-es';
defineOptions({ name: 'DeptTree' });
@ -21,9 +23,9 @@
async function fetch() {
treeData.value = (await getDeptList()) as unknown as TreeItem[];
//
//
nextTick(() => {
unref(asyncExpandTreeRef)?.expandAll(true);
unref(asyncExpandTreeRef)?.filterByLevel(1);
});
}
@ -37,4 +39,30 @@
defineExpose({
fetch
})
function onLoadData(treeNode) {
return new Promise((resolve: (value?: unknown) => void) => {
if (isArray(treeNode.children) && treeNode.children.length > 0) {
resolve();
return;
}
console.log(treeNode)
getChildrenTree({parentId: treeNode.id}).then(res => {
const asyncTreeAction: TreeActionType | null = unref(asyncExpandTreeRef);
console.log(res)
if (asyncTreeAction) {
const nodeChildren = res
asyncTreeAction.updateNodeByKey(treeNode.eventKey, { children: nodeChildren });
asyncTreeAction.setExpandedKeys(
uniq([treeNode.eventKey, ...asyncTreeAction.getExpandedKeys()]),
);
}
resolve();
return;
}).catch(err => {
console.log(err)
resolve();
return;
})
});
}
</script>

View File

@ -0,0 +1,272 @@
<template>
<div style="padding: 24px; overflow-y: hidden">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="zhifa" tab="执法端APP">
<div class="flex-column">
<a-row style="overflow-y: hidden">
<a-col :span="12" style="padding: 20px; border: 1px silver solid; margin-left: 10px">
<a-form
ref="form"
:model="form"
labelAlign="right"
label-width="80px"
:label-col="labelCol"
:wrapper-col="wrapperCol"
size="mini"
>
<a-form-item label="当前版本">
<span style="font-size: 15px; font-weight: bold; color: #000">
<a-input v-model:value="currentAppInfo.edition" disabled="true" />
</span>
</a-form-item>
<a-form-item label="版本号">
<a-input v-model:value="form.edition" />
</a-form-item>
<a-form-item label="项目名称">
<a-input v-model:value="form.project_name" />
</a-form-item>
<a-form-item label="上传">
<a-upload-dragger
v-model:fileList="fileList"
action="#"
name="file"
:maxCount="limit"
:multiple="false"
:previewFile="handlePreview"
:beforeUpload="beforeUpload"
:remove="handleRemove"
@change="handleChange"
@drop="handleDrop"
>
<Icon icon="ant-design:cloud-download-outlined" :size="16" color="blue" />
<p class="ant-upload-text">点击或拖拽文件至此处以上传</p>
</a-upload-dragger>
</a-form-item>
<a-form-item label="描述信息">
<a-input type="textarea" v-model:value="form.description" />
</a-form-item>
<a-form-item label="是否必须更新" label-width="120px">
<a-radio-group v-model:value="form.must_update" size="medium">
<a-radio border :value="1"></a-radio>
<a-radio border :value="0"></a-radio>
</a-radio-group>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="onSubmit"></a-button>
</a-form-item>
</a-form>
</a-col>
</a-row>
</div>
</a-tab-pane>
<a-tab-pane key="feikong" tab="飞控端APP">
<div class="flex-column">
<a-row style="overflow-y: hidden">
<a-col :span="12" style="padding: 20px; border: 1px silver solid; margin-left: 10px">
<a-form
ref="form"
:model="flyControlForm"
labelAlign="right"
label-width="80px"
:label-col="labelCol"
:wrapper-col="wrapperCol"
size="mini"
>
<a-form-item label="当前版本">
<span style="font-size: 15px; font-weight: bold; color: #000">
<a-input disabled="true" />
</span>
</a-form-item>
<a-form-item label="版本号">
<a-input v-model:value="flyControlForm.edition" />
</a-form-item>
<a-form-item label="项目名称">
<a-input v-model:value="flyControlForm.project_name" />
</a-form-item>
<a-form-item label="描述信息">
<a-input type="textarea" v-model:value="flyControlForm.description" />
</a-form-item>
<a-form-item label="是否必须更新" label-width="120px">
<a-radio-group v-model:value="flyControlForm.must_update" size="medium">
<a-radio border :value="1"></a-radio>
<a-radio border :value="0"></a-radio>
</a-radio-group>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="onFlyControlSubmit"></a-button>
</a-form-item>
</a-form>
</a-col>
</a-row>
</div>
</a-tab-pane>
</a-tabs>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { useMessage } from '@/hooks/web/useMessage';
import { Icon } from '/@/components/Icon';
// api
import { fun_GetUpdateFiles, fun_Upload, fun_AddAppFiles } from '@/api/demo/version';
//
import { uploadApi } from '@/api/sys/upload';
const { createMessage } = useMessage();
//
const labelCol = { span: 4 };
const wrapperCol = { span: 20 };
let currentAppInfo = {};
let activeKey = ref('zhifa');
let limit = 1;
let fileList = ref([]);
let form = {
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
};
let flyControlForm = {
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
};
async function getAppInfo() {
fun_GetUpdateFiles({ project: 'drone_enforcement' }).then((res) => {
if (res) {
currentAppInfo = res;
form.project_name = res.project_name;
}
});
}
//
function handlePreview() {}
//
function handleRemove(file, filelist) {
fileList.value = filelist;
}
//
function handleSuccess(res, file, filelist) {
createMessage.success('文件上传成功');
}
//
function handleError() {
createMessage.error('文件上传失败');
}
//
function handleExceed() {
createMessage.warn(`只能选择 ${limit} 个文件进行上传!!`);
}
//
function handleChange(file, filelist) {
form.name = file.name.split('.')[0];
if (file) {
fileList.value = filelist;
}
}
//
function beforeUpload(file) {
let extension = file.name.substring(file.name.lastIndexOf('.') + 1);
let size = file.size / 1024 / 1024;
if (extension !== 'apk') {
createMessage.warn('只能上传后缀是.apk的文件');
return false;
}
if (size > 100) {
createMessage.warn('文件大小不得超过100M');
return false;
}
return true;
}
function onSubmit() {
let formData = new FormData();
fileList.value.forEach((item) => {
formData.append('files', item.raw);
});
if (fileList.value.length === 0) {
createMessage.warn(`请选择上传文件!!`);
return;
}
fun_Upload(formData).then((res) => {
if (res) {
form.filepath = res[0].filePath;
fun_AddAppFiles(form).then((res2) => {
if (res2) {
createMessage.warn(`上传成功`);
form = {
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
};
fileList.value = [];
} else {
createMessage.warn(`接口错误!!`);
}
});
} else {
createMessage.warning(`接口错误!!`);
}
});
}
function onFlyControlSubmit() {
let formData = new FormData();
fileList.value.forEach((item) => {
formData.append('files', item.raw);
});
if (fileList.value.length === 0) {
createMessage.warn(`请选择上传文件!!`);
return;
}
fun_Upload(formData).then((res) => {
if (res) {
flyControlForm.filepath = res[0].filePath;
fun_AddAppFiles(flyControlForm).then((res2) => {
if (res2) {
createMessage.warn(`上传成功`);
flyControlForm = {
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
};
fileList.value = [];
} else {
createMessage.warn(`接口错误!!`);
}
});
} else {
createMessage.warn(`接口错误!!`);
}
});
}
async function fetch() {
getAppInfo();
}
onMounted(() => {
fetch();
});
</script>
<style scoped>
/deep/.el-upload-dragger {
height: 100px;
line-height: 20px;
}
/deep/ .el-icon-upload {
}
/deep/.el-upload__text {
}
</style>

View File

@ -0,0 +1,278 @@
<template>
<div style="padding: 24px; overflow-y: hidden">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="执法端APP" name="zhifa">
<div class="flex-column">
<el-row style="overflow-y: hidden">
<el-col :span="12" style="padding: 20px; border: 1px silver solid; margin-left: 10px">
<el-form ref="form" :model="form" label-width="80px" size="mini">
<el-form-item label="当前版本">
<span style="font-size: 15px; font-weight: bold; color: #000">{{
currentAppInfo.edition
}}</span>
</el-form-item>
<el-form-item label="版本号">
<el-input v-model="form.edition"></el-input>
</el-form-item>
<el-form-item label="项目名称">
<el-input v-model="form.project_name"></el-input>
</el-form-item>
<el-form-item size="mini">
<el-upload
size="mini"
class="upload-demo"
action="#"
drag
:limit="limit"
:on-preview="handlePreview"
:file-list="fileList"
:auto-upload="false"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:on-change="handleChange"
:on-success="handleSuccess"
:on-error="handleError"
>
<i class="el-icon-upload" style="font-size: 60px; line-height: 0px"></i>
<div class="el-upload__text">将APP文件拖到此处<em>点击上传</em></div>
</el-upload>
</el-form-item>
<el-form-item label="描述信息">
<el-input type="textarea" v-model="form.description"></el-input>
</el-form-item>
<el-form-item label="是否必须更新" label-width="120px">
<el-radio-group v-model="form.must_update" size="medium">
<el-radio border :label="1"></el-radio>
<el-radio border :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit"></el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane label="飞控端APP" name="feikong">
<div class="flex-column">
<el-row style="overflow-y: hidden; padding-bottom: 50px">
<el-col :span="12" style="padding: 20px; border: 1px silver solid; margin-left: 10px">
<el-form ref="form" :model="flyControlForm" label-width="80px" size="mini">
<el-form-item label="当前版本">
<span style="font-size: 15px; font-weight: bold; color: #000"></span>
</el-form-item>
<el-form-item label="版本号">
<el-input v-model="flyControlForm.edition"></el-input>
</el-form-item>
<el-form-item label="项目名称">
<el-input v-model="flyControlForm.project_name"></el-input>
</el-form-item>
<el-form-item>
<el-upload
class="upload-demo"
action="#"
drag
:limit="limit"
:on-preview="handlePreview"
:file-list="fileList"
:auto-upload="false"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:on-change="handleChange"
:on-success="handleSuccess"
:on-error="handleError"
>
<i class="el-icon-upload" style="font-size: 60px; line-height: 0px"></i>
<div class="el-upload__text">将APP文件拖到此处<em>点击上传</em></div>
</el-upload>
</el-form-item>
<el-form-item label="描述信息">
<el-input type="textarea" v-model="flyControlForm.description"></el-input>
</el-form-item>
<el-form-item label="是否必须更新" label-width="120px">
<el-radio-group v-model="flyControlForm.must_update" size="medium">
<el-radio border :label="1"></el-radio>
<el-radio border :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onFlyControlSubmit"></el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { postMethodCommon, getMethodCommon } from '../../api/common';
export default {
name: 'version',
data() {
return {
currentAppInfo: {},
activeName: 'zhifa',
limit: 1,
fileList: [],
form: {
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
},
flyControlForm: {
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
},
};
},
mounted() {
this.getAppInfo();
},
methods: {
getAppInfo() {
getMethodCommon('/TaxProductEquipment/GetUpdateFiles', {
project: 'drone_enforcement',
}).then((res) => {
if (res.code == 200) {
this.currentAppInfo = res.result;
this.form.project_name = res.result.project_name;
}
});
},
//
handlePreview(file) {},
//
handleRemove(file, fileList) {
this.fileList = fileList;
},
//
handleSuccess(res, file, fileList) {
this.$message.success('文件上传成功');
},
//
handleExceed(files, fileList) {
this.$message.warning(`只能选择 ${this.limit} 个文件进行上传!!`);
},
//
handleChange(file, fileList) {
this.form.name = file.name.split('.')[0];
if (file) {
this.fileList = fileList;
}
},
//
handleError(err, file, fileList) {
this.$message.error('文件上传失败');
},
beforeUpload(file) {
let extension = file.name.substring(file.name.lastIndexOf('.') + 1);
let size = file.size / 1024 / 1024;
if (extension !== 'apk') {
this.$message.warning('只能上传后缀是.apk的文件');
return false;
}
if (size > 100) {
this.$message.warning('文件大小不得超过100M');
return false;
}
return true;
},
onSubmit() {
let _this = this;
let formData = new FormData();
this.fileList.forEach((item) => {
formData.append('files', item.raw);
});
if (this.fileList.length === 0) {
this.$message.warning(`请选择上传文件!!`);
return;
}
let url = `/Files/Upload`;
postMethodCommon(url, formData).then((res) => {
if (res.code === 200) {
_this.form.filepath = res.result[0].filePath;
postMethodCommon('/TaxProductEquipment/AddAppFiles', _this.form).then((res2) => {
if (res2.code === 200) {
_this.$message.warning(`上传成功`);
_this.form = {
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
};
_this.fileList = [];
} else {
_this.$message.warning(`接口错误!!`);
}
});
} else {
_this.$message.warning(`接口错误!!`);
}
});
},
onFlyControlSubmit() {
let _this = this;
let formData = new FormData();
this.fileList.forEach((item) => {
formData.append('files', item.raw);
});
if (this.fileList.length === 0) {
this.$message.warning(`请选择上传文件!!`);
return;
}
let url = `/Files/Upload`;
postMethodCommon(url, formData).then((res) => {
if (res.code === 200) {
_this.flyControlForm.filepath = res.result[0].filePath;
postMethodCommon('/TaxProductEquipment/AddAppFiles', _this.flyControlForm).then(
(res2) => {
if (res2.code === 200) {
_this.$message.warning(`上传成功`);
_this.flyControlForm = {
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
};
_this.fileList = [];
} else {
_this.$message.warning(`接口错误!!`);
}
},
);
} else {
_this.$message.warning(`接口错误!!`);
}
});
},
},
};
</script>
<style scoped>
/deep/.el-upload-dragger {
height: 100px;
line-height: 20px;
}
/deep/ .el-icon-upload {
}
/deep/.el-upload__text {
}
</style>